AnsweredAssumed Answered

RT1020 resets original boot_data when returning from plugin function?

Question asked by rshipman on Nov 8, 2019
Latest reply on Nov 13, 2019 by Kerry Zhou

IDE: MCUXpresso IDE v11.0.1 [Build 2563] [2019-09-01]

Platform: MIMXRT1020-evk eval board

Example project: demos/iled_blinky

 

I am experimenting with the boot plugin functionality of the RT1021 using the iled_blinky demo.

 

As a very quick first step, I created a simple plugin function that simply calls ResetISR (which then calls main() - which I modified to flash the led a couple of times and return 0).

 

Both the plugin and application images are identical apart the following changes:

 

The image as loaded into flash by MCUXpresso:

   IVT entry field points to my plugin function

   boot_data plugin field is set to 1 (plugin mode)

 

The image just before the plugin function returns:

   IVT entry field points to ResetISR

   boot_data plugin field is set to 0 (plugin mode off)

 

Both images run, but between the return from the plugin function and the (second) call to ResetISR the boot_data fields have been overwritten with the original values. So the boot_data plugin field is set to 1 again.

I have confirmed this using the MCUXpresso debugger.

I cannot see how this is possible as there is only one image in flash and none of the code is run between the end of the plugin function and the start of ResetISR as far as I am aware (seeing as one is an image exit point and the other is an image entry point).

Also when returning from execution of the second image it crashes with a hard fault. The entry field is now set to call ResetISR but the plugin field has been set to 1, so presumably all the arguments and return values the ARM bootloader is expecting from a plugin function are missing/garbage.

 

Note that my plugin function simply calls ResetISR, sets the above fields and then sets up the function arguments before returning.

 

The source mods follow (- they're not beautiful mods, just a quick experiment to get something working).

You may need to add a couple forward declarations etc:

 

In source/iled_blinky.c:

 

Near the top:

 

#include "fsl_flexspi_nor_boot.h"

 

In the main function, change main while (1) loop to:

/* Flash led n times */
int n = 2;

int i = n*2;

while (i--)

{

  :

  :

}

return 0;

 

After main() function:

 

extern void ResetISR(void);

int PluginFunction(void **start, uint32_t *bytes, uint32_t *ivt_offset)

{

  ResetISR();

 

  *start = (void*)boot_data.start;

  *bytes = boot_data.size;

  *ivt_offset = 0x1000;

 

  // Reuse the same image, just not this plugin function.

  // Bodge away const etc.

  *((uint32_t*)&(image_vector_table.entry)) = IMAGE_ENTRY_ADDRESS;

  *((uint32_t*)&(boot_data.plugin)) = 0; // This gets set back to 1. The MCUXpresso confirms this is set to 0 here. And set back to 1 by the start of the next call to ResetISR

 

  // The following I added as experiments, the problem exists without these three lines.

  *((uint32_t*)&(boot_data.size)) -= 4; // Experiment - this gets overwritten.

  *((uint32_t*)&(image_vector_table.dcd)) = 0x60001234; // Experiment - this does not get overwritten.

  *((uint32_t*)&(boot_data.start)) = 0x60005678; // Experiment - this gets overwritten.

 

  return 1; // 1 is success

}

 

In fsl_flexspi_nor_boot.c:

 

const ivt image_vector_table = {

  IVT_HEADER, /* IVT Header */

  ((uint32_t)PluginFunction), // IMAGE_ENTRY_ADDRESS

  :

  :

 

In fsl_flexspi_nor_boot.h:

 

#define PLUGIN_FLAG (uint32_t)1

 

In startup_mimxrt1021.c, comment out while(1) {;} loop at end of ResetISR function.

 

I will eventually have two separate images, so I think it is important to understand what is going on here.

 

Any help appreciated.

Outcomes