【OTA升级】Cotex-M0中断向量表重定向

全文以凌通科技电机芯片GPM32F0118B为例

前言

赶上大环境降本增效热潮,我司电机方案由Cotex-M23架构芯片GD32E230RCT6切换成Cotex-M0架构芯片GPM32F0118B,该芯片由中国台湾凌通科技制造,属于旗下电机芯片。
官网的资料没有GD的多,寄存器编程,需要频繁看datasheet,官网也只有Keil IDE相关demo,由于我司主用IAR IDE,在移植过程中也出现了一些麻烦,如启动文件缺失、不分汇编语言不兼容等问题,好在技术支持很给力,有问必答,还给我赠送了一个G+ Link-PRO仿真调试器,很是感谢。
整体调试下来,bsp层都已经正常使用了,最后是调试OTA升级部分,发现我们在Cotex-M23/M3/M4这几个系列都有SCB系统控制块结构体成员,可以通过SCB-VTOR对中断向量表重定向,Cotex-M0中也有SCB系统控制块结构体成员,其成员无VTOR,因此需要自行对其做一个中断向量表重定向。
下图为Cotex-M0与Cotex-M3中SCB系统控制块结构体成员的对比
在这里插入图片描述

启动模式

  1. User Flash Memory (用户闪存储存器启动模式)
    GPM32F0118B闪存地址为[0x0100 0000,0x0100 EFFF],程序从该0x0100 0000位置开始写入, 中断向量表位于该位置后第一个字(4byte),地址为0x0100 0004。
  2. System Memory (系统存储器启动模式)
    GPM32F0118B系统存储器地址为[0x0200 0000,0x0200 0FFF],系统存储器是芯片内的一块特定的区域,系统存储器中预置了一段bootloader,bootloder将程序下载到flash区,通过flash启动。
  3. SRAM (SRAM启动模式)
    在这里插入图片描述
    GPM32F0118B SRAM地址为[0x2000 0000,0x2000 1FFF],从内存中直接启动代码,避免因小修改反复擦写flash内存,一般用于高速调试。使用该模式特性,可以取出一部分空间用于存储app层中断向量表,由于GPM32F0118B栈顶指针+异常+中断(1+15+32)有48个字,因此需要占用48*4=192byte,因此定义不可修改内容范围为[0x2000 0000, 0x2000 00C0]。
    下图为GPM32F0118B存储器结构图
    在这里插入图片描述
    GPM32F0118B的启动模式由程序编程来选择启动模式
#define NVM_b_BOOT_SRAM      0U
#define NVM_b_BOOT_SYSTEM    2U
#define NVM_b_BOOT_PROGRAM   3U

NVM->CTRL_b.BOOT = NVM_b_BOOT_SRAM;

bin文件解析

在这里插入图片描述

  1. 红色方框为栈顶指针SP,里面的内容为该程序的RAM存储大小,可知该RAM占用最大到0x2000 0888。
  2. 绿色方框为mcu复位后PC指针指向的地址,也就是当前运行的地址,该地址为复位中断Reset_Handle。在启动文件可以看到以下汇编内容,说明复位后会先运行SystemInit(),之后才会进行__iar_program_start,这部分涉及IAR IDE内容,想要了解的自行查阅一下,这里不做过多介绍,知道运行完之后会定位到main函数运行就可以。
  3. 黑色方框为中断向量表。
    在这里插入图片描述

内存管理文件

熟悉Keil IDE的肯定是知道如何配置.sct文件的,IAR IDE中是以.icf文件表示,在app工程下的.icf文件中对SRAM配置地址范围[0x2000 00C0, 0x2000 1FFF],如下图所示,那么,在程序运行过程当中产生的SRAM数据会存储在上述范围内,保证不会影响到中断向量表的SRAM区间。
在这里插入图片描述

功能实现

将该函数在main函数开始时调用即可

#define SRAM_START_ADDR             0x20000000UL
#define VECTOR_SIZE                 ((16+32)*sizeof(uint32_t))
void m0VectorRedirect(void)
{ 
    /* Copy the vector table from the Flash (mapped at the base of the application
	load address appAddrStart) to the base address of the SRAM at 0x20000000. */  
	memcpy((uint32_t *)SRAM_START_ADDR, (uint32_t *)appAddrStart, VECTOR_SIZE);
   
	/* Boot from SRAM memory */
	nvm_unlock();
	NVM->CTRL_b.BOOT = NVM_b_BOOT_SRAM;
	nvm_lock();
}
  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值