在在本节课看,我们介绍一种解决任务间共享资源冲突问题的解决方案:开关中断。

这种方式最简单、有效、易于理解,但看起来往往会显得很粗暴。它可以完全禁用任务切换,使得任务在进入临界区代码后,其它任务无法打断该任务。

主要内容

在本节课中,我们学习用怎么样用中断去p实现资源互斥的访问控制。其工作原理是通过禁止任务切换来实现。
关中断解决任务间资源共享问题 - 图1
在引入了开关中断后,原任务对共享计数器之间的访问流程发生了变化。分别如下:
关中断解决任务间资源共享问题 - 图2

关中断解决任务间资源共享问题 - 图3
可以看到,使和该方案解决了之前的问题。
在使用开关中断进行保护时,还需要额外注意几点。

  • 开关中断的嵌套问题。例如:
    关中断解决任务间资源共享问题 - 图4
  • 对整个系统的影响
    关中断解决任务间资源共享问题 - 图5

    重点难点

    总体评价来说,开关中断是一种简单粗爆但是十分有效的方式。

    注意事项

    补充一下视频课程中没有提到的问题。注意,这两个问题都在提醒你使用该接口时要注意RTOS在这些接口上的实现细节。

    关中断禁止的是任务抢占

    严格来说,关中断是通过禁止任务抢占来实现本课程的解决方案。”抢占”指的是高优先级任务强制剥夺了低优先级任务对CPU的使用权。
    在革个任务正在运行时,该任务出现抢占的情况时,那只能是当前发生了某些外部事件,导致高优先级任务就绪。这些外部事件主要包含硬件系统中的中断(如信号量唤醒任务)、系统时钟节拍中断(任务延时到达)。如果禁用了中断,则会避免这些事件发生,进而避免抢占。
    如果是同优先级的任务,由于关中断同时关闭了系统时钟节拍中断,所以不会出现因时间片而切换至该任务。
    最后,我们还需要考虑一点:即任务在进入临界区后,主动执行了某些操作放弃CPU,如延时、发送事件唤醒高优先级任务等。在这种情况下,关中断是否有效,则取决于RTOS的具体实现。
    例如,在基于cortex-m3上的tinyOS实现,因其任务切换借助的是pendsvc异常,因而关中断能够禁止pendsvc异常响应,即无法禁用tTaskSched()执行,但能阻止tTaskSwitch()的执行,进而阻止切换过程。所以,即便此时任务主动放弃CPU,也是没有办法切换到其它任务。大多数其它的RTOS,任务切换也是通过异常/中断进行。
    但是不排除某些RTOS在执行任务切换时,不借助中断进行。此时,关中断方式并不能阻止任务切换。在这种情况下,关中断对于资源保护是失效的。

    开关中断是否支持嵌套取决于实现

    有些RTOS对于开关中断的实现,其内部实现了一个开关的计数器,用于实现保护。
    也有的RTOS仅仅提供了接口定义,具体实现取决于移植,例如ucos/tinyOS。有可能在你所用的RTOS中移植时,只是简单的开关中断,此时就会出现如下图左侧所示问题。
    关中断解决任务间资源共享问题 - 图6
    也有可能在移植时,采用了上图右侧的方式。具体采用哪一种方式,请在使用之前先确认。

    常见问题