Using CCS 6.0.1.00040 when a new project was created for a TM4C1294NCPDT using the GNU v4.7.4 compiler, noticed there were errors in the generated project which caused run time failures. E.g. using a project containing the following code:
/* * main.c */ #include <string.h> char test_string[20] = "Hello World\n"; int main(void) { volatile size_t len = strlen(test_string); return 0; }
The first problem is that the data segment has not been initialized correctly. E.g. the text in the test_string appears offset by 12 bytes:
The incorrect data segment initialization is caused by the tm4c1294ncpdt_startup_ccs_gcc.c added to the project by CCS. The error is that the ResetISR() function uses __etext as the source of the data segment initialization, whereas it should be using __data_load__. i.e. change the tm4c1294ncpdt_startup_ccs_gcc.c to contain:
//***************************************************************************** // // The following are constructs created by the linker, indicating where the // the "data" and "bss" segments reside in memory. The initializers for the // for the "data" segment resides immediately following the "text" segment. // //***************************************************************************** extern uint32_t __data_load__; extern uint32_t __data_start__; extern uint32_t __data_end__; extern uint32_t __bss_start__; extern uint32_t __bss_end__; //***************************************************************************** // // This is the code that gets called when the processor first starts execution // following a reset event. Only the absolutely necessary set is performed, // after which the application supplied entry() routine is called. Any fancy // actions (such as making decisions based on the reset cause register, and // resetting the bits in that register) are left solely in the hands of the // application. // //***************************************************************************** void ResetISR(void) { uint32_t *pui32Src, *pui32Dest; // // Copy the data segment initializers from flash to SRAM. // pui32Src = &__data_load__; for(pui32Dest = &__data_start__; pui32Dest < &__data_end__; ) { *pui32Dest++ = *pui32Src++; }
The second problem is that the strlen function was crashing the processor - causing the FaultISR() to be entered. This is because the strlen function was being linked from the c:/ti_ccs6_0/ccsv6/tools/compiler/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib\libc.a library. That library has been compiled for ARM mode, whereas the TM4C1294NCPDT device only supports Thumb mode.
The incorrect library being linked is caused by the GNU compiler -march option being left blank when the project was created by CCS. -march should be set to "armv7e-m" for a TM4C1294NCPDT to cause the GNU compiler to select the correct run time library.
With these two changes the above example then worked when compiled with the GNU v4.7.4 compiler