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: TI-RTOS
Hi,
Has anyone found examples on what are the steps required to execute the TI-RTOS from RAM, and how the copying of functions is done nowadays?
I would be perfectly happy to just read through code files if nothing more thorough pops up.
I have tried looking at SPRA958, but all the pictures seem outdated, and that makes me suspicious of whether it will work.
Best regards,
Tero
Hi,
So I have tried to follow the instructions on the SPRA958, and I'm getting unresolved symbols errors.
Here is the code I'm trying:
#include <string.h> #include <xdc/std.h> #include <xdc/runtime/Error.h> #include <xdc/runtime/System.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <xdc/cfg/global.h> extern unsigned int hwi_vec_loadstart; extern unsigned int hwi_vec_loadsize; extern unsigned int hwi_vec_runstart; Int main() { EALLOW; memcpy(&hwi_vec_runstart, &hwi_vec_loadstart, (uint32_t)&hwi_vec_loadsize); EDIS; memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); Task_Handle task; Error_Block eb; // Initialize the GPIO InitGpio(); InitPeripheralClocks(); // Setup the GPIO for DEVboard LEDs SetupGpio(conf_TI_EPWM); // Setup ADC A-D for operation InitAdcA(); InitAdcB(); InitAdcC(); InitAdcD(); InitEPwm(); System_printf ("enter main()\n"); Error_init (&eb); // Create first task task = Task_create(taskFxn1, NULL, &eb); if (task == NULL) { System_printf ("Task_create() failed!\n"); BIOS_exit(0); } // Create second task task = Task_create(taskFxn2, NULL, &eb); if (task == NULL) { System_printf ("Task_create() failed!\n"); BIOS_exit(0); } BIOS_start(); /* does not return */ return(0); }
There are some files around the example as well for the init functions but this is just to show the general structure. I don't think I can reduce my code enough to be able to paste it here without issues regarding data security.
I'm missing something but I can't figure out what. The SPRA958 says that those symbols are created automatically.
I have also specified this init-function that I have put on the Start-up page of app.cfg (as a reset function, hopefully this is correct):
#include <string.h> #include <xdc/cfg/global.h> extern unsigned int trcdata_loadstart; extern unsigned int trcdata_loadsize; extern unsigned int trcdata_runstart; /** * @brief Copy the trcData to RAM to execute faster * * \todo Add description * */
void Copy_trcData(void) { asm(" EALLOW"); memcpy(&trcdata_runstart, &trcdata_loadstart, (uint32_t)&trcdata_loadsize); asm(" EDIS"); }
This throws the same errors for the symbols.
o what am I missing here? Is there an include I'm missing or is this information completely out of date? I have not made any changes to my linker cmd file (unfortunately, the file format is blocked as an attachment). I'm using compiler 18.1.5.LTS and SYS/BIOS 6.75.1.05
My goal, at the moment, is to get the TI-RTOS to execute efficiently from RAM, and I have four ADC-hwis defined I want to run according to a 8kHz ePWM trigger. At the moment, my logging shows as I would be executing closer to 3kHz.
Thanks for any input.
Best regards,
Tero
Hi,
So I managed to rid myself of the "undefined symbol" errors by adding these lines to the linker file (basically copied from the ramfuncs-section) :
.hwi_vec : > FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0 LOAD_START(_hwi_vec_loadstart), LOAD_SIZE(_hwi_vec_loadsize), LOAD_END(_hwi_vec_loadend), RUN_START(_hwi_vec_runstart), RUN_SIZE(_hwi_vec_runsize), RUN_END(_hwi_vec_runend) .trcdata : > FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0 LOAD_START(_trcdata_loadstart), LOAD_SIZE(_trcdata_loadsize), LOAD_END(_trcdata_loadend), RUN_START(_trcdata_runstart), RUN_SIZE(_trcdata_runsize), RUN_END(_trcdata_runend)
This will allow me to compile, but I'm still executing closer to 3kHz (the scheme is to process two channels per ADC in burst mode, and I'm incrementing a global variable in the hwi to keep count (this is my estimator on the frequency)).
Am I on the right tracks or should I be looking somewhere else?
Best regards,
Tero
I believe the .hwi_vec and .trcdata sections mentioned in that document are DSPBIOS things that should no longer apply to SYSBIOS.
For the SYS/BIOS code, can you try the solution suggested in this thread:
https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/355/t/203478
It shows the knl modules specifically, but you could do the same for others.
Whitney
Hi Whitney,
I followed the instructions on the post you gave, but I'm still seeing less than optimal behavior. My hwi are only executed at 3kHz when they are supposed to be triggered at 18kHz.
But my CPU load went up so definitely something happened (21->31%) .
I added the following lines:
From linker cmd file: .knl: { *.*(.text:*ti_sysbios_knl*) } LOAD = FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, RUN = RAMGS0 | RAMGS1 PAGE = 1, LOAD_START(_KnlLoadStart), LOAD_SIZE(_KnlLoadSize), LOAD_END(_KnlLoadEnd), RUN_START(_KnlRunStart) app.cfg: Startup.firstFxns[Startup.firstFxns.length++] = '&Copy_knl'; One of my many c-files: void Copy_knl(void) { EALLOW; memcpy(&KnlRunStart, &KnlLoadStart, (uint32_t)&KnlLoadSize); EDIS; }
This is from my disassembly window: 08919c: 28A9000E MOV @AL, #0x000e 173 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 08919e: 6F34 SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 174 mov @al, #15 ; dispIsr15 08919f: 28A9000F MOV @AL, #0x000f 175 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 0891a1: 6F31 SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 176 mov @al, #16 ; dispIsr16 0891a2: 28A90010 MOV @AL, #0x0010 177 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 0891a4: 6F2E SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 178 mov @al, #17 ; dispIsr17 0891a5: 28A90011 MOV @AL, #0x0011 179 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 0891a7: 6F2B SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 180 mov @al, #18 ; dispIsr18 0891a8: 28A90012 MOV @AL, #0x0012 181 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 0891aa: 6F28 SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 182 mov @al, #19 ; dispIsr19 0891ab: 28A90013 MOV @AL, #0x0013 183 sb _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 0891ad: 6F25 SB _ti_sysbios_family_c28_Hwi_dispatchPie, UNC 184 mov @al, #20 ; dispIsr20
It seems to me that not everything was moved to the RAM ( according to manual 08xxxx is FLASH region) .
Do you happen to know what are the other modules i should be allocating to RAM are?
Best regards,
Tero
You would want to do something like .hwi: { *.*(.text:*ti_sysbios*_Hwi_*) } to create a section in your cmd file for all the Hwi functions.
Whitney
Hi Whitney,
Where can I find which section I need to copy to move for every item in the TI-RTOS? While the hwis now execute from RAM, it seems that the idle functionality is not. I believe there might other portions as well, I just haven't found them yet..
I managed to catch the system in Void Load_idleFxn(Void) and it executes from 0x89538 which is in Flash again. I think I need to move the whole TI-RTOS to RAM to overcome this. Any tips for achieving this?
I did another test with the system to rule out some of the issues, and I reduced the number of overlapping hwi to 1 (ADCA1 only, instead of B1,C1, and D1). I also made the ePWM trigger it at only 2kHz frequency, but I'm still seeing only a 1/6th of the actual frequency in the ADCA1 hwi.
I believe since some of the system is running from FLASH still, it slows down the whole process. Would this be a good assumption?
Best regards,
Tero
Hi,
I tried moving more of the system to RAM. I added the following line as well, .sysbios: { *.*(.text:*ti_sysbios_*) } , to my linker file and to the same "first function" as knl, and hwi.
This seems to work to some extent, but there are still some stuff that needs to be cleaned I think. I noticed I have:
1. *xdc_runtime_*
2. *ti_uia_*
in the .text-section still that are run from FLASH. I think I need to move these as well, but apparently they are not moved in the "first function". Doing so will result the executable hitting an ESTOP0 at a location where no symbols are defined.
There are also a couple of others like this: rts2800_fpu32.lib : memcpy.c.obj (.text) , but I'm hoping they have a technical paper available on how to move them to RAM.
Best regards,
Tero
Hi,
I think there is a partial solution here at least, but it doesn't solve all my issues as far as running the whole BIOS from RAM.
I'm still facing the issue of placing rts2800_fpu.lib to RAM, I have used this as a guide:
Copying rts2800_fpu32.lib from Flash to RAM on TMS320F28335. No matching section. - C2000 microcontrollers...
But I get a warning "10247-D null: creating output section ".reset" without a SECTIONS specification" when compiling, and the board will not boot correctly.
I'm also still facing the issue of moving uia and xdc components to RAM as the RTSC wiki is down, I can't go digging in there if there are any helpful articles, and I haven't looked into what TI is offering.
But moving at least some of the BIOS to RAM seems to work if you have in your linker file:
.knl: { *.*(.text:*ti_sysbios_knl*) } LOAD = FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, RUN = RAMGS0 | RAMGS1 | RAMGS2 | RAMGS3 | RAMGS4 | RAMGS5 | RAMGS6 PAGE = 1, LOAD_START(_KnlLoadStart), LOAD_SIZE(_KnlLoadSize), LOAD_END(_KnlLoadEnd), RUN_START(_KnlRunStart) /* hwi is the hardware interrupt system */ .hwi: { *.*(.text:*ti_sysbios*_Hwi_*) } LOAD = FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, RUN = RAMGS0 | RAMGS1 | RAMGS2 | RAMGS3 | RAMGS4 | RAMGS5 | RAMGS6 PAGE = 1, LOAD_START(_hwiLoadStart), LOAD_SIZE(_hwiLoadSize), LOAD_END(_hwiLoadEnd), RUN_START(_hwiRunStart) .sysbios: { *.*(.text:*ti_sysbios_*) } LOAD = FLASHA | FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ | FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, RUN = RAMGS0 | RAMGS1 | RAMGS2 | RAMGS3 | RAMGS4 | RAMGS5 | RAMGS6 PAGE = 1, LOAD_START(_sysbiosLoadStart), LOAD_SIZE(_sysbiosLoadSize), LOAD_END(_sysbiosLoadEnd), RUN_START(_sysbiosRunStart)
And you load all these via the "first function" functionality. This can be done via the app.cfg xml-format on page "Startup" and adding the following line
Startup.firstFxns[Startup.firstFxns.length++] = '&Copy_knl';
You still need to define the 'Copy_knl' function in your files (this was my naming policy). And do the normal memcpy-routine (example can be found via 'ramfuncs' found in most, if not all, the lab exercises.
Hopefully this is of help to someone else as well.
Best regards,
Tero