Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SAM7SE застревает прерывание
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
KITA
AT91SAM7SE512. На SYS_IRQ (ID=2) висит обработчик. Всё работает долго и успешно, но в какой-то момент обработчик перестаёт вызываться. При этом, AIC_IPR=2 , AIC_IMR=2 , AIC_DCR.GMSK=0 , CPSR.I=0 , CPSR.MODE без изменений. А обработчик не вызывается. Вот как такое может быть?! Подскажите, люди добрые!
DmitryM
Цитата(KITA @ May 27 2013, 20:51) *
AT91SAM7SE512. На SYS_IRQ (ID=2) висит обработчик. Всё работает долго и успешно, но в какой-то момент обработчик перестаёт вызываться. При этом, AIC_IPR=2 , AIC_IMR=2 , AIC_DCR.GMSK=0 , CPSR.I=0 , CPSR.MODE без изменений. А обработчик не вызывается. Вот как такое может быть?! Подскажите, люди добрые!

Что в AIC.SVR[1]? Может просто в периферии запретили прерывания?
KITA
В AIC_SVR[1] адрес моего обработчика. Дык в периферии уже вроде поздняк запрещать, если он уже в AIC_IPR попал...
DmitryM
Цитата(KITA @ May 27 2013, 21:18) *
В AIC_SVR[1] адрес моего обработчика. Дык в периферии уже вроде поздняк запрещать, если он уже в AIC_IPR попал...

а FIQ используется?
KITA
Нет, FIQ не используется.
DmitryM
Цитата(KITA @ May 27 2013, 21:29) *
Нет, FIQ не используется.

Приведите обработчик прерывания. Что висит на SYS_IRQ? Учитываете, что SYS_IRQ несколько источников?
aaarrr
Проверьте, нет ли вероятности выхода из какого-либо прерывания без записи AIC_EOICR.
KITA
Цитата(DmitryM @ May 27 2013, 21:37) *
Приведите обработчик прерывания. Что висит на SYS_IRQ? Учитываете, что SYS_IRQ несколько источников?

