Перейти к содержанию

    

STm32F4 Возникает неразрешенное прерывание по заднему фронту

9 минут назад, vlad_new сказал:

Не знаю что там библиотеках индюшка понаписал

Забавно слышать от человека, пишущего в EXTI->PR через операцию "|=".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем ISB? Для этого как раз DSB нужен. Хотя и он может не помочь, если память работает с буфером записи. Джозеф Ю рекомендовал однозначно хорошую идею - после записи регистра сброса "pending"-бит считать его же, перед выходом из прерывания. А вот саму очистку флажка прерывания лучше да, делать в начале обработчика.

1 hour ago, jcxz said:

Писали уже не раз про этот фиче-баг в STM32...

Дак вроде ж архитектурная особенность, а не только STM32, разве не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 минуты назад, Arlleex сказал:

Зачем ISB? Для этого как раз DSB нужен. Хотя и он может не помочь, если память работает с буфером записи.

Вроде и то и то должно работать. Хотя сам я чаще применяю DMB.  ;)

А при чём тут память? Разговор о записи в регистры IO. Как я понимаю любые буферы в МК на пути записываемых данных (если они есть) должны влиять на эти команды.

 

2 минуты назад, Arlleex сказал:

Дак вроде ж архитектурная особенность, а не только STM32, разве не так?

Может и так, но сколько я разных МК перепробовал на Cortex-M - нигде с этим не сталкивался. Но про STM32 слышал, что люди сталкиваются. Подозреваю, что в других МК ядро может автоматом выполнять аналог одной из этих инструкций при выходе из прерывания (при переходе по адресу 0xFFFFFFXX), а в STM32 - нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
12 minutes ago, jcxz said:

А при чём тут память? Разговор о записи в регистры IO. Как я понимаю любые буферы в МК на пути записываемых данных (если они есть) должны влиять на эти команды.

Ну я к тому, что регистры - это, грубо говоря, память с атрибутом доступа "Device, Non-shareable": http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16220.html

Про ситуацию, где DSB при выходе из прерывания может не помочь, я имел ввиду в случае, если DSB находится перед непосредственно выходом из прерывания, поскольку память типа "Device" (а это регистры I/O) может буферизоваться:

Quote

The different ordering requirements for Device and Strongly-ordered memory mean that the memory system can buffer a write to Device memory, but must not buffer a write to Strongly-ordered memory.

Ссылка на первоисточник: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/CIHGEIID.html

Таким образом, из-за буфера записи можно успеть выйти из прерывания (даже после DSB) и тут же в него влететь. Я об этой коварной ситуации:smile:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 hour ago, Сергей Борщ said:

Забавно слышать от человека, пишущего в EXTI->PR через операцию "|=".

Ну это ограничение самого GCC. Пока есть всего два доступных модификатора const и volatile для типов - ситуация не изменится. Тут нужен модификатор "только запись", но его пока не изобрели.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
38 минут назад, AVI-crak сказал:

Ну это ограничение самого GCC

Правда? А как поступют счастливые пользователи ИАРа, Кейла и прочих компиляторов?

38 минут назад, AVI-crak сказал:

Пока есть всего два доступных модификатора const и volatile для типов - ситуация не изменится

Если бы там был const, то оператор "|=" компилятор не пропустил бы. Вы, похоже, не поняли сути - бит в этом регистре сбрасывается записью единицы и использвание операции "|=" сбрасывает все установленные в этом регистре биты. Не сильно гордые, но грамотные программисты используют в таких случаях конструкцию 

EXTI->PR = (1<<12);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
13 minutes ago, Сергей Борщ said:

Правда? А как поступют счастливые пользователи ИАРа, Кейла и прочих компиляторов?

Совершают точно такие-же ошибки.

Модификаторы const и volatile, а так-же их комбинации - не позволяют реализовать условие - "только запись". 

Наличие такого нового модификатора могло-бы запретить чтение из регистра. Выдав ошибку ещё в процессе набора кода.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
21 минуту назад, AVI-crak сказал:

Наличие такого нового модификатора могло-бы запретить чтение из регистра.

Но этот регистр доступен как на чтение, так и на запись.

22 минуты назад, AVI-crak сказал:

Совершают точно такие-же ошибки.

Тогда при чем тут GCC?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 minute ago, Сергей Борщ said:

Но этот регистр доступен как на чтение, так и на запись.

Физически - да, а по смыслу - нет. Чтение их этого регистра не имеет смысла, он всегда успевает сбросится в ноль аппаратно. Но GCC об это не знает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 минуты назад, AVI-crak сказал:

Чтение их этого регистра не имеет смысла, он всегда успевает сбросится в ноль аппаратно.

Что за ерунда? Чтение этого регистра - вполне штатная и очень полезная в определенных ситуациях операция. И аппаратно он не сбрасывается.

4 минуты назад, AVI-crak сказал:

Но GCC об это не знает.

Еще раз: при чем тут GCC? Что об этом знают ИАР, Кейл и прочие?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
18 minutes ago, AVI-crak said:

Физически - да, а по смыслу - нет. Чтение их этого регистра не имеет смысла, он всегда успевает сбросится в ноль аппаратно. Но GCC об это не знает.

:shok:

А как же:

EXTI_GetITStatus(...)

Функция:

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
{
  FlagStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
  
  if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
  
}

Как без чтения убедиться, что сработало именно то прерывание, что нужно? Вы что-то явно перепутали:scratch_one-s_head:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перепроверил.

EXTI->PR сбрасывается в ноль после записи единицы. Читать его нужно только в случае множества линий на одно прерывание, а таких всего два EXTI9_5_IRQHandler и EXTI15_10_IRQHandler.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
20 minutes ago, AVI-crak said:

Перепроверил.

EXTI->PR сбрасывается в ноль после записи единицы. Читать его нужно только в случае множества линий на одно прерывание, а таких всего два EXTI9_5_IRQHandler и EXTI15_10_IRQHandler.

А это и есть общий случай. А это значит, что запрещать средствами компилятора чтение никак не представится возможным.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
17 hours ago, AVI-crak said:

Модификаторы const и volatile, а так-же их комбинации - не позволяют реализовать условие - "только запись". 

Мне кажется это неверное утверждение, не по теме и может вводить в заблужение, можно сказать так:
 const - позволяет реализовать только чтение
 volatile - позволяет реализовать и запись и чтение

Это вроде как стандарт, неважно это GCC, ARMCC или IAR Compiler

P.S Извиняюсь перед TS за ответ не по теме

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
On 11/12/2018 at 4:57 PM, vlad_new said:

EXTI->PR|=(1<<12);                                         // clear pending interrupt PA12

 

Вообще-то EXTI->PR = (1<<12);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти