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

 
 
> Cortex и гонки при сне
ataradov
сообщение Mar 28 2016, 17:12
Сообщение #1


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

Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202



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

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

Проблема видится в следующем: если сразу перед вызовом __WFI() происходит прерывание, которое начинает эту долгую работу. Но как только обработка прерывания завершится, все уйдет в сон.

Что я пропустил? Как правильно обрабатывать такие ситуации?

Edit:
Похоже __WFI() проснется даже если прерывания заблокированы, так что правильная последовательность:

__disable_irq();
// подготовка ко сну
__WFI();
__enable_irq();

Сообщение отредактировал ataradov - Mar 28 2016, 17:13
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AVI-crak
сообщение Mar 28 2016, 20:01
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Цитата(ataradov @ Mar 29 2016, 00:12) *
Что я пропустил? Как правильно обрабатывать такие ситуации?


Само понятие сна - это ожидание прерывания без работы ядра мк.

Допустим в коде без ос: прерывание связанное с точкой останова сбрасывает бинарный флаг, в точке сна в цикле проверяется флаг - профит, спим лишнее время.
do
{
__WFI();
}while(флаг);
сначала спим, а потом проверяем.

В коде с ос всё немного сложнее. Тут простой запрет прерываний применять нельзя, их необходимо выключать по одному - в момент когда они полностью отработали. Иначе получится банальный сбой программы. Ведь прерывание по сути - это отложенное событие. После - все задачи должны быть переведены в зависимость от главного потока (вытолкнуть из диспетчера в ожидание). Ну а сам основной поток - просто обязан "переключаться диспетчером в холостом режиме", но теперь он будет всё время находится в бесконечном цикле проверки флага от важного внешнего прерывания ( его есно нужно оставить). Всё это происходит очень быстро, а паузы между активностью просто громадные. МК спит, хотя это и не 100% сон, получается где-то 99,99% от номинала.

Сообщение отредактировал AVI-crak - Mar 28 2016, 20:10
Go to the top of the page
 
+Quote Post
ataradov
сообщение Mar 28 2016, 20:12
Сообщение #3


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

Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202



QUOTE (AVI-crak @ Mar 28 2016, 13:01) *
сначала спим, а потом проверяем.
Это все верно если ждем прерывания от внутренних источников, да и то не всегда.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 28 2016, 23:48
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ataradov @ Mar 29 2016, 02:12) *
Это все верно если ждем прерывания от внутренних источников, да и то не всегда.

Вам тут уже ответили об общем принципе:
WFI должна выполняться только тогда, когда выполнена вся запланированная работа и нет работы, которую надо выполнить.
Т.е. (в случае наличия ОС) задача самого нижнего приоритета (фоновая) должна выполнять простой цикл с всего одной инструкцией: WFI (или WFE).
Вся остальная работа - в ISR-ах или задачах ОС более высокого приоритета.
Всё моё ПО именно так и построено, вне зависимости от того - надо экономить энергию или нет - выполнение WFI в фоновом процессе - это просто правило хорошего тона если хотите wink.gif
Когда нужно установить Ваш флаг, ставите его (хоть в ISR, хоть в любой задаче) и какой-то объект синхронизации ОС (мэйлбокс например) переводите в состояние "готов'.
Далее - у Вас есть задача, ожидающая этот мэйлбокс. Как только мэйлбокс перешёл в сост. "готов" и нет более приоритетных задач, задача получает управление и обрабатывает его.
Любая установка готовности любому объекту синхронизации ОС - это вызов диспетчера ОС, который просмотрит список задач и переведёт те из них, которые готовы к выполнению, в состояние "готова".
Если окажется, что текущая задача ОС имеет приоритет ниже, чем новая готовая задача, то будет вызван переключатель контекста ОС. Вызов переключателя контекста ОС - это собственно программное возбуждение прерывания PendSV, имеющего самый низший приоритет из всех прерываний (ниже любого аппаратного IRQ).
Соответственно в ISR PendSV управление войдёт:
а) или сразу, если выполняется какая-то задача ОС (с более низким приоритетом, чем активизируемая);
б) или после завершения всех текущих ISR, если выполняется любой ISR.

Даже если Вы не используете ОС и у Вас всего одна полезная задача, всё равно лучше построить ПО по тому-же принципу: процедура установки Вашего флага, после его установки, возбуждает PendSV, которое переключит контекст с фоновой на полезную задачу (если уже не выполняется полезная), которая, сделав всю работу (и проверив в конце что флаг опять не установился), вызовет переключатель контекста на фоновую задачу.
Таким образом - как только возникает прерывание, ISR которого ставит флаг, управление находится в ISR-ах до тех пор, пока управление не получит полезная задача и не обработает флаг. И WFI может выполниться только тогда, когда флаг сброшен. И никакие гонки в принципе невозможны.

Цитата(ataradov @ Mar 29 2016, 01:23) *
1. Спим
2. Прерывание
3. Установили флаг
4. Работаем
5. Сбросили флаг
6. Готовимся ко сну
7. Спим
Но теперь если произойдет 6a - Прерывание, то мы успешно установим флаг и уйдем в сон.

