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.
Dear support,
During a debug session with CCSv6 on my project, my initialized global variables doesn't get initialized at startup because the flashing tool of CCSv6 seems to not load those data in flash. I'm using as usual the following code to populate those variables at startup:
pul_src = &_etext; for(pul_dst = &_data; pul_dst < &_edata;) { *pul_dst++ = *pul_src++; }
The memory content at _etext is filled with 0 and thus my global variables get initialized with 0.
Here is the linker script I'm currently using:
MEMORY { FLASH (RX) : ORIGIN = 0x00200000, LENGTH = (0x00080000 - 44) FLASH_CCA (RX) : ORIGIN = (0x00200000 + (0x00080000 - 44)), LENGTH = 44 NRSRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00004000 SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 } /* heap section */ _eheapdata = ORIGIN(SRAM) + LENGTH(SRAM); /* We put the usb related init and non-init data in the non-retention SRAM. The Load Memory Address (LMA) is stored in a variable and used by the program to initiliaze the usb data once needed. */ SECTIONS { .text : { _text = .; KEEP(*(.vectors)) *(.text*) *(.rodata*) _etext = .; } > FLASH= 0 .socdata (NOLOAD) : { *(.udma_channel_control_table) } > SRAM .data : { _data_lma = LOADADDR(.data); _data = .; *(EXCLUDE_FILE(*usb*.o) .data*) _edata = .; } > SRAM AT > FLASH .ARM.exidx : { *(.ARM.exidx*) } > FLASH .bss : { _bss = .; *(EXCLUDE_FILE(*usb*.o) .bss*) *(EXCLUDE_FILE(*usb*.o) COMMON) . = ALIGN(4); _ebss = .; _heapdata = ABSOLUTE(.); } > SRAM .nrdata : { _nrdata_lma = LOADADDR(.nrdata); _nrdata = .; *(.nrdata*) *usb*.o(.data) _enrdata = .; } > NRSRAM AT > FLASH .nrbss (NOLOAD) : { _nrbss = .; *(.nrbss*) *usb*.o(.bss COMMON) _enrbss = .; } > NRSRAM .flashcca : { KEEP(*(.flashcca)) } > FLASH_CCA }
By looking at the symbol table generated by arm-none-eabi-nm.exe I noticed that the initialized data are effectively present after the .text section (0x0021e098-0x0021db9a = 1278):
0021db9a A _data_lma 0021db9a T _etext 0021e098 A _nrdata_lma 0027ffd4 0000002c R __cca
CCSv6 appear to be unconcerned about what is coming after the .text section during a debug session and won't load this part in flash.
Note that everything works fine and I'm able to run my program when I'm flashing the device with the Flash Programmer 2 software. After that, if a run a debug session by loading only the symbols, the content after the .text section are not zero and my global variables get initialized properly.
Thanks a lot for your help if there is a solution to this problem.
There is a bug in the ResetISR function in the *_startup_ccs_gcc.c files in CCS 6.0.1. The error is that the ResetISR() function uses __etext as the source of the data segment initialization, whereas it should be using __data_load__. See https://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/365689 for the suggested fix.dark0 said:During a debug session with CCSv6 on my project, my initialized global variables doesn't get initialized at startup because the flashing tool of CCSv6 seems to not load those data in flash. I'm using as usual the following code to populate those variables at startup:pul_src = &_etext; for(pul_dst = &_data; pul_dst < &_edata;) { *pul_dst++ = *pul_src++; }
I now see that the linker script isn't the default one in CCS, in that it has two initialized data sections:dark0 said:I tried then to use __data_load__ instead of _etext but still nothing.
.data : { _data_lma = LOADADDR(.data); _data = .; *(EXCLUDE_FILE(*usb*.o) .data*) _edata = .; } > SRAM AT > FLASH .nrdata : { _nrdata_lma = LOADADDR(.nrdata); _nrdata = .; *(.nrdata*) *usb*.o(.data) _enrdata = .; } > NRSRAM AT > FLASH
Therefore, you would need two loops to copy the initial data values from flash to ram / nrsram, with the source and destination symbols matching those in the linker script:
pul_src = &_data_lma; for(pul_dst = &_data; pul_dst < &_edata;) { *pul_dst++ = *pul_src++; } pul_src = &_nrdata_lma; for(pul_dst = &_nrdata; pul_dst < &_enrdata;) { *pul_dst++ = *pul_src++; }
[I don't have a CC2538 to be able to test these changes]
Yes of course but I don't initialize this second data section at startup. I do it latter in the code with a function this isn't a problem. To see the changes I'm directly watching the memory with the Memory Browser. Here the issue by images:
Program loaded by the debugger:
Program loaded with external flasher and then debug by loading only symbols:
(edit)
Further note: Now that there is a flashing verbose output option in v6.1.0 I can notice that the data are effectively loaded, but then why would this area be filled with 0? When I flash the device with an external tool I use the arm-none-eabi-objcopy.exe program to create a binary file from the .out file. This latter contains with no doubt the the initialized data because the program works in that case.
Cortex_M3_0: GEL Output: Memory Map Initialization Complete. Cortex_M3_0: Writing Flash @ Address 0x00200000 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x00207ff0 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x0020ffe0 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x00217fd0 of Length 0x00002ebe Cortex_M3_0: Writing Flash @ Address 0x0021ae8e of Length 0x000004f0 Cortex_M3_0: Writing Flash @ Address 0x0021b380 of Length 0x00000008 Cortex_M3_0: Writing Flash @ Address 0x0021b388 of Length 0x00000060 Cortex_M3_0: Writing Flash @ Address 0x0027ffd4 of Length 0x0000002c Cortex_M3_0: GEL Output: CPU Reset.
OK, I now see that the flash hasn't been programmed correctly by the CCS debugger.dark0 said:To see the changes I'm directly watching the memory with the Memory Browser.
To investigate can you:
1) Under CCS Project Properties -> Debug -> Flash Settings tick "Enable Verbose Output".
2) Enable CCS Debug Server Logging as defined here
3) Download the program using the CCS debugger and post the CCS Console output and Debug Server log file.
Could you also post the complete project, or failing that the linker .map file to determine what sections should be written to flash?
I just edited my previous post for the verbose output :)
The debug server log:
And here the .map file.
Note that when I'm doing "Verify Program" in Run->Load->Verify Program... I got an error:
Cortex_M3_0: File Loader: Verification failed: Values at address 0x000000000021AE8C do not match Please verify target memory and memory map.
Here is my gel file (not edited from the original):
/* \file cc2538.gel * \brief GEL script for CC2538 device family. This file includes a * system reset macro. * * \revision $Revision: 31199 $ */ menuitem "StartUp" hotmenu StartUp() { memorymap_init(); } menuitem "CC2538" unsigned int _GEL_Backup_FP_COMP0; unsigned int _GEL_Backup_FP_COMP1; unsigned int _GEL_Backup_FP_COMP2; unsigned int _GEL_Backup_FP_COMP3; unsigned int _GEL_Backup_FP_COMP4; unsigned int _GEL_Backup_FP_COMP5; unsigned int _GEL_WaitTimeout = 0; int GEL_Timer1Lock = 0; int GEL_Timer2Lock = 0; hotmenu MassErase() { // Store connect states int ctxWasConnected = GEL_IsConnected(); GEL_EvalOnTarget("<parent>", "ConnectStateStore()", 1); GEL_EvalOnTarget("<parent>", "GEL_EvalOnTarget(\"<parent>\",\"ConnectStateStore()\", 1)", 1); // If connected to Cortex, disconnect if(ctxWasConnected == 1) { GEL_Disconnect(); } // Disconnect DAP GEL_EvalOnTarget("<parent>", "DisconnectIfConnected()", 1); // Connect to icepick and do mass erase GEL_EvalOnTarget("<parent>", "GEL_EvalOnTarget(\"<parent>\",\"ConnectIfDisconnected()\", 1)", 1); GEL_EvalOnTarget("<parent>", "GEL_EvalOnTarget(\"<parent>\",\"IP_CC2538_MASSERASE = 1\", 1)", 1); // Reset device GEL_AdvancedReset("System Reset"); // Restore connect state if(ctxWasConnected == 1) { // Connects to cortex, dap and icepick GEL_Connect(); } else { GEL_EvalOnTarget("<parent>", "ConnectStateRestore()", 1); GEL_EvalOnTarget("<parent>", "GEL_EvalOnTarget(\"<parent>\",\"ConnectStateRestore()\", 1)", 1); } GEL_TextOut("Mass Erase Complete.\n"); } hotmenu SystemReset() { GEL_Timer1Lock = 0; GEL_Timer2Lock = 0; GEL_Halt(); // 1. Save all FPB unit registers _GEL_Backup_FP_COMP0 = *((int*)(0xE0002008)); _GEL_Backup_FP_COMP1 = *((int*)(0xE000200C)); _GEL_Backup_FP_COMP2 = *((int*)(0xE0002010)); _GEL_Backup_FP_COMP3 = *((int*)(0xE0002014)); _GEL_Backup_FP_COMP4 = *((int*)(0xE0002018)); _GEL_Backup_FP_COMP5 = *((int*)(0xE000201C)); // Write to RAM area that signals resetISR to stop execution *((int*)(0x20003000)) = 0xA5F01248; // Let the arm run freely GEL_RunF(); GEL_SetTimer( 100, 1, "WaitForRun()", 1 ); // Don't let this function return until all the callbacks are finished GEL_EvalOnTarget("IcePick_C", "GEL_Waiting = 1", 1); GEL_EvalOnTarget("IcePick_C", "WaitForSignal()", 1); } WaitForRun() { int wasFirstThread = ++GEL_Timer1Lock; if( 1 != wasFirstThread ) return; GEL_CancelTimer( 1); _GEL_WaitTimeout = 0; // 2. Issue reset from icepick GEL_EvalOnTarget("IcePick_C", "GEL_AdvancedReset(\"System Reset\")"); // Wait for reset to complete by using a timer and checking // every 100 ms GEL_SetTimer( 100, 2, "WaitForReset()", 1 ); } WaitForReset() { unsigned int isAtResetIsr; unsigned int FP_CTRL; int wasFirstThread = ++GEL_Timer2Lock; if( 1 != wasFirstThread ) return; GEL_CancelTimer( 2 ); // Wait for reset to complete // 3. Halt CPU GEL_Halt(); isAtResetIsr = *((int*)(0x20003004)); if(isAtResetIsr != 0xAABBAABB && _GEL_WaitTimeout == 0) { _GEL_WaitTimeout = 1; GEL_RunF(); GEL_Timer2Lock = 0; GEL_SetTimer( 100, 2, "WaitForReset()", 1 ); return; } // 4.1 Enable FPB unit (FP_CTRL |= 0x03) FP_CTRL = *((int*)(0xE0002000)); FP_CTRL |= 0x3; *((int*)(0xE0002000)) = FP_CTRL; // 4.2 Restore all FPB unit registers *((int*)(0xE0002008)) = _GEL_Backup_FP_COMP0; *((int*)(0xE000200C)) = _GEL_Backup_FP_COMP1; *((int*)(0xE0002010)) = _GEL_Backup_FP_COMP2; *((int*)(0xE0002014)) = _GEL_Backup_FP_COMP3; *((int*)(0xE0002018)) = _GEL_Backup_FP_COMP4; *((int*)(0xE000201C)) = _GEL_Backup_FP_COMP5; // Signal to resetISR it can continue run *((int*)(0x20003000)) = 0; // Issue CPU reset GEL_Reset(); // Let SystemReset() complete GEL_EvalOnTarget("IcePick_C", "GEL_Waiting = 0", 1); if(_GEL_WaitTimeout == 1) { // Target code does not implement "catch" for system reset workaround GEL_TextOut("CPU Reset.\n"); } else { GEL_TextOut("System Reset.\n"); } } // Issue System Reset after flash load OnFileLoaded(int nErrorCode, int bSymbolsOnly) { // Only do system reset if a program is downloaded onto device. if(!bSymbolsOnly) { // Issue a system reset SystemReset(); // Only restart if "Run to label on restart" is enabled if ( DEBUG_GetBoolProperty("AutoRunToLabelOnRestart") ) { GEL_Restart(); } } } memorymap_init() { GEL_MapOff(); GEL_MapReset(); GEL_MapOn(); /* * Syntax for GEL_MapAddStr. * GEL_MapAddStr(address, page, length, "attribute", waitstate); Basic Attribute Types Derived Attribute Types String Description String Description R Read NONE No memory/protected W Write RAM Read and write P Port ROM Read only EX External WOM Write only EM Emulator INPORT Port read only PR Programmable OUTPORT Port write only ER Erasable IOPORT Port read and write DA Dual access SARAM Single access RAM ASn Access size DARAM Dual access RAM SHnC Shared FLASH Flash ROM CACHE Cache EXRAM External RAM TX Text EXROM External ROM MN Monitor EPROM Erasable write-able EPROM SA Single access MONITOR Monitor ROM FL Flash PRAM Program RAM MR Memory mapped PROM Program ROM NULL NULL NULL NULL */ GEL_MapAddStr(0x00200000, 0, 0x00080000, "R", 0); /* Flash */ GEL_MapAddStr(0x00000000, 0, 0x00004000, "R", 0); /* ROM */ GEL_MapAddStr(0x00280000, 0, 0x00001000, "R", 0); /* Flash info page */ GEL_MapAddStr(0x20000000, 0, 0x00008000, "R|W", 0); /* SRAM */ GEL_MapAddStr(0x40000000, 0, 0x04010100, "R|W", 0); /* Peripherals */ GEL_MapAddStr(0xE000E000, 0, 0x00001000, "R|W", 0); /* NVIC */ GEL_MapAddStr(0xE0002000, 0, 0x00000020, "R|W", 0); /* FPB */ GEL_TextOut("Memory Map Initialization Complete.\n"); } wait() { int delay = 0; for (delay = 0; delay <= 100; delay ++) {} }
The debug server log doesn't appear to show any flash erase or program operations. Was the debug server logging enabled before starting the CCS debug session?dark0 said:The debug server log:(Please visit the site to view this file)
If not, can you try to enable debug server logging and then start a CCS debug session, and then post the debug server log again.
dark0 said:Note that when I'm doing "Verify Program" in Run->Load->Verify Program... I got an error:Cortex_M3_0: File Loader: Verification failed: Values at address 0x000000000021AE8C do not match Please verify target memory and memory map.
The address 0x21ae8c at which the verification error occurs seems to occur at the boundary of two sections which aren't word aligned. Not sure if this is significant.dark0 said:Cortex_M3_0: Writing Flash @ Address 0x00217fd0 of Length 0x00002ebeCortex_M3_0: Writing Flash @ Address 0x0021ae8e of Length 0x000004f0
I enabled the debug log before launching the debug. Note that this time I enabled the "Full Verification" in the debug configuration and the program won't load completely and stop here:
Cortex_M3_0: GEL Output: Memory Map Initialization Complete. Cortex_M3_0: Writing Flash @ Address 0x00200000 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x00207ff0 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x0020ffe0 of Length 0x00007ff0 Cortex_M3_0: Writing Flash @ Address 0x00217fd0 of Length 0x00002ebe Cortex_M3_0: Writing Flash @ Address 0x0021ae8e of Length 0x00000530 Cortex_M3_0: File Loader: Verification failed: Values at address 0x000000000021AE92 do not match Please verify target memory and memory map. Cortex_M3_0: GEL: File: D:\workspace\ccs\CC2538DebugTest\Debug\CC2538DebugTest.out: a data verification error occurred, file load failed.
Here is the debug log:
I found in this file that the data section seems to be loaded but without error here (I don't understand everything in this file thought):
0x00005294 22279 4 OFS D: OFS LOAD Section added: name: .data 0x00005294 22279 4 OFS D: size in bytes: 1328, or 0x530 0x00005294 22279 4 OFS D: load location: 0x21ae8e 0x00005294 22279 4 OFS D: run location: 0x20004000 0x00005294 22279 4 OFS D: memory page: 0 0x00005294 22279 4 OFS D: offset in file: 147456 or 0x24000
That part of the log file is reporting the size and location of the .data section, rather than actually loading the section.dark0 said:I found in this file that the data section seems to be loaded but without error here (I don't understand everything in this file thought):0x00005294 22279 4 OFS D: OFS LOAD Section added: name: .data
The point at which the initialized contents of the .data section is written to flash is the following in the debug log:
0x00002DD8 33625 3 Cortex_M3_0 FLASH C: IFlashDevice::WriteDataToFlash( 4195F170, 0x000000000021AE8E, 1328, 0 ) 0x00002DD8 34044 3 Cortex_M3_0 FLASH R: IFlashDevice::WriteDataToFlash( 4195F170, 0x000000000021AE8E, 1328, 0 ) = (null)
No apparent errors are reported during the flash to write. However, following a readback of the flash a verification error is reported (where the readback is aligned to a 32-bit word boundary):
0x00005294 34047 3 Cortex_M3_0 GTI C: GTI_READMEM_WITH_STAT( 0x41B65ED0, 0x0021AE8C, 0x00000000, 0x00000534, 0x00000001, "R", 0x00000000, 0x00000000, *0x40960238 = 0x00000000, 0xFFFFFFFF, *0x00000000 = (nullptr) ) 0x00005294 34093 3 Cortex_M3_0 GTI R: GTI_READMEM_WITH_STAT( 0x41B65ED0, 0x0021AE8C, 0x00000000, 0x00000534, 0x00000001, "R", 0x00000000, 0x00000000, *0x40960238 = 0x00000000, 0xFFFFFFFF, *0x00000000 = (nullptr) ) = 0x00000000 0x00005294 34096 3 XPCOM C: ( (dsIStringEventCallback*)3DEB0B60 )->onEvent( Cortex_M3_0: File Loader: Verification failed: Values at address 0x000000000021AE92 do not match Please verify target memory and memory map. )
Based upon the information in the log file, I can't tell what caused the programming failure. Hopefully a TI employee will be able to investigate further.
Your previous message put me on the right track and I finally managed to resolve the issue.
I aligned the end of the .text section to 4-bytes boundary:
I changed my linker script from:
.text : { _text = .; KEEP(*(.vectors)) *(.text*) *(.rodata*) _etext = .; } > FLASH= 0
to:
.text : { _text = .; KEEP(*(.vectors)) *(.text*) *(.rodata*) . = ALIGN(4); _etext = .; } > FLASH= 0
I don't know why this caused error during the debug session but it works now and I learned a lot.
Thanks a lot for all your help!