关于嵌入式:RTThread学习笔记-7RTThread中断管理学习总结

117次阅读

共计 3973 个字符,预计需要花费 10 分钟才能阅读完成。

后面几篇文章总结了 RT-Thread 多线程相干内容的学习过程,包含多线程的应用,多线程的同步,多线程的通信,对于多线程相干的学习总结,能够查看之前的文章。

本文的内容是对于 RT-Thread 中断治理的学习总结,包含简略地介绍了什么是中断,裸机中断与 RT-Thread 中断有什么区别,RT-Thread 是如何解决中断的,RT-Thread 内核提供哪些中断相干的接口,等等。

对于 RT-Thread 中断治理相干的内容,官网提供了比拟丰盛的文档作为参考,具体能够查看以下链接:
https://www.rt-thread.org/doc…

本文尝试从以下几个方面总结一下 RT-Thread 中断治理的学习过程

中断相干的概念形容

什么是中断?中断,顾名思义就是一项正在进行的工作,忽然间被其余事件打断,导致原来正在进行的工作不能持续失常进行,而须要去把其余事件解决完,能力回来持续进行原来的工作。

如何艰深地了解中断?设想一下这样的场景,周末你正在家里欢快地写着代码,忽然间你的手机铃声响了,你必须停下手里的工作,记录代码写到哪个阶段,而后就去接这个电话了。“写代码”就是正在进行的工作,“电话响起”就是中断事件。

这个电话是媳妇打过去的,她让你去菜市场买点韭菜和猪肉,早晨包饺子吃,媳妇的话哪敢不听,于是你感觉菜市场买货色比拟重要,挂掉电话后就去买货色了,买完货色回来后,再接着写刚刚还没实现的代码。“菜市场买货色”就是中断服务程序,这就是一个典型的中断处理过程。

对于中断的操作模式和特权级别,Cortex- M 的处理器有三种状态划分,别离是:特权级解决模式,特权级线程模式,用户级线程模式。这三种状态的关系,如下图所示。

从上图能够看出,中断或异样的服务程序,总是处于特权级解决模式的。而 RT-Thread 零碎内核复位上电时启动的主线程(main 线程),是运行在特权级线程模式的。其余用户创立的线程,是运行在用户级线程模式的。

为什么处理器要辨别特权级和用户级?特权,顾名思义就是处理器如果工作在这个级别下,权限就会比拟高,就能够拜访一些非凡的寄存器,以避免用户级的代码拜访这些非凡寄存器,对数据进行毁坏。中断因为其特殊性,所以,中断函数是工作在特权级别下的。

裸机中断与操作系统中断两者有什么区别呢?咱们在裸机代码中解决硬件中断的时候,个别只有编写中断处理函数就能够了,这种形式解决中断,简略且间接。

然而,有了操作系统之后,所有的货色都变了,要思考的问题就多了很多。因为操作外面运行了很多线程,中断来了之后,就要告知操作系统,把以后运行线程的信息保留到栈外面,再去解决中断服务程序,解决完中断要再回去解决线程,此时又可能波及到线程切换调度,而线程切换自身又须要 PendSV 中断参加。

所以,在裸机解决中断和在操作系统中解决中断,几乎就是天壤之别。
RT-Thread 中断解决机制

理解过 Cortex- M 系列单片机的工程师,个别都晓得在芯片的汇编启动文件 startup_xxx.s 外面,有一个中断向量表,所有的中断都是通过这个中断向量表来进行解决的。

当一个中断异样触发的时候,处理器将会判断是哪个中断源,而后跳转到固定地位进行解决,每个中断服务程序的地址入口必须是放到对立的地址上,也就是须要设置到 NVIC 的中断向量偏移寄存器外面,中断向量表如下图所示。

其实,不论有没有操作系统的参加,一旦硬件发送中断和异样之后,中断的入口都是在这个中断向量表的。区别无非就是在裸机环境下,间接解决中断服务程序,而在有操作系统的状况下,须要先保留线程的运行状况,而后再解决中断,解决完中断后,再复原线程的运行环境。

硬件中断的优先级是最高的,任何线程的优先级都要低于硬件中断,因而,只有产生了硬件中断事件,零碎就必须要进行相应的解决。

RT-Thread 在解决中断的时候,个别都会有三个阶段:中断前导程序,中断服务程序,中断后续程序,这三个阶段,如下图所示。

中断前导程序的次要工作是,当中断事件产生的时候,处理器的硬件会把以后 CPU 相干的寄存器参数主动压入中断栈外面。程序须要调用 rt_interrupt_enter()函数,把全局变量 rt_interrupt_nest 进行加 1 操作,这个全局变量是用来记录中断的嵌套层数的。

用户中断服务程序的次要工作分两种状况,一种是不进行线程切换,另一种是进行线程切换。不进行线程切换的话,中断服务程序和中断后续程序运行实现后,将返回被中断的线程。

而如果要进行线程切换,则会调用 rt_hw_context_switch_interrupt() 函数进行上下文切换,这个函数次要是设置变量 rt_interrupt_to_thread,而后触发 PendSV 中断。

