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.

TMS320F28386S: Flash kernel loaded in flash, running from ram.

Part Number: TMS320F28386S

We need to develop a modified version of firmware update via the Serial Flash Programmer since our tx/rx pin pair is not in the accepted list for SCIA boot. Also the transfer is very slow as ReadFile() in the VS C++ based serial flash programmer takes 15 ms to return each byte even with baud rate at 115200.

Part of the solution is to place 3 flash kernels (3 not 4, as we do not use CPU2) in flash on the F28386 and then copy to RAM and execute from RAM. I do not understand all the intricacies of the run time setup, etc, so I must ask some stupid questions.

The kernel projects each generate an .out file and several object files.

Q1: Would it be possible to have the .out files copied from flash to ram and then run?

Another option I think might work would be to use the object files from each kernel project. For instance the flash_kernel_c28x_dual_ex1_c28x1 project generates 7 unique objects.

Q2: Could the object files be specified like this in SECTIONS? Of course a copy routine would be needed.

SECTIONS

{

...

flashKernelCPU1: >> FLASH5 | FLASH6, run >> RAMM1

{

flash_kernel_c28x_dual_ex1_sci_flash_kernel_cpu1.obj

flash_kernel_c28x_dual_ex1_sci_get_function_cpu1.obj

}

...

}

Q3: How would the load, run, and start addresses be determined (function main() been stripped off)?

Another linking method I have seen in the TI documents for code that needs different load and run addresses uses input sections “.TI.ramfunc”.

Q4: To use this concept would it be necessary to preface dozens and dozens of functions in these projects with something like this:

#pragma CODE_SECTION(ldfuLoad, ".TI.ramfunc") ?

 

Any help or suggestions you can offer are much appreciated as I am critically overdue on delivering this solution.

Thanks,

John

  • John,

    I don't believe you can "Copy" the .out file from Flash to RAM, since the .out file would consist of code, data, etc. You can specify individual functions that you want to run from RAM, as you've done in .TI.ramfunc, and then have the corresponding memcpy() in your initialization code.

    As an example, you could place a set of functions within a section called isrcodefuncs, and have the following in your linker command file, and then the corresponding CODE_SECTION pragma against every function that you want to be placed in that section.

    In this case, the linker defines all the symbols like isrcodefuncsLoadStart, isrcodefuncsLoadSize, etc. which you can use in your code by using the extern keyword.

    Linker command file:

    isrcodefuncs :      LOAD = FLASH_BANK0_SEC8_9_10,

                                            RUN =  RAMLS5LS6,

                                            LOAD_START(isrcodefuncsLoadStart),

                                            LOAD_SIZE(isrcodefuncsLoadSize),

                                            LOAD_END(isrcodefuncsLoadEnd),

                                            RUN_START(isrcodefuncsRunStart),

                                            RUN_SIZE(isrcodefuncsRunSize),

                                            RUN_END(isrcodefuncsRunEnd),

                                            ALIGN(8)

    Extern declaration of linker symbols (e.g. device.h):

    extern uint16_t isrcodefuncsLoadStart;
    extern uint16_t isrcodefuncsLoadEnd;
    extern uint16_t isrcodefuncsLoadSize;
    extern uint16_t isrcodefuncsRunStart;
    extern uint16_t isrcodefuncsRunEnd;
    extern uint16_t isrcodefuncsRunSize;

    Memory copy (e.g. device.c)

    memcpy(&isrcodefuncsRunStart, &isrcodefuncsLoadStart, (size_t)&isrcodefuncsLoadSize); 

    Code:

    #pragma CODE_SECTION(ISR1,"isrcodefuncs");

    Void function_name(….)

    {

    }

     

    To further optimize this approach, it is also possible to use the --ramfunc option provided by the compiler to specify that all functions need to run from RAM. This option can also be limited to specific source files. Instead of selecting this for the project, you will right click on the specific source file and select this option. I believe this is equivalent to the .obj options that you've indicated in your Q2 . I don't know the syntax for that off the top of my head. Likewise, if you have a specific library within your executable that you want to run from RAM, you can do that as well, again I don't know the syntax - I'm trying to dig it up.

    Refer here for details: https://software-dl.ti.com/C2000/docs/optimization_guide/phase3/memory.html#executing-from-ram

    Thanks,

    Sira

  • Wow, Sira! Thank you for the timely and very detailed answer.

    You told me what I despaired to hear, adding" #pragma CODE_SECTION "to all of the functions. But you also gave me a lot of good information. I am looking forward to moving forward with this.

    The --ramfunc control will be quite useful. It will allow the regular app code to run from flash but my kernels can run from ram while flash is updated.

    I don't think I need isrcodefuncsLoadEnd, isrcodefuncsRunStart, and isrcodefuncsRunEnd. Are thy used by the linker? Maybe interesting or useful in a map file?

    Again, many, many thanks.

  • I have noticed many files using this construct where the first argument is the name of the next function.

    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            #pragma CODE_SECTION(exampleError,".TI.ramfunc");
        #else
            #pragma CODE_SECTION(exampleError,"ramfuncs");
        #endif
    #endif

    Your example above is like this:

    #pragma CODE_SECTION(ISR1,"isrcodefuncs");
    
    Void function_name(….)
    
    {
    
    }

    What does ISR1 refer to?

    Thanks.

  • John,

    You do need the linker variables used in the memcpy() as I pointed out. Yes, you may not need the others in your code.

    Thanks,

    Sira

  • Yes, that was a Typo when I copy and pasted from my code. I tried to make it generic and changed ISR1 to function_name.

    It should be:

    #pragma CODE_SECTION(function_name,"isrcodefuncs");
    
    Void function_name(….)
    
    {
    
    }

  • Thanks again. Could you tell me why the ".TI.ramfunc" version is used for the higher compiler versions?

  • John,

    If you use the --ramfunc option in your project (or for specific source files), the linker in newer compiler versions (after v15.9) places these in a section called .TI.ramfunc, not ramfuncs. Therefore, it expects the linker command file to define a section called .TI.ramfunc.

    This option does not come into the picture if you place specific functions in RAM in your own user-defined sections.

    Thanks,

    Sira