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.

CCS/TMS320C6418: User boot routine boot.asm

Part Number: TMS320C6418

Tool/software: Code Composer Studio

Hi there,

I'm developing an application with TMS320C6418, using CCS5.5.0

My configuration will use the external flash boot, but due to the 1K ROM boot limitation for this device I will need a second boot.

Looking at the "BlinkEVM6418" example I understand that with a boot.asm file I'm able to define an "User boot code" but something is not clear to me:

1) How is the "boot.asm" file added to the project? Do I simply add it as a file, or something needs to be changed on the project properties for the compilation?

2) Once the .out file is generated and the hex utility generates the .hex file, where do I have to store the file on the external flash? Does it have to be stored starting from the beginning of the external flash (EMIF CE1-> 0x9000 0000 - Flash address: 0x0000) or an offset of 1kbytes has to be considered (due to the 1k boot from ROM)?

3) Flash Burn plugin is considered on "BlinkEVM6418" example but I'm not able to find it, is it included on the CCS5 as a plugin?

Thank you

Regards

Karles

  • Hi Karles,

    The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Hello!

    As you already learned, after reset your device copies 1 KB of data from EMIFA CE1 to processor memory starting at address. After that device starts executing copied code starting at address 0. Thus, you have to make your boot loader small enough to fit in 1 KB, and put it at origin of memory device at EMIFA CE1. This bootloader could be either standalone application - you may have separate project with boot.asm alone, build executable and flash it as origin of memory device. The space beyond 1KB could be used for other purposes, particularly for you main application image. So these two images - loader and application - could be separate. However, your loader have to know location and size of you application to load it properly.

    Thus you may want to make them parts of one single image. In that case you may add boot.asm as a source to your project, but make sure 1) loader code goes to separate section; 2) with linker command file make sure that section is placed at the beginning of output binary. Then if you flash it to memory device, bootloader still will be found at origin of CE1. This way bootloder looks prepended to useful image.

    There is a possibility to reuse 1 KB of memory occupied by bootloader after booting for other purpose if you're short on memory.

    Hope this helps.

  • Thank you so much for your reply,it did help me but I would add a step to my issue.
    I would prefer to have one sigle image with both bootloader and application.
    Since I'm short on memory I was thinking about configuring a linker command file so that:
    1) as you suggested: loader code goes to separate section; with linker command file so that section is placed at the beginning of output binary.
    2) keep .text, .cinit, .binit into the external memory.

    Let's say my application is very simple: it just sets a GPIO to high state!
    I place the main function at the beginning of external flash + 1 kbytes, with a linker.cmd as follow:


    MEMORY
    {
    IRAM(RWXI) : org = 0x00000400, len = 0x00FA00 // Internal RAM
    BOOTMEM (RX) : org = 0x90000000, len = 0x000400 // Beginning of external ROM, CE1, 1Kbytes boot
    EMIF_CE1 (RX) : org = 0x90000400, len = 0x0FFC00 // External memory with 1kbytes boot offset, where the application has to be placed
    }


    SECTIONS
    {
    .boot > BOOTMEM
    .fastcode: load > EMIF_CE1, run > IRAM // fastcode section is loaded from external ram and runs into internal ram
    .text: > EMIF_CE1
    .stack: > IRAM
    .bss: > IRAM
    .cinit: > EMIF_CE1
    .binit: > EMIF_CE1
    .far: > IRAM
    .fardata: > IRAM
    .rodata: > IRAM
    .neardata: > IRAM
    .const load > EMIF_CE1, run > IRAM
    }



    If I specify that the main function goes to the .fastcode section as follow, isn't it enough to achieve a second-bootloader, without a boot.asm file?
    How is the linker command file managed at startup?

    #pragma CODE_SECTION (main, ".fastcode")
    void main (void)
    {
    setGpio(GPIO1,HIGH);
    }

    I hope I was clear enough
    Thank you!
  • Hello!
    If you instructed linker to have .fastcode section be loaded from flash on EMIF_CE1, this job still needs to be performed by someone. I am not that much familiar with running program from flash, but it seems that _c_int00 routine should be called well before any other code, including main() could be executed. Perhaps, code of _c_int00 should be loaded to DSP memory. To my understanding, this is exactly the job of boot.asm: it provides a code to load DSP memory with absolutely necessary code and branches to _c_int00 routine. So imagine, you provided no code to 1 KB at DSP memory origin, then upon 1 KB copying completed, DSP sets program counter to zero, and if there is no useful code, you know what will happen.
    If there is a code of boot.asm, it must copy required pieces of the program to memory and branch to _c_int00. I am not sure, whether it could be executed from flash, better linker gurus tell us, though I could imagine that is possible. Then this initialization routine will setup runtime environment and call main() afterwards.
    So assuming any copying isn't needed, still code of boot.asm should have instruction to call _c_int00., and this way boot.asm is absolutely necessary. Other point is that you may implement booting routine in C as well.

  • Thank you again for your replay!
    Ok I understand what you say, and I agree that the solution you proposed is the right one.
    I was reading this about _c_int00:
    processors.wiki.ti.com/.../Accessing_c_int00

    It seems to me that I can avoid using a boot.asm by linking the boot.obj on the rts6400.lib, that should manage the _c_int00 and link to the c program, starting from main. If that is true, I can link the boot.obj at the beginning of the external ROM, without a boot.asm code, with a linker commanf file like this:

    --args 0x0
    -heap 0x0
    -stack 0x2000

    MEMORY
    {
    MSMSRAM (RWXI) : org = 0x00000400, len = 0x00FA00
    EMIF16_CS2 (RX) : org = 0x90000400, len = 0x0FFC00
    BOOTMEM (RX) : org = 0x90000000, len = 0x000400
    }


    SECTIONS
    {
    .boot > BOOTMEM
    {
    -l rts6400.lib<boot.obj> (.text)
    }
    .fastcode: load > EMIF16_CS2, run > MSMSRAM, table(BINIT)
    {
    -l main.obj (.text)
    }
    .text: > EMIF16_CS2
    .stack: > MSMSRAM
    .bss: > MSMSRAM
    .cinit: > EMIF16_CS2
    .binit: > EMIF16_CS2
    .far: > MSMSRAM
    .fardata: > MSMSRAM
    .rodata: > MSMSRAM
    .neardata: > MSMSRAM
    }


    Could this work?
  • Hello!

    If bootstrap from boot.obj fits into that 1 KB, it looks possible, though there was precaution on the wiki page you were referring about placing it in ram.

    I don't want to mislead you here as I had no experience working from flash.

    I hope it's not that big deal to try and hope you'll share your experiment result.

  • Hello!
    Thank you for your reply!
    At the moment I don't have a board to test it out, but I will try it soon. Compiling the project I can see from the map file that boot.obj occupies 96bytes, so it should fit.
    I will let you know whem I will try it. In the mean time, if someone have some advice I will be happy to listen to it!

    Thanks