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

 
 
 
Reply to this topicStart new topic
> TEventFlag Cortex-M3 LPC1766, вызов Signal() в прерывании не пробуждает процесс
LessNik
сообщение Mar 15 2011, 09:26
Сообщение #1


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

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Добрый день.
Возникла проблема при использовании TEventFlag. Если в прерывании используестя метод SignalISR, то процесс, ожидающий событие просыпается, а если Signal, то не пробуждается. Причём перестают работать все процессы и крутимся в void TKernel::Sched().
Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом? У кого-нибудь проявлялся данный эффект?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 15 2011, 09:49
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (LessNik @ Mar 15 2011, 11:26) *
Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом?
А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
LessNik
сообщение Mar 15 2011, 10:36
Сообщение #3


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

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(Сергей Борщ @ Mar 15 2011, 12:49) *
А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано.


В документации написано, что TEventFlag::SignalISR() "нельзя использовать вне кода обработчика прерываний", так я его и не использую вне обработчика. А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания.
Цитата
TEventFlag::Signal()
«сигналить». Процесс, который желает сообщить
посредством объекта TEventFlag другим процес-
сам о том, что то или иное событие произошло,
должен вызвать функцию Signal(). При этом все
процессы, ожидающие указанное событие, будут
переведены в состояние готовых к выполнению,
а управление получит самый приоритетный из
них (остальные в порядке очередности приорите-
тов);

А функция-член TEventFlag::SignalISR(), как написано, оптимизированный вариант для использования в прерываниях.
Цитата
TEventFlag::SignalISR()
вариант вышеописанной функции, оптимизиро-
ванный для использования в прерываниях (при
использовании способа передачи управления на
основе программного прерывания). Функция яв-
ляется встраиваемой и использует специальную
облегченную встраиваемую версию планировщи-
ка. Этот вариант нельзя использовать вне кода
обработчика прерываний.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 15 2011, 10:57
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (LessNik @ Mar 15 2011, 12:36) *
А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания.
Да, действительно. Спасибо, исправим. Логика проста: Signal() запускает перепланировку. Перепланировка делается в обработчике программного прерывания. Приоритет у обработчика - самый низкий. А вы уже находитесь обработчике более высокоприоритетного прерывания. Поэтому прерывание переключения контекста не может быть вызвано и перепланировка не может закончиться.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 15 2011, 11:31
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(LessNik @ Mar 15 2011, 16:36) *
В документации написано, что TEventFlag::SignalISR() "нельзя использовать вне кода обработчика прерываний", так я его и не использую вне обработчика. А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания.

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

INLINE void Scheduler() { if(ISR_NestCount) return; else Sched(); }

ISR_NestCount инкрементируется в конструкторе класса TISRW, объект которого должен быть объявлен в ISR.

Т.е. негатив тут только в том, что процесс, который ждёт флага, будет переведён в готовые к выполнению только при следующем вызове планировщика, что, конечно, ухудшает время реакции на событие. Но нарушения целостности работы тут не должно возникать.

А вот нехорошести могут происходить, если в обработчике прерываний не завели "обёртку" TISRW. И если это так, то это по-любому ошибка, любой ISR, использующий сервисы ОС, должен содержать объект этого класса.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
LessNik
сообщение Mar 15 2011, 13:16
Сообщение #6


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

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(dxp @ Mar 15 2011, 14:31) *
А вот нехорошести могут происходить, если в обработчике прерываний не завели "обёртку" TISRW. И если это так, то это по-любому ошибка, любой ISR, использующий сервисы ОС, должен содержать объект этого класса.


Да, действительно. Именно в этом прерывании и забыл TISRW. Спасибо. Заработало и с Signal.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 16 2011, 03:03
Сообщение #7


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(LessNik @ Mar 15 2011, 19:16) *
Заработало и с Signal.

sm.gif Но все равно правильнее SignalISR использовать.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
LessNik
сообщение Mar 16 2011, 06:12
Сообщение #8


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

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(dxp @ Mar 16 2011, 06:03) *
sm.gif Но все равно правильнее SignalISR использовать.


Да, но проблема в том, что я не знаю откуда вызвалась функция, которая дёргает SignalISR. sm.gif Она может вызваться не только из прерывания
Go to the top of the page
 
+Quote Post

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

 


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


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