imx rt 1020 - Custom bootloader - relocate VTOR

cancel
Showing results for 
Search instead for 
Did you mean: 

imx rt 1020 - Custom bootloader - relocate VTOR

Jump to solution
824 Views
bp1979
Contributor IV

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
787 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

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
788 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

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.
-------------------------------------------------------------------------------

821 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

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
791 Views
bp1979
Contributor IV

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
168 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
159 Views
bp1979
Contributor IV

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.