本帖最后由 Killoser 于 2022-4-13 15:40 编辑

本文分享自中移OneOS微信公众号《中断管理》。

中断是指计算机运行过程中,出现某些意外情况需及时处理时,CPU能自动停止正在运行的程序并转入处理意外情况的程序,处理完毕后又返回原被暂停的程序继续运行。中断是一种异常,正确地处理异常,避免错误发生是提高软件稳定性非常重要部分。

中断工作机制
中断向量表是所有中断处理程序的入口,一般是在地址空间的0地址,因为中断处理与芯片架构强相关,下文以Cortex-M系列来进行说明。
在Cortex-M内核上,所有中断都采用中断向量表的方式进行处理。当一个中断触发时,处理器能判定到是哪个中断源,然后查找中断向量表跳转到相应的位置进行处理。这就要求每个中断服务程序的地址指针必须挂接在统一的地址上,这个地址必须要设置到中断向量偏移寄存器中,默认是0x08000000。

中断处理过程
在操作系统中断管理中,将中断处理程序分为3个部分,中断前导程序、用户中断服务程序、中断后续程序。

中断前导程序
保存运行现场,不同CPU架构的实现方式有差异。对于Cortex-M来说,该工作由硬件自动完成,软件不需要处理,当一个中断触发时,处理器会自动将当前运行部分的上下文寄存器(PSR、PC、LR、R12、R3-R0)压入中断栈中。
调用os_interrupt_enter接口,该函数是将全局变量os_interrupt_nest加1,用它来实现中断嵌套的记录,代码如下所示:
void os_interrupt_enter(void)
  • {
  •     os_base_t level;
  •     level = os_hw_interrupt_disable();
  •     g_os_interrupt_nest ++;
  •     os_hw_interrupt_enable(level);
  • }
  • 复制代码
    用户中断服务程序
    在用户中断服务程序中,如果释放了其他高优先级任务阻塞等待的资源或者其他情况使得有更高优先级任务就绪,则会调用os_hw_context_switch_interrupt接口进行任务切换。如果无释放资源等情况,则不进行切换,中断程序执行完毕后返回原任务。
    os_hw_context_switch_interrupt的实现与CPU架构相关,在Cortex-M 架构中,该函数会设置需要切换的任务到一个全局变量,然后触发低优先级的PendSV异常,待当前中断处理结束后会切换到PendSV异常处理函数执行,PendSV是Cortex-M系列专门用来辅助上下文下换的异常。

    中断后续程序
    调用os_interrupt_leave()函数,将全局变量g_os_interrupt_nest减1,代码如下所示:
    void os_interrupt_leave(void)
  • {
  •     os_base_t level;
  •     level = os_hw_interrupt_disable();
  •     g_os_interrupt_nest--;
  •     os_hw_interrupt_enable(level);
  • }
  • 复制代码
    如果在中断处理过程中未进行任务切换,直接恢复中断前任务的上下文,如果在中断中进行了任务切换,那么恢复切换任务的上下文。对于有任务切换的场景,整个中断过程的时序关系如下图。
    up-fcf020ad1f5a77f7e39fb3600a31979e571.png
    中断过程示意图

    中断嵌套
    如果在执行中断服务程序的过程中触发了更高优先级的中断,当前的中断程序会被暂停,执行高优先级中断服务程序;待高优先级中断执行完成后,暂停的继续执行。如果执行中涉及到任务切换,会等待所有中断执行完成后进入pendSV中进行上下文切换,如下图。
    up-59060509807e37e5af4413690f943415a24.png
    中断嵌套示意图
    中断管理接口设计如下:
    (1)挂接中断服务程序
    up-7d3e5e433e2bc699e6a7d2480907c9f829d.png
    (2)屏蔽中断源
    up-fdf2e45cc1a7c67c9790cd4d1960771dcc4.png
    (3)打开中断源
    up-8e3e91457b437748e68873690cee2653fee.png
    (4)关闭全局中断
    up-208a8cf3bb2a58a7de9ef6a305f54a9f98e.png
    (5)恢复全局中断
    up-9ad582532ecb37a99c89ae2268b291279bc.png
    (6)中断进入通知
    up-8bf8e9f53c4b78d132eb018ef4cab0c03ed.png
    (7)中断退出通知
    up-b7dfc00c067a214c5c6264f9ee935097854.png