1、理论基础:
Stm32f030R8 有64KFlash + 8KSram
Stm32f0系列MCU中断矢量表的定位跟STM32其它系列相比有点差异,即M0系列没有像其它M3/M4/M0+系列所具备的中断矢量表重定位寄存器,其中断矢量表不能借助矢量重定位寄存器简单修改实现。所以Stm32f0 IAP的过程会跟其它系列的STM32芯片的IAP动作有所不同。
我们知道,做IAP往往需要两部分代码,一部分是用来升级的IAP程序,一部分用来运行用户实际应用功能的应用程序APP代码。
IAP程序及自身的中断向量表放在内部FLASH的低端地址区。对于STM32 MCU而言,就是从0X0800 0000处开始放IAP代码。APP程序代码及自身中断矢量表存放在离0X0800 0000某个地址偏移量【offset】的地方,即从0x0800 0000+offset的地址开始存放APP代码及中断矢量。显然那个【offset】要大于IAP的程序空间。假设这里OFFSET为0x4000,即APP程序的起始地址为0x08004000。为了APP程序能正常相应中断,这里需要做2个步骤:
1、将APP的中断向量表拷贝到SRAM里面去。M0的中断向量表由48个有序字(32bit)组成,把它们从flash区0x08004000开始的中断向量表拷贝到0x2000 0000的SRAM区。
2、做存储地址的映射,即把SRAM映射到代码执行区的地址0X00处。
[c++] view plain copy
#define FLASH_BOOTLOADER_SIZE (uint32_t)(0x4000)
#define APPLICATION_ADDRESS (uint32_t)(0x08000000+FLASH_BOOTLOADER_SIZE)
#if (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined ( __GNUC__ )
__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#elif defined ( __TASKING__ )
__IO uint32_t VectorTable[48] __at(0x20000000);
#endif
//做中断向量表的拷贝
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Remap SRAM at 0x00000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
经过上述操作步骤后,当APP里发生中断时,内核就从地址0x00处的向量表取相应中断的入口地址,即相当于从0x2000 0000处的向量表取中断入口地址,当然也相当于从0x08003000处的向量表取中断入口地址,然后去执行相应中断程序。
关于STM32F0的IAP,ST官方有套参考代码,即STM32F0xx_AN4065_FW_V1.0.0例程。
上一篇:STM32F030 Nucleo-多样的SPI通信之Master标准模式-SPIFlash读写
下一篇:keil环境下IAP使用中 stm32中M0 M3中断偏移对比
推荐阅读最新更新时间:2024-03-16 16:08