AnsweredAssumed Answered

constant structure on 9S12

Question asked by John Dammeyer on Feb 19, 2015
Latest reply on Mar 6, 2015 by Pascal Irrle

I found an incorrect index was generated in an constant array of structures.  I'm curious if it's possible to get the compiler to flag this as a warning or error.

The project creates an array of structures that represent CANOpen Object Dictionary entries.  Here are the typedefs.


typedef union _DICT_PTRS {  /* Pointers to objects */

    long EEAdr;

    const unsigned char * pRom;

    unsigned char * pRam;

    void (* pFunc)(PCHAR pDict);

} DICT_PTRS;

 

 

typedef struct _DICTIONARY_OBJECT_TEMPLATE

{

    unsigned int index;                  

    unsigned char subindex;

    BYTE ctl;

    unsigned int len;

    DICT_PTRS p;

}DICT_OBJECT_TEMPLATE;

 

Next the array definition.

const DICT_OBJECT_TEMPLATE manufacturer[] = {

    {0x3000,0x00,CONST,1,(long)&UserDictionaryLen},

    {0x3000,0x01,RO,2,(long)&ObjectDictionary[BIM_INPUTS_NDX]},  

    {0x3000,0x02,RO,2,(long)&ObjectDictionary[SMU_INPUTS_NDX]},

    {0x3000,0x03,RO,2,(long)&ObjectDictionary[GIM_INPUTS_NDX]},

    {0x3000,0x04,RO,2,(long)&ModBusRegisters[OUTBACK_SOURCE_VOLTAGE_NDX]},

...

 

First of all, there's nothing wrong with the code as is.  It's possible to use the functions that work with the array to return the values.  In each case the constants that end with NDX are simple #defines that are eventually integers.  Looking at the code with the debugger the pointers to the data are correct.  Except for the ModBusRegsters[OUTBACK_SOURCE_VOLTAGE_NDX] which is 0.

The problem is that OUTBACK_SOURCE_VOLTAGE_NDX isn't an integer but is (adrChargeControllerBlk+9) and adrChargeControllerBlk is a variable filled in from a MODBUS messages identifying the location of the source voltage value.  So the index into the Modbus Registers is dynamic and normally has the value 362..  That doesn't work in a constant array because at compile time the contents of adrChargeControllerBlk are unknown.


In the function that receives the Modbus values it's easy enough to assign the value into a global variable and then use this array entry instead.

{0x3000,0x33,RO,2,(long)&SolarInputVoltage},// Filled in if MODBUS active

Now the constant array has a pointer to the variable SolarInputVoltage and accessing it via the 3000:04 CANOpen Index:Sub-Index returns the correct value.  A look with the debugger now shows the correct address in the data structure.

 

So using the contents of a variable to index a constant array is the problem.  The compiler generates a 0 instead of the actual location which it can't know because it doesn't know what's in the variable.  All perfectly logical.  But shouldn't the compiler complain?  I shouldn't have named the index an NDX type.  That fooled me into thinking it was an integer a year later when I started using it in this data structure.   But still I'd expect an error or at least a warning.

 

Any suggestions?

Outcomes