在这里要留神一下:因为 PendSV 中断的优先级最低,不能进行中断抢占,因而即便触发了该中断,但因为此时还在用户中断处理函数外面,所以 PendSV 中断还处于期待阶段,只有退出了中断后续程序,才会进行 PendSV 中断解决,才会进行线程的上下文切换。所以,线程的上下文切换是不会在用户中断外面进行的,是在中断完结后进行的。

中断后续程序的次要工作是,告诉零碎内核来到中断状态,通过调用 rt_interrupt_leave()函数,将全局变量 rt_interrupt_nest 进行减 1 操作,而后从中断栈外面复原复原 CPU 相干的寄存器参数。

这里复原 CPU 寄存器参数的时候须要留神,如果在用户中断外面波及到线程切换,那么这个时候就须要复原到新的线程 CPU 寄存器参数,而不是复原到被中断打断的线程 CPU 寄存器参数。

RT-Thread 操作系统在解决中断的时候,通常采纳“上半局部(Top Half)”和“底半局部(Bottom Half)”这种形式。起因在于,操作系统自身不会对中断服务程序的解决工夫做任何假如和限度,但为了保证系统的实时性,用户须要保障中断服务程序在尽可能短的工夫内实现。

如何了解“上半局部(Top Half)”和“底半局部(Bottom Half)”这种中断解决形式?还是以买菜为例。媳妇来电话让你到菜市场买菜(中断事件),但你思考到如果长时间中断不写代码,会导致思路断链,为了防止这种状况(防止长时间解决中断服务),齐全能够在网上下单购买(短时间的中断解决),生鲜超市收到下单信息(信号量、邮件、音讯队列),就会安顿快递小哥送货上门,买菜这么耗时的工作就由其他人(其余线程)去实现了。

“上半局部(Top Half)”和“底半局部(Bottom Half)”这种中断解决形式,次要是利用在一些须要耗时解决中断事务的场合,比方数据的接管和解决。通常接收数据的工夫比拟短,只有把接管到的数据保留下来即可,但解决数据的过程就可能比拟耗时,这样就须要离开来解决,上半局部就是接收数据,底半局部就是耗时的数据处理。
RT-Thread 中断相干的 API 函数接口

为了把操作系统和硬件底层的中断异样隔离开来,RT-Thread 零碎内核把中断和异样封装为一组形象的接口,具体的函数接口如下图所示。

RT-Thread 中断相干的利用示例

RT-Thread 中断相干的利用示例,次要是为了验证中断相干的 API 接口函数,例如全局中断开关的应用示例,通过按键中断示例来验证“上半局部(Top Half)”和“底半局部(Bottom Half)”这种中断解决形式。

示例源码下载链接:https://github.com/embediot/r…

全局中断开关示例,次要是为了验证多线程拜访同一个变量时,应用开关全局中断的形式对该全局变量进行临界区爱护。

按键中断示例次要是为了验证“上半局部(Top Half)”和“底半局部(Bottom Half)”这种中断解决形式。通过按键触发中断事件,在中断服务函数外面发送邮件,告诉线程进行相应的解决。
在 irq_test.h 头文件外面,通过关上相应的宏定义开关,从新编译工程源码,下载到开发板即可验证试验景象,如下图所示。

RT-Thread 中断利用的注意事项

中断是一种异样,当零碎产生中断异样的时候就必须要进行解决,在 RT-Thread 实时操作系统外面解决中断的时候,如果不及时处理或对中断处理不当,轻则会造成零碎出错或逻辑凌乱,重则会导致系统毁灭性地瘫痪。

在解决 RT-Thread 中断异样的时候,有以下注意事项:

1. 中断服务程序工作在特权级解决模式,优先级比任何线程要高,任何线程都不能抢占中断服务程序。

2. 在操作系统外面,能够反对中断嵌套,高优先级中断能够抢占低优先级中断,线程的从新调度是在所有中断都解决完之后才重新启动的。

3. 在 Cortex- M 架构外面,中断产生时 CPU 的寄存器入栈是由硬件主动实现的,中断的前导程序通常只是记录中断的嵌套层数。

4.RT-Thread 采纳独立的内存空间作为中断栈,而不是采纳线程栈作为中断栈,这种形式随着线程的减少,缩小内存占用的成果也越显著。

5. 倡议采纳“上半局部(Top Half)”和“底半局部(Bottom Half)”这种形式来解决中断异样,中断服务程序的解决工夫应尽可能短。

6. 应用全局中断开关是禁止多线程拜访临界区最简略的一种形式,这种形式能够利用在任何场合,但要留神这种形式对系统实时性影响微小,使用不当会毁坏零碎的实时性能。应用全局中断锁的工夫应尽可能短。

7. 全局中断开关反对多级中断嵌套应用,每次调用 rt_hw_interrupt_enable()函数,能够让零碎复原到关中断之前的状态(这个状态有可能是关中断也有可能是开中断)。

8. 中断服务程序是运行在特权解决模式下的,在这种运行模式外面是不能应用挂起以后线程操作的相干函数的,因为中断服务程序的运行环境外面基本不存在线程。

感激浏览!

原文链接:https://club.rt-thread.org/as…

正文完
 0