|
AT91RM9200 после разрешения прерываний улетает на непонятные адреса, Под IAR + SAM-ICE-JTAG всё работает... |
|
|
|
Apr 12 2007, 10:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Paramedic @ Apr 11 2007, 15:31)  Место слёта определил: после инициализации таймера и разрешения всех прерываний. Был в похожей ситуации. Вкратце так: загрузчик настраивает контроллер прерываний по-своему, отрабатывает, передает управление основной программе. Основная программа, надеясь на настройки контроллера прерываний по умолчанию прописывает только свои значения и разрешает прерывания. Срабатывает какое-то из непереназначенных прерываний загрузчика и программа улетает в несуществующий обработчик. Здесь может быть что-то похожее? При старте ядро успевает выполнить несколько инструкций из флеша до того, как управление перехватит JTAG и остановит его. За это время старый код вполне мог успеть проинициализировать контроллер прерываний. Может поэтому под отладчиком и работает?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 17 2007, 14:31
|
Частый гость
 
Группа: Свой
Сообщений: 181
Регистрация: 15-01-07
Пользователь №: 24 436

|
Цитата(sergeeff @ Apr 12 2007, 10:55)  Да дело не в этих процедурах. Скорее всего в startup модуле прописана таблица прерываний в короткой форме, т.е. в виде branch instruction. Но это позволяет адресоваться в пределах 32 Mb.
Надо просто создать эту таблицу в виде load PC instruction:
Vector_Init_Block LDR pc, Reset_Addr LDR pc, Undefined_Addr LDR pc, SVC_Addr LDR pc, Prefetch_Addr LDR pc, Abort_Addr NOP ;Reserved vector LDR pc, IRQ_Addr LDR pc, FIQ_Addr
Reset_Addr DCD Start_Boot Undefined_Addr DCD Undefined_Handler SVC_Addr DCD SVC_Handler Prefetch_Addr DCD Prefetch_Handler Abort_Addr DCD Abort_Handler DCD 0 ;Reserved vector IRQ_Addr DCD IRQ_Handler FIQ_Addr DCD FIQ_Handler
Про это хорошо написано в RealView Compilation Tools Developer Guide (ARM DUI 0203G) на сайте ARM'a. Сделал всё по Вашей рекомендации и согласно документу - не помогло. Цитата(Сергей Борщ @ Apr 12 2007, 11:22)  Был в похожей ситуации. Вкратце так: загрузчик настраивает контроллер прерываний по-своему, отрабатывает, передает управление основной программе. Основная программа, надеясь на настройки контроллера прерываний по умолчанию прописывает только свои значения и разрешает прерывания. Срабатывает какое-то из непереназначенных прерываний загрузчика и программа улетает в несуществующий обработчик. Здесь может быть что-то похожее? При старте ядро успевает выполнить несколько инструкций из флеша до того, как управление перехватит JTAG и остановит его. За это время старый код вполне мог успеть проинициализировать контроллер прерываний. Может поэтому под отладчиком и работает? При выходе из-загрузчика там запрещаются все прерывания, а при входе в основную программу вектора переназначаются... Вообще, попробовал написать простейший проект с мигающим светодиодом - даже с ним сложности возникли - нестабильно стартует и всё. Под дебагером работает устойчиво. Может в загрузчике где-то проблема. Не понятно в какую сторону копать...
|
|
|
|
|
Apr 17 2007, 15:57
|
Частый гость
 
Группа: Свой
Сообщений: 181
Регистрация: 15-01-07
Пользователь №: 24 436

|
Цитата(amw @ Apr 17 2007, 16:31)  Возможно в этих двух случаях разны карты памяти. Смотреть код и даташит на предмет REMAP. Remap делаю, да и под отладчиком-то всё работает. А кто-нибудь вообще атмеловкий RomBoot использовал? Не было проблем?
|
|
|
|
|
Apr 17 2007, 16:07
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Цитата(Paramedic @ Apr 17 2007, 15:57)  Remap делаю, да и под отладчиком-то всё работает.
А кто-нибудь вообще атмеловкий RomBoot использовал? Не было проблем? Кроме самого remap нужно еще убедится, что смещения в командах Exception vectors правильны. Возможно это поможет http://electronix.ru/forum/index.php?showtopic=25634
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Apr 17 2007, 16:08
|
Частый гость
 
Группа: Свой
Сообщений: 181
Регистрация: 15-01-07
Пользователь №: 24 436

|
Цитата(sergeeff @ Apr 17 2007, 17:05)  Можно до разрешения прерываний распечатать таблицу прерываний с адреса 0х000000000 и посмотреть, что-же там реально прописано. Делал. В сбойном и не сбойном случае одно и тоже. Даже CRC кода считал - тоже не меняется...
|
|
|
|
|
Apr 17 2007, 16:13
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Цитата(Paramedic @ Apr 17 2007, 16:08)  Делал. В сбойном и не сбойном случае одно и тоже. Даже CRC кода считал - тоже не меняется... А таблица ссылается на правильные адреса обработчиков?
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Apr 18 2007, 07:40
|
Частый гость
 
Группа: Свой
Сообщений: 181
Регистрация: 15-01-07
Пользователь №: 24 436

|
Цитата(amw @ Apr 17 2007, 17:13)  А таблица ссылается на правильные адреса обработчиков? Да, тем более иногда-то запускается...
|
|
|
|
|
Apr 18 2007, 13:10
|
Частый гость
 
Группа: Свой
Сообщений: 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".
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|