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 Bootloader

Other Parts Discussed in Thread: TM4C129XNCZAD

I'm trying to convert the enet_s2e to be my bootloader.  I'm doing this because I would like to use telnet for the bootloader instead of using the bootp from the bootloader example.  I've modified the enet_s2e example to remove all the serial code since I'm actually not converting serial to Ethernet so basically I have a telnet server application.  Within the application I have a command interpreter so when a command is received from the telnet connection, I would jump to the application portion.  To test this, I program the DK-TM4C129x with application code starting at 0x10000 and I program the modified enet_s2e at 0x0.  I'm then able to open a telnet session and send the command to jump to the application.  In my testing, if my application has no interrupts such as the hello example, then this works just fine, it jumps to the application and displays hello on the display.  However, if the application contains interrupt such as the freertos_demo, then this doesn't work.  It looks like the issue is with the interrupts.  So my question is there something that needs to be done with the vector table?  I do set the NVIC_VTABLE to the application starting address before the jump.  So that's not the issue, my guess is that it's when an interrupt occurs, the application faults so I'm trying to figure out what else I need to do with the interrupts?  Is there something that needs to be done with regards to the interrupt handler besides setting the NVIC_VTABLE such as copying the actual vector table of the application to overwrite the bootloader vector table?

Any insight is greatly appreciated.

Thanks.

  • On the application side:

    • Did you build the application to run from location 0x10000? This can be done by updating the linker script. Please refer to "boot_demo1" and "boot_demo2" examples to see how this is done.

    On the bootloader side, before jumping to the application,

    • Is the address of application's interrupt vector table (in your case it could be 0x10000, if you used the default linker script) copied to NVIC_VTABLE? How are you ensuring that the correct address is copied?
    • Is the stack pointer being loaded from the application's vector table?
    • Is the program value being loaded from the application's vector table?

    On the bootloader side, all the above mentioned steps should be followed in that order. The flash-based bootloader in TivaWare could be a good resource to refer. Some of the main difference, from your set-up, is that the flash-based bootloader runs from SRAM and it also copies the application's vector table to SRAM.

    Thanks,

    Sai

  • Hi Sai,

    I did build the application to run from location 0x10000.

    As for the boot loader, here's the code that I used to perform the jump:

    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;

    HWREG(NVIC_VTABLE) = APPLICATION_START_ADDRESS;

    __asm(" movd r0, #65536 \n"
    " ldr r1, [r0] \n"
    " mov sp, r1\n");
    __asm(" ldr r1, [r0, #4]\n"
    " bx r1\n");

    Do you know if it's even possible to do what I'm trying to do and that's to have an RTOS boot loader that runs from flash and the application to run from flash?  Perhaps, my issue is where the vector table is defined.  Can you provide some additional information on the vector table or where I can read about it? One final question is that I do see the linker file being different for the boot_emac_flash than the linker file that I have for my bootloader, is it possible to use the boot_emac_flash linker file for my bootloader to see if that would resolve the problem?

    Thanks.

  • Are you using the following statement in you code?

    HWREG(NVIC_DIS4) = 0xffffffff;

    I looked in the datasheet for TM4C129NCPDT and "NVIC_DIS4" is not available. Which device are you using? Please confirm if this register is available on your device. Using an unavailable register could cause a fault.

    You code looks alright. Can you place a breakpoint and make sure that correct values are copied to NVIC_VTABLE and SP?

    For the location of vector table refer the startup code and linker script of the projects.

    I think you should be able to do what you are doing. But managing two different interrupt vector tables is a little tricky. You have to make sure that the interrupts are disabled when jumping from bootloader to application code and vice versa.

    Alternatively, you can also try to have the interrupt vector tables of both the bootloader and application in the same location, that is in SRAM. The flash-based bootlaoder does this using assembly code. You can use that code as reference.

    Thanks,
    Sai
  • Hi Sai,

    I was using that statement. I've removed it now but it didn't make a difference. I am using the DK-TM4C129x with the TM4C129XNCZAD part.

    I did put a breakpoint when I was performing the jump and verified that the NVIC_TABLE and SP were the correct values. When the jump occurred to the application and I pause the execution, I see that there are faults, NVIC_FAULT_STAT_BFARV and NVIC_FAULT_STAT_PRECISE. I'm not sure what these faults indicate, any help with this is greatly appreciated.

    I'm using the default startup code and linker script of the example projects that I started with, except for changing the application starting address. So wouldn't changing the starting address of the application code cause the vector table to be in two separate area. I'm thinking that when an interrupt occurred, it didn't know how to handle it, like it couldn't find the handle. But I don't know how to verify that this is the case.

    Thanks.
  • SL said:
    I'm using the default startup code and linker script of the example projects that I started with, except for changing the application starting address.

    Please use the linker scripts and startup code of "boot_demo1" as the base for the application to ensure nothing else is missed

    SL said:
    So wouldn't changing the starting address of the application code cause the vector table to be in two separate area. I'm thinking that when an interrupt occurred, it didn't know how to handle it, like it couldn't find the handle.

    Yes. That's the reason before jumping to the application code, the interrupts have to be disabled and the address of the new vector table written into "NVIC_TABLE" register.

    As mentioned before, both the bootloader and application codes interrupt vector table can be copied into SRAM to overcome any issues of handling two Vector Tables. The flash-based bootloader handles the vector tables this way.

    For diagnosing faults, please refer ISSUE#7: Code goes to FaultISR in the forum sticky: e2e.ti.com/.../374640

    Thanks,

    Sai

  • Hi Sai,

    Thanks for helping me through this.  I've found what I was doing wrong.  It looks like I can't jump from within the bootloader.  I need to put the jump in the ResetISR like the bootloader example does.  And from the application, I need to generate a reset.  With the jump in the ResetISR, it looks like things are working as expected, for now.

    Thanks again.

  • Glad it's working!

    Sai