CODE
__nested __irq __arm void IRQ_Handler(void){
static char ADC_Av=0;
static int ADC_Acc=0;
unsigned int SavI=__get_CPSR();
__set_CPSR((SavI&(~I_BIT)));

//*********** DBGU BEGIN *****************
__no_init static unsigned char RX_D_Buf[RX_D_BUF_LEN]; // Áóôåð ïðèåìà èç RS232
static unsigned short int RX_D_Buf_Head; // Óêàçàòåëè â áóôåðå ïðèåìà èç RS232
unsigned int Status;
static unsigned char Ready=0,PrevByte=0;
unsigned char Tmp;

Status=*AT91C_DBGU_CSR; // Ñ÷èòûâàåì èñòî÷íèê ïðåðûâàíèÿ

if ( Status & AT91C_US_RXRDY ){ // Åñëè áûë ïðèíÿò áàéò
Tmp=*AT91C_DBGU_RHR;
if(Ready) RX_D_Buf[RX_D_Buf_Head++]=Tmp; // Åñëè áûëà ïîéìàíà ñèíõðà, ïåðåïèñûâàåì áàéò â áóôåð
if(RX_D_Buf_Head>=RX_D_BUF_LEN){ // Åñëè áóôåð íàïîëíèëñÿ, ïåðåâàëèâàåì åãî â ñòðóêòóðó
Bat_Data=*((struct Bat_Struct*)RX_D_Buf);
Ready=0; BuiltInBattary_Connected=1; }
if(PrevByte==0xFA && Tmp==0xF0){ RX_D_Buf_Head=0; Ready=1; } //Èùåì ñèíõðó
PrevByte=Tmp;
*AT91C_DBGU_CR = AT91C_US_RSTSTA; // Î÷èùàåì ôëàãè îøèáîê
}


//*********** DBGU END *****************

//*********** PIT BEGIN *****************
if(((*AT91C_PITC_PISR)&(AT91C_PITC_PITS))){
if((*AT91C_ADC_SR&(1<<4))){ //Åñëè ÀÖÏ ñîçðåëî
if(ADC_Av++<10) ADC_Acc+=*AT91C_ADC_LCDR; else //Êîïèì
{ Batt_Volt=(ADC_Acc*275)/10240; // (25/10)/10240*N*11 //Íàêîïèëîñü - âû÷èñëÿåì íàïðÿæåíèå
ADC_Acc=0; ADC_Av=0;
if(!CritSect){
if(!BuiltInBattary_Connected && Batt_Volt<=Batt_Threshold_Off){ LowBat(); TurnOff(); }
/* if(BuiltInBattary_Connected && ( Bat_Data.UBat[0]<Batt_Threshold_Off_Li ||
Bat_Data.UBat[1]<Batt_Threshold_Off_Li || Bat_Data.UBat[2]<Batt_Threshold_Off_Li) ){ LowBat(); TurnOff(); }
*/
}
}
*AT91C_ADC_CR=AT91C_ADC_START; }


unsigned char *KeyPressU,KeyNum;
static unsigned char KPR,KeyPress[KEY_ROW*KEY_COL],BeepCount=1;
unsigned short int BinRow,Key_St;

if(BeepCount){ BeepCount--; if(!BeepCount) NoSound(); }

// Åñëè íè ïðè ïîñëåäíåì ïðîõîäå íè ñåé÷àñ íè îäíà êíîïêà íå íàæàòà - íå÷åãî ñêàíèðîâàòü
if(KPR==0 && (KEY_DATA_PIN&(KEY_MSK_COL<<KEY_D0))==(KEY_MSK_COL<<KEY_D0)){ KeyDown=0; goto SYS_EOI; } else KeyDown=1;

KeyPressU=KeyPress; KPR=0; BinRow=1; KeyNum=0;
KEY_DATA_INP=KEY_MSK_ROW<<(KEY_D0+KEY_COL); // Êîãäà ñêàíèðóåì, òîëüêî òåêóùàÿ íîãà íà âûõîä,
KEY_DATA_OUT=BinRow<<(KEY_D0+KEY_COL); // îñòàëüíûå íà âõîä è ïðèòÿíóòû ïîäòÿæêîé
for(char nop=0;nop<KEY_NOPS;nop++) asm("nop");// Çàäåðæêà, ÷òîáû ïðîøëî ÷åðåñ RC (RC, ÷òîáû íå ãàäèëî â ýôèð)

for(char x=0;x<KEY_ROW;x++){
for(char nop=0;nop<KEY_NOPS;nop++) asm("nop");// Çàäåðæêà, ÷òîáû ïðîøëî ÷åðåñ RC
Key_St=KEY_DATA_PIN>>KEY_D0; // Ñ÷èûâàåì ñòðî÷êó BinRow
KEY_DATA_INP=BinRow<<(KEY_D0+KEY_ROW); // Âêëþ÷àåì
BinRow<<=1; // ñëåäóþùóþ
KEY_DATA_OUT=BinRow<<(KEY_D0+KEY_ROW); // íîãó
for(char y=0;y<KEY_COL;y++,Key_St>>=1,KeyNum++) // Èùåì, â êàêîì ñòîëáöå íàæàòà êíîïêà
if((Key_St&1)) *(KeyPressU++)=0; else // Êíîïêà íå íàæàòà
{ char k=++*(KeyPressU); KPR=1; // Êíîïêà íàæàòà - ñ÷èòàåì ñêîëüêî âðåìåíè
if((k==2 || k==2+KEY_WAIT_REP) && KeyBufLen!=(KEY_LEN-1)){
KeyBuf[++KeyBufLen]=KeyNum; // Åñëè ïðîøëî ñîîòâ. âðåìÿ - çàïèñûâàåì êíîïêó â áóôåð
Sound(3000); BeepCount=5; }
if( k==1+KEY_WAIT_REP+KEY_REP )
*KeyPressU=1+KEY_WAIT_REP-1;
KeyPressU++; // Ïåðåõîäèì ê ñëåäóþùåé êíîïêå
}
}
// Ñòîëáöû íà âûõîä, ÷òîáû ðàçîì ìîæíî áûëî ïîñìîòðåòü, íå íàæàòî ëè ÷òî-íèáóäü
KEY_DATA_OUT=KEY_MSK_ROW<<(KEY_D0+KEY_COL);


SYS_EOI:

if(TimeMenuTimer) TimeMenuTimer--; else {
TimeMenuTimer=KEY_SEC; TimeMenu=0; }

WarmUpTimer++;
*AT91C_PITC_PIVR; }// else while(1);

__set_CPSR(SavI);

*AT91C_AIC_ICCR=1<<AT91C_ID_SYS;
*AT91C_AIC_EOICR=1; // Îòïðàâëÿåì ñèãíàë îêîí÷àíèÿ îáðàáîòêè ïðåðûâàíèÿ EOI
}

