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.

RTOS/TMS320F28379D: Executing TI-RTOS from RAM and copying functions

Part Number: TMS320F28379D
Other Parts Discussed in Thread: SYSBIOS

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...

    e2e.ti.com
    Hi, I'm trying to copy sections of my code from Flash to RAM for better performance. I can do this with my own functions using the following section of the linker

    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