0x00中断简述
中断:MCU在程序正常运行时,由于MCU内核异常或MCU的各个模块发出请求事件,使正在运行的MUC转去处理执行中断服务程序。
中断源:引起MCU发生中断的事件。以KEA128为例,中断源分为内核中断,非内核中断。
内核中断:内核中断主要是异常中断,在出现错误时候会触发中断,可能会复位芯片或者做出其他操作。
非内核中断:指MCU的各个模块被中断源引起的中断,又称为可屏蔽中断,这类中断可以通过编程控制开关。MCU之前完中断服务程序后,接着处理中断前的正常执行的程序。
0x01什么是中断向量表
中断向量表:表示中断源的中断向量序号的固定顺序,用于存放中断服务程序的入口地址。该地址每个占用4B,KEA128中断向量表存放在flash中0x0000 0000——0x0000 00BF,192B。
表中给出中断向量号,IRQ中断号(非内核中断请求),IRQ寄存器号。该编号不能更改,出厂设置,每个编号代表一个非内核中断源。
0x02中断向量表的使用
在启动文件中,通过一个数组定义中断源的中断向量编号序列,在编译时,由链接文件将这个数组加载到中断向量表的位置。
#startup_SKEAZ1284.S 文件
.section .isr_vector,"a" //定义一个段.isr_vector,a表示可使用
.align 2 //4字节对齐
.globl __isr_vector //定义全局变量__isr_vector
//开始定义中断向量表
__isr_vector:
.long __StackTop //栈顶
.long Reset_Handler //芯片复位
.long NMI_handler //NMI 中断处理程序
.long HardFault_Handler //中断默认处理程序
...
.../*保留位*/
...
.long SVC_Handler //SVC 应答处理程序
.../*保留位*/
.long PendSV_Handler //PendSV 中断处理
.long SysTick_Handler //时钟
...
.../*保留位*/
...
//以下是外部中断,只展示部分例子
.long Reserved16_IRQHandler //保留
....
.long FTMRE_Handler //命令完成与读取冲突
.long UART0_IRQHandler //UART0中断
.long UART1_IRQHandler //UART1中断
.long UART2_IRQHandler //UART2中断
.long ADC_IRQHandler //ADC中断
...
...
...
.size __isr_vector, . - __isr_vector//定义该段大小
...
.align 1
.thumb_func //支持thumb指令集
.weak Default_Handler //弱定义
.type Default_Handler,%function //函数Default_Handler
Default_Handler:// 缺省中断服务例程
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
// 用弱符号方式定义缺省的中断向量表项
/* Exception Handlers */
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler SVC_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler Reserved16_IRQHandler
def_irq_handler Reserved17_IRQHandler
def_irq_handler Reserved18_IRQHandler
def_irq_handler Reserved19_IRQHandler
def_irq_handler Reserved20_IRQHandler
def_irq_handler FTMRE_IRQHandler
def_irq_handler PMC_IRQHandler
def_irq_handler IRQ_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler SPI0_IRQHandler
def_irq_handler SPI1_IRQHandler
def_irq_handler UART0_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler UART2_IRQHandler
def_irq_handler ADC_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler FTM0_IRQHandler
def_irq_handler FTM1_IRQHandler
def_irq_handler FTM2_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler ACMP1_IRQHandler
def_irq_handler PIT_CH0_IRQHandler
def_irq_handler PIT_CH1_IRQHandler
def_irq_handler KBI0_IRQHandler
def_irq_handler KBI1_IRQHandler
def_irq_handler Reserved42_IRQHandler
def_irq_handler ICS_IRQHandler
def_irq_handler WDOG_IRQHandler
def_irq_handler PWT_IRQHandler
def_irq_handler MSCAN_RX_IRQHandler
def_irq_handler MSCAN_TX_IRQHandler
def_irq_handler DefaultISR
.end
只需要了解一下几点
- 定义了中断向量表数组__isr_vector,并将其放在链接文件中的指定区域.isr_vecor。
- 为定义中断向量表的所有表项填入缺省值,以中断向量所对应外设的英文名称作为中断处理函数。例如在串口0模块的中断向量表填入UART0_IRQHandler
- 定义默认中断处理函数Default_Handler,实际上是一个永久循环。
- 以弱符号方式,将缺省的中断向量表项都定义为默认中断处理函数Default_Handler。实际使用时,只需在用户自定义的中断服务程序文件再定义一个与所需中断向量缺省函数名相同的函数,再将用户编写的具体中断服务程序名指向其即可。例如:
void UART0_IRQHandler(void);
#define isr_uart0_re UART0_IRQHandler
其中函数UART0_IRQHandler的名称与串口0缺省的中断服务程序名称相同,此时编译器默认将其设别为强符号,在编译时会覆盖掉中断向量表中原来的若符号定义的缺省值。这时再用宏定义的方式,将用户编写的串口0中断服务程序isr_uart0_re指向此函数,即可实现外部中断到用户中断服务程序的映射。
用户在实际编程中,用户实际编写使用的中断服务程序。
`
《汽车电子KEA系列微控制器》