Извиняюсь за кракозябры вместо комментов, но почему то вот так скопировалось
aaarrr
Код
*AT91C_AIC_ICCR=1<<AT91C_ID_SYS;

Если прерывание сконфигурировано для работы по уровню, то эта строчка не имеет смысла; если по фронту - это готовый источник проблем.
KITA
Цитата(aaarrr @ May 27 2013, 23:26) *
Проверьте, нет ли вероятности выхода из какого-либо прерывания без записи AIC_EOICR.


Вероятность всегда естьsm.gif Только вот где бы это могло случиться, я не вижу. Во всех обработчиках, return один и последним оператором. А предпоследним EOICR. Ну допустим, что где-то, что-то сглючивается, и вылетает она из какого-нибудь обработчика посередине. А увидеть, что AIC_EOICR не записали в каком-нибудь регистре можно?

Цитата(aaarrr @ May 28 2013, 00:53) *
Код
*AT91C_AIC_ICCR=1<<AT91C_ID_SYS;

Если прерывание сконфигурировано для работы по уровню, то эта строчка не имеет смысла; если по фронту - это готовый источник проблем.

А, да, это атавизм. Спасибо, уберу.
aaarrr
Цитата(KITA @ May 28 2013, 00:58) *
А увидеть, что AIC_EOICR не записали в каком-нибудь регистре можно?

Увы, нет.
KITA
Цитата(aaarrr @ May 28 2013, 01:14) *
Увы, нет.


Печалько... Но видимо, больше ничего быть не может. Буду пока копать в этом направлении. Спасибо за подсказку.
aaarrr
Цитата(KITA @ May 28 2013, 01:27) *
Печалько... Но видимо, больше ничего быть не может. Буду пока копать в этом направлении. Спасибо за подсказку.

Похоже: сброс внутри прерывания по записи ICCR тоже привел бы к неработающим прерываниям, но в этом случае не было бы единички в IPR.
UPD: или оно все же сконфигурировано по уровню? Если нет, то настоятельно рекомендую.

Попробуйте записать EOICR, когда поймаете "зависание" - если логика была нарушена, то после этой записи должно запустится прерывание.

Еще неплохо бы проверить листинг на предмет корректности кода для вложенных прерываний.
KITA
Цитата(aaarrr @ May 28 2013, 01:36) *
Похоже: сброс внутри прерывания по записи ICCR тоже привел бы к неработающим прерываниям, но в этом случае не было бы единички в IPR.
UPD: или оно все же сконфигурировано по уровню? Если нет, то настоятельно рекомендую.


По уровню.

Цитата(aaarrr @ May 28 2013, 01:36) *
Попробуйте записать EOICR, когда поймаете "зависание" - если логика была нарушена, то после этой записи должно запустится прерывание.


Да, до этого я уже додумался, но теперь надо подождать денёк, пока эта тварь снова повиснетsm.gif

Цитата(aaarrr @ May 28 2013, 01:36) *
Еще неплохо бы проверить листинг на предмет корректности кода для вложенных прерываний.

А вложенных нету, без _nested что-то не так с вызовом процедур из обработчика было (давно было, не помню, что-то они там в один регистр с обработчиком адрес возврата запоминали что-ли...). Сейчас уже, правда, вызовов нет, ну а _nested остался, по-моему так надёжнееsm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.