6а - прерывание, установившее флаг и мэйлбокс (либо просто активировавшее PendSV если без ОС).
6б - сразу после завершения ISR вход в ISR PendSV (если без ОС); если с ОС - вход в PendSV только если выполнялась менее приоритетная задача, если более приоритетная - вход в PendSV после перехода её в сост. ожидания.
В любом случае после прерывания 6а и до пункта 7, будет выполнено PendSV (сразу или не сразу), которое переключит контекст на задачу обрабатывающую флаг. И управление дойдёт до пункта 7 только когда флаг уже будет обработан.
Запрет прерываний тут нигде не нужен. Хотя можно и запретить если сильно хочется - WFI вроде игнорит маску PRIMASK.
Можете, если без ОС, собственно сам обработчик PendSV сделать полезной задачей, обрабатывающей Ваш флаг. Тогда вся полезная работа у Вас всегда будет выполняться только в ISR-ах, установка Вашего флага будет всегда вызывать установку запроса PendSV.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ataradov   Cortex и гонки при сне   Mar 28 2016, 17:12
- - jcxz   А что собственно смущает? И зачем запрещать прерыв...   Mar 28 2016, 17:34
|- - ataradov   QUOTE (jcxz @ Mar 28 2016, 10:34) А что с...   Mar 28 2016, 17:48
|- - jcxz   Цитата(ataradov @ Mar 28 2016, 23:48) Обр...   Mar 28 2016, 17:55
|- - ataradov   QUOTE (jcxz @ Mar 28 2016, 10:55) А кто д...   Mar 28 2016, 18:05
|- - KnightIgor   Цитата(ataradov @ Mar 28 2016, 19:05) whi...   Mar 28 2016, 19:16
|- - ataradov   QUOTE (KnightIgor @ Mar 28 2016, 12:16) К...   Mar 28 2016, 19:23
|- - KnightIgor   Цитата(ataradov @ Mar 28 2016, 20:23) И п...   Mar 28 2016, 19:45
|- - ataradov   QUOTE (KnightIgor @ Mar 28 2016, 12:45) П...   Mar 28 2016, 19:51
- - aaarrr   Еще можно так: Код /* Clear event register */ __s...   Mar 28 2016, 19:41
- - Kabdim   Вчера уткнулся ровно в ту же задачу. Кмк большинст...   Mar 29 2016, 06:30
|- - ataradov   QUOTE (Kabdim @ Mar 28 2016, 23:30) А ваш...   Mar 29 2016, 06:33
|- - jcxz   Цитата(Kabdim @ Mar 29 2016, 12:30) Вчера...   Mar 29 2016, 08:22
|- - Kabdim   Цитата(jcxz @ Mar 29 2016, 11:22) А что т...   Mar 29 2016, 11:21
||- - jcxz   Цитата(Kabdim @ Mar 29 2016, 17:21) Нрави...   Mar 29 2016, 12:13
|- - AVI-crak   Цитата(jcxz @ Mar 29 2016, 19:13) Что там...   Mar 29 2016, 23:31
|- - GetSmart   Цитата(AVI-crak @ Mar 30 2016, 03:31...   Mar 30 2016, 01:59
||- - AVI-crak   Цитата(GetSmart @ Mar 30 2016, 08:59) Что...   Mar 30 2016, 03:30
|- - jcxz   Цитата(AVI-crak @ Mar 30 2016, 05:31...   Mar 30 2016, 05:32
|- - AVI-crak   Цитата(jcxz @ Mar 30 2016, 12:32) Бред...   Mar 30 2016, 06:38
||- - jcxz   Цитата(AVI-crak @ Mar 30 2016, 12:38...   Mar 30 2016, 07:41
|- - ataradov   QUOTE (jcxz @ Mar 29 2016, 22:32) Полност...   Mar 30 2016, 07:54
|- - jcxz   Цитата(ataradov @ Mar 30 2016, 13:54) Все...   Mar 30 2016, 08:19
|- - ataradov   QUOTE (jcxz @ Mar 30 2016, 01:19) Вы даже...   Mar 30 2016, 08:23
|- - AVI-crak   Цитата(ataradov @ Mar 30 2016, 15:23) Раз...   Mar 30 2016, 13:02
|- - ataradov   QUOTE (AVI-crak @ Mar 30 2016, 06:02...   Mar 30 2016, 15:32
- - Alechek   Дейсвтельно мутно. Как оно может ПОТЕРЯТСЯ? Особен...   Mar 30 2016, 04:24
- - ViKo   Не нашел, чтобы кто-то из участников данной дискус...   Mar 30 2016, 06:07
|- - jcxz   Цитата(ViKo @ Mar 30 2016, 12:07) Не наше...   Mar 30 2016, 06:20
- - Alechek   Я тоже не понял, к чему весь этот треп. Последова...   Mar 30 2016, 12:12
- - ViKo   Не имеет значения, как долго тянется прерывание, е...   Mar 30 2016, 16:39
- - jcxz   Цитата(ViKo @ Mar 30 2016, 22:39) Не имее...   Mar 31 2016, 05:58
- - ataradov   QUOTE (jcxz @ Mar 30 2016, 22:58) Я это у...   Mar 31 2016, 06:01
- - jcxz   Цитата(ataradov @ Mar 31 2016, 12:01) Ну ...   Mar 31 2016, 06:21


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

 


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


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