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.
Tool/software: TI C/C++ Compiler
One of my functions is getting a usage fault error indicating unaligned access when the following line of code executes:
*so2est = -1.0F;
The so2est variable is a parameter that gets passed into the function.
The calling function is passing a pointer to a struct member as the so2est parameter. The struct is defined as:
struct SO2Result { FloatSP fUAArrayCombNorm[5]; FloatSP fUAArraySrc1[5]; FloatSP fUAArraySrc2[5]; FloatSP fUSArraySrc1[5]; FloatSP fUSArraySrc2[5]; FloatSP fMinErrSqAvg; FloatSP fSO2Estimate; FloatSP fSO2ErrSq; };
Note: FloatSP is typdefed as float.
For some reason, the struct variable, even though it contains all floating point members, is being stored at at non-4-byte-aligned address:
As you can see, the address of the variable is 0x20010C3B, and address of the member being passed to the function is 0x20019CA3.
I do not understand why the compiler/linker is not automatically aligning this structure. I tried changing the project settings in CCS Build>ARM Compiler>Advanced Options>Runtime Model Options>Generate unaligned loads and stores to off, but that did not make a difference.
I also tried to use #pragma DATA_ALIGN, but since the variable is on the stack it would not accept it.
Any idea how I can get the strucutre to align properly?
I am running CCS version 8.0.0.00016 and the TI v18.1.1.LTS compiler version.
Regards,
Dave
This looks like a bug in the compiler. That structure should be aligned on a 4 byte boundary, but it isn't. My guess is that when it is local to a function, and other kinds of variables precede it on the stack frame, something goes wrong. For the source file with the function that has the local resultSO2Current, please submit a test case as described in the article How to Submit a Compiler Test Case.
Thanks and regards,
-George
Thanks for the quick response, George. I will try to get a test case submitted as soon as possible.
Regards,
Dave
I was unable to reproduce the issue from a clean start, so I stripped out as much of the proprietary code from the original file as I could. I will send the pre-processed file via private message.
The resultSO2Current structure is being located at address 0x2002FB77, as shown in the following debugger output:
The version of the compiler is 18.1.1.LTS. The compiler options are:
"C:\\ti\\ccsv8\\utils\\bin\\gmake" -k -j 8 MP_Application/src/MP_TaskO2SatCalc.obj -O
Building file: "../MP_Application/src/MP_TaskO2SatCalc.c"
Invoking: ARM Compiler
"C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --opt_for_speed=0 --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/include" --include_path="C:/Firmware/TripleRing/VIO_TIVA/MP_Application/inc" --include_path="C:/Firmware/TripleRing/VIO_TIVA" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/EvalBoards/TI/DK-TM4C129X/BSP" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/EvalBoards/TI/DK-TM4C129X/OS2" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uC-CPU" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uC-CPU/ARM-Cortex-M4/CCS" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uC-LIB" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uCOS-II/Source" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uCOS-II/Ports/ARM-Cortex-M4/Generic/CCS" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/TivaWare" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/TivaWare/inc" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/TivaWare/driverlib" --include_path="C:/Firmware/TripleRing/VIO_TIVA/Platform/inc" --include_path="C:/Firmware/TripleRing/VIO_TIVA/Platform/Device/src" --include_path="C:/Firmware/TripleRing/VIO_TIVA/BSP/inc" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II" --include_path="C:/Firmware/TripleRing/VIO_TIVA/COTS/Micrium-uCOS-II/Micrium/Software/uC-CPU/ARM-Cortex-M4/CCS" --define=ccs="ccs" --define=PART_TM4C129XNCZAD -g --gcc --preproc_only --preproc_with_compile --diag_suppress=9 --diag_warning=225 --diag_wrap=off --display_error_number --unaligned_access=on --abi=eabi --obj_directory="MP_Application/src" "../MP_Application/src/MP_TaskO2SatCalc.c"
Note that the compiler generated a lot of warnings about variables being declared but not referenced, because I stripped out the code that referenced them.
One interesting thing that I noticed about the code is that there is a #pragma pack directive that temporarily sets the packing to 1. I thought that might be the culprit, but removing the #pragma statements made no difference.
Hope the info I am providing will allow you to easily track down the problem.
Regards,
Dave
Thank you for sending in a test case. This is user error.
One of these ...
#pragma pack ( 1 )
... is in effect when this structure definition is seen ...
Dave Hohl said:struct SO2Result
{
FloatSP fUAArrayCombNorm[5];FloatSP fUAArraySrc1[5];
FloatSP fUAArraySrc2[5];FloatSP fUSArraySrc1[5];
FloatSP fUSArraySrc2[5];FloatSP fMinErrSqAvg;
FloatSP fSO2Estimate;
FloatSP fSO2ErrSq;
};
Since this structure type contains all float members, the pack(1) has no effect on the layout of the structure. But it does mean the compiler does not align the base address of a variable of this structure type. Then you pass the address of one of the members of this structure variable to some other function. That function presumes the pointer to a float is aligned. It isn't, and things go downhill from there.
The fix is to make sure #pragma pack(1) is not in effect for this structure type.
Thanks and regards,
-George
OK, I think I have figured out what is going on. I am porting some legacy code from the Sourcery CodeBench compiler to CCS. The code has numerous instances where the following is used:
#pragma pack (1)
... // a struct definition
#pragma pack()
The #pragma pack() directive is intended to restore the packing to its default state. This works for Sourcery CodeBench, as well as IAR and GCC. However, it appears that the TI compiler does not support this.
In the file I was working on, even when I completely removed the #pragma pack statements I still had an alignment problem. This is because the file includes header files that use the #pragma pack directive. So I need to update all the files in the project to use push/pop rather than rely on #pragma pack() to restore the default.
Perhaps a feature request could be entered in the TI database asking that the use of #pragma pack() restore the default pack setting, so it would be compatible with other commonly used compilers?
Regards,
Dave
I suspect you misunderstand how #pragma pack works. The pack attribute attaches to the struct type. It remains, even if the range of #pragma pack(1) is ended by a subsequent #pragma pack(). For example ...
#pragma pack(1) struct struct_type { /* field definitions here */ }; #pragma pack() struct struct_type struct_variable;
Even though struct_variable is defined outside the range of #pragma pack(1), it is packed. This is because struct_type is packed.
Thanks and regards,
-George