LessNik 0 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба Добрый день. Возникла проблема при использовании TEventFlag. Если в прерывании используестя метод SignalISR, то процесс, ожидающий событие просыпается, а если Signal, то не пробуждается. Причём перестают работать все процессы и крутимся в void TKernel::Sched(). Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом? У кого-нибудь проявлялся данный эффект? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба Это так задумано, что в прерываниях я обязан использовать SignalISR или дело в чём-то другом?А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LessNik 0 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба А как вы думаете, для чего была введена функция-член SignalISR? Да, обязан. В документации об этом сказано. В документации написано, что TEventFlag::SignalISR() "нельзя использовать вне кода обработчика прерываний", так я его и не использую вне обработчика. А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания. TEventFlag::Signal() «сигналить». Процесс, который желает сообщить посредством объекта TEventFlag другим процес- сам о том, что то или иное событие произошло, должен вызвать функцию Signal(). При этом все процессы, ожидающие указанное событие, будут переведены в состояние готовых к выполнению, а управление получит самый приоритетный из них (остальные в порядке очередности приорите- тов); А функция-член TEventFlag::SignalISR(), как написано, оптимизированный вариант для использования в прерываниях. TEventFlag::SignalISR() вариант вышеописанной функции, оптимизиро- ванный для использования в прерываниях (при использовании способа передачи управления на основе программного прерывания). Функция яв- ляется встраиваемой и использует специальную облегченную встраиваемую версию планировщи- ка. Этот вариант нельзя использовать вне кода обработчика прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания.Да, действительно. Спасибо, исправим. Логика проста: Signal() запускает перепланировку. Перепланировка делается в обработчике программного прерывания. Приоритет у обработчика - самый низкий. А вы уже находитесь обработчике более высокоприоритетного прерывания. Поэтому прерывание переключения контекста не может быть вызвано и перепланировка не может закончиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба В документации написано, что TEventFlag::SignalISR() "нельзя использовать вне кода обработчика прерываний", так я его и не использую вне обработчика. А вот про TEventFlag::Signal() не написано, что его нельзя использовать в обработчике прерывания. Вообще-то, фатального поведения вызов Signal() в обработчике прерываний порождать не должен. При этом вызове просто не будет реально вызван планировщик, потому что: INLINE void Scheduler() { if(ISR_NestCount) return; else Sched(); } ISR_NestCount инкрементируется в конструкторе класса TISRW, объект которого должен быть объявлен в ISR. Т.е. негатив тут только в том, что процесс, который ждёт флага, будет переведён в готовые к выполнению только при следующем вызове планировщика, что, конечно, ухудшает время реакции на событие. Но нарушения целостности работы тут не должно возникать. А вот нехорошести могут происходить, если в обработчике прерываний не завели "обёртку" TISRW. И если это так, то это по-любому ошибка, любой ISR, использующий сервисы ОС, должен содержать объект этого класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LessNik 0 15 марта, 2011 Опубликовано 15 марта, 2011 · Жалоба А вот нехорошести могут происходить, если в обработчике прерываний не завели "обёртку" TISRW. И если это так, то это по-любому ошибка, любой ISR, использующий сервисы ОС, должен содержать объект этого класса. Да, действительно. Именно в этом прерывании и забыл TISRW. Спасибо. Заработало и с Signal. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 16 марта, 2011 Опубликовано 16 марта, 2011 · Жалоба Заработало и с Signal. :) Но все равно правильнее SignalISR использовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LessNik 0 16 марта, 2011 Опубликовано 16 марта, 2011 · Жалоба :) Но все равно правильнее SignalISR использовать. Да, но проблема в том, что я не знаю откуда вызвалась функция, которая дёргает SignalISR. :) Она может вызваться не только из прерывания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться