Search code examples
c++embeddedstm32iar

IAR C/C++ comparsion operator behaviour


I have following define:

#define DEVICE_ID   ((uint8_t)0x3f)

and I have following function:

void LIS3DSH_Init(LIS3DSH_InitTypeDef* LIS3DSH_InitStruct)
{
//    uint8_t ctrl=0x00;
    uint8_t ident=0x00;

    LIS3DSH_LowLevel_Init();

    LIS3DSH_Read(&ident,
                 LIS3DSH_WHOAMI_REG_ADDR,
                 1);

    if(DEVICE_ID==ident)
    {
        // LIS3DSH detected
    }
    else
    {
        // LIS3DSH not detected

        failureHandler();
    }

}   // LIS3DSH_Init

Now, if I go step-by-step in this function, the ident variable gets value 0x3f after LIS3DSH_Read function call, which is ok. My question is, why the hell if clause jumps to failureHandler? The values of DEVICE_ID and ident are the same - both are 0x3f, if should not jump to failureHanlder(). I am working on LIS3DSH accelerator library using IAR C/C++ and STM32F4 Discovery Board. Here is a screenshot of situation:If clause going wrong?!


Solution

  • You should type-cast the if(DEVICE_ID==ident) to be if( (uint8_t)DEVICE_ID == (uint8_t)ident)

    This has been an issue for me in the past.

    And yes, declare ident as volatile, and for debugging purposes, try adding a delay before the comparison via a for-loop with __no_operation(); inside it. Note that there are 2 underscores in front of that, not 1 (intrinsic NOP instruction), and that a single NOP takes roughly ~29ns on a 168MHz board, measured via scope.

    Also, since you have IAR, you might as well pop open the "assembly" view and look at what registers and/or constants are actually being compared. Open the "register" view as well...so you can see the register values themselves.