Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как грамотно управлять прерываниями?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Master
Доброго времени суток!

Есть очередь байт, к которой имеют доступ функции записи и чтения. Причём если эта очередь передатчика, то чтение выполняется из прерывания, а если очередь приёмника, то, соответственно, из прерывания выполняется запись.
Так вот вопрос: как грамотно запретить прерывания устройства (например DBGU), чтобы после разрешения прерываний выполнились те из них, которые за время запрещения-разрешения выставили соответствующие биты в регистре статуса устройства?
Andy Mozzhevilov
Цитата(Master @ Jun 5 2006, 20:07) *
Доброго времени суток!

Есть очередь байт, к которой имеют доступ функции записи и чтения. Причём если эта очередь передатчика, то чтение выполняется из прерывания, а если очередь приёмника, то, соответственно, из прерывания выполняется запись.
Так вот вопрос: как грамотно запретить прерывания устройства (например DBGU), чтобы после разрешения прерываний выполнились те из них, которые за время запрещения-разрешения выставили соответствующие биты в регистре статуса устройства?


Может не понял вопроса, но по моему просто запретить, а потом разрешить. Можно запрещать прерывания глобально, либо только конкретное прерывание в контроллере прерываний.
После разрешения прерывания оно активируется, если соответсвующий флаг наличия прерывания
в регистре периферии будет установлен.
Или поясните, почему эта схема не работает, по вашему мнению?
Master
Цитата(Andy Mozzhevilov @ Jun 6 2006, 06:41) *
Может не понял вопроса, но по моему просто запретить, а потом разрешить. Можно запрещать прерывания глобально, либо только конкретное прерывание в контроллере прерываний.
После разрешения прерывания оно активируется, если соответсвующий флаг наличия прерывания
в регистре периферии будет установлен.
Или поясните, почему эта схема не работает, по вашему мнению?

C удовольствием! Бьюсь уже... счёт дням потерял.
Глобальное запрещение не пройдёт - в проекте крутятся ещё помимо DBGU и USART устройства на SPI, Timers, RTT. А впоследствии будут "прикручены" PDC, PIT, USB и ADC.
Конкретное прерывание запрещать пробовал и в AIC, и непосредственно в DBGU, но байты по прежнему теряются, из чего я делаю вывод, что после их обратного разрешения, прерывания по установившимся флагам не срабатывают. В документации на AT91SAM7S соответствующего пункта я не нашёл sad.gif Например в документации по AVR сказано, что
Цитата
Writing this bit to one enables interrupt on the RXC Flag. A USART Receive Complete interrupt will be generated only if the RXCIE bit is written to one, the Global Interrupt
Flag in SREG is written to one and the RXC bit in UCSRA is set.
Тоесть при совпадении всех трёх событий вырабатывается прерывание. Хоть явно и не описано, что при срабатывании последнего неслучившегося из трёх события генерится прерывание, так происходит на самом деле - проверено, и очередь работает как говорится без сучка, без задоринки.
Здесь же какая-то засада, и как именно нужно запрещать-разрешать прерывания, остаётся неясно.
Andy Mozzhevilov
Цитата(Master @ Jun 6 2006, 14:45) *
C удовольствием! Бьюсь уже... счёт дням потерял.
Глобальное запрещение не пройдёт - в проекте крутятся ещё помимо DBGU и USART устройства на SPI, Timers, RTT. А впоследствии будут "прикручены" PDC, PIT, USB и ADC.
Конкретное прерывание запрещать пробовал и в AIC, и непосредственно в DBGU, но байты по прежнему теряются, из чего я делаю вывод, что после их обратного разрешения, прерывания по установившимся флагам не срабатывают. В документации на AT91SAM7S соответствующего пункта я не нашёл


Попрбуйте после разрешения прерывания искуственно программно вызвать прерывание, если это возможно. Либо обработать периферию по поллингу флагов.
Master
Цитата(Andy Mozzhevilov @ Jun 6 2006, 11:52) *
Попрбуйте после разрешения прерывания искуственно программно вызвать прерывание, если это возможно. Либо обработать периферию по поллингу флагов.

Согласен, мой ход мысли был аналогичным. Вот сейчас проверил один вариант, на который раньше не решался. Искусственно вызывать не получалось потому, что прерывания в DBGU были запрограммированы на AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, и после разрешения прерываний выдача команды AT91F_AIC_Trig( AT91C_BASE_AIC, m_ID ) не приводила к желаемому результату. Но после выставления режима AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE результат порадовал: данные передаются без потерь! disco.gif
Не решался из-за того, что в документации написано вот что:
Цитата
24.7.1.1 Interrupt Source Mode
The internal interrupt sources wired on the interrupt outputs of the embedded peripherals can be
programmed either in level-sensitive mode or in edge-triggered mode. The active level of the
internal interrupts is not important for the user.
Тоесть что в лоб, что по лбу, что по уровню, что по фронту, и мол активный уровень не важен. А оказывается, ещё как важен!
Поллинг флагов с Вашего позволения оставлю без комментариев. Отмечу лишь, что предпочитаю делать код не только работающим, но и красивым smile.gif

P.S. Строго говоря у меня сегодня получился ещё один вариант - подсчёт количества оставшихся свободных байт в очереди и запись с гистерезисом. Но он менее красивый и немного более программно нагружен.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.