Доброго дня!
Решил поднять тему вот таким вопросом.
Создаю ПО под Freescale M0+ с использованием scmRTOS. Четыре процесса:
CODE
typedef OS::process<OS::pr0, 512> TProc1;
typedef OS::process<OS::pr1, 512> TProc2;
typedef OS::process<OS::pr2, 512> I2C0_TASK;
typedef OS::process<OS::pr3, 1024> TBackgroundProc;
Есть прерывания:
CODE
TRTC rtc;
OS_INTERRUPT void RTC_second_Handler()
{
OS::TISRW TISRW_O;
rtc.RtcSecondIrqHandler();
OneSecondFlag.signal_isr();
}
Устанавливаю флаг в прерывании и ловлю его в процессе TProc1:
CODE
template<> OS_PROCESS void TProc1::exec()
{
for(;;)
{
OneSecondFlag.wait();
// while (!rtc.getNewSecondFlag());
led_bl.Cpl();
sleep(5);
}
}
Вылетает по HardFault. Если закомментировать OneSecondFlag.signal_isr(); то не вылетает. Ковыряюсь уже довольно долго. Накопал, что при восстановлении контекстов из критических секций происходит лишнее действие, которое затирает правильно восстановленный контекст.
Если использовать флаг rtc.getNewSecondFlag(), вызываемый из объекта, то всё ОК.
Куда копать?
Вдогонку:
Вылетает при выполнении кода:
CODE
bool OS::TEventFlag::wait(timeout_t timeout)
{
TCritSect cs;
if(Value) // if flag already signaled
{
Value = efOff; // clear flag
return true;
}
else
{
cur_proc_timeout() = timeout;
suspend(ProcessMap);
if(is_timeouted(ProcessMap))
return false; // waked up by timeout or by externals
cur_proc_timeout() = 0; <== вылетает при попытке выполнить эту инструкцию - обращение к несуществующей памяти
return true; // otherwise waked up by signal() or signal_isr()
}
}