Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Подскажите по прерываниям
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Димон Безпарольный
До сих пор в системном контроллере у меня прерывания генерировал только интервальный таймер 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). Но в самом системном контроллере теперь два прерывания. Как произвести дальнейшее ветвление??
aaarrr
Цитата(Димон Безпарольный @ Apr 5 2011, 15:44) *
Как произвести дальнейшее ветвление??

Вручную проверить возможные источники, только так.

Проверять AIC_ISR не нужно, тем более столь экстравагантным способом.

Если хотите использовать RTT, то нужно учесть, что его линия прерывания сбрасывается не сразу, а через 2 цикла SCLK. Т.е. будете терять 60us впустую.
Димон Безпарольный
Цитата(aaarrr @ Apr 5 2011, 14:48) *
Вручную проверить возможные источники, только так.

Проверять AIC_ISR не нужно, тем более столь экстравагантным способом.

Если хотите использовать RTT, то нужно учесть, что его линия прерывания сбрасывается не сразу, а через 2 цикла SCLK. Т.е. будете терять 60us впустую.

AIC_ISR я проверяю способом из примера. Если не трудно, подскажите что в нем экстравагантного?

Если не проверять AIC_ISR, то каким способом можно осуществить ветвление? Т.е. вопрос - то и был в том, как проверять источники таких прерываний?
aaarrr
Цитата(Димон Безпарольный @ Apr 5 2011, 16:53) *
AIC_ISR я проверяю способом из примера. Если не трудно, подскажите что в нем экстравагантного?

Откуда пример? Вообще-то ISR содержит ID текущего прерывания, а не битовую маску, отсюда и экстравагантность (=неправильность) проверки.

Цитата(Димон Безпарольный @ Apr 5 2011, 16:53) *
Если не проверять AIC_ISR, то каким способом можно осуществить ветвление? Т.е. вопрос - то и был в том, как проверять источники таких прерываний?

Читать статусы задействованной периферии.
Димон Безпарольный
Цитата(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.
aaarrr
Цитата(Димон Безпарольный @ Apr 5 2011, 17:32) *
Странно, почему я должен терять это время, если контроллер прерываний запрограммирован на передний фронт?

Увы, такая настройка по понятным причинам весьма плохо сочетается с несколькими заOR'енными источниками.
Димон Безпарольный
Цитата(aaarrr @ Apr 5 2011, 16:51) *
Увы, такая настройка по понятным причинам весьма плохо сочетается с несколькими заOR'енными источниками.

Понял. Если не отслеживать задний фронт программно, то я рискую потерять прерывание от другого источника System Controller'а.
aaarrr
Вы рискуете вообще потерять прерывания от System Controller'а, если какой-либо из его источников не будет обслужен до выхода из ISR, а возникать они могут в любое время.
sasamy
Цитата(Димон Безпарольный @ 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, помоему в атмеловских примерах так и делают.

DmitryM
[quote name='sasamy' date='Apr 5 2011, 21:40' post='910844']

А почему не пользоваться механизмом AIC, предлагаемым Atmel? Когда переход на процедуру прерываний формируется автоматом, а в процедуре ID_SYS делать необходимые разборки по OR-источнику?

З.Ы. Это конечно создает зависимость от среды программирования и лишних (левых) просмотров статусных регистров, но? Как обычно, палка о двух концах.
sasamy
Цитата(DmitryM @ Apr 5 2011, 21:56) *
З.Ы. Это конечно создает зависимость от среды программирования и лишних (левых) просмотров статусных регистров, но? Как обычно, палка о двух концах.


Пример неполный - перед вызовом диспетчера прерываний есть еще код - установка текущего приоритета и запрет низкоприоритетных прерываний поэтому сразу перейти на обработчик нельзя, если у вас простое приложение это вам конечно может и не понадобится.- тут удобней чтобы каждому ID ставилась в соответствие конкретная периферия. Так например системный таймер срабатывает постоянно - получается каждый раз нужно делать тупой разбор от кого пришло прерывание - сыкономили атмеловцы на количестве векторов в AIC sm.gif
aaarrr
Цитата(sasamy @ Apr 5 2011, 22:04) *
Пример неполный - перед вызовом диспетчера прерываний есть еще код - установка текущего приоритета и запрет низкоприоритетных прерываний поэтому сразу перейти на обработчик нельзя

Ладно, а AIC_ISR тогда чем не устроил?

Димону Безпарольному могу только посоветовать забросить RTT, как самый кривой таймер из всего набора. По человечески использовать его прерывание совместно с другими из SC просто нельзя.
sasamy
Цитата(aaarrr @ Apr 5 2011, 22:17) *
Ладно, а AIC_ISR тогда чем не устроил?


Тем что AIC_IVR читать при входе в обработчик нужно обязательно - какой смысл еще статусный регистр читать когда в моем примере это все делается одной командой ?

UPD Я кажется понял смысл вашего вопроса - не заметил что у ТС обработчик
Цитата
__irq void PIT_int (void) {

я думал это общий диспетчер прерываний.
DmitryM
Цитата(sasamy @ Apr 5 2011, 22:04) *
Пример неполный - перед вызовом диспетчера прерываний есть еще код - установка текущего приоритета и запрет низкоприоритетных прерываний поэтому сразу перейти на обработчик нельзя, если у вас простое приложение это вам конечно может и не понадобится.- тут удобней чтобы каждому ID ставилась в соответствие конкретная периферия. Так например системный таймер срабатывает постоянно - получается каждый раз нужно делать тупой разбор от кого пришло прерывание - сыкономили атмеловцы на количестве векторов в AIC sm.gif


Да, да ldr pc, [pc, #-0xF20] /* irq */
З.Ы.
Только на системном, а там не так уж много, да и Линух справляется. А приоритетов 8 не хватит ли? А по остальной встроенной периферии AIC и сам разрулит.
sasamy
Цитата(DmitryM @ Apr 6 2011, 00:14) *
З.Ы.
Только на системном, а там не так уж много,


Например на sam9g45/m10 на одном векторе SYSC - 8 источников прерываний по OR висит, на одном векторе TC - все 6 таймеров.

Цитата
да и Линух справляется. А приоритетов 8 не хватит ли? А по остальной встроенной периферии AIC и сам разрулит.


Кроме Linux есть и другие ОС - в той из которой я пример привел 12 уровней приоритетов и в результате аппаратный контроллер приоритетов атмеловский нужен там как русалке лыжи.
Димон Безпарольный
Цитата(aaarrr @ Apr 5 2011, 16:58) *
Вы рискуете вообще потерять прерывания от System Controller'а, если какой-либо из его источников не будет обслужен до выхода из ISR, а возникать они могут в любое время.

Собственно, так и случилось. Прерывание от PIT не было обслужено и прерывания от System Controller'а вообще перестали поступать.

Отказался я от прерываний RTT. Но понял главное - ветвление лучше осуществлять чтением статусных регистров устройств, в которых разрешены прерывания.

Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.