реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> В прерываниях CM0/CM3 в конце нужен ClearPending?
GetSmart
сообщение Nov 15 2013, 07:35
Сообщение #1


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Сталкивался ли кто-нибудь с прерываниями NVIC, не требующими вызова NVIC_ClearPendingIRQ() ?

Помнится, в начале своего знакомства с LPC176x не зная NVIC у меня прерывание таймера срабатывало в 2 раза чаще из-за отсутствия в его конце сброса пендинга. Пришлось принять за правило, ставить в конце всех прерываний NVIC_ClearPendingIRQ(). Но сейчас обнаружил в прерывании USB_IRQHandler() биоса LPC1343 тоже отсутствие сброса пендинга. Как и в проекте NXP AN11018.zip, который очень похож на код биоса.

Если кто-то знает такие тонкости сброса пендинга, подскажите, плиз.

И зачем в инициализации проекта AN11018 стоит включение тактирования таймера CT32B1, хотя в коде он не используется? Остаток от другого проекта?

Сообщение отредактировал GetSmart - Nov 16 2013, 00:33


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 15 2013, 08:11
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(GetSmart @ Nov 15 2013, 11:35) *
Сталкивался ли кто-нибудь с прерываниями NVIC, не требующими вызова NVIC_ClearPendingIRQ() ?

Помнится, в начале своего знакомства с LPC176x не зная NVIC у меня прерывание таймера срабатывало в 2 раза чаще из-за отсутствия в его конце сброса пендинга. Пришлось принять за правило, ставить в конце всех прерываний NVIC_ClearPendingIRQ(). Но сейчас обнаружил в прерывании USB_IRQHandler() биоса LPC1343 тоже отсутствие сброса пендинга. Как и в проекте NXP AN11018.zip, который очень похож на код биоса.

Если кто-то знает такие тонкости сброса пендинга, подскажите, плиз.

И зачем в инициализации проекта AN11018 стоит включение тактирования таймера CT32B1, хотя в коде он не используется? Остаток от другого проекта?

Вроде, если ставить воследней инструкцией обработчика сброс подтверждения прерывания, то возможен повторных вход в обработчик.
В конце нужни либо NOPы, либо DSB. Где читал уже не помню...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 16 2013, 00:32
Сообщение #3


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(adnega @ Nov 15 2013, 14:11) *
Вроде, если ставить воследней инструкцией обработчика сброс подтверждения прерывания, то возможен повторных вход в обработчик.
В конце нужни либо NOPы, либо DSB. Где читал уже не помню...

Проверил на LPC1343. Работает. Если же в хэндлере таймера последней командой стоит TMR32B0IR = 0xff, то это прерывание завершается, но далее перестаёт вызываться. При этом другие прерывания продолжают работать.

Тогда непонятно, почему прерывание таймера LPC1768, запрограммированное на 100 гц могло вызываться 200 гц. Когда же я в его конец поставил NVIC_ClearPendingIRQ(), то оно стало вызываться с правильной частотой. Года 2-3 назад дело было и не могу точно припомнить код хэндлера. Возможно последней командой стоял сброс IR регистра таймера.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 17 2013, 22:02
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Сравниваю разные исходники из примеров Кейла, Иара, NXP и прочих.

IAR-LPC-1343-SK\VirtualCom\modules\usb_hw.c (автор Stanimir Bonev, Date April 8, 2008)

В конце USBIRQ_IRQHandler() стоит NVIC_ClrPend(NVIC_USB_IRQ);


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 18 2013, 08:51
Сообщение #5


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если прерывание не успело обработаться до прихода следующего запроса, тогда взведется Pending бит, и после выхода из прерывания программа снова в него зайдет. Если же его стереть перед выходом, то не зайдет. Пока следующий запрос не появится. Разве не так?
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 18 2013, 10:22
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ViKo @ Nov 18 2013, 12:51) *
Если прерывание не успело обработаться до прихода следующего запроса, тогда взведется Pending бит, и после выхода из прерывания программа снова в него зайдет. Если же его стереть перед выходом, то не зайдет. Пока следующий запрос не появится. Разве не так?

