imx rt 1020 - Custom bootloader - relocate VTOR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx rt 1020 - Custom bootloader - relocate VTOR

Jump to solution
1,558 Views
bp1979
Senior Contributor I

Hi,

In our current application we have the following approach for our OTA (over the air) application.

In flash we store

- our bootloader in the first sector (64k)

- our rescue app in the next two sectors (128K)

- our real app in the fourth sector (128K)

In the bootloader, depending on some configuration (also written in flash, in the last sector), we jump to either the rescue app, or the real app.

In STM, I wrote the following function:

    void JumpToApp() const
    {
        typedef void (*functionPointer)();

        auto mspAddress = *(reinterpret_cast<volatile uint32_t*>(_appStartAddress));
        auto resetHandlerAddress = *(reinterpret_cast<volatile uint32_t*>(_appStartAddress + 4));

        auto resetHandler = reinterpret_cast<functionPointer>(resetHandlerAddress);
        __set_MSP(mspAddress);

        SCB->VTOR = _appStartAddress;

        resetHandler();
    }

I understand you don't have an interest in STM, but I hope you can relate to what happens in this bit of code. I have the address of where my app is stored (either rescue or regular app) and I also know where the reset vector is stored. This way I can relocate the vector table to the correct address, and jump to the reset handler of my app.

Since for my NXP board, I also have to deal with XIP (some bytes are written to at the beginning of flash memory), and my actual program starts at an offset off 0x2000, I think things get a bit more complicated.

What is the easiest approach (preferably in the same analogy of our current implementation).

Many thanks in advance!

 

0 Kudos
1 Solution
1,521 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
1)Is that about right?
-- Yes, your understanding is correct.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

5 Replies
1,522 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
1)Is that about right?
-- Yes, your understanding is correct.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

1,555 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Firstly, I think the JumpToApp() function is good, next, I'd highly recommend you to refer to the application note to learn how to implement a second boot loader on i.MX RT1050, i.MX RT1020, and i.MX RT1060 part based on XIP flash and its downloading link is below.

https://www.nxp.com/docs/en/application-note-software/AN12604SW.zip
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,525 Views
bp1979
Senior Contributor I

Hi @jeremyzhou 

Sorry for the late reply and thx for the information. I have read the AN and found some additional ones that clarified a few things for me too.

Just to double check if I am understanding things correctly:

I can write my "2nd bootloader" as a regular app. When I want to run it from external flash, I should keep the XIP stuff enabled, and simply upload my 2nd bootloader from MCUXpresso.

My actual application should then :

- remove XIP, since XIP is already taken care of by the bootloader program.

- change the linker settings so that it gets compiled to a different section in external flash (e.g. 0x60010000)

On POR the following should happen for typical operation:

- make my 2nd bootloader relocate VTOR table to 0x60010000

- make my 2nd bootloader jump to 0x60010004

- the startup code of my "actual app" should be executed as a result of the jump, and my application can start normal operation.

Is that about right?

Many thanks in advance 

 

0 Kudos
902 Views
ergingursoy
Contributor I

Hi @bp1979 

I have been triying to do same thing but could not handle it. Were you able to write custom bootloader that jumps to actual application? If so could you share the bootloader project?

Regards

0 Kudos
893 Views
bp1979
Senior Contributor I

Hi @ergingursoy 

I have a lot more going on in my bootloader which will only distract and besides that I am not at liberty to share the whole project.

But it's really dead simple in the end. All you need to do is point to the place where you vector table is located in flash, and jump to that address.

 

            typedef void (*functionPointer)();
            // Lets assume your vtor is written in flash at 0x60020000
            auto vtor = reinterpret_cast<unsigned int*>(0x60020000);
            // the ARM vtor table is an array of uint32_t
            // [0] = main stack pointer address
            // [1] = reset handler address
            // [2] .. [158] = other interrupt handlers we don't care about

            // We need to address in flash to the reset handler
            auto reset_handler_address = sram_vector_table[1];
            // Cast that address to a void function pointer
            auto reset_handler = reinterpret_cast<functionPointer>(reset_handler_address);

            // And simply call the function to make the jump
            reset_handler();

That's pretty much all you need to do.

You can set the main stack pointer before you jump, or let the reset handler of the actual app deal with it. The reset handler is a naked function, so it can't do anything on the stack anyway. And if you jump to an application which is based on any C/C++ project created with mcuxpresso, then it will deal with setting the stack for you.