在MCU内部闪存中从一种固件跳到另一种固件

在MCU内部闪存中从一种固件跳到另一种固件

本文介绍了在MCU内部闪存中从一种固件跳到另一种固件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在从事针对STM32F030C8的引导加载程序固件应用程序.我在分散文件中指定了引导加载程序应用程序将占用主内存位置0x08000000至0x08002FFF(扇区0至扇区2).我还写了一个主要的固件应用程序,存储在0x08003000到0x0800C800之间.将两个固件都下载到MCU内部闪存后,我使用以下代码从引导加载程序启动了主应用程序:

I am currently working on a bootloader firmware application targeted to STM32F030C8. I specified in my scatter file that the bootloader app will occupy main memory location 0x08000000 to 0x08002FFF (sector 0 to sector 2). I also wrote a main firmware application that is stored from 0x08003000 to 0x0800C800. After downloading both firmware to the MCU internal FLASH, I lauched the main app from the bootloader using the code below:

/************************************************************//**
* \brief Start the main application if available and correct
*****************************************************************/
void INTFLASH_execute_main_app(const char mode)
{
  MyFunc_ptr AppEntry;
  uint32_t temp[1];
  IRQn_Type index;

  memcpy(temp, (void*)&NVIC->ISER, sizeof(NVIC->ISER));  //Save enabled interrupts

  for( index = (IRQn_Type)0; index<= (IRQn_Type)28; index++) //Disable all interrupts
    NVIC_DisableIRQ(index);

  AppEntry = (MyFunc_ptr) INTFLASH_calculate_page_addr(IAP_APP_START_PAGE);

  if( mode || intflash_check_main_app() )
  {
    Main_App_ptr = (uint8_t*)AppEntry;
    if( (*Main_App_ptr != 0xFF) &&  (Main_App_ptr) )
    {
      AppEntry();
    }
  }
  memcpy( (void*)&NVIC->ISER, temp, sizeof(NVIC->ISER) ); //Restore interrupts
}

由于某种原因,当它执行AppEntry()时,它会跳转到以下代码,并且不会在0x08003000位置执行主应用程序:

For some reason, when it executes AppEntry(), it jumps to the code below and does not execute the main app at location 0x08003000:

HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler              [WEAK]
                B       .
                ENDP

我以前在ARM7 MCU上使用过这种逻辑,并且运行良好,我无法弄清楚为什么它不能在基于Cortex M0的MCU上运行.任何帮助将不胜感激.

I have used this sort of logic before on ARM7 MCU and it works fine, I cannot quite figure out why it doesnt work on this cortex M0 based MCU. Any help would be greatly appreciated.

请参阅下面的有关引导加载程序和主应用程序的分散文件:

See Scatter files for bootloader and main app below:

LR_IROM1 0x08000000 0x00003000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00003000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00002000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

LR_IROM1 0x08003000 0x0000C800  {    ; load region size_region
  ER_IROM1 0x08003000 0x0000C800  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00002000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

推荐答案

您必须跳转到应用程序地址+ 4",因为应用程序的基地址保存了初始堆栈指针的位置.因此,跳转到该地址意味着跳转到堆栈基址.在应用程序地址+ 4下(由于32位体系结构,因此为+ 4B)是复位处理程序的地址.

You have to jump to "the application address + 4" because the base address of the application holds the initial stack pointer position. So jumping to this address means jumping to the address of stack base.Under the app address + 4 (+4B because of 32-bit architecture) there's the address of reset handler procedure.

这篇关于在MCU内部闪存中从一种固件跳到另一种固件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 05:25