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

 
 
> Прерывание EXTI
juvf
сообщение Nov 5 2016, 10:30
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



st32f401. Поподаю в прерывание EXTI3_IRQHandler(). Флаги прерывания нулю равны, но прерывание срабатывает. Не могу понять почему. Вот обработчик дебажный
Цитата
extern "C" void EXTI3_IRQHandler()
{
static uint32_t a;
a = EXTI->PR;
EXTI_ClearFlag(EXTI_Line3);
}
EXTI->PR равно нулю. а всегда равна нулю. Почему попадаю в прерывание. Как это отловить?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
scifi
сообщение Nov 5 2016, 11:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Остановиться в обработчике прерывания, посмотреть регистры NVIC.
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 5 2016, 21:05
Сообщение #3


Гуру
******

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



Цитата(juvf @ Nov 5 2016, 13:30) *
Почему попадаю в прерывание. Как это отловить?

Видимо, вы его разрешили и сконфигурировали - вот и попадаете.
Вопрос не понятный: вас смущает, что вообще прерывание возникает? или что оно и должно возникать, но PR при этом нулевой?

Есть у Cortex такая штука как повторный вход в прерывание по уму обработчик должен проверять условие.
Например,
Код
void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /* Toggle LED3 */
    STM_EVAL_LEDToggle(LED3);
    
    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }
}
Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 08:57
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(scifi @ Nov 5 2016, 16:39) *
Остановиться в обработчике прерывания, посмотреть регистры NVIC.

А какие регистры?

Цитата
Вопрос не понятный: вас смущает, что вообще прерывание возникает? или что оно и должно возникать, но PR при этом нулевой?
Смущяет то, то оно не должно возникать, PR равен нулю, как и положенно, а вызов обработчика есть.


Суть в следующем: я настраиваю прерывание EXTI3 как переход из "1" в "0" на ноге РА3 и ухожу в стоп режим (PWR_STOPEntry_WFI). на ноге РА3 стоит "1"... ни каких дерганий и помаргиваний.... процессор выходит из стоп режима. Почему? Единственное разрешенное прерывание для выхода из стопа это переход на ноге РА3 из 1 в 0. Может вовсе не по EXTI3 выхожу из стопа.... поставил ловушку в обработчике прерывания EXTI3_IRQHandler(). Попадаю после стопа сразу в этот обработчик..... значит просыпаюсь по ексти3 всётаки.....
далее... сразу после пробуждения, ещё до входа в прерывание читаю EXTI->PR, там ноль. после настройки HSE разрешаю прерывания и тут же попадаю в обработчик EXTI3_IRQHandler(). Опять проверяю EXTI->PR. Там НОЛЬ!!! черт с ним, со стопом... потом разберусь.... вопрос в следующем - почему я попадаю в обработчик прерывания, когда флаг прерывания равен нулю? Если EXTI->PR == 0, то не было событий ни каких в эксти. Раз не было событий, какого лешего идет вызов обработчика?
Go to the top of the page
 
+Quote Post
scifi
сообщение Nov 6 2016, 09:18
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(juvf @ Nov 6 2016, 11:57) *
А какие регистры?

Очевидно же: те, которые могут представлять интерес. Можно все. Не стесняйтесь, открывайте мануал и читайте про то, что такое NVIC, зачём он нужен, и как он работает.
Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 10:06
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(scifi @ Nov 6 2016, 14:18) *
Очевидно же: те, которые могут представлять интерес. Можно все. Не стесняйтесь, открывайте мануал и читайте про то, что такое NVIC, зачём он нужен, и как он работает.
...ять.... знал бы прикуп, жилбы в рио как решить проблему и какие регистры помогут, сюда бы не обращался. Какой конкретно регистр в NVIC может сказать чем было вызвано прерывание? Их там не так много.
Interrupt set-enable registers (NVIC_ISERx) - этот? наврятли.
может это Interrupt clear-enable registers (NVIC_ICERx)? Из названия видно что не этот.
может быть вот этот "The IABR0-IABR2 registers indicate which interrupts are active.".... 512 в нем. это вроде как 9-ый бит в "1", т.е. 9-ое прерывание активно. 9-е прерывание это как раз EXTI Line3 interrupt. Но ПОЧЕМУ оно активно? В каком NVIC регистре конкретно посмотреть ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 6 2016, 10:37
Сообщение #7


Гуру
******

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



Цитата(juvf @ Nov 6 2016, 13:06) *
ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?

Похоже на чудеса. Попробуйте запретить прерывание для EXTI3 (точнее не разрешайте его в NVIC).
Может, у вас где-то в другом месте бага и управление как-то попадает в функцию EXTI3_IRQHandler().
Go to the top of the page
 
+Quote Post
scifi
сообщение Nov 6 2016, 10:39
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(juvf @ Nov 6 2016, 13:06) *
может быть вот этот "The IABR0-IABR2 registers indicate which interrupts are active.".... 512 в нем. это вроде как 9-ый бит в "1", т.е. 9-ое прерывание активно. 9-е прерывание это как раз EXTI Line3 interrupt. Но ПОЧЕМУ оно активно? В каком NVIC регистре конкретно посмотреть ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?

