本帖最后由 guiyan 于 2023-11-26 18:25 编辑
前言
本文旨在分析APM32F411系列芯片例程在Keil MDK环境下,如何自定义一个函数,实现中断服务函数的重映射。
一、中断服务函数相关的基本知识介绍
1.1 Flash启动
APM32F411系列的flash起始地址是0x0800 0000,确定boot引脚为flash启动。
芯片上电/复位启动的时候,会从实际地址0x0000 0000地址开始运行;
而实际情况,因为boot引脚的设定,把0x0800 0000地址映射到0x0000 0000上,所以芯片上电/复位启动时,会从0x0800 0000开始执行代码。
1.2 中断向量表
我们查看手册,可以了解到,中断向量表中的向量地址是存放中断服务函数的入口地址的。当芯片发生中断请求时,硬件会自动根据当前发生中断的中断编号,从0x0000 0000地址开始查询向量表去响应对应的中断请求;
因为boot引脚的设定,把0x0800 0000地址映射到0x0000 0000上,还需要对向量表重映射,如下图所示。当发生中断请求,芯片硬件会自动从0x0800 0000处进行查表,找到对应中断编号偏移的向量地址,读取其保存的服务函数入口地址,即可跳转至该入口地址,实现响应的函数功能。
从启动文件可以查看到中断向量表的内容(如下图所示),并从链接文件.sct中,我们可以知道中断向量表被链接存放到0x0800 0000的地址上的,而这些中断服务函数名(即入口地址)就会被对应存放到其相应的位置上,所以MCU响应中断,会找到对应的入口地址,从而跳转至其入口地址上执行函数功能。
1.3 中断服务函数实体的编写
启动文件中的各个中断服务函数名是固定的,是手册定义好的。
在启动文件中,我们可以看到各个中断服务函数都有一个弱定义,使用[WEAK]进行弱定义如下图所示。
我们需要在应用中使用该中断服务函数名,且名字必须是一样的(如下图所示),否则程序会跑到弱定义的中断服务函数中,就会在那里一直循环。
这样,就能响应中断请求,并能实现执行中断服务函数功能。
二、实现中断服务函数的重映射
整体思路如下:
2.1 修改入口地址
根据第一章的介绍,我们知道当芯片发生中断请求时,会根据中断编号,去查询中断向量表响应的位置,从而获取到中断服务函数的入口地址。那么我们可以把中断编号向量地址保存的入口地址修改成我们自定义的函数入口地址,即可实现中断服务函数的重映射,即当发生该中断请求时,会跳转至我们自定义函数的入口地址上,执行其函数功能。
因为启动文件中的向量表是下载到flash中的,而我们去修改这个向量表,就需要操作flash,擦除和编程flash较为复杂,所以我们需要把该向量表内容复制到RAM区,这样直接改RAM对应地址即可实现修改入口函数地址了,如下图所示。
注:因为RAM区的向量表占有一定空间,所以堆栈区域也需调整。
2.2 向量表重映射
还需要把向量表重映射到RAM区的向量表上,这样发生中断请求时,就会去查询RAM区的向量表了,从而达到实现中断服务函数的重映射的目的。
如下图所示:
2.3 自定义一个函数
自定义一个函数,并编写函数体。
2.1节的入口地址,就是该自定义函数的地址。如下图所示:
三、例程演示
4.1 断点调试
使能KEY2的EINT0外部中断和使能KEY1的EINT1外部中断;
在自定义中断服务函数中打断点,按下对应按键,程序会跑进其函数体中执行代码,说明成功实现中断服务函数的重映射。
以上,就是在APM32F411开发板上,实现中断服务函数重映射的方法,附件是源码工程,供大家参考。
DEMO.zip
(219.84 KB)
|