本文章分析了ARM架构下SylixOS内核中断流程,共包含三部分:数组
分析SylixOS运用数组和双向链表实现中断服务函数的注册架构
阐述ARM硬件中断机制ide
分析SylixOS中断处理流程函数
SylixOS中断注册是经过数组和双向链表实现的。spa
_K_idescTable [256]是SylixOS内核中的系统中断向量结构索引数组,用于索引注册的中断服务函数,其类型如清单 21所示指针
清单 21索引
typedef struct { LW_LIST_LINE_HEADER IDESC_plineAction; /* 判断中断服务函数列表 */ ULONG IDESC_ulFlag; /* 中断向量选项 */ LW_SPINLOCK_DEFINE (IDESC_slLock); /* 自旋锁 */ } LW_CLASS_INTDESC
每进行一次中断注册,内核建立一个中断向量结构。若是有多个中断源共享一个中断号,内核将这些中断源的各个中断向量结构连接成双向链表。中断向量结构类型如清单 22所示:事务
清单 22内存
typedef struct { LW_LIST_LINE IACT_plineManage; /* 管理链表 */ INT64 IACT_iIntCnt[LW_CFG_MAX_PROCESSORS]; /* 中断计数器 */ PINT_SVR_ROUTINE IACT_pfuncIsr; /* 中断服务函数 */ VOIDFUNCPTR IACT_pfuncClear; /* 中断清理函数 */ PVOID IACT_pvArg; /* 中断服务函数参数 */ CHAR IACT_cInterName[LW_CFG_OBJECT_NAME_SIZE]; } LW_CLASS_INTACT
构建一个中断向量结构io
在此中断向量结构中记录中断服务函数地址和中断服务函数名等信息
将此中断向量结构插入到此中断号的中断向量结构链表
以中断向量号为下标索引_K_idescTable数组,将其中的头指针指向上一步构建的双向链表
如图 21所示,中断注册实质是构建中断向量结构双向链表。
图 21中断注册
当中断发生后,ARM内核自动完成以下事务:
保存执行状态:保存CPSR到中断模式的SPSR中
模式切换:处理器进入中断模式,并关闭中断,防止中断嵌套
保存返回地址:保存PC-4到中断模式的LR中
跳入中断向量表:强制设置PC为中断向量地址,跳转到中断处理程序中
当前程序的执行状态是保存在CPSR中的,中断发生时,要保存当前CPSR中的执行状态到中断模式的SPSR中,未来中断返回时,恢复到CPSR,恢复执行状态。
硬件自动将中断异常码写入CPSR中的模式位,CPU进入中断模式。同时硬件自动切换处理器到ARM状态下执行指令,而且CPU经过设置CPSR相应位来关闭中断。
当前程序被中断打断,切换到中断处理程序里,中断处理完后,返回当前被打断模式继续执行,所以必需要保存当前指令的下一条指令的地址到中断模式下的LR中。因为ARM异常模式不一样以及ARM内核采用流水线技术,中断处理程序须要从新计算正确的返回地址。
该操做是CPU硬件自动完成的,当异常发生时,CPU强制将PC的值改成一个固定内存地址,并跳到此地址处执行。
SylixOS中断处理程序完成以下事务:
修正返回地址,LR=LR-4
保存现场寄存器
中断处理阶段1
恢复现场寄存器
返回现场,PC=LR,回到返回地址处继续执行
中断处理阶段1完成了3件事务:
得到中断源的中断向量号
中断处理阶段2
中断结束处理
得到中断向量号通常都是经过读取中断控制器的某个寄存器来得到;中断处理结束后须要通知中断控制器中断处理已经完成,通常都是向某个寄存器写入任意值便可。
此阶段是真正的进行中断处理,完成如下事务:
以中断向量号做为索引,经过_K_idescTable数组找到此中断向量号的中断结构链表
依次遍历以前注册的中断服务函数,并根据返回值判断是否已经执行了相应中断源的中断服务函数。若是已经执行则退出遍历,不然继续遍历直到找到相应的服务函数或者找不到退出。
经过中断注册构建中断向量结构链表
中断发生时经过中断向量号索引_K_idescTable数组找到此中断向量号的中断结构链表,而后遍历以前注册在其中的中断服务函数,直到找到相应的服务函数或者找不到退出。