【问题标题】:Micrium OS -III Timer callback function not getting calledMicrium OS -III 定时器回调函数没有被调用
【发布时间】:2015-09-16 07:01:16
【问题描述】:

我正在为 arm(stm32F4) 使用 keil 编译器。在我的代码中,我创建了一个计时器来调用从 *.lib 文件调用函数的函数。

如果我使用链接器优化级别 0 (O-0) 并且应用程序工作正常,则会调用该函数。如果我将优化级别更改为 (O-1),则该函数不会包含在可执行文件中。

我检查了监视窗口中的计时器结构,计数器值正在更新,并且存在与映射文件中的地址匹配的回调函数地址。

从 keil 的帮助中我了解到,在 Level 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" 

【问题讨论】:

  • “函数未包含在可执行文件中”和“存在与映射文件中的地址匹配的回调函数地址”是什么意思?
  • 回调函数存在于地图文件中。我无法在该函数中设置断点。从 keil 帮助中,我了解到在 1-o1 级优化中完成了以下优化。 • 不能在死代码上设置断点。 • 变量的值在初始化后可能在其范围内不可用。例如,如果他们分配的位置已被重复使用。 • 没有副作用的函数可能被乱序调用,或者如果不需要结果则可能被省略。
  • 我怀疑lib函数是死代码,但供应商否认
  • 我尝试直接从任务中调用该函数。仍然发生同样的事情。它与 Micrium 计时器无关。

标签: c++ static-libraries keil micrium


【解决方案1】:

由于它在没有优化的情况下工作,我建议在优化打开时欺骗编译器。具体来说,您可以这样做:

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

您不想实际进行调用,因为这会改变您在优化关闭时的工作逻辑。并且编译器可能足够聪明,可以理解if ( false ) ... 之类的内容,因此有一个函数调用(funcReturnsFalse())可能足以让编译器相信你会使用CallBackFcn()

我以前遇到过这个问题(不是使用 Micrium),这种技术对我有用。

【讨论】:

  • 我通过创建 returnFalse() 尝试了您的建议,但编译器仍然没有包含回调。每次都会调用 returnFalse()。在您的答案中的代码 sn-p 之后,我输入了 CallBackFn(param1,param2)。代码是这样的: 'code' if (returnFalse()) { callback(0,0); } 回调(0,0); '代码'
  • @kernel,你能给我贴一些代码吗?计时器设置、回调函数以及带有地图的编译命令(编辑以适应)可能会有所帮助。
  • 我已编辑问题以添加代码。 OSWrappers::signalVSync(); & HAL::getInstance()->frontPorchEntered();库函数是否被调用
  • @kernel,上面提到的类名OSWrappers和HAL不在上面贴的源代码中。
  • @donjeudo 此代码对我不可用,因为这是库代码。它是不可见的。
猜你喜欢
  • 1970-01-01
  • 2017-07-26
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多