rt-thread调度锁与关闭中断深度探究

2020-03-31 16:39:40 浏览数 (2)

01

说明

对于使用rt-thread操作系统的人来说,我提出几个问题?什么时候用到调度锁,又什么时候用到关闭中断?关闭调度器后可以做什么事情?关闭中断后又能做什么事情?本文从解决这些问题的角度出发,从实际项目应用的角度去分析这些问题。

02

调度锁与关闭中断

在rt-thread中,保护临界区的方法除了IPC线程间通信机制,然后就是调度锁与关闭中断了。

调度锁

rt-thread调度锁的目的是让调度器停止工作,这时不进行线程的切换工作。也就是说,在调度锁范围内的代码是独占CPU资源的,当前的被调度锁锁住的代码不能切换到其他的线程。

调度锁不会阻止系统的响应中断,中断处理完成退出后,继续执行被锁住的线程。

我们一般使用调度器锁是成对的使用,这点要非常注意,如果只有上锁,没有解锁,那会带来系统毁灭性的灾难。

rt-thread调度锁的接口如下:

void rt_enter_critical(void);//进入调度临界区

void rt_exit_critical(void);//退出调度临界区

中断关闭

rt-thread的关闭中断和其它的系统关闭中断的措施一致,其存在的目的是让系统执行时,不会被外界事情干扰。此时系统将按照程序设定的指令一条一条的执行,不会出现其他的异常情况。

比如我们在升级系统的时候,这时不允许有其他的中断来干扰升级的过程,或者我们在操作内存或者flash的时候,不希望其他的中断扰乱执行逻辑,此时我们就需要关闭中断。

在关闭中断时,接口也是成对使用,并且可以支持嵌套的方式调用。

rt-thread中断关闭接口如下:

rt_base_t rt_hw_interrupt_disable(void);//屏蔽中断

void rt_hw_interrupt_enable(rt_base_t level);//中断使能

03

使用调度锁说明

在rt-thread中如何使用好调度锁,或者在实际项目中,什么样的场合会使用调度锁?

第一种情况,就是使用到了共享内存的情况,为了防止这块共享内存被一个线程写的中途,另外一个高优先级的线程抢占并使用了这块没有操作完全的内存,我们可以在写这块共享内存的时候,将其用调度锁上锁,此时线程的调度器将不会的工作,此时操作内存就完全没问题了。解决这个问题也可以使用IPC机制,但是一定要注意临界区资源的保护问题。

第二种情况就是实时性要求很高的场合,比如我们在线程中操作一个电机的转动,由于电机的转动只要给定特定信号的电平就能转动,但是是否旋转到位,则需要通过特定的引脚检测状态或者通过ADC判断电流情况,如果到位了还不停止转动,则会对电机的寿命有很大的影响,此时我们就可以用调度锁锁住这个过程,而后在检测的时候,不必等待其他高优先级任务释放线程使用权。此时低优先级的转动电机的线程将会保持很好的性能去处理电机转动。当然这种用法比较特殊,但是有时候也无法避免。

调度器如果主动去执行rt_thread_delay或者rt_thread_mdelay会发生什么事情?

我们知道,我们如果要让线程释放资源,只需要调用上述两个函数,就可以切换到其他线程,同时我们的理解上常常会认为这个就是一个等待延时函数,从而当做延时函数来使用,实际上来说,当在调度锁中执行这个delay函数,实际上是无效的,也就是说,无论delay的时间多大,在调度锁中都不会生效。

调度锁在调度器未初始化的时候被调用会发生什么?

原则上来说,这个情况是不允许的,但是有的时候,我们笔误,出现了这样的问题,那么将会发生事情呢?

答案就是这个操作是无效的,也就是并没有意义,只是增加了几行代码而已,为什么会这样,可以自行查阅代码。

04

使用中断锁说明

中断锁是保护临界区的终极武器,在中断锁中发生的事情,都不会被打断,外部中断也不能响应,那么我们使用中断锁的场合以及如何合理的使用中断锁呢?

第一种就是系统做完了所有的事情,需要进入休眠或者等待进入休眠的期间可采用,另外就是程序升级的过程中可以采用中断锁,此时系统不应该被外界事情打断。

第二种就是我们在操作内存资源或者flash资源的时候,不希望中断打断我们的操作逻辑,否则将会让数据不同步,此时也会让中断锁用上。

第三种就是调度锁中其实也用到了中断锁操作,这个是为了保证临界区变量的可靠性和唯一性,因为锁是全局的变量,操作时必须要进行保护。

那么这么强大的中断锁副作用是什么呢?

当然,我们采用rtos一般来说都是希望实时性要求高,如果使用了中断锁,那么中断响应延时会拉长,这样对于实时性特别极端的场合,我们可能达不到如此高的实时性要求了,为了解决这个问题,我们可以少用中断锁来进行程序的设计,另外就是可以采用中断嵌套的方式进行设计。

误区:中断锁中是否无法进行线程调度?

当然是可以进行系统调度的,我们往往理解成,既然有了中断锁,那么相关的操作系统的tick也无法工作了,调度器自然也无法轮训了。其实我们在中断锁中,主动去切换线程的调度,这样是可以的。因为本质上来说,线程的切换就是前一个线程入栈,后一个线程出栈的过程,具体这样的操作会用到什么样的业务场合,这个也是根据具体的需求来确定的。

05

总结

本文详细分析了rt-thread调度锁与关闭中断的相关理论知识与适用背景,同时列出了一些适用场合,合理的利用这些临界区保护方式,对于我们做业务逻辑来说非常的重要,合理的去设计好线程的优先级,线程的临界区资源保护,将让我们的设计锦上添花,达到一个更高的高度。

0 人点赞