通常情况下,为了产品后续的升级,程序都会分为两部分Bootloader+App,因为有两个程序,所以需要对中断向量表进行处理,否则,当程序已经跳转到app中运行,当中断产生的时候,响应函数仍然是Bootloader的中断函数,而不是app的
在STM32F103 M3内核上是可以配置寄存器SCB->VTOR设置中断向量表偏移,CH579是M0内核,并不支持这样操作,中断向量表位置固定在(地址0x00000000)位置上

解决思路:

  1. 将中断向量表重映射到RAM(内存)
  2. 根据当前运行程序将FLASH中的向量表拷贝到RAM中

解决步骤

  1. 将地址0x00000000的中断向量表中的全部中断函数都设置为同一个函数,用于映射
  2. 编写映射函数
  3. 修改RAM配置信息
  4. 根据前当前运行的程序拷贝中断向量表到RAM

(注意:以下代码都是编写在Bootloader程序中)
第一步:设置映射
这里利用编译器设置函数属性的就可以简单实现

#define ALIAS(x) __attribute__ ((alias (#x)))void NMI_Handler(void)      ALIAS(interrupt_vector_relay);
void HardFault_Handler(void)ALIAS(interrupt_vector_relay);
void SVC_Handler(void)      ALIAS(interrupt_vector_relay);
void PendSV_Handler(void)   ALIAS(interrupt_vector_relay);
void SysTick_Handler(void)  ALIAS(interrupt_vector_relay);
void TMR0_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void GPIO_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void SLAVE_IRQHandler(void) ALIAS(interrupt_vector_relay);
void SPI0_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void BB_IRQHandler(void)    ALIAS(interrupt_vector_relay);
void LLE_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void USB_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void ETH_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void TMR1_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void TMR2_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void UART0_IRQHandler(void) ALIAS(interrupt_vector_relay);
void UART1_IRQHandler(void) ALIAS(interrupt_vector_relay);
void RTC_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void ADC_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void SPI1_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void LED_IRQHandler(void)   ALIAS(interrupt_vector_relay);
void TMR3_IRQHandler(void)  ALIAS(interrupt_vector_relay);
void UART2_IRQHandler(void) ALIAS(interrupt_vector_relay);
void UART3_IRQHandler(void) ALIAS(interrupt_vector_relay);
void WDT_IRQHandler(void)   ALIAS(interrupt_vector_relay);

这里利用**attribute ((alias ()))**,将全部的中断函数都设置为函数interrupt_vector_relay()的别名,通过这样声明函数,所有的中断函数等于interrupt_vector_relay()这个函数

步骤2:编写映射函数
我们只需要读取寄存器查看当前是发生了哪个中断,然后对应跳转到真正执行动作的函数即可
_vector_table_pointer 这个是RAM地址,这里利用RAM前面的0x100字节作为中断向量表存放位置

//中断向量表位置
#define _vector_table_pointer  0x20000000
__asm void interrupt_vector_relay(void) {//IPSR是中断状态寄存器,因为每个中断函数地址是4个字节,因此将读取数值*4(左移两位)得到的就是地址偏移mrs     r0, ipsr;//将值左移2位lsls    r0, r0, #0x02;//从存储器地址取数据到R1ldr        r1, =_vector_table_pointer;//计算出偏移adds r1, r1, r0;//将该地址的值给r1ldr       r1, [r1];  //跳转到相对应的中断bx        r1;nop
}

步骤三:修改RAM信息
因为使用了RAM的一部分存放中断向量表,所以要配置RAM的起始地址,否则这部分会被程序占用使用,导致错误,修改只需要将起始位置向前+0x100即可,当然size也要相应的减去0x100
注意:这个在Bootloader和App中都要修改

步骤四:拷贝向量表到内存
在跳转到APP前,将APP的中断向量表拷贝到RAM里面即可

//APP的地址,根据实际修改
#define APP_BASE       0x00004000
//拷贝中断向量表
memcpy((void *)(_vector_table_pointer),(void *)(APP_BASE),0x100);

.

补充:app的中断函数编写和使用与正常情况下一致,无需特殊处理
但如果在Bootloader需要用到中断,比如使用定时器中断

 UINT32 TIM_IRQ_ADDR;TIM_IRQ_ADDR = (UINT32)DFU_TMR0_IRQHandler;memcpy((void *)(_vector_table_pointer + 0x40),&TIM_IRQ_ADDR,4);

Bootloader不能直接编写TMR0_IRQHandler() 因为这个名字已经被占用了, 需要自定义一个函数比如DFU_TMR0_IRQHandler(),然后将该函数的地址拷贝到RAM中的特定位置,这里的0x40就是对应定时器的中断函数

