|
Подскажите по прерываниям, Как происходит ветвление в случае System Controller Interrupt?? |
|
|
|
Apr 5 2011, 11:44
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
До сих пор в системном контроллере у меня прерывания генерировал только интервальный таймер PIT. Процедура была простой: Код __irq void PIT_int (void) { //Прерывание от интервального таймера (System, переферийный номер 1, стр 35) if (*AIC_ISR1 & (1)) { //Чья здесь стоит единица??????????? Предположительно это Peripheral Id System Controller Strob = 1; //Установка строба для Main //Прерывание обязано читать PIT_PIVR для сброса бита PITS, вызывающего прерывание. *AIC_EOICR1 = *PIT_PIVR1;} //Конец прерывания. В EOICR пишется ЛЮБОЕ значение. else {*AIC_EOICR1 = 0;}} //Если источник прерывания не интервальный таймер: конец прерывания Теперь потребовался Real-time Timer. Но он тоже в System Controller. Я плохо себе представляю - кажется чтение Цитата if (*AIC_ISR1 & (1)) Фильтрует прерывание от System Controller (единица это его Peripheral Id). Но в самом системном контроллере теперь два прерывания. Как произвести дальнейшее ветвление??
Сообщение отредактировал Димон Безпарольный - Apr 5 2011, 11:46
|
|
|
|
|
Apr 5 2011, 12:53
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(aaarrr @ Apr 5 2011, 14:48)  Вручную проверить возможные источники, только так.
Проверять AIC_ISR не нужно, тем более столь экстравагантным способом.
Если хотите использовать RTT, то нужно учесть, что его линия прерывания сбрасывается не сразу, а через 2 цикла SCLK. Т.е. будете терять 60us впустую. AIC_ISR я проверяю способом из примера. Если не трудно, подскажите что в нем экстравагантного? Если не проверять AIC_ISR, то каким способом можно осуществить ветвление? Т.е. вопрос - то и был в том, как проверять источники таких прерываний?
Сообщение отредактировал Димон Безпарольный - Apr 5 2011, 12:54
|
|
|
|
|
Apr 5 2011, 12:58
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Димон Безпарольный @ Apr 5 2011, 16:53)  AIC_ISR я проверяю способом из примера. Если не трудно, подскажите что в нем экстравагантного? Откуда пример? Вообще-то ISR содержит ID текущего прерывания, а не битовую маску, отсюда и экстравагантность (=неправильность) проверки. Цитата(Димон Безпарольный @ Apr 5 2011, 16:53)  Если не проверять AIC_ISR, то каким способом можно осуществить ветвление? Т.е. вопрос - то и был в том, как проверять источники таких прерываний? Читать статусы задействованной периферии.
|
|
|
|
|
Apr 5 2011, 13:32
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(aaarrr @ Apr 5 2011, 15:58)  Читать статусы задействованной периферии. Понятно. Применительно к данному случаю это бит PITS из PIT_SR и бит RTTINC из RTT_SR. Спасибо. Цитата(aaarrr @ Apr 5 2011, 14:48)  Если хотите использовать RTT, то нужно учесть, что его линия прерывания сбрасывается не сразу, а через 2 цикла SCLK. Т.е. будете терять 60us впустую. Странно, почему я должен терять это время, если контроллер прерываний запрограммирован на передний фронт? Цитата because the status register is cleared two Slow Clock cycles after read.
|
|
|
|
|
Apr 5 2011, 17:40
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Димон Безпарольный @ Apr 5 2011, 16:53)  AIC_ISR я проверяю способом из примера. Если не трудно, подскажите что в нем экстравагантного? Если не нужен быстрый переход на обработчик (тогда в SVR записывают адрес обработчика) - в SVR удобно вписывать ID периферии. Код for (i = 0; i < NIRQS; i++) { /* Put irq number in Source Vector Register */ AIC_SVR[i] = i;
/* Unstack nested interrupts */ if (i < 8) AIC_EOICR = 0; }
/* Spurious Interrupt ID in Spurious Vector Register is NIRQS */ AIC_SPU = NIRQS; Тогда при чтении IVR сразу получаете ID прерывания Код /* Get interrupt source */ vector = AIC_IVR;
/* Detects a spurious interrupt */ if (vector == NIRQS) goto out;
/* Dispatch interrupt */ irq_handler(vector); ...........
out: /* Restore the previous current level if one exists on the stack */ AIC_EOICR = 0; Чтобы максимально ускороить определение IRQ можно вместо PIT использовать например TC0, помоему в атмеловских примерах так и делают.
|
|
|
|
|
Apr 5 2011, 18:20
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(aaarrr @ Apr 5 2011, 22:17)  Ладно, а AIC_ISR тогда чем не устроил? Тем что AIC_IVR читать при входе в обработчик нужно обязательно - какой смысл еще статусный регистр читать когда в моем примере это все делается одной командой ? UPD Я кажется понял смысл вашего вопроса - не заметил что у ТС обработчик Цитата __irq void PIT_int (void) { я думал это общий диспетчер прерываний.
Сообщение отредактировал sasamy - Apr 5 2011, 18:32
|
|
|
|
|
Apr 5 2011, 20:14
|
Знающий
   
Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840

|
Цитата(sasamy @ Apr 5 2011, 22:04)  Пример неполный - перед вызовом диспетчера прерываний есть еще код - установка текущего приоритета и запрет низкоприоритетных прерываний поэтому сразу перейти на обработчик нельзя, если у вас простое приложение это вам конечно может и не понадобится.- тут удобней чтобы каждому ID ставилась в соответствие конкретная периферия. Так например системный таймер срабатывает постоянно - получается каждый раз нужно делать тупой разбор от кого пришло прерывание - сыкономили атмеловцы на количестве векторов в AIC  Да, да ldr pc, [pc, #-0xF20] /* irq */ З.Ы. Только на системном, а там не так уж много, да и Линух справляется. А приоритетов 8 не хватит ли? А по остальной встроенной периферии AIC и сам разрулит.
|
|
|
|
|
Apr 6 2011, 00:34
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(DmitryM @ Apr 6 2011, 00:14)  З.Ы. Только на системном, а там не так уж много, Например на sam9g45/m10 на одном векторе SYSC - 8 источников прерываний по OR висит, на одном векторе TC - все 6 таймеров. Цитата да и Линух справляется. А приоритетов 8 не хватит ли? А по остальной встроенной периферии AIC и сам разрулит. Кроме Linux есть и другие ОС - в той из которой я пример привел 12 уровней приоритетов и в результате аппаратный контроллер приоритетов атмеловский нужен там как русалке лыжи.
Сообщение отредактировал sasamy - Apr 6 2011, 00:41
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|