简体   繁体   中英

Why does optimization change my pointer address for no reason?

I am having issues with optimization in an embedded C application. The address of the pointer changes to 0x0 unexpectedly and breaks my code.

I am using GNU MCU Eclipse ARM Embedded GCC toolchain. I am using a sensor with which I with communicate via SPI. The sensor has 8 configuration registers of 16bits each. I keep a local copy of the configurations in a struct called “hallsensor_zTleConfig” I read the sensor's stored configuration regularly (“zTleSensorConfig”) and compare it against the local copy to see if any memory corruption occurred.

With no optimization this process works.

With optimization, in the code below, the pointer to the master/local copy suddenly changes to 0x0 for no apparent reason.

// Master copy of configuration of the TLE chips
static TLE5012B_zCONFIG hallsensor_zTleConfig[ HALLSENSOR_COUNT ];

static void Hallsensor_VerifyConfig( HALLSENSOR_eUNIT eUnit )
{
    TLE5012B_zCONFIG zTleSensorConfig;
    uint16* pu16MasterConfigPointer = &hallsensor_zTleConfig[ eUnit ];
    uint16* pu16SensorConfigPointer = &zTleSensorConfig;
    uint8 u8Index;

    // Read all configuration parameters
    (void)Hallsensor_ReadRegister( TLE5012B_MOD_2, &zTleSensorConfig, sizeof( TLE5012B_zCONFIG ) );

    // Copy over configurations modified by Auto-calibration and reserved bits
    hallsensor_zTleConfig[ eUnit ].zMod3.u12ANG_BASE     =     zTleSensorConfig.zMod3.u12ANG_BASE;
    hallsensor_zTleConfig[ eUnit ].zSynch.i12AmpSynch    =     zTleSensorConfig.zSynch.i12AmpSynch;
    hallsensor_zTleConfig[ eUnit ].zOffsetX.i12XOffset   = zTleSensorConfig.zOffsetX.i12XOffset;
    hallsensor_zTleConfig[ eUnit ].zOffsetY.i12YOffset   = zTleSensorConfig.zOffsetY.i12YOffset;
    hallsensor_zTleConfig[ eUnit ].zMod4.u7TCO_X_T       = zTleSensorConfig.zMod4.u7TCO_X_T;
    hallsensor_zTleConfig[ eUnit ].zTcoY.u7TCO_Y_T       = zTleSensorConfig.zTcoY.u7TCO_Y_T;
    hallsensor_zTleConfig[ eUnit ].zMod2.u1Reserved      = zTleSensorConfig.zMod2.u1Reserved;
    hallsensor_zTleConfig[ eUnit ].zMod4.u1Reserved      = zTleSensorConfig.zMod4.u1Reserved;
    hallsensor_zTleConfig[ eUnit ].zOffsetX.u4Reserved   = zTleSensorConfig.zOffsetX.u4Reserved;
    hallsensor_zTleConfig[ eUnit ].zOffsetY.u4Reserved   = zTleSensorConfig.zOffsetY.u4Reserved;
    hallsensor_zTleConfig[ eUnit ].zSynch.u4Reserved     = zTleSensorConfig.zSynch.u4Reserved;

    // Compare local Master config setting to sensor settings and look for corrupted data
    for ( u8Index = 0; u8Index < TLE5012B_CONFIG_REG_COUNT; u8Index++ )
    {
        // Configuration invalid?
        if ( pu16MasterConfigPointer[u8Index] != pu16SensorConfigPointer[u8Index] )
        {
            hallsensor_bConfigOk[ eUnit ] = FALSE;
        }
    }

    // Data corrupted?
    if ( !hallsensor_bConfigOk[ eUnit ] )
    {
        // Do stuff
    }
}

At the start of the function, pu16MasterConfigPointer and pu16SensorConfigPointer correctly hold the address of their corresponding structs. However, right before the first for loop, pu16MasterConfigPointer changes to 0x0 and all the for loop conditions result TRUE.

I have tried many combinations of volatile for different variables and pointers and the results still break the code in various other ways (eg for loop does not branch out for if statement looking at the asm code resulting in statement always going to "hallsensor_bConfigOk[ eUnit ] = FALSE;")

PS: A good resource to learn about how to protect your code against optimization issues would be very welcome.

Screenshot of debugger showing pointer = 0x0 w/ asm code

在此处输入图片说明

@John Bollinger was right saying that the pointers violate the strict aliasing rule which was unknown to me. There is a good explanation of this rule in this post .

Replacing the for loop with memcmp did the trick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM