У меня есть этот код, который работает под KEIL, но не под GCC, и я не знаю, почему это происходит. Он тестирует некоторые функциональные возможности RTX OS.Почему моя программа не вводит режим обработчика в GCC?
Handler:
void GenWait_IRQHandler (void) {
switch (ISR_ExNum) {
case 0: Stat_Isr = osDelay (10); break;
#if (osFeatureWait)
case 1: Stat_Isr = osWait (10); break;
#endif
}
}
Приведенный выше код вводится путем установки отложенного IRQ от основной:
...
ISR_ExNum = 0; /* Test: osDelay */
NVIC_SetPendingIRQ((IRQn_Type)SWI_HANDLER);
ASSERT_TRUE (Stat_Isr == osErrorISR);
...
Проблема заключается в том, что это ASSERT_TRUE()
терпит неудачу, потому что Stat_Isr
не равна osErrorISR
, которые она должна быть поскольку в режиме обработчика не разрешается звонить osDelay()
:
osStatus osDelay (uint32_t millisec) {
if (__get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcDelay(millisec);
}
Как я уже говорил, при компиляции под KEIL он отлично работает, но при компиляции под GCC он терпит неудачу. Похоже, что IPSR не обновляется при вводе обработчика, и osDelay()
не знает, что он должен возвращать ошибку. Любая идея, почему это происходит?
SWI_Handler
- это программный обработчик, и я звоню в GenWait_IRQHandler()
.
EDIT:
Это реализация доступна из KEIL пакетов в качестве проверки RTX, я просто пытаюсь заставить его работать на чипе, я работаю с. Поэтому он должен работать, даже если я вызываю функции из ISR.
Кроме того, как я написал в комментарии:
(от www.keil.com):
обслуживания прерываний (ISR) можно назвать некоторые функции CMSIS-RTOS. Когда функция CMSIS-RTOS не может быть вызвана из контекста ISR, она отклоняет вызов.
И потом:
Функции, которые не могут быть вызваны из ISR проверяемая статуса прерывания и возврата, в случае, если они вызываются из контекста ISR, код состояния
osErrorISR
. В некоторых реализациях это условие может быть захвачено с использованием вектора HARD FAULT.
EDIT2:
Снижение оптимизации от -O3 до -O1 фиксированной ISSE, но я до сих пор не знаю, почему она была оптимизирована, как это и как я могу легко предотвратить компилятор от делать это. Я знаю, что самый простой ответ - добавить пару «volatile», но это не так просто в этом случае, я думаю.
Вы уверены, что безопасно вызывать функции OS в обработчике прерываний? – EOF
Я уверен, что это так, как я ожидаю, что он вернет ошибку. –
Ищите различия в сборке, сгенерированной компиляторами. Являются ли 'ISR_ExNum' и' Stat_Isr' объявленными как изменчивые? Оптимизация компилятора отключена для обеих цепочек инструментов? – kkrambo