На самом деле я имел в виду исключить вариант, когда другое прерывание вызывает этот обработчик (кривая таблица векторов, например). Исключили.
Про EXTI и выход из Stop mode, увы, ничего не могу сказать, ибо не доводилось использовать. В мануале оно всё как-то хитровывернуто описано, разбираться лень.
Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 10:51
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(adnega @ Nov 6 2016, 15:37) *
Попробуйте запретить прерывание для EXTI3 (точнее не разрешайте его в NVIC).
Может, у вас где-то в другом месте бага и управление как-то попадает в функцию EXTI3_IRQHandler().

Да я тоже думал что где-то НЕ из-за эксти падает в EXTI3_IRQHandler(). Но NVIC всётаки говорит что активное прерывание EXTI3 (спс scifi wink.gif ). Есть ещё мысль, что к EXTI3 подключено какоенить другое событие не только порт РА3? например RTC или какая нить другая периферия.... лан... буду разбираться...

Цитата
Похоже на чудеса.
Согласен.... хоть проц перепаивай...
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 6 2016, 11:56
Сообщение #10


Гуру
******

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



Цитата(juvf @ Nov 6 2016, 13:51) *
Согласен.... хоть проц перепаивай...

Может, оптимизация как-то мудрит и выкидывает переменную "a".
Как вы установили, что PR == 0 ?
Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 12:00
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(adnega @ Nov 6 2016, 16:56) *
Как вы установили, что PR == 0 ?

в статическую переменную записал EXTI->PR после выхода из стопа и после входа в прерывание.

ПОБЕДИЛ ЧУДО!!! Заработало!!! В 2-х словах - обработчик может быть вызван без флага прерывания, или это можно назвать отложенное прерывание. Если интересно... распишу...
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 6 2016, 12:27
Сообщение #12


Гуру
******

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



Цитата(juvf @ Nov 6 2016, 15:00) *
ПОБЕДИЛ ЧУДО!!! Заработало!!! В 2-х словах - обработчик может быть вызван без флага прерывания, или это можно назвать отложенное прерывание. Если интересно... распишу...

Как правило есть два бита: периферийный и NVIC-овский.
Когда периферийный срабатывает, он устанавливает NVIC-овский.
Когда дело доходит до обработчика, NVIC-овский аппаратно сбрасывается (при выходе?),
а в обработчике нужно сбросить периферийный. Если делать это в самом конце, то
будет повторное вхождение в обработчик, но уже со сброшенным периферийным битом.
Поэтому всегда нужно проверять установку периферийного бита. И сбрасывать его как можно раньше,
а если сбрасываешь в конце обработчика, то перед выходом добавить NOP, а еще правильнее барьер (DSB?).

Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 12:50
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



2adnega, это всё известно и периферийный сбрасывается сразу же при входе в прерывание. подвох в другом месте был. в NVIC. вобщем при входе в стоп готовлю эксти3 для пробуждения, разрешаю прерывание от ексти3 и ухожу в стоп. после пробуждения сбрасываю флаг эксти3 и запрещаю прерывания от эксти3. Вот тут и грабля....

после выхода из стопа всего лиш запрещал прерывания, т.е. думал что строчки NVIC_DisableIRQ(EXTI3_IRQn); для запрета прерывания достаточно. Так то да, NVIC больше не вызывал обработчик, но нога РА3 дергалась и EXTI3_IRQn срабатывало и взводило флаг прерывания в EXTI, и флаг NVIC-овский, так называемый IRQn pending.

перед очередным стопом я сбрасывал флаг в EXTI (PR) и разрешал NVIC-ку прерывание. А у NVIC взведён и ждет IRQn pending. Он принудительно вызывал обработчик прерывания, не смотря на то, что у EXTI прерывания нет.

ps а сбросить IRQn pending в NVIC не получилось. Вроде NVIC_ClearPendingIRQ(EXTI3_IRQn) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг.
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 6 2016, 13:59
Сообщение #14


Гуру
******

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



Цитата(juvf @ Nov 6 2016, 15:50) *
после пробуждения сбрасываю флаг эксти3 и запрещаю прерывания от эксти3. Вот тут и грабля....

Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ?

Цитата(juvf @ Nov 6 2016, 15:50) *
ps а сбросить IRQn pending в NVIC не получилось. Вроде NVIC_ClearPendingIRQ(EXTI3_IRQn) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг.

Я обычно делаю так: настраиваю периферию, но не разрешаю прерывание; настраиваю и разрешаю NVIC предварительно сбросив флаг от периферии;
разрешаю прерывание в периферии.

Запрещаю прерывания только на уровне периферии (например, при передаче по UART).
Запрещать/разрешать в NVIC давным-давно решил для себя считать источником потенциальных проблем (приоритеты, многопоточность,
правильные последовательности разрешения/запрещения).
Go to the top of the page
 
+Quote Post
juvf
сообщение Nov 6 2016, 14:07
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(adnega @ Nov 6 2016, 18:59) *
Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ?
да кстати.... может вы правы... я тоже делаю все запреты/разрешения прерывания на уровне перефирии, например

Код
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_TC, DISABLE);
Но с EXTI первый раз свезался, нужен был стоп режим.... почему-то на уровень NVIC ушел. Спс за совет.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:17
Рейтинг@Mail.ru


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