|
|
  |
scmRTOS. Вопросы и ответы. |
|
|
|
Jan 22 2008, 06:40
|

Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118

|
Цитата(Сергей Борщ @ Jan 19 2008, 03:47)  Очень похоже, что ваша программа некорректно (без записи в AIC_EOICR) завершает какое-то из прерываний. При этом перестают вызываться прерывания с таким же и более низкими приоритетами. На это косвенно указывет и то, что программа крутится в Idle,т.е. не вызывается и переключатель контекста. Возможно, в каком-то из прерываний вы забыли завести объект OS:TISRW, в деструкторе которого и выпоняется эта запись. Если какое-либо ваше прерывание не использет никакие сервисы ОС, то можно не заводить в нем объект OS:TISRW, но тогда вы должны сами в конце этого прерывания вручную прописать AIC_EOICR. Получается, если я завожу объект OS:TISRW, то мне не нужно прописывать AIC_EOICR? Я не нашел в деструкторе этого объекта записи в AIC_EOICR. Я обычно прописывал AT91C_BASE_AIC->AIC_EOICR = 0; И в примере тоже вручную прописывали: Код OS_INTERRUPT void Timer_ISR() { OS::TISRW ISRW; volatile dword Tmp = AT91C_BASE_TCB->TCB_TC0.TC_SR; // read to clear int flag
AT91C_BASE_PIOA->PIO_SODR = (1 << 0); Timer_Ovf.SignalISR();
AT91C_BASE_AIC->AIC_EOICR = 0; } Если не дописывать, то прерывание больше не вызывается Попробовал так: Код OS_INTERRUPT void TimerCounter0Interrupt(void) { OS::TISRW ISRW; volatile dword Tmp = AT91C_BASE_TCB->TCB_TC0.TC_SR; // read to clear int flag
// AT91C_BASE_AIC->AIC_EOICR = 0; без этой строчки не работает
}
|
|
|
|
|
Jan 31 2008, 10:24
|

Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118

|
Цитата(Сергей Борщ @ Jan 19 2008, 03:47)  Надеюсь, что ОС в данном случае не виновата. Но если вы все же найдете в ней недоработку-обязательно сообщите. И даже если не в ОС дело-все равно отпишитесь здесь, интересно же  Нашёл! При настройке AIC, нужно использовать не AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, как было в примере, а AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Тогда всё работает стабильно: Код AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL/*AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE*/ | AT91C_AIC_PRIOR_LOWEST + 1;
|
|
|
|
|
Jan 31 2008, 13:02
|

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

|
Цитата(LessNik @ Jan 31 2008, 12:24)  При настройке AIC, нужно использовать не AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, как было в примере, а AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Тогда всё работает стабильно: Угу. Действительно. В моем проекте, где используется DBGU тоже стоит AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Внесу изменения в примеры ОСи. Спасибо! Интересно, кто-нибудь знает, зачем я там делал EDGE? P.S. гляньте вот сюда: ветка на сахаре. Обнаружился баг в TEeventFlag, там идет обсуждение путей его ликвидации.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 5 2008, 06:11
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(spf @ Feb 4 2008, 17:21)  Все работает, народ подтягивается. По данной ссылке http://index.php/?showtopic=42800&hl= так и не могу зайти. Ссылка правильная? PS Нашёл правильную ссылку в соседней ветке.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|