Хуже! (хотя описаное Вами тоже имеет место быть).
Если последней инструкцией обработчика будет команда сброса флага прерывания, то из-за конвеера/работы_NVIC_с_pending/шин_процессора
она "как бы не успевает выполниться" (т.е. сигнал дойдет до NVIC, но через несколько тактов), а по данным NVIC запрос на прерывание от
периферийного блока не сброшен - милости просим в повторное прерывание.
Но горе мне: не помню, где об этом читал((
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 18 2013, 11:12
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Тогда почему об этом не заботятся в библиотечной функции? Или не предупреждают?
Код
/** \brief  Clear Pending Interrupt
    The function clears the pending bit of an external interrupt.
    \param [in]      IRQn  External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}

Наверное, пока произойдет возврат из прерывания (там же восстанавливаются регистры из стека, по-моему, говорится о 12 тактах, или о 6, если в новое прерывание улетает?), конвейер освободится.
Go to the top of the page
 
+Quote Post
Flexz
сообщение Nov 18 2013, 11:29
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797



Цитата(ViKo @ Nov 18 2013, 15:12) *
Наверное, пока произойдет возврат из прерывания (там же восстанавливаются регистры из стека, по-моему, говорится о 12 тактах, или о 6, если в новое прерывание улетает?), конвейер освободится.

12 тактов (на аппаратное восстановление регистров из стека) будет если нет запроса прерывания. А если новый запрос есть, или старый не успел сбросится - сработает правило Interrupt tail chaining и процессор сразу пойдет на исполнение запроса.
Что бы не было повторной обработки прерывания используют барьеры - __DSB();
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 18 2013, 11:32
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ViKo @ Nov 18 2013, 15:12) *
Тогда почему об этом не заботятся в библиотечной функции? Или не предупреждают?
Код
/** \brief  Clear Pending Interrupt
    The function clears the pending bit of an external interrupt.
    \param [in]      IRQn  External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}

Наверное, пока произойдет возврат из прерывания (там же восстанавливаются регистры из стека, по-моему, говорится о 12 тактах, или о 6, если в новое прерывание улетает?), конвейер освободится.

Предупреждают! "Мамой клянусь" где-то читал.
Возврат из прерывания занимает 12 тактов, если только нет других разрешенных необработанных прерываний.
Если есть хоть одно, сразу вызывается обработчик без восстановления стека (т.н. Tail-chaining).
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Nov 18 2013, 11:36
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



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

Если просто сбросить триггер не проверив нового запроса - то больше прерываний не будет, поскольку (обычно) они ставятся по фронту запроса, а он уже был и триггер мы сбросили после его прихода.

Но с NVIC могут происходить любые чудеса...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 18 2013, 18:02
Сообщение #11


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



А не проще ли сбрасывать флаг сразу по входу в прерывание?
Зачем это делать перед выходом?
Go to the top of the page
 
+Quote Post
Lagman
сообщение Nov 18 2013, 19:06
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(adnega @ Nov 15 2013, 12:11) *
Вроде, если ставить воследней инструкцией обработчика сброс подтверждения прерывания, то возможен повторных вход в обработчик.
В конце нужни либо NOPы, либо DSB. Где читал уже не помню...

На MIPSы больше похоже.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 18 2013, 22:38
Сообщение #13


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(sonycman @ Nov 19 2013, 00:02) *
А не проще ли сбрасывать флаг сразу по входу в прерывание?
Зачем это делать перед выходом?

Если вопрос ко мне по поводу сброса IR регистра, то где сбрасывать решает программист по своим хотелкам. Я решал так чтобы была меньше вероятность повторного залёта в текущее прерывание из-за повторно установившегося флага, который в начале обработчика сбрасывался. Например из-за какого-то очень медленного прерывания, прерывающего текущее, или тоже медленное, вызванное накануне установки флага таймера и по времени занявшее около периода срабатывания таймера. Если внутри обработчика вызываются какие-то относительно долгие алгоритмы (но ессно меньшие периода таймера), то чтобы они два раза подряд не вызывались, когда внутри обработчика снова взвёлся тот же флаг в IR для вызова обработчика.

Но учитывая пока мне непонятную логику/схемотехнику NVIC, выбор где ставить сброс IR становится сложнее. Особенно, если эта логика будет хоть немного отличаться в разных ревизиях/процессорах.

Правильно ли я понимаю, что NVIC сам сбрасывает запрос/бит в регистре ISPR на выходе текущего прерывания? Или на входе?

Upd
Перепроверил сброс IR последней командой обработчика. Раньше ошибся из-за (двойной) инверсии светодиода внутри обработчика. Поставил вывод байта в УАРТ и заметил. Оказывается точно так же - прерывание вызывается два раза подряд. Прерывание таймера, настроенное на 1 Гц вызывается дважды с паузами в 1 сек. Учту, что впритык к выходу из обработчика нельзя без нопов или барьера. Спасибо adnega, ни за что бы сам не догадался о причине.

А вне обработчика программно его инициировать SetPending-ом корректно? У меня есть такие вещи в CM0, у которого нет регистра STIR. В описании CM3 (LPC134x) об этом регистре есть предложение "The STIR register provides an alternate way for software to generate an interrupt, in addition to using the ISPR registers."

Сообщение отредактировал GetSmart - Nov 19 2013, 07:01


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 19 2013, 09:21
Сообщение #14


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(GetSmart @ Nov 19 2013, 02:38) *
Если вопрос ко мне по поводу сброса IR регистра, то где сбрасывать решает программист по своим хотелкам. Я решал так чтобы была меньше вероятность повторного залёта в текущее прерывание из-за повторно установившегося флага, который в начале обработчика сбрасывался.

Если флаг, сброшенный в начале обработчика, успевает установиться вновь до конца обработки прерывания - то его необходимо обработать второй раз, что будет эффективно сделано механизмом tail-chaining.
Для этого даже не потребуется делать каких-то своих проверок в коде.
Иначе получите пропуск события и некорректную работу программы.

С другой стороны, если обработчик настолько медленный, что не успевает закончить обработку за время между прерываниями - как то криво у вас всё организовано.

Цитата
Правильно ли я понимаю, что NVIC сам сбрасывает запрос/бит в регистре ISPR на выходе текущего прерывания? Или на входе?

Некоторые прерывания сбрасываются автоматически при входе в ISR. Но не все.
Читайте мануал на каждый конкретный случай.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 21 2013, 04:42
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(adnega @ Nov 18 2013, 16:22) *
Но горе мне: не помню, где об этом читал((

Как можно гарантировать, что комада DSB, стоящая последней командой обработчика прерывания будет корректно завершать прерывание NVIC и в текущих версиях кортексов и в последующих их модификациях? Если в последних её будет недостаточно, то об этом где-то объявят? sm.gif

На эту же тему мне любопытно, когда я программно инициирую прерывание через SetPending() или через STIR, то его как нужно завершать? Через DSB мне кажется нелогичным, т.к. эта команда, судя по первым постам, всего-лишь ожидает окончания синхронизации периферии и NVIC, а программно вызваное прерывание не имело запроса от периферии. По ClearPending() более логичным, но одновременно немного сомнительным. Но с другой стороны, если программно вызванное прерывание медленное и в процессе его работы более приоритетные прерывания могут повторно взводить флаг этого прерывания, а перед выходом из этого медленного программного я намеренно хочу сбросить все дополнительные запросы этого прерывания, возникшие в процессе его работы, то корректно ли ставить перед выходом из него ClearPending(), возможно даже со следующей командой DSB ?

Не прояснит ли кто-то, хотя вопрос уже звучал, новая прокладка с названием Pending, появившаяся в кортексах с NVIC, для чего введена?И на какой логике работает - на динамических триггерах или статических (RS) ? Слово "Pending" вроде как переводится "в обработке", но смысл слишком широкий. Важно знать, когда на этом уровне аппаратно сбрасывается бит прерывания - только на входе в прерывание, или при любом входе на его уровень (например после возврата из более приоритетного) или вообще строго на выходе из него. И насколько изначально заданная логика NVIC будет эталоном для будущих версий чипов и ПО? Если её чуть-чуть изменят и не "объявят очень громко", то корректно написанные программы в будущих модификациях чипов, а так же просто переносимые программистами из старых проектов в новые, могут не просто перестать работать, что было бы выгодней, а вместо этого начать глючить самым сказочным образом.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 06:15
Рейтинг@Mail.ru


Страница сгенерированна за 0.01516 секунд с 7
ELECTRONIX ©2004-2016