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:
Hi,
We are using Code Composer Studio Version: 12.8.0.00012 with compiler version 22.6.1LTS, C2000Ware version 5.2.0 and SysConfig version 1.21.0. We have configured two tasks to run on CLA. Basically these are two controllers: Inverter controller & Battery controller. The outputs are the duty cycles for the converters. The tasks have been running fine until recently when we have added some more code to Task2. The task 2 is generating expected duty cycles but the duty cycles from task 1 remain at fix value. We have profiled the two tasks and confirmed that both the tasks are executing and taking almost the same time as when both the tasks were generating the correct outputs. Please refer to the below picture for the time profiling of the tasks where we have used GPIOs to mark the starting and ending of each task as being executed in the CLA.
The rising edge of channel 2 (blue) records when Task 1 function is called & its falling edge records when the function execution is finished. Similarly the channel 1 records the start and end of Task 2 function. The tasks are called @16Khz so both the CLA tasks are executed in around 13 uSec of the available 67u Sec. We have assigned three LSRAM segments to the CLA program memory and two LSRAM segments to the CLA data memory.
The linker file is also attached for reference:
//CPU1 PROGRAM GSRAM is allocated to GS7 & GS8 #define CPU1_RAMGS_PROG_START 0x013000 #define CPU1_RAMGS_PROG_LENGTH 0x002000 //CPU1 DATA GSRAM is allocated from GS2 RAM to GS6 RAM #define CPU1_RAMGS_DATA_START 0x00E000 #define CPU1_RAMGS_DATA_LENGTH 0x005000 //required for MemCfgRegs settings #define RAMGS_START 0x00000C #ifdef CLA_BLOCK_INCLUDED // Define a size for the CLA scratchpad area that will be used // by the CLA compiler for local symbols and temps // Also force references to the special symbols that mark the // scratchpad are. CLA_SCRATCHPAD_SIZE = 0x100; --undef_sym=__cla_scratchpad_end --undef_sym=__cla_scratchpad_start #endif //CLA_BLOCK_INCLUDED MEMORY { PAGE 0 : /* BEGIN is used for the "boot to SARAM" bootloader mode */ BEGIN : origin = 0x000000, length = 0x000002 BEGIN_FLASH : origin = 0x080000, length = 0x000002 /*Defining CLA program and data memory*/ #if (CPU_RAMLS_PROG_LENGTH > 0) RAMLS_PROG : origin = CPU_RAMLS_PROG_START, length = CPU_RAMLS_PROG_LENGTH #endif //CPU_RAMLS_PROG_LENGTH RAMLS_CLA_PROG : origin = CLA_RAMLS_PROG_START, length = CLA_RAMLS_PROG_LENGTH RAMLS_CLA_DATA : origin = CLA_RAMLS_DATA_START, length = CLA_RAMLS_DATA_LENGTH /*Defining CPU1 program memory in GSRAM*/ #if (CPU1_RAMGS_PROG_LENGTH > 0) RAMGS_PROG : origin = CPU1_RAMGS_PROG_START, length = CPU1_RAMGS_PROG_LENGTH #endif //(CPU1_RAMGS_PROG_LENGTH > 0) RESET : origin = 0x3FFFC0, length = 0x000002 /* Flash sectors */ FLASHA_N : origin = 0x080002, length = 0x03FFFE /* on-chip Flash 256 K Words */ PAGE 1 : BOOT_RSVD : origin = 0x000002, length = 0x000120 /* Part of M0, BOOT rom will use this for stack */ RAMM0M1 : origin = 0x000122, length = 0x0006DE RAMD0D1 : origin = 0x00B000, length = 0x001000 RAMGS_DATA : origin = CPU1_RAMGS_DATA_START, length = CPU1_RAMGS_DATA_LENGTH CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080 CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080 CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400 CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400 } SECTIONS { #if BOOT_FROM_FLASH /* Allocate program areas: */ .init_array : > FLASHA_N PAGE = 0, ALIGN(128) .cinit : > FLASHA_N PAGE = 0, ALIGN(128) .pinit : > FLASHA_N, PAGE = 0, ALIGN(128) .text : > FLASHA_N PAGE = 0, ALIGN(128) codestart : > BEGIN_FLASH PAGE = 0, ALIGN(128) .switch : > FLASHA_N PAGE = 0, ALIGN(128) .const : > FLASHA_N PAGE = 0, ALIGN(128) .data : > RAMLS_PROG, PAGE = 0 .bss : > RAMGS_DATA , PAGE = 1 #if defined(__TI_EABI__) .TI.ramfunc : {} LOAD = FLASHA_N, #if CPU_RAMLS_PROG_LENGTH>0 RUN = RAMLS_PROG, #else // Applicable when CLA BLOCK is included and CPULSRAM is zero RUN = RAMGS_PROG, #endif LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), PAGE = 0, ALIGN(128) #else .TI.ramfunc : {} LOAD = FLASHA_N, #if CPU_RAMLS_PROG_LENGTH>0 RUN = RAMLS_PROG, #else // Applicable when CLA BLOCK is included and CPULSRAM is zero RUN = RAMGS_PROG, #endif LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), RUN_SIZE(_RamfuncsRunSize), RUN_END(_RamfuncsRunEnd), PAGE = 0, ALIGN(128) #endif /* Initalized sections go in Flash */ /* Allocate IQmath areas: */ IQmath : > FLASHA_N, PAGE = 0, ALIGN(128) /* Math Code */ IQmathTables : > FLASHA_N, PAGE = 0, ALIGN(128) /* CLA specific sections */ Cla1Prog : LOAD = FLASHA_N, RUN = RAMLS_CLA_PROG, LOAD_START(Cla1funcsLoadStart), LOAD_END(Cla1funcsLoadEnd), RUN_START(Cla1funcsRunStart), LOAD_SIZE(Cla1funcsLoadSize), PAGE = 0, ALIGN(128) .const_cla : LOAD = FLASHA_N, RUN = RAMLS_CLA_DATA, RUN_START(Cla1ConstRunStart), LOAD_START(Cla1ConstLoadStart), LOAD_SIZE(Cla1ConstLoadSize), PAGE = 0 #else codestart : > BEGIN, PAGE = 0 #if (CPU_RAMLS_PROG_LENGTH > 0) .cinit : > RAMLS_PROG, PAGE = 0 #else .cinit : > RAMGS_PROG, PAGE = 0 #endif ramfuncs : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .TI.ramfunc : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .pinit : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .switch : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .econst : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* Allocate IQ math areas: */ IQmath : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* Math Code */ IQmathTables : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* CLA specific sections */ Cla1Prog : > RAMLS_CLA_PROG, PAGE = 0 .text : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .const_cla : > RAMLS_CLA_DATA, PAGE = 0 .ebss : > RAMGS_DATA , PAGE = 1 #endif //BOOT_FROM_FLASH .stack : > RAMM0M1, PAGE = 1 .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */ .sysmem : > RAMD0D1, PAGE = 1 #ifdef CLA_BLOCK_INCLUDED .cio : > RAMLS_PROG | RAMGS_PROG, PAGE = 0 #else .cio : > RAMLS_PROG PAGE = 0 #endif //CLA_BLOCK_INCLUDED /* CLA C compiler sections */ // // Must be allocated to memory the CLA has write access to // Cla1DataRam0 : > RAMLS_CLA_DATA, PAGE=0 Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1 CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1 CLAscratch : { *.obj(CLAscratch) . += CLA_SCRATCHPAD_SIZE; *.obj(CLAscratch_end) } > RAMLS_CLA_DATA, PAGE = 0 .scratchpad : > RAMLS_CLA_DATA, PAGE = 0 .bss_cla : > RAMLS_CLA_DATA, PAGE = 0 /*Allocate area for SPI DMA transfer buffers*/ GSRAM : > RAMGS_DATA, PAGE=1 /* Allocate twiddle factors area: */ twiddleFactors : > FLASHA_N, ALIGN = 2048, PAGE = 0 /*Allocate areas for 32 points RFFT input and output buffers*/ buffer1 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer2 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer3 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer4 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer5 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 } /* //=========================================================================== // End of file. //=========================================================================== */
when we modify task 2 for some added functionality then CLA program memory usage is increased to 97% from 95% and we get into the issue that the task 1 outputs do not update even through the task gets executed as probed on the oscilloscope.
We have tried increasing the CLA program memory usage by taking away the LS2RAM segment from CLA data memory and assigning it to CLA program memory but this does not resolve the issue. As per our finding the issue is related to increased code size of Task 2. The new code does not seem problematic as if we comment out some old functionality from Task 2 (to keep the overall CLA program size same) while keeping the new code then both tasks still generate the expected outputs.
Please let me know if more details are required.
Hi Asad,
I am reviewing this thread. I will get back to you shortly.
Thanks,
Susmitha
Hi Asad,
Are you using the linker command file from C2000ware? If yes, can you please let me know what are the changes/modifications done.
Thanks,
Susmitha
Hi Susmitha,
I have already attached linker file to my initial post and it was taken from C2000ware but then customized according to our project requirements. There are lot of changes according to our requirements and we have been using this file for more than 2 years without any issues. The issue happened only very recently when we added some more code to CLA Task 2. I am attaching the file again here
//CPU1 PROGRAM GSRAM is allocated to GS7 & GS8 #define CPU1_RAMGS_PROG_START 0x013000 #define CPU1_RAMGS_PROG_LENGTH 0x002000 //CPU1 DATA GSRAM is allocated from GS2 RAM to GS6 RAM #define CPU1_RAMGS_DATA_START 0x00E000 #define CPU1_RAMGS_DATA_LENGTH 0x005000 //required for MemCfgRegs settings #define RAMGS_START 0x00000C #ifdef CLA_BLOCK_INCLUDED // Define a size for the CLA scratchpad area that will be used // by the CLA compiler for local symbols and temps // Also force references to the special symbols that mark the // scratchpad are. CLA_SCRATCHPAD_SIZE = 0x100; --undef_sym=__cla_scratchpad_end --undef_sym=__cla_scratchpad_start #endif //CLA_BLOCK_INCLUDED MEMORY { PAGE 0 : /* BEGIN is used for the "boot to SARAM" bootloader mode */ BEGIN : origin = 0x000000, length = 0x000002 BEGIN_FLASH : origin = 0x080000, length = 0x000002 /*Defining CLA program and data memory*/ #if (CPU_RAMLS_PROG_LENGTH > 0) RAMLS_PROG : origin = CPU_RAMLS_PROG_START, length = CPU_RAMLS_PROG_LENGTH #endif //CPU_RAMLS_PROG_LENGTH RAMLS_CLA_PROG : origin = CLA_RAMLS_PROG_START, length = CLA_RAMLS_PROG_LENGTH RAMLS_CLA_DATA : origin = CLA_RAMLS_DATA_START, length = CLA_RAMLS_DATA_LENGTH /*Defining CPU1 program memory in GSRAM*/ #if (CPU1_RAMGS_PROG_LENGTH > 0) RAMGS_PROG : origin = CPU1_RAMGS_PROG_START, length = CPU1_RAMGS_PROG_LENGTH #endif //(CPU1_RAMGS_PROG_LENGTH > 0) RESET : origin = 0x3FFFC0, length = 0x000002 /* Flash sectors */ FLASHA_N : origin = 0x080002, length = 0x03FFFE /* on-chip Flash 256 K Words */ PAGE 1 : BOOT_RSVD : origin = 0x000002, length = 0x000120 /* Part of M0, BOOT rom will use this for stack */ RAMM0M1 : origin = 0x000122, length = 0x0006DE RAMD0D1 : origin = 0x00B000, length = 0x001000 RAMGS_DATA : origin = CPU1_RAMGS_DATA_START, length = CPU1_RAMGS_DATA_LENGTH CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080 CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080 CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400 CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400 } SECTIONS { #if BOOT_FROM_FLASH /* Allocate program areas: */ .init_array : > FLASHA_N PAGE = 0, ALIGN(128) .cinit : > FLASHA_N PAGE = 0, ALIGN(128) .pinit : > FLASHA_N, PAGE = 0, ALIGN(128) .text : > FLASHA_N PAGE = 0, ALIGN(128) codestart : > BEGIN_FLASH PAGE = 0, ALIGN(128) .switch : > FLASHA_N PAGE = 0, ALIGN(128) .const : > FLASHA_N PAGE = 0, ALIGN(128) .data : > RAMLS_PROG, PAGE = 0 .bss : > RAMGS_DATA , PAGE = 1 #if defined(__TI_EABI__) .TI.ramfunc : {} LOAD = FLASHA_N, #if CPU_RAMLS_PROG_LENGTH>0 RUN = RAMLS_PROG, #else // Applicable when CLA BLOCK is included and CPULSRAM is zero RUN = RAMGS_PROG, #endif LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), PAGE = 0, ALIGN(128) #else .TI.ramfunc : {} LOAD = FLASHA_N, #if CPU_RAMLS_PROG_LENGTH>0 RUN = RAMLS_PROG, #else // Applicable when CLA BLOCK is included and CPULSRAM is zero RUN = RAMGS_PROG, #endif LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), RUN_SIZE(_RamfuncsRunSize), RUN_END(_RamfuncsRunEnd), PAGE = 0, ALIGN(128) #endif /* Initalized sections go in Flash */ /* Allocate IQmath areas: */ IQmath : > FLASHA_N, PAGE = 0, ALIGN(128) /* Math Code */ IQmathTables : > FLASHA_N, PAGE = 0, ALIGN(128) /* CLA specific sections */ Cla1Prog : LOAD = FLASHA_N, RUN = RAMLS_CLA_PROG, LOAD_START(Cla1funcsLoadStart), LOAD_END(Cla1funcsLoadEnd), RUN_START(Cla1funcsRunStart), LOAD_SIZE(Cla1funcsLoadSize), PAGE = 0, ALIGN(128) .const_cla : LOAD = FLASHA_N, RUN = RAMLS_CLA_DATA, RUN_START(Cla1ConstRunStart), LOAD_START(Cla1ConstLoadStart), LOAD_SIZE(Cla1ConstLoadSize), PAGE = 0 #else codestart : > BEGIN, PAGE = 0 #if (CPU_RAMLS_PROG_LENGTH > 0) .cinit : > RAMLS_PROG, PAGE = 0 #else .cinit : > RAMGS_PROG, PAGE = 0 #endif ramfuncs : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .TI.ramfunc : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .pinit : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .switch : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .econst : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* Allocate IQ math areas: */ IQmath : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* Math Code */ IQmathTables : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 /* CLA specific sections */ Cla1Prog : > RAMLS_CLA_PROG, PAGE = 0 .text : >> RAMLS_PROG | RAMGS_PROG, PAGE = 0 .const_cla : > RAMLS_CLA_DATA, PAGE = 0 .ebss : > RAMGS_DATA , PAGE = 1 #endif //BOOT_FROM_FLASH .stack : > RAMM0M1, PAGE = 1 .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */ .sysmem : > RAMD0D1, PAGE = 1 #ifdef CLA_BLOCK_INCLUDED .cio : > RAMLS_PROG | RAMGS_PROG, PAGE = 0 #else .cio : > RAMLS_PROG PAGE = 0 #endif //CLA_BLOCK_INCLUDED /* CLA C compiler sections */ // // Must be allocated to memory the CLA has write access to // Cla1DataRam0 : > RAMLS_CLA_DATA, PAGE=0 Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1 CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1 CLAscratch : { *.obj(CLAscratch) . += CLA_SCRATCHPAD_SIZE; *.obj(CLAscratch_end) } > RAMLS_CLA_DATA, PAGE = 0 .scratchpad : > RAMLS_CLA_DATA, PAGE = 0 .bss_cla : > RAMLS_CLA_DATA, PAGE = 0 /*Allocate area for SPI DMA transfer buffers*/ GSRAM : > RAMGS_DATA, PAGE=1 /* Allocate twiddle factors area: */ twiddleFactors : > FLASHA_N, ALIGN = 2048, PAGE = 0 /*Allocate areas for 32 points RFFT input and output buffers*/ buffer1 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer2 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer3 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer4 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 buffer5 : > RAMGS_PROG, ALIGN = 256, PAGE = 0 } /* //=========================================================================== // End of file. //=========================================================================== */
some symbols are used in this file and are described as below:
Please let me know if more details are required.
Hi Asad,
It seems memory allocation is fine. Can you please send the extra code, you have added?
Also, how the memory allocation looks like after extra code is added in Task2?
You can step through the code for both tasks and see the line at which PWM signals in task1 aren't working as expected. Check the status of PWM registers.
Thanks,
Susmitha
Thank you for continued investigation. The memory allocation with extra code added to CLA Task 2 is shown below:
Regarding the extra code please note the following points:
1- Task2 which contains extra code still works fine in all cases. If Task1 is called alone then this task also generates the expected outputs and works fine. Only when both the tasks are called together (we are using software triggers to force CLA tasks) then we observe that Task1 does not update its outputs but Task 2 updated the outputs correctly. Task 1 is however getting executed as we have profiled it and discussed in the start of the thread.
2- The extra code does not include any additions in CPU to CLA or CLA to CPU message RAMs. It is simply a logic to gradually ramp up the battery current value from initial set point to a new set point (to avoid some over shoots) so the only effect that it can have could be addition of some more local variables in Task 2 and some additional code size.
We suspect that it could be some memory leakage issue or some kind of optimizations by compiler. Can you provide some guide lines to systematically debug this issue?.
We have not used any background CLA task and are not much aware of its use case. Please let us know if it is recommended to use it. If any additional info is required then please let me know.
If you still think that the actual code can be helpful then please let me know and I will share the complete source files for CLA Task 2 for both cases.
Hi Asad,
Can you please check project properties to make sure optimizations are turned off and then try stepping through task 1, when both tasks are enabled?
Thanks,
Susmitha
I understand that using optimizations is a good practice to improve execution efficiency and saving code space. As you can see we are already hitting the available CLA program memory turning off the optimizations is not a practical solution for us. Please also note that we have now around 4 years experience with the C2000 series and have developed quite stable applications. The guide lines that you are providing seem trivial to me. May I request if you can refer this ticket to a more experienced resource?.
Hi Asad,
As far as I know, there isn't any reason having 97% full CLA program memory would cause an issue at runtime. As long as the project is building without any errors/warnings, this should indicate that the linker is able to allocate enough space for the program in the sections you have provided in the linker cmd file. And since your program memory is being assigned to an LSRAM section that the CLA has access to, as well giving the CLA permissions to this memory through the Sysconfig generated code, I don't see an issue here. Sometimes the scratchpad memory (similar to the CLA's stack) can overflow at runtime due to too many function calls, local variables etc. being pushed, however the scratchpad is located in data memory which there looks to be enough space left for.
It would be helpful to see the code in both of your tasks. As Susmitha mentioned, stepping through your tasks in the debugger to monitor the execution would also be helpful to see if there is a specific line where the execution stops working. Does the code you added have multiple layers of nested function calls, or use complex pointers/structures? This could indicate scratchpad overflow. I am consulting another expert to see if they have any other ideas here as well.
Best Regards,
Delaney
Hi Asad,
Some more things to check, from the other expert:
Are both CLA tasks in the same memory location for all three cases (you can check this in the map file):
Could the main CPU be interfering perhaps by accessing the same peripheral or changing shared data between the CPU and CLA?
Best Regards,
Delaney
Hi Delaney,
Thank you very much for more pointers to debug the issue. Let me look into the points that you have mentioned. I have a small confusion regarding the map file. I understand that these are generated during the link stage so how can these be different for the three cases that you have mentioned?. The cases that you mention are the run time conditions of our code. We are using software trigger for CLA tasks. Task 1 basically generates the inverter PWMs and it always execute when the system is in run state. Task 2 executes the battery converter PWMs and it executes only if the battery is available. Now the availability of battery is a run time condition and can change. Please clarify this point.
Hi Delaney,
Just want to let you know that we got occupied some urgent matters so please do not close this ticket. We will resume investigating the issue hopefully from start of next week and update you accordingly.
Hi Asad,
Ok, I will leave the ticket open, let me know when you have checked the things I mentioned previously.
For the three different cases, I thought by calling the tasks alone you meant commenting out the software triggers for one or the other, thereby changing the source code for each case. In this scenario, the code sizes and out files would be different for each different build and the linker could be allocating the memory differently. However, if the three cases all happen at different times in the same build, you would only have one map file. It would still be helpful to check the map file to see where the task is being placed in memory.
Best Regards,
Delaney