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.

TMS320F280049C: Different behavior of simple code if run from RAM

Part Number: TMS320F280049C
Other Parts Discussed in Thread: CODECOMPOSER

Tool/software:

On a TMS320F280049C, we had this snippet of code in two different functions in our project. One is placed in GSRAM (let’s call it funcRAM) and the other in flash (funcFLASH). funcFlash executes correctly (Ptr->x is updated) but the other one does not. Here’s the snippet:

 

if (rxCAN.msg <= 8U) {

    Ptr->x= rxCAN.msg;

} else {

    Ptr->x= 8U;

}

 flag = true;

 

To add more details:

 

The code is executed using CPU, not CLA.

 

One of the functions is executed when message A is received and the other one when B is received. Flag will trigger an answer, thus we know that each is executed at the right time and that the code passes through the lines where Ptr->x is updated. What I’m trying to say is that the rest of the code shouldn’t be the problem, it is localized here.

 

Furthermore, Ptr points to a struct which is located in GSRAM (address of the struct 0xd180) but the pointer itself is in flash (addresss 0x912be). funcRAM is run from address 0x12000. This function also accesses a specific part of the 0xd180 struct using another pointer which is itself in RAM (address 0xc004). That other code, which does not use the flash pointer, works both on funcRAM and funcFLASH.

 

We no longer need funcRAM to be executed from RAM and thus we have a workaround. On the other hand, we need to understand why this happens to uncover any possible bugs stemming from the same root cause. On the past, we observed also different behavior on some code depending if it was placed on LSRAM or GSRAM (executed with CPU, not CLA). I don’t have the details top of mind; I would have to dig them if needed. I would like to know if that behavior is related or it is something different.

The code was generated using Simulink, btw, although I don’t think it has anything to do with that.

This is taken from our Makefile:


C:/ti/ccs1210/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/cl2000" --define=MODEL=fw_EPC_50A_NI --define=NUMST=2 --define=NCSTATES=0 --define=HAVESTDIO --define=MODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 --define=CLASSIC_INTERFACE=0 --define=ALLOCATIONFCN=0 --define=TID01EQ=0 --define=CLA_BLOCK_INCLUDED --define=TERMFCN=0 --define=ONESTEPFCN=1 --define=MAT_FILE=0 --define=MULTI_INSTANCE_CODE=0 --define=INTEGER_CODE=0 --define=MT=1 --define=DAEMON_MODE=1 --define=XCP_CUSTOM_PLATFORM --define=EXTMODE_DISABLE_ARGS_PROCESSING=1 --define=MW_PIL_SCIFIFOLEN=16 --define=CPU1 --define=F2837X_REG_FORMAT --define=MW_F28004X --define=STACK_SIZE=1024 --define=__MW_TARGET_USE_HARDWARE_RESOURCES_H__ --define=RT --define=F280049C --define=BOOT_FROM_FLASH=1 --define=CPU_RAMLS_DATA_START=0x8800 --define=CPU_RAMLS_DATA_LENGTH=0x800 --define=CPU_RAMLS_PROG_START=0x8000 --define=CPU_RAMLS_PROG_LENGTH=0x800 --define=CLA_RAMLS_PROG_START=0x9800 --define=CLA_RAMLS_PROG_LENGTH=0x2800 --define=CLA_RAMLS_DATA_START=0x9000 --define=CLA_RAMLS_DATA_LENGTH=0x800 --abi=coffabi -s -v28 -ml  --abi=coffabi  --preproc_dependency=@:%.obj=%.dep) --preproc_with_compile --large_memory_model --silicon_version=28 --define=LARGE_MODEL -I -I/include -I -O3 --opt_for_speed=5 --unified_memory --idiv_support=none --cla_signed_compare_workaround=on -k -DCLA_BLOCK_INCLUDED --cla_support=cla2 -v28 --float_support=fpu32 -ml -DF280049C -DBOOT_FROM_FLASH=1 --tmu_support=tmu0 --fp_mode=relaxed -DCPU_RAMLS_DATA_START=0x8800 -DCPU_RAMLS_DATA_LENGTH=0x800 -DCPU_RAMLS_PROG_START=0x8000 -DCPU_RAMLS_PROG_LENGTH=0x800 -DCLA_RAMLS_PROG_START=0x9800 -DCLA_RAMLS_PROG_LENGTH=0x2800 -DCLA_RAMLS_DATA_START=0x9000 -DCLA_RAMLS_DATA_LENGTH=0x800 -z --warn_sections -i"C:/ti/ccs1210/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/lib" -i"C:/ti/ccs1210/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/include" --reread_libs --define=CLA_BLOCK_INCLUDED --define=F280049C --define=BOOT_FROM_FLASH=1 --define=BOOT_USING_BL=0 --define=CPU_RAMLS_DATA_START=0x8800 --define=CPU_RAMLS_DATA_LENGTH=0x800 --define=CPU_RAMLS_PROG_START=0x8000 --define=CPU_RAMLS_PROG_LENGTH=0x800 --define=CLA_RAMLS_PROG_START=0x9800 --define=CLA_RAMLS_PROG_LENGTH=0x2800 --define=CLA_RAMLS_DATA_START=0x9000 --define=CLA_RAMLS_DATA_LENGTH=0x800 --rom_model --stack_size=1024 --warn_sections --heap_size=1024 --reread_libs --rom_model --priority -mfw_project.map -o "fw_project.out" $(ORDERED_OBJS)

