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.
Hi there,
I have been developing firmware and suddenly I noticed an unrelated variable being changed when I modified some completely unrelated code. It appears to me that it is unrelated to the code itself and more of an illegal access situation. I am certain of this because I traced the point where the variable becomes modified to a strange value to a point BEFORE it even reaches the code which I changed.
Note the variable changes to a value of 48 and there is no possibility that any other piece of code would set it to this value. (it normally ranges from 0-12)
I also swapped my TMS320F280025C hardware to another sample to verify that the memory was not damaged in some way.
Any advice on where to start looking would be appreciated. I have also attached my flash linker file below.
Thanks in advance,
MEMORY
{
BEGIN : origin = 0x080000, length = 0x000002
BOOT_RSVD : origin = 0x00000002, length = 0x00000126
RAMM0 : origin = 0x00000128, length = 0x000002D8
RAMM1 : origin = 0x00000400, length = 0x000003F8 /* on-chip RAM block M1 */
// RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
/* RAMLS4 : origin = 0x0000A000, length = 0x00000800
RAMLS5 : origin = 0x0000A800, length = 0x00000800
RAMLS6 : origin = 0x0000B000, length = 0x00000800
RAMLS7 : origin = 0x0000B800, length = 0x00000800*/
/* Combining all the LS RAMs */
RAMLS4567 : origin = 0x0000A000, length = 0x00002000
RAMGS0 : origin = 0x0000C000, length = 0x000007F8
// RAMGS0_RSVD : origin = 0x0000C7F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
// FLASHBANK1 : origin = 0x00080000, length = 0x0000FFF0
// FLASH_BANK1_RSVD : origin = 0x0008FFF0, length = 0x00000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
BOOTROM : origin = 0x003F0000, length = 0x00008000
BOOTROM_EXT : origin = 0x003F8000, length = 0x00007FC0
RESET : origin = 0x003FFFC0, length = 0x00000002
/* Flash sectors */
/* BANK 0 */
FLASH_BANK0_SEC0 : origin = 0x080002, length = 0x000FFE /* on-chip Flash */
FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000 /* on-chip Flash */
FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x000FF0 /* on-chip Flash */
// FLASH_BANK0_SEC15_RSVD : origin = 0x08FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
}
SECTIONS
{
codestart : > BEGIN, ALIGN(8)
.text : >> FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4 | FLASH_BANK0_SEC5 | FLASH_BANK0_SEC6 | FLASH_BANK0_SEC7, ALIGN(8)
.cinit : > FLASH_BANK0_SEC0, ALIGN(8)
.switch : > FLASH_BANK0_SEC0, ALIGN(8)
.reset : > RESET, TYPE = DSECT /* not used, */
.stack : > RAMM1
// .init_array : > FLASH_BANK0_SEC1, ALIGN(8) //ss not used for some reason
.bss : > RAMLS4567
.bss:output : > RAMLS4567
.bss:cio : > RAMGS0
.const : >> FLASH_BANK0_SEC9| FLASH_BANK0_SEC10, ALIGN(8) //SS problem with sector 9
.data : > RAMLS4567
.sysmem : > RAMLS4567
ramgs0 : > RAMGS0
/* Allocate IQ math areas: */
IQmath : > RAMLS4567
IQmathTables : > RAMLS4567
.TI.ramfunc : LOAD = FLASH_BANK0_SEC0, //was sec1
RUN = RAMGS0,
LOAD_START(RamfuncsLoadStart),
LOAD_SIZE(RamfuncsLoadSize),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
RUN_SIZE(RamfuncsRunSize),
RUN_END(RamfuncsRunEnd),
ALIGN(8)
}
/*
//===========================================================================
// End of file.
//===========================================================================
*/
Steven,
If you open a memory window(View->Memory Browser), you should be able to type the variable name into the address field and CCS will pull up that memory region(you may need to do @var_name, I can't recall at the moment). We can then see where it is being stored. I would then look back at your linker file to see what all is assigned to that region to see if there is some conflict.
You can also look at the .map file (that should be in the same directory as your .out file) to cross check with the .cmd file what is getting stored in that region.
At first glance it may be some conflict with GS0, since you are copying code to that region, but I also see .bss:cio mapped there as well. There is also a section definition "ramgs0" that is also assigned here, not sure if you are using that in your .c file for a data section, etc. I'm not sure if the linker is aware of any conflicts since for code it is a load to flash run from RAM...
I don't think this is your stack overflowing, I don't see anything else assigned to RAMM1 in the above linker.
Best,
Matthew
HI Adam,
Thanks for your quick response.
Regarding the linker allocation code: "ramgs0 : > RAMGS0" and ".bss:cio : > RAMGS0",
this was in the linker file by default and I did not modify it.
I tried to open the memory browser but was unable to search for the variable name with the @name (It says "Unable to go to specified address") but I manually was able to find the location at 0xA4C0 as per the below (variable name is screenPage).
I then checked the map file and for some reason the variable is showed as being in location a286 for some reason. Any idea if this is normal/possible?
Interestingly RAMLS4567 appears to be the location for this as it starts at 0xA000:
RAMLS4567 : origin = 0x0000A000, length = 0x00002000
There are a few commands/lines to allocate memory to RAMLS4567 in the linker file (see original post). Any suggestions as to what to try?
Let me know if I should check the stack as well if the above seems okay. Stack usage seems high for _c_int00, not sure if this is normal:
Thanks again,
Steven
Sorry I meant Matthew in my previous post. Quick update for you,
As an experiment I tried manually allocating some section to the RAMLS4 RAMLS5 RAMLS6 RAMLS7 locations instead of the single RAMLS4567. It seems to be working now without overwriting that variable, I am still not sure what could have caused that variable to be overwritten as the original RAMLS4567 allocations were default TI settings - I am concerned that this will occur again and maybe next time it won't be so obvious?
Please let me know what I could look at fixing in my linker file to prevent this happening.
Many thanks
.stack : > RAMM1
// .init_array : > FLASH_BANK0_SEC1, ALIGN(8) //ss not used for some reason
.bss : > RAMLS4
.bss:output : > RAMLS4
.bss:cio : > RAMGS0
.const : >> FLASH_BANK0_SEC10| FLASH_BANK0_SEC11, ALIGN(8) //SS problem with sector 9
.data : > RAMLS6
.sysmem : > RAMLS5
ramgs0 : > RAMGS0
/* Allocate IQ math areas: */
IQmath : > RAMLS5
IQmathTables : > RAMLS5
Steven,
I'm glad you've worked around this, but agree something is not adding up with the root cause of this overload to that memory region. I've not seen the allocation in physical memory not match the .map file either.
Even with the contiguous memory defined, the linker should not be double assigning memory addresses, i.e. even though .bss and .data are "sharing" the same space, the linker should be giving unique locations/spans for each. When you assigned the sections uniquely you've made it so the linker can't do this, even though that shouldn't be necessary on your part(at least that is my thinking)
Does screenPage get assigned to the .bss(uninitialized data) or the .data(initialized data)?
If you go back to your original .map file can you see what it thinks should be at 0xA4C0(where you saw the screenPage variable in memory).
Best,
Matthew
Hi Matthew,
Many thanks for your reply. Thanks for confirming this double behaviour is not normal as suspected. I managed to find the cause which was due to an array location write (via a pointer) beyond the maximum defined size of the array. This kind of random location write can wreak havoc although I am not sure how I would have found it had I not noticed the error in the code.
Either way I am happy to have found the cause!
Many thanks again,
Steven
Steven,
Thanks for the follow up, and glad we found the culprit.
I would like to mention some features we have in HW that may be of help in the future; either for debug or in general.
In the TRM https://www.ti.com/lit/pdf/spruin7 in section 3.11 Memory Controller Module/3.11.1.5Access Protection:
We have ability to enforce read/write/fetch protection from the CPU or write protection from the DMA on a memory block basis. Not only will the action be blocked but the address that was improperly accessed will also be logged. This can also trigger an ISR.
So, if this data was static after some init, you could block modification to it in HW. This would be dependent if all the memory in that region were static, etc.; but could be something helpful to catch things like this, or to prevent them from happening at all.
Best,
Matthew
Thanks Matthew, I had no idea about this. I think this will definitely be helpful going forward,