|
Есть ли жизнь после WFI?, атомарность WFI |
|
|
|
Jun 1 2015, 18:34
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078

|
Здравствуйте! Я тут задумался о такой потенциальной проблеме при использовании инструкции WFI: Предположим, что программа должна дождаться получения байта по UART, логичным был бы код Код while(!Uart.DataAvailable()) { __WFI(); } // тут обработка данных Но проблема в том что искомый байт может придти между Uart.DataAvailable() и __WFI(), вызовется обработчик прерывания, после которого вызовется __WFI() и МК больше никогда не проснется. Вставка критических секций: Код __disable_irq(); // тут что-то __enable_irq(); __WFI(); не спасет ситуацию, так как между __enable_irq(); и __WFI(); может проскочить нужное прерывание(а может не проскочить). Поиски вывели меня на вот эту англоязычную тему: http://community.arm.com/message/8927 и доку http://infocenter.arm.com/help/index.jsp?t...a/BIHBFEIB.htmlНо я так и не понял, что есть решение проблемы. Так есть ли в Cortex-M гарантированный способ проснуться после WFI?
|
|
|
|
|
 |
Ответов
(15 - 29)
|
Jun 4 2015, 00:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Brain13 @ Jun 3 2015, 21:01)  Тема начинается со слов "Предположим, что программа должна дождаться получения байта по UART" В системе присутствует множество источников прерываний: SPI, UART, SysTick, Таймеры, Внешние прерывания и прочее. Но все это к решению задачи не относится. К решению какой задачи? Про сферического коня в вакууме в которой специально создаются некие условия, отметается другая постановка задачи и системные решения и начинается решаться "задача"? QUOTE Если это так важно, то я делал код для бутлоадера, который Да, ну очень важная функция бутлоадера засыпать между отправками байтов. Ну, допустим, без экономии жить нельзя... QUOTE при переполнении буфера ждет пока хотябы один байт будет отправлен в UART и тогда в буфере появится место для добавления еще одного байта. DMA, FIFO а так-же, прочие "ценные ресурсы" контролера не должны использоваться, потому, что потому  .... QUOTE Использовать таймер или любую другую периферию для ожидания байта по UART - вот это решение через анус. Понятое дело, что в конечом итоге процессор проснется, но это костыль и надежда на "авось его что-нибудь другое разбудит". Через анус, большой и огромный, это НЕ использовать в Вашем загрузчике те-же таймауты для выхода и множества других ситуаций, когда по множеству причин отвалится тот-же канал связи с загрузчиком или вообще весь мир забудет о том, что какой-то там контроллер передавал байты. QUOTE (aaarrr @ Jun 3 2015, 23:49)  Вообще, не понимаю шума, поднятого отдельными товарищами. ТС озвучил вполне реальную проблему и один из путей её решения. Не открытие, но за напоминание, безусловно спасибо. QUOTE Так ведь нет, надо свести к частным случаям и доказать, что это никому не нужно. А тут у меня диаметрально противоположная точка зрения о том, что является "частным случаем". К частному, вырожденному случаю свел именно Автор.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 4 2015, 08:07
|

Знающий
   
Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663

|
Цитата(Golikov A. @ Jun 4 2015, 10:26)  Поэтому правильно этот кусок кода писать в таком виде
_irq_disable(); .... //какие то проверки возможности уснуть __WFI(); _irq_enable(); Прошу пощения, как (чем) при запрещённых прерываниях ядро будет выведено из (цитирую ARM DDI 0403E.  "suspend execution and enter a low-power state. It can remain in that state until the processor detects one of the following WFI wakeup events: • A reset. • An asynchronous exception at a priority that, if PRIMASK was set to 0, would preempt any currently active exceptions. Note The processor ignores the value of PRIMASK in determining whether an asynchronous exception is a WFI wakeup event. • If debug is enabled, a debug event. • An IMPLEMENTATION DEFINED WFI wakeup event."? (конец цитаты) Какое событие из списка позволит исполнить _irq_enable()?
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Jun 4 2015, 10:51
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ViKo @ Jun 4 2015, 13:34)  А что в ней написано?  Действительно, что? Цитата(ViKo @ Jun 4 2015, 13:34)  В тех примерах, что я посмотрел, везде разрешаются прерывания перед использованием WFI. Далеко не всегда в запрещении прерываний есть необходимость. Необходимость возникает, когда WFI выполняется в зависимости от условия, которое может измениться в прерывании.
|
|
|
|
|
Jun 4 2015, 11:45
|

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

|
Цитата(aaarrr @ Jun 4 2015, 13:51)  Действительно, что? Что независимо от запрещенных прерываний (установленного бита в BASEPRI командой _disable_irq) может разбудить процессор: • событие Debug • некое IMPLEMENTATION DEFINED WFI. Это говорит о том, что любое запрещенное прерывание может разбудить процессор? Неправильно. Примечание относится к пункту 2. Хорошо... будем искать дальше...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|