Thank you in advance.

  • The biggest difference between flash and RAM in this case is that the flash is waitstated (4 cycles at 100MHz CPU) vs the RAM is 0WS memory.  This would mean the code in flash will take longer to execute than the same code placed in RAM.  

    Is it possible to set a BP in the RAM version of code to see what is happening incorrectly; i.e. does the value that is written incorrect, or the value doesn't get written at all, etc?  Other than the WS, Flash can't be modified by normal code execution, but that I mean if the flash memory was somehow overloaded, you can't "overwrite" flash contents with out the flash API.  RAM, on the other hand, if there was a stack overflow; or some type of over-used region, you could start to see odd behaviors based on code execution.

    There should be ability to block writes from certain regions of RAM if we wanted to test this out, etc.

    Best,

    Matthew

  • I've been seeing other issues of code that works in one project CodeComposer project but not in another. For example: a register not being written, an interrupt executing an increment but not an asigment inside of a short function that the ISR calls. This is code executed from flash, not RAM.

    I now believe that this issue has to do with -O3 optimization. By using #pragma FUNCTION_OPTIONS ( ... , "--opt_level=0" ) on several short functions related to the call sequence of the skipped assigment, I get the expected behavior.

    Is this normal? Is -O3 not recommended? I'm reading the compiler user guide and I see there are cautionary notes but I don't see anything related to an assigment "skipped".

    Thank you

  • Ivan,

    I don't know of any restrictions on -O3, we typically use/recommend O2 for optimum performance vs code read-ability tradeoffs.

    I can say that even with -O2, the optimization will become such that setting breakpoints in the C source will not always resolve to a exact line of code, and in general things become more difficult to debug.

    I read the just read the warnings as well, any chance there are shared globals used in ISRs?  Those need to be declared as volatile according to the document.

    Best,
    Matthew

  • Thank you Matthew.

    This may not be related to the difference between RAM and flash but it is related to the issue of my latest comment. The shared globals where volatile, but I've observed something else:

    I'm calling Interrupt_enable(INT_DMA_CH5); INT_DMA_CH5 is defined in hw_ints.h by TI. I notice that IER7 is never set and the ISR is never triggered, but if I introduce a breakpoint inside Interrupt_enable, it will be set and the ISR is triggered.

    Any clues as to what could cause this? I've even tried creating my own copy of Interrupt enable with #pragma FUNCTION_OPTIONS ( ..., "--opt_level=0" ), but it does not make a difference.

    I'm really baffled by this behavior.

    This happens both with v22.6.0 and v20.2.1.

    The original minimal project where this code related to the interrupt worked was compiled in EABI format, the project where I integrated it is in COFF and we are not planning to migrate.

  • Note: on this issue of only writing to IER if run the code step by step with the debugger, I see no difference between -O2 and -O3.

  • Please see my private message to follow up on this issue.

  • Hello again

    Please, we would like to advance on solving this bug. We want to understand the root cause to evaluate if there are other possible consequences.

    Thanks

  • Ivan,

    I know it has been some time from our side communicating back to you.  I've been trying to import/replicate, but running into issues with CCS, etc.  I can run the .out files, but since I don't have an EEPROM connected, I believe the code just stalls well before the issue would occur.

    Two paths:

    1)You can reach out to The Mathworks for help, they may be aware of what issues you are running up against.

    2)I have installed The Mathworks package, 2025b.  If you think that sharing that level of project off forum will help I can try and import it.

    Best,

    Matthew

  • Matthew,

    The code which does work will work differently with or without EEPROM, as shown on the screenshots I included in the zip file, nevertheless it does send with SPI through DMA. The code which doesn't will only send the first bytes using the CPU but will never trigger the corresponding ISR and won't send those next bytes.

    1. OK FW with EEPROM connected:


    2. OK FW without EEPROM connected (it keeps sending because there is no answer):


    3. FW that does not work (either with or without EEPROM):


    Hope that clears it out. Anything else I can do to facilitate your work?

    Iván

  • Hi,

    Any news on this issue?

    Thanks

  • Hi,

    Any news on this issue?

    Thanks

  • Hi Ivan,

    Apologies for the delay on getting back to you. I spoke to Matt about this issue and wanted to see if you had any resolution or if it is still open before I look into it further. 

    Regards

    Lori