我正在使用arm的keil编译器(stm32F4)。在我的代码中,我创建了一个计时器来调用一个从* .lib文件调用函数的函数。
如果我使用链接器优化级别0(O-0)并且应用程序正常工作,则会调用该函数。如果我将优化级别更改为(O-1),则该函数不会包含在可执行文件中。
我在监视窗口中检查了计时器结构,并且正在更新计数器值,并且存在与地图文件中的地址匹配的回调函数地址。
从keil帮助中我了解到,在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"
答案 0 :(得分:0)
由于它在没有优化的情况下工作,我建议在启用优化时欺骗编译器。具体来说,你可以这样做:
if ( funcReturnsFalse() )
{
CallBackFcn( param1, param2 ); // Whatever your real callback is
}
您不想实际拨打电话,因为这会在优化关闭时更改您的工作逻辑。编译器可能足够聪明,可以理解像if ( false ) ...
这样的东西,所以有一个函数调用(funcReturnsFalse())可能足以让编译器相信你将使用CallBackFcn()
。
我之前遇到过这个问题(不是Micrium),这种技术对我有用。