Функция обратного вызова таймера Micrium OS -III не вызывается

Я использую компилятор Keil для руки (STM32F4). В своем коде я создал таймер для вызова функции, которая вызывает функцию из файла * .lib.

Функция вызывается, если я использую оптимизацию компоновщика уровня 0 (O-0) и приложение работает нормально. Если я изменяю уровень оптимизации на (O-1), функция не включается в исполняемый файл.

Я проверил структуру таймера в окне просмотра, обновляются значения счетчика и присутствует адрес функции обратного вызова, который совпадает с адресом в файле карты.

Из помощи Кейла я узнал, что при оптимизации уровня 1-o1 выполняются следующие оптимизации.

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

Я пытался вызвать функцию lib из задачи. Но все же происходит то же самое.
Поскольку на функцию ссылались напрямую, я подозреваю, что компилятор считает, что эта функция не имеет побочных эффектов.

Как я могу решить это?

void LCDVsync_TMRHandler(void *ptmr, void *parg)
{
OS_ERR err;
OSWrappers::signalVSync();

}

void LCDFrontPorch_TMRHandler(void *ptmr,void *arg)
{
OS_ERR err;
HAL::getInstance()->frontPorchEntered();
OSTmrStart(&ostmr_LCDVsync,&err);

}

Код, который создает таймер.

OSTmrCreate(&ostmr_LCDVsync,"LCD vsync signalling",10,0,OS_OPT_TMR_ONE_SHOT,LCDVsync_TMRHandler,(void *)0,&err);
if(OS_ERR_NONE != err)
{
DEBUG_ERROR_APP("ERROR: APP.C : AppTmrCreate : LCD vsync signalling tmr create failure");
}
OSTmrCreate(&ostmr_LCDFrontPorch,"LCD Front porch",0,20,OS_OPT_TMR_PERIODIC,LCDFrontPorch_TMRHandler,(void *)0,&err);
if(OS_ERR_NONE != err)
{
DEBUG_ERROR_APP("ERROR: APP.C : AppTmrCreate : LCD vsync signalling tmr create failure");
}

Код, запускающий периодический таймер.

OSTmrStart(&ostmr_LCDFrontPorch,&err);

Строка управления компилятором.

c --cpu Cortex-M4.fp -g -O0 --apcs=interwork -I..\platform\3rd_Party_ST\Drivers\CMSIS\Include
-I C:\Users\bro\Desktop\Project\Charger\Workspace\some\yeah\RTE
-I C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0
-I C:\Keil_v5\ARM\CMSIS\Include
-I    C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\Drivers\CMSIS\Device\ST\STM32F4xx\Include
-D__UVISION_VERSION="513" -DSTM32F429xx -DUSE_HAL_DRIVER -DSTM32F429xx -DUSE_STM324x9I_EVAL -DUSE_I2C1 -DUSE_SPIX -DUSE_USB_FS -DUSECB_SDOREQ -o ".\Objects\*.o" --omf_browse ".\Objects\*.crf" --depend ".\Objects\*.d"

1

Решение

Так как он работает без оптимизации, я бы предложил обмануть компилятор, когда оптимизация включена. В частности, вы можете сделать что-то вроде этого:

if ( funcReturnsFalse() )
{
CallBackFcn( param1, param2 );   //  Whatever your real callback is
}

Вы не хотите фактически делать вызов, потому что это меняет логику, с которой вы работаете, пока оптимизация выключена. И компилятор, вероятно, достаточно умен, чтобы понять что-то вроде if ( false ) ...поэтому для вызова компилятора, вероятно, достаточно иметь вызов функции (funcReturnsFalse ()) CallBackFcn(),

Я сталкивался с этой проблемой раньше (не с Micrium), и эта техника работала для меня.

0

Другие решения


По вопросам рекламы [email protected]