Update FW in QSPI flash from secondary bootloader in internal flash

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Update FW in QSPI flash from secondary bootloader in internal flash

1,433 次查看
klaas_hoekstra
Contributor I

Hello,

For a project I am writing a bootloader on an EA LPC4088 Display Module.
The firmware is running from QSPI flash and uses the external SDRAM.

I've written a bootloader in internal flash that uses the spifi rom api to update the firmware on the QSPI flash.

I first read the binary file of my firmware and then program it to QSPI flash per 4096 bytes.

Here is the code I use to program the QSPI flash:

SpifiError_t spifi_program(uint32_t address, uint8_t *data, uint16_t lenght)
{
   if (!_initialized) {
      return SpifiError_Uninitialized;
   }

   int rc;
   SPIFIopers opers;

   opers.dest = (char *) address;
   opers.length = lenght;
   opers.scratch = NULL; // unprogrammed data is not saved/restored
   opers.protect = -1; // save & restore protection
   opers.options = S_VERIFY_PROG;

   rc = _spifi->spifi_program (&_romData, (char *)data, &opers);
   if (rc) {
      return spifi_translateError(rc);
   }
   return SpifiError_Ok;
}

This all works as expected, and the binary file is copied to the QSPI flash.
However, when I try to jump to the QSPI flash, a hard fault is detected.
When I program the firmware to QSPI with the GUI flash tool in MCUXpresso and then start my bootloader, the jump to the QSPI works as expected.

This is the code to jump to the QSPI flash:

void Execute_Application(unsigned address)
{
   pFunction appEntry;
   uint32_t appStack;

   appStack = (uint32_t) *((__IO uint32_t*) address);

   appEntry = (pFunction) *(__IO uint32_t*) (address + 4);

   __disable_irq(); // Disable interrupts before changing interrupt vectors

   SCB->VTOR = address;

   __set_MSP(appStack);

   __enable_irq();

   appEntry();
}

Can somebody tell me what I am missing and why the firmware will not execute when I program the QSPI flash though the bootloader?
Thank you in advance!

标签 (2)
0 项奖励
回复
2 回复数

1,207 次查看
Alexis_A
NXP TechSupport
NXP TechSupport

Hi klaas.hoekstra@sparkholland.com‌,

This is the function used in the AN12384 - Application note: LPC5460x UART Secondary Bootloader using YModem to jump to the image: 

/*
* The vector table is in the front of the image, and the following is for the normal code.
* The new image is just like the normal image file but with a indicated base address offset. 
*/
void FwBoot_BootToFwImage(uint32_t fwImageBaseAddr)
{
    void (*firmwareFunc)(void);
    uint32_t fwStackVal = *((uint32_t *)(fwImageBaseAddr));     /* the first word is for the stack pointer. */
    uint32_t fwEntryVal = *((uint32_t *)(fwImageBaseAddr+4U));  /* the second works is for the boot function. */
    firmwareFunc = (void (*)(void))fwEntryVal;

    SCB->VTOR = fwImageBaseAddr; /* The stack address is also the start address of vector. */
    __set_MSP(fwStackVal);
    __set_PSP(fwStackVal);
    firmwareFunc();
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

So comparing with the function you're using is pretty similar, but I have a doubt about it, how are you debugging your application?

If after the binary update your debugging your application, the IDE will not know where you need to jump in your debug session, that's why when you only flash your MCU and the application without this the program succesfuly starts.

Maybe this post can help you to set correctly the debug session:

https://community.nxp.com/thread/454190

Please let me know if this helps you.

Best Regards,

Alexi Andalon

0 项奖励
回复

1,206 次查看
klaas_hoekstra
Contributor I

Alexis,

Thank you for your reply, and excuse me for the late answer.

First of all, I should say I already fixed the issue.
There was a bug in the reading of the binary file, so wrong data was programmed to the QSPI flash.

With that fixed, my above code works to program the QSPI flash and to jump from the bootloader to the external flash.


Looking to the code from AN12384, the only difference I see is:

__set_PSP(fwStackVal);

Could you tell me what this line does?

Debugging is hard for this project, since the code is executed from external QSPI flash (XIP).
We use the onboard DAP link over USB for debugging, but I have not managed to set breakpoints in QSPI flash.

0 项奖励
回复