【Cortex-M0 中断向量表偏移这样实现】

前言

因为公司项目中用到了一个Coretex-M0架构的MCU,需要让我实现bootloader功能,当实现中断向量表偏移时发现这个架构的MCU竟然不支持寄存器设置中断偏移,于是在网上查询之后发现了解决方案,在这里也记录下我的实现。
在这里插入图片描述

一、中断向量表重定向

	将app的中断向量表拷贝至ram中,在bootloader的中断处理函数判别调用者的身份,选择不同的中断处理函数。

1.1、bootloader 处理

		在bootloader中需要重新实现中断处理函数函数	。首先将app的中断向量表拷贝到ram 0x2000 0000 处,定义中断处理函数重映射结构体,然后定义结构体指针指向0x2000 0000地址,最后中断处理函数进行重定义。

定义中断处理函数结构体:

typedef struct
{
    void (*pInitial_SP);        /*   Top of Stack   */
    void (*pReset_Handler)(void);
    void (*pNMI_Handler)(void);
    void (*pHardFault_Handler)(void);
    void (*pMemManage_Handler)(void);
    void (*pBusFault_Handler)(void);
    void (*pUsageFault_Handler)(void);
    void (*pReserved0_Handler)(void);
    void (*pReserved1_Handler)(void);
    void (*pReserved2_Handler)(void);
    void (*pReserved3_Handler)(void);
    void (*pSVCall_Handler)(void);
	......
	......
    void (*pDebugMon_Handler)(void);
    void (*pReserved4_Handler)(void);
    void (*pUART3_4_IRQHandler)(void);
	void (*pFLEXCAN_IRQHandler)(void);
	void (*pUSB_IRQHandler)(void);
}NVIC_TABLE_t;

定义结构体指针指向0x2000 0000:

  //拷贝中断向量表(注意:这里需要按照自己真实的中断向量表大小进行处理)
  for(i = 0; i < 48; i++)
  {
    *((uint32_t*)(0x20000000 + (i<<2))) = *(__IO uint32_t*)(YTD_APP1_BASE_ADDR + (i<<2));
  }
NVIC_TABLE_t* tNVIC_Table = 0x20000000;

中断函数重定义实例:

void UART2_IRQHandler(void){
	
	//如果此时是bootloader
	u16 update_flag = 0x0;
	flash_read(UPGRADE_FLAGE_ADDR, (uint8_t *)&update_flag, 2);  //这里的标识为当跳转app动作发生时写入的表示,读到0xa1b1值即能确认调用者的身份为app,
	if(update_flag == 0xa1b1)
		tNVIC_Table->pUART2_IRQHandler();     //调用映射的中断处理函数
	else
		Boot_UART2_IRQHandler();                     //bootloader 自己的处理函数
}

1.2、app处理

app程序处理相对简单,只需要重新执行一遍中断向量表拷贝动作即可。因为跳转app时首先进入的是Reset_Handler中断处理函数,对堆栈应该是进行了重新分配,因此需要重新拷贝一次,否则发生中断时将无法找到中断处理函数。
//拷贝中断向量表
	  for(i = 0; i < 48; i++)
  {
    *((uint32_t*)(0x20000000 + (i<<2))) = *(__IO uint32_t*)(YTD_APP1_BASE_ADDR + (i<<2));
  }
	

1.3、MDK配置RAM

在程序运行时会使用ram资源,为了防止中断向量表所在位置被占用,需要在keil中配置应用程序(这里包含bootloader和app)的ram使用范围。我这里因为是48个中断:48 * 4 = 192 = 0xc0, 所以设置ram范围为 0x2000000c0 ~
0x20003ffff

在这里插入图片描述

本文参考文章:

http://www.weilez.cn/?p=1310
https://mp.weixin.qq.com/s/D-zA7Fb3bHEZM8WsSHHBaQ
https://ask.csdn.net/questions/7918618

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值