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.

tms570ls20212 custom bootloader and freertos

Other Parts Discussed in Thread: HALCOGEN

I am in the process of developing the bootloader. everything works well. but only if the target application does not use the operating system. in the attachment is an example of my target application.

tmsosserial.tar.gz
  • Hi Dmitry,

    Ok, this could make sense as sharing the exception vectors between a bootloader and your application can be tricky.

    Did you have a specific question though?

  • here is my intvect.asm from bootloader.

        .sect ".intvecs"
        .ref _c_int00
        .ref phantomInterrupt
    
            b   _c_int00
    undefEntry
            b   #0x00080004
    svcEntry
            b   #0x00080008
    prefetchEntry
            b   #0x0008000C
    dataEntry
            b   #0x00080010
            b   phantomInterrupt
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

    question is, how to make it work ? 

    why example without os works flawlessly ?

  • Dmitry,

    What code do you have at address 0x00080004, 0x00080008, 0x0008000C, 0x00080010?

    In addition to the interrupts which can be handled by VIM in vector mode (bypassing the vector table) freeRTOS uses a SWI handler and it normally installs ths branch to vPortSWI at address 0x00000008 when you don't have  a bootloader.

    I'd bet this is the first thing to break when you add the bootloader.   There needs to be a path from address 0x00000008 to the vPortSWI function.  And that path needs to not disturb any registers because the context save won't happen until you reach vPortSWI.  So the 'b' is OK but a 'bl' in the path would be bad.

  • as you can see in my example, at the address 0x80000, begins vector table.

    MEMORY
    {
        VECTORS (X)  : origin=0x00080000 length=0x00000020
        KERNEL  (RX) : origin=0x00080020 length=0x00008000 
        FLASH1  (RX) : origin=0x00088020 length=0x00077FE0
        FLASH2  (RX) : origin=0x00100000 length=0x00080000
        FLASH3  (RX) : origin=0x00180000 length=0x00080000
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        KRAM    (RW) : origin=0x08001500 length=0x00000800
    	RAM     (RW) : origin=(0x08001500+0x00000800) length=(0x00026B00 - 0x00000800)
    }

    intvect.asm from target application...

            b   _c_int00
    undefEntry
            b   undefEntry
            b   vPortSWI
    prefetchEntry
            b   prefetchEntry
    dataEntry
            b   dataEntry
            b   phantomInterrupt
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

  • ok. I figured out what's the catch.

    bootloader intvect.asm should be like that:

        .sect ".intvecs"
        .ref _c_int00
        .ref phantomInterrupt
    
    
            b   _c_int00
            b   #0x0007fff8
            b   #0x0007fff8
            b   #0x0007fff8
            b   #0x0007fff8
            b   phantomInterrupt
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

  • Ok thanks Dmitry - so are you up and running?

    Would be go summarize what isn't working.   Why did you have to change your vector table to branch to 0x7FFF8?

  • yep. it works.

    if i set intvect like this

            b   _c_int00
    undefEntry
            b   #0x00080004
    svcEntry
            b   #0x00080008
    prefetchEntry
            b   #0x0008000C
    dataEntry
            b   #0x00080010

    in fact, in the compiled code, addresses is incorrect. they have some offset.

    but if i set it like 

        b   _c_int00
        b   #0x0007fff8
        b   #0x0007fff8
        b   #0x0007fff8
        b   #0x0007fff8
        b   phantomInterrupt

    in fact, it will be 0x00080004,0x00080008, 0x0008000C and so on.

    looks like it is compiler feature.

  • That is the way the "branch to immediate" instruction works. The value specified as the "immediate" operand is treated as an offset to the program counter. Also, the program counter always points to the instruction being fetched in the CPU pipeline, which is two instructions after the one that is being executed. This is due to the CPU's instruction pipeline.

    So, when you have the instruction: b #0x0007fff8 at address 0x4, the actual branch target address will be 0xC + 0x0007fff8, that is, 0x00080004.

    Regards, Sunil

  • Sunil,

    Ok, so the confusion here is that when a label is used as the branch target, there is no need to correct for the pipeline like this.   For example the standard HalCoGen code is:

    resetEntry
            b   _c_int00
    undefEntry
            b   undefEntry
    svcEntry
            b   svcEntry
    prefetchEntry
            b   prefetchEntry
            b   _dabort
            b   phantomInterrupt


    But when you use an immediate value instead of a label, it's up to you to insert the pipeline correction factor manually....

  • Anthony,

    Actually the CPU always branches to a target address calculated using an offset from the current PC.

    In case that you specify a label as an address, this calculation is done for you by the assembler. You can see this in the encoding of the branch instruction.

    In case that you specify an immediate as an address, you need to do the calculation manually and enter the correct offset address.

    This is also why a "branch-to-here" instruction can be written as:

    B #-0x8

    Regards,

    Sunil