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

TEventFlag Cortex-M3 LPC1766

Добрый день.

Возникла проблема при использовании TEventFlag. Если в прерывании используестя метод SignalISR, то процесс, ожидающий событие просыпается, а если Signal, то не пробуждается. Причём перестают работать все процессы и крутимся в void TKernel::Sched().

Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом? У кого-нибудь проявлялся данный эффект?

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


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

Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом?
А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано.

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


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

А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано.

 

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

TEventFlag::Signal()

«сигналить». Процесс, который желает сообщить

посредством объекта TEventFlag другим процес-

сам о том, что то или иное событие произошло,

должен вызвать функцию Signal(). При этом все

процессы, ожидающие указанное событие, будут

переведены в состояние готовых к выполнению,

а управление получит самый приоритетный из

них (остальные в порядке очередности приорите-

тов);

А функция-член TEventFlag::SignalISR(), как написано, оптимизированный вариант для использования в прерываниях.

TEventFlag::SignalISR()

вариант вышеописанной функции, оптимизиро-

ванный для использования в прерываниях (при

использовании способа передачи управления на

основе программного прерывания). Функция яв-

ляется встраиваемой и использует специальную

облегченную встраиваемую версию планировщи-

ка. Этот вариант нельзя использовать вне кода

обработчика прерываний.

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


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

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

 

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


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

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

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

 

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

 

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

 

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

 

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

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


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

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

 

Да, действительно. Именно в этом прерывании и забыл TISRW. Спасибо. Заработало и с Signal.

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


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

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

 

Да, но проблема в том, что я не знаю откуда вызвалась функция, которая дёргает SignalISR. :) Она может вызваться не только из прерывания

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...