реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> AT91RM9200 после разрешения прерываний улетает на непонятные адреса, Под IAR + SAM-ICE-JTAG всё работает...
Paramedic
сообщение Apr 18 2007, 13:10
Сообщение #16


Частый гость
**

Группа: Свой
Сообщений: 181
Регистрация: 15-01-07
Пользователь №: 24 436



Всем большое спасибо за советы, вроде решил проблему.
Закоментировал участок стартапа загрузчика:
/*----------------------------------------
Read/modify/write CP15 control register
----------------------------------------*/
mrc p15, 0, r0, c1, c0,0 /* read cp15 control registre (cp15 r1) in r0 */
ldr r3,= 0xC0000080 /* Reset bit :Little Endian end fast bus mode */
ldr r4,= 0xC0001000 /* Set bit :Asynchronous clock mode, Not Fast Bus, I-Cache enable */
bic r0, r0, r3
orr r0, r0, r4
mcr p15, 0, r0, c1, c0,0 /* write r0 in cp15 control registre (cp15 r1) */

то есть похоже что кэш инструкций мешал при переходе от бутлоадера к основной программе.

И ещё в библиотеке lib_AT91RM9200.h вроде ошибка (помечена /*!!!!!!!!!!!!!!!!!!*/):

inline void AT91F_AIC_Open(
AT91PS_AIC pAic, // \arg pointer to the AIC registers
void (*IrqHandler) (), // \arg Default IRQ vector exception
void (*FiqHandler) (), // \arg Default FIQ vector exception
void (*DefaultHandler) (), // \arg Default Handler set in ISR
void (*SpuriousHandler) (), // \arg Default Spurious Handler
unsigned int protectMode) // \arg Debug Control Register
{
int i;

// Disable all interrupts and set IVR to the default handler
for (i = 0; i < 32; ++i) {
AT91F_AIC_DisableIt(pAic, i);
AT91F_AIC_ConfigureIt(pAic, i, AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, DefaultHandler);
}

// Set the IRQ exception vector
AT91F_AIC_SetExceptionVector((unsigned int *) 0x18/*!!!!!!!!!!!!!!!!!!*/, IrqHandler);
// Set the Fast Interrupt exception vector
AT91F_AIC_SetExceptionVector((unsigned int *) 0x1C/*!!!!!!!!!!!!!!!!!!*/, FiqHandler);

pAic->AIC_SPU = (unsigned int) SpuriousHandler;
pAic->AIC_DCR = protectMode;
}

inline unsigned int AT91F_AIC_SetExceptionVector (
unsigned int *pVector, // \arg pointer to the AIC registers
void (*Handler) () ) // \arg Interrupt Handler
{
unsigned int oldVector = *pVector;

if ((unsigned int) Handler == (unsigned int) AT91C_AIC_BRANCH_OPCODE)
*pVector = (unsigned int) AT91C_AIC_BRANCH_OPCODE;
else
*pVector = (((((unsigned int) Handler) - ((unsigned int) pVector) - 0x8) >> 2) & 0x00FFFFFF) | 0xEA000000;

return oldVector;
}

0x18 и 0x1C никак не "pointer to the AIC registers".
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Apr 18 2007, 18:48
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Ну добрались таки до самого интересного. Стандартная функция AT91F_AIC_SetExceptionVector прописывает правильный handler обработчика прерывания только!!! для "короткой" таблицы прерываний. В твоем случае должна использоваться "длинная" таблица, т.к. вектора прерываний лежат с адреса 0х00000000, а программа твоя стартует из SDRAM с адресов 0х20000000. Поэтому я написал для этого варианта функцию:

void SetExceptionVector(unsigned int *IrqVec, void (*Handler)(void))
{
DWORD *pbHandler;

switch ((int)IrqVec)
{
case 0x0C:
case 0x10:
case 0x04:
pbHandler = (DWORD *)(0x20 + (int)IrqVec);
*pbHandler = (DWORD)Handler;
break;
default:
break;
}
}
Ну и надо самому нормально инициализиривать AIC и не пользоваться стандартной AT91F_AIC_Open.

А насчет i-cache - это, похоже, вторичный эффект.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th August 2025 - 02:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016