CH579(M0内核)中断向量表偏移处理相关推荐

  1. 32 位 ARM® Cortex®-M0+内核 单片机

    PY32F003 系列微控制器采用高性能的 32 位 ARM® Cortex®-M0+内核,宽电压工作范围的 MCU.嵌入高达 32Kbytes flash 和 4Kbytes SRAM 存储器,最高 ...

  2. 32位ARM®Cortex®-M0+内核单片机 XL32F003系列MCU

    XL32F003系列微控制器采用高性能的32位ARM®Cortex®-M0+内核,宽电压工作范围的MCU.嵌入高达64 Kbytes flash和8 Kbytes SRAM存储器,最高工作频率32 M ...

  3. 在华大半导体的M0+内核HC32L136上移植freertos

    创建一个基础工程(为了方便,可以直接选择官方SDK的Demo里例子) 把freertos源码里的Source文件拷贝过来 工程新建分组freertos,添加如下文件: 3.1Source目录下的所有. ...

  4. PY32F002A开发板,32位 M0内核,最高20KB的flash,3KB的SRAM

    PY32F002A开发板为PY32F002A芯片提供了一个简易的硬件开发环境.开发板使用 type c 接口作为供电源.提供包括扩展引脚在内的以及 SWD.Reset.Boot.User button ...

  5. 国产高性能32位M0内核MCU单片机DP32G003

    DP32G003TS20内嵌ARM Cortex M0 内核,最高工作频率可达48MHz,内置高速存储器,丰富的增强型IO端口和外设连接到总线.本产品包括16路IO.1个(9 通道)12位的ADC.2 ...

  6. CW32超低功耗家族再添新成员:32位M0+内核MCU CW32L052系列产品

    2023年2月,武汉芯源半导体超低功耗家族再添新成员--32位M0+内核MCU CW32L052系列芯片. CW32L052 是基于 eFlash 的单芯片低功耗微控制器,集成了主频高达 48MHz ...

  7. linux内核中断向量表,中断向量表

    5.4.3  中断向量表 上节已指出CPU是根据中断号获取中断向量值,即对应中断服务程序的入口地址值.因此为了让CPU由中断号查找到对应的中断向量,就需要在内存中建立一张查询表,即中断向量表(在32位 ...

  8. STM32F0芯片IAP实现之中断向量表重映射(没有中断向量表偏移寄存器SCB->VTOR的应对方法)

    问题背景 项目使用STM32F030,需要通过IAP进行固件升级,在FLASH里面要烧录两份代码:一个Boot loader,一个用户应用程序APP.在开发应用程序APP时,外设中断不能正确响应进到对 ...

  9. CH579 Cortex-M0 内核低功耗蓝牙 MCU 集成 ARM 内核 32 位微控制器

    概述 CH579 是集成 BLE 无线通讯的 ARM 内核 32 位微控制器.片上集成低功耗蓝牙 BLE 通讯模块.以太网控制器及收发器.全速 USB 主机和设备控制器及收发器.段式 LCD 驱动模块 ...

最新文章

  1. 清华大学:2021元宇宙发展研究报告
  2. 使用yum更新时不升级Linux内核的方法
  3. eShopOnContainers 知多少[4]:Catalog microservice
  4. Machine Learning(CF-940F)
  5. php试题库,PHP试题库一
  6. VSCode自定义代码片段13——Vue的状态大管家
  7. 下岗工人到达退休年龄,养老保险未缴纳满15年,补缴合适吗?
  8. Java loadlibrary分析及如何unload
  9. eclipse+testng+maven错误及解决办法记录
  10. STM32——库函数版——超声波测距模块
  11. VMware vSAN入门必会知识点
  12. cad中lisp文件给恶作剧_AutoCAD小秘密062:紧急插播,关于LISP的病毒防治
  13. 普通用户sudo echo权限依旧写入不了文件
  14. NLP︱词向量经验总结(功能作用、高维可视化、R语言实现、大规模语料、延伸拓展)
  15. android hidl简单实例1
  16. C语言学习:除去剪切板内容的换行与回车
  17. 你好,你是谁,可不可以向我出示源代码让我确认身份
  18. 2D动画设计制作软件—“Reallusion Cartoon Animator”
  19. C语言自动分配宿舍问题
  20. 当局讳莫如深 青龙县避震成功经验获联合国嘉奖

热门文章

  1. 高斯消去法的python实现
  2. 瓷砖铺贴方法_5种常见的瓷砖铺贴以及施工方法介绍
  3. 服务器操作系统linux,关于服务器的操作系统
  4. jmeter学习指南之察看结果树,你知道都有哪些功能吗
  5. 推荐场景下融合多模态信息的内容召回模型
  6. CDH6中的各种目录
  7. 0到9的数字替换成零 到 玖 的 大写汉字的函数
  8. gurobi学习笔记(一)
  9. Silverlight的开发工具
  10. 六-体系结构 Architecture