This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Union Struct data field problem



Hello,

I'm working on a program in CC6.1 and have come across a strange problem that I cannot resolve.  

I have a definition of a structure as shown below:

typedef union {

struct {

uint8_t SID; 
uint16_t SLFD; 
uint32_t Param; 
uint8_t Fill; 

};
uint8_t byte[1+7];

}TYPE_CAN_SREQ;

Then I fill and call the structure as shown below again:

CAN_SReq.SID = 0xFF; 
CAN_SReq.SLFD= 0xAABB; 
CAN_SReq.Param = 0x11223344; 
CAN_SReq.Fill = 0xDD;

wait(1000);
canTransmit(canREG1, canMESSAGE_BOX8, CAN_SReq.byte); 

The problem comes when I actually look at the results in CAN_SReq.byte.  The output of this is shown in the image below.  There is extra data in byte[1] that shouldn't be there.  It's not data from any of the existing variables, so I don't know where it's coming from or how it's getting there.  Any help would be much appreciated. 

  • Christopher, I'm going to move this question to the CCS forum since it's a better fit there.
  • It might be some padding issue. What device and compiler version are you using?

    Thanks
    ki
  • Also provide the build options being used (easiest to just cut and paste the build output from the build console)

    Thanks
    ki
  • Is this what you are looking for?

    **** Build of configuration Debug for project Interface ****

    "C:\\ti\\ccsv6\\utils\\bin\\gmake" -k all
    'Building file: ../source/sys_main.c'
    'Invoking: ARM Compiler'
    "C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/bin/armcl" -mv7R4 --code_state=32 --float_support=VFPv3D16 --abi=eabi --include_path="C:/Users/CL/Documents/workspace_v6_1/Interface/include" --include_path="C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/include" -g --display_error_number --diag_warning=225 --diag_wrap=off --enum_type=packed --preproc_with_compile --preproc_dependency="source/sys_main.pp" --obj_directory="source" "../source/sys_main.c"
    'Finished building: ../source/sys_main.c'
    ' '
    'Building target: Interface.out'
    'Invoking: ARM Linker'
    "C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/bin/armcl" -mv7R4 --code_state=32 --float_support=VFPv3D16 --abi=eabi -g --display_error_number --diag_warning=225 --diag_wrap=off --enum_type=packed -z -m"Interface.map" --heap_size=0x800 --stack_size=0x800 -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/lib" -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/include" --reread_libs --warn_sections --display_error_number --diag_wrap=off --xml_link_info="Interface_linkInfo.xml" --rom_model --be32 -o "Interface.out" "./source/can.obj" "./source/dabort.obj" "./source/esm.obj" "./source/gio.obj" "./source/notification.obj" "./source/pinmux.obj" "./source/rti.obj" "./source/sci.obj" "./source/sys_core.obj" "./source/sys_dma.obj" "./source/sys_intvecs.obj" "./source/sys_main.obj" "./source/sys_mpu.obj" "./source/sys_pcr.obj" "./source/sys_phantom.obj" "./source/sys_pmm.obj" "./source/sys_pmu.obj" "./source/sys_selftest.obj" "./source/sys_startup.obj" "./source/sys_vim.obj" "./source/system.obj" "../source/sys_link.cmd" -l"rtsv7R4_T_be_v3D16_eabi.lib"
    <Linking>
    'Finished building target: Interface.out'
    ' '

    **** Build Finished ****
  • In genreal, C compiler will make structure fields "aligned". A uint8_t variable will align with 1-byte boundary while a uint16_t variable will align with 2-bytes boundary. This is important because old CPUs can't access data which are not aligned. It will case exception. But newer CPU such as Cortex-M3 can handle unaligned data automatically. It will access data bus twice and give you a correct data value without causing exception.

    So, C compiler will insert a padding byte after SID to make SLFD 2-bytes aligned. If you don't want the padding byte then you can use GCC extension to do it.

    struct __attribute__((packed)) {
        uint8_t SID; 
        uint16_t SLFD; 
        uint32_t Param; 
        uint8_t Fill; 
    };

    Note that even Cortex-M3 can handle unaligned data correctly, this feature could be disabled and causing exception. Check your CPU User's Guide for this.

  • That fixed it. Thanks so much Robert!