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 (e.g. 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