1

I am using keil compiler for arm(stm32F4). In my code I have created a timer to call a function which calls a function from a *.lib file.

The function is getting called if I am using linker optimization level-0 (O-0) and the application works fine. If I am changing optimization level to (O-1), the function is not getting included in executable.

I checked the timer structure in watch window and the counter values are being updated and the callback function address is present which matches the address in map file.

From the keil help I got to know that in Level 1-o1 optimization the following optimizations are done.

  • Breakpoints may not be set on dead code.
  • Values of variables may not be available within their scope after
    they have been initialized. For example if their assigned location
    has been reused.
  • Functions with no side-effects may be called out of sequence, or may be omitted if the result is not needed.

I tried calling the lib function from a task. But still the same thing is happening. As the function was directly referenced , I suspect the compiler thinks that the function is having no-side effects.

How can I resolve this?

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);

}

Code which creates the timer.

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");
}

Code which is starting the periodic timer.

OSTmrStart(&ostmr_LCDFrontPorch,&err);

Compiler control string.

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" 
kernel
  • 326
  • 1
  • 3
  • 18
  • What do you mean by "function is not getting included in executable" and "the callback function address is present which matches the address in map file"? – donjuedo Sep 21 '15 at 09:58
  • The callback function is present in the map file. I am not able to put a breakpoint in that function.From the keil help I got to know that in Level 1-o1 optimization the following optimizations are done. • Breakpoints may not be set on dead code. • Values of variables may not be available within their scope after they have been initialized. For example if their assigned location has been reused. • Functions with no side-effects may be called out of sequence, or may be omitted if the result is not needed. – kernel Sep 21 '15 at 10:11
  • I am suspecting that the lib function is a dead code.But the vendor denies that – kernel Sep 21 '15 at 10:13
  • I tried directly calling the function from a task.Still the same thing is happening. It is not related to Micrium timer. – kernel Sep 21 '15 at 10:14

1 Answers1

0

Since it works without optimization, I would suggest tricking the compiler while optimization is turned on. Specifically, you can do something like this:

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

You don't want to actually make the call, because that changes the logic you have working while optimization is off. And the compiler is likely smart enough to understand something like if ( false ) ..., so having a function call ( funcReturnsFalse() ) is probably enough for the compiler to believe you will be using CallBackFcn().

I have run into this problem before (not with Micrium), and this technique worked for me.

donjuedo
  • 2,475
  • 18
  • 28
  • I tried your suggestion by creating returnFalse() But still the compiler has not included the callback. The returnFalse() is getting called every time.After the code snippet in your answer I put my CallBackFn(param1,param2). The code is like this: 'code' if (returnFalse()) { callback(0,0); } callback(0,0); 'code' – kernel Sep 21 '15 at 10:40
  • @kernel, could you post some of the code for me? The timer set up, the callback function, and also the compile command with the map (edited to fit) might be helpful. – donjuedo Sep 21 '15 at 11:24
  • I have edited the question to add the code. OSWrappers::signalVSync(); & HAL::getInstance()->frontPorchEntered(); are the library functions getting called – kernel Sep 25 '15 at 09:33
  • @kernel, The class names OSWrappers and HAL mentioned above are not in the source code posted above. – donjuedo Sep 25 '15 at 16:42
  • @donjeudo This code is not available to me as this is library code. It is not visible. – kernel Sep 28 '15 at 02:24
  • As a test, what if you call your timer function explicitly, and use the debugger to try to step into it? Even seeing assembly would show the function did link OK. – donjuedo Sep 28 '15 at 10:50
  • Also, you might want to try the `--feedback=filename` compiler option to see what functions it *thinks* it stripped. – donjuedo Sep 28 '15 at 11:04
  • When tried calling debugger function explicitly I was not able to step into the function. – kernel Sep 28 '15 at 11:21