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

 
 
> 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
Ответов
jcxz
сообщение Mar 28 2016, 17:34
Сообщение #2


Гуру
******

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



А что собственно смущает? И зачем запрещать прерывания перед WFI? Прерывание происходит - работаем, вышли из последнего ISR - сразу в сон по WFI.
Go to the top of the page
 
+Quote Post
ataradov
сообщение Mar 28 2016, 17:48
Сообщение #3


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

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



QUOTE (jcxz @ Mar 28 2016, 10:34) *
А что собственно смущает? И зачем запрещать прерывания перед WFI? Прерывание происходит - работаем, вышли из последнего ISR - сразу в сон по WFI.


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

Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 28 2016, 17:55
Сообщение #4


Гуру
******

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



Цитата(ataradov @ Mar 28 2016, 23:48) *
Обработчик прерывания устанавливает флаг, что нужно что-то послать, он не делает никакой полезной работы, так что если сразу заснуть, то данные не будут отправлены.

А кто должен обслужить этот флаг? Код находящийся в другом ISR? Тогда нет проблем - произойдёт то IRQ и будет обработка.
Go to the top of the page
 
+Quote Post
ataradov
сообщение Mar 28 2016, 18:05
Сообщение #5


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

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



QUOTE (jcxz @ Mar 28 2016, 10:55) *
А кто должен обслужить этот флаг?


while (1) цикл в основной программе. Флаг имеется в виду программный - переменная.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Mar 28 2016, 19:16
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(ataradov @ Mar 28 2016, 19:05) *
while (1) цикл в основной программе. Флаг имеется в виду программный - переменная.

Программу надо организовать таким образом, чтобы инструкция "спать" исполнялась условно только тогда, когда все необходимые действия уже исполнены.
Предположим, что после сна в результате прерывания процессор проснулся и побежал исполнять инструкции после команды __WFI(). В прерывании, которое, по-видимому, и разбудило процессор, будут произведены некоторые короткие действия, после чего будет установлен флаг для синхронного цикла, завершить начатое. По крайней мере пока такой флаг установлен, исполнять инструкцию __WFI() нельзя. Когда же синхронный процесс всё сделает, флаг будет сброшен, и инструкция __WFI() будет исполнена.
В более сложных системах, например с OS, можно послать некоторое сообщение всем участникам сабантуя на предмет готовности поспать. Если все ответили согласием, инструкция __WFI() исполняется. И т.д, и т.п.

Go to the top of the page
 
+Quote Post
ataradov
сообщение Mar 28 2016, 19:23
Сообщение #7


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

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



QUOTE (KnightIgor @ Mar 28 2016, 12:16) *
Когда же синхронный процесс всё сделает, флаг будет сброшен, и инструкция __WFI() будет исполнена.
И получили гонку. Так как внешнее прерывание от кнопки может произойти когда угодно.

1. Спим
2. Прерывание
3. Установили флаг
4. Работаем
5. Сбросили флаг
6. Готовимся ко сну
7. Спим

Но теперь если произойдет 6a - Прерывание, то мы успешно установим флаг и уйдем в сон.

Правильный способ:

CODE
if (flag == 0)
{
  __disable_irq();

  if (flag == 0)
  {
    // подготовка ко сну
    __WFI();
  }

  __enable_irq();
}

Повторная проверка обязательная, иначе гонка все-равно будет.

Сообщение отредактировал ataradov - Mar 28 2016, 19:23
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Mar 28 2016, 19:45
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(ataradov @ Mar 28 2016, 20:23) *
И получили гонку.

Пока висит необработаное прерывание, __WFI() спать не кладёт. Конечно, если срубить флаг неатомарной операцией, то да, может получиться, что убъется только что установленный флаг. Но это не имеет отношения к __WFI(), это есть тема гонки с учетом неатомарности доступа к флагу. На то есть LDREX и иже с ним.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ataradov   Cortex и гонки при сне   Mar 28 2016, 17:12
|- - ataradov   QUOTE (KnightIgor @ Mar 28 2016, 12:45) П...   Mar 28 2016, 19:51
- - aaarrr   Еще можно так: Код /* Clear event register */ __s...   Mar 28 2016, 19:41
- - AVI-crak   Цитата(ataradov @ Mar 29 2016, 00:12) Что...   Mar 28 2016, 20:01
|- - ataradov   QUOTE (AVI-crak @ Mar 28 2016, 13:01...   Mar 28 2016, 20:12
|- - jcxz   Цитата(ataradov @ Mar 29 2016, 02:12) Это...   Mar 28 2016, 23:48
- - 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 Текстовая версия Сейчас: 21st July 2025 - 13:32
Рейтинг@Mail.ru


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