AnsweredAssumed Answered

Possible bug in LPCXpresso IDE - (Optimize for Size) and (ISR) and (INLINE code)

Question asked by Bill Mather on Aug 2, 2016
Latest reply on Aug 6, 2016 by Bill Mather

Hi,

I have a project using CMSISv2p10_LPC13Uxx,FreeRTOS v8.2.2 and my code in an LPC1347.

 

The code compiles correctly and operates correctly in DEBUG mode, where optimization is default none (-O0).

In RELEASE, with default optimization - Optimize for size (-Os), the code fails, in a timer interrupt handler.

Tested: Setting the optimization for the ISR to either none (-O0) or most (-O3) results in correct program operation, compiled with both 7.5.0_254 on WinXP (the latest which works on WinXP) and 8.2.0_647 on Ubuntu32 14

 

The code is an ISR with volatile variables, one of which is cleared in another ISR (safe for race conditions, so no issue there), and it also contains a call to an INLINE function.

 

The purpose of the code is to set a SIGNAL, start a timer which when it times out, starts another operation. When the operation is complete, the timer is restarted, and when it times out, the SIGNAL is de-asserted, ie the SIGNAL wraps the other operation.

 

I have not investigated the reason for the failure - I have accepted that changing the optimization for the function removes the problem.

 

The code which performs incorrectly is attached, updated with optimize pragma, and with variable names changed:

 

volatile bool pending = false;

volatile bool isStartWait = false;

 

#define SIGNAL_ON()                             (LPC_GPIO->SET[0] = (1<<17))

#define SIGNAL_OFF()                            (LPC_GPIO->CLR[0] = (1<<17))

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

#pragma GCC push_options

#pragma GCC optimize ("O3")

void CT16B0_IRQHandler(void)

{

    if (isStartWait)

    {

        pending = true;

        isStartWait = false;

        NVIC_SetPendingIRQ(USART_IRQn);

    }

    else

    {

        LPC_CT16B0->TCR = TCR_CRST | TCR_CEN_DISABLE;   // stop timer, force output low

        SIGNAL_OFF();                                   // and turn signal off

    }

    LPC_CT16B0->IR = 0xff;                              // clear Int Flags set by transfer

}

#pragma GCC pop_options

Outcomes