rt-thread怎么修改默认的串口配置(如何打开rt-thread工程)

技术如何进行RT-Thread中断管理本篇文章给大家分享的是有关如何进行RT-Thread中断管理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。下面是关于R

这篇文章是关于如何管理RT-Thread中断。边肖觉得很实用,所以分享给大家学习。希望你看完这篇文章能有所收获。让我们和边肖一起看看。

以下是RT-Thread中断管理的学习总结,包括什么是中断,裸机中断和RT-Thread中断有什么区别,RT-Thread如何处理中断,RT-Thread内核提供了哪些与中断相关的接口等等。

从以下几个方面总结RT-Thread中断管理的学习过程。

如何进行RT-Thread中断管理

中断相关概念的描述

什么是中断?中断,顾名思义就是一项正在进行的工作,突然被其他事情打断,使得原本正在进行的工作无法正常继续,但是需要先完成其他事情,才能回来继续原来的工作。

如何通俗地理解中断?想象一下这一幕。周末,你在家里愉快地写代码。突然,你的手机响了。你必须停止工作,记录下编写代码的阶段,然后接听电话。“写代码”是正在进行的工作,“电话铃声”是中断事件。

这个电话是我媳妇打来的。她让你去菜市场买些韭菜和猪肉,晚上在饺子里吃。她不敢听她的话,所以你觉得在菜市场买东西更重要。挂断电话后,你去购物了。当你购物回来,你继续写刚刚没有完成的代码。“菜市场购物”是中断服务程序,是典型的中断处理流程。

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

如何进行RT-Thread中断管理

从上图可以看出,中断或异常的服务程序总是处于特权处理模式。另一方面,当RT-Thread系统内核复位并通电时启动的主线程(main thread)以特权线程模式运行。由其他用户创建的线程正在用户级线程模式下运行。

为什么处理器区分特权级别和用户级别?特权,顾名思义,就是指如果处理器在这个级别工作,它会有更高的特权,可以访问一些特殊的寄存器,防止用户级代码访问这些特殊的寄存器,破坏数据。由于其特殊性,中断功能工作在特权级别。

裸机中断和操作系统中断有什么区别?我们在裸机代码中处理硬件中断时,通常只需要编写中断处理函数,简单直接。

然而,随着操作系统的出现,一切都变了,还有很多问题需要考虑。由于操作中运行的线程较多,在中断到来后,需要通知操作系统,将当前运行线程的信息保存到堆栈中,然后处理中断服务程序。处理完中断后,有必要返回处理线程。此时可能涉及到线程切换调度,线程切换本身需要PendSV中断的参与。

因此,在裸机和操作系统中处理中断有着天壤之别。

线程中断处理机制

熟悉Cortex-M MCU的工程师一般都知道芯片的汇编启动文件startup_xxx.s中有一个中断向量表,所有的中断都是通过这个中断向量表来处理的。

当一个中断被异常触发时,处理器将确定它是哪个中断源,然后跳转到一个固定的位置进行处理。每个中断服务程序的地址条目必须放在一个统一的地址,也就是说,它需要被设置到NVIC的中断向量偏移寄存器中。

事实上,无论操作系统是否参与,一旦硬件发送中断和异常,中断的条目就在这个中断向量表中。不同的是,在裸机环境下,直接处理中断服务程序,而在操作系统的情况下,需要先保持线程的运行状态,再处理中断,处理完中断后再恢复线程的运行环境。

硬件中断的优先级最高,任何线程的优先级都低于硬件中断。因此,每当出现硬件中断事件时,系统必须相应地进行处理。

RT-Thread处理中断时,一般有三个阶段:中断前导、中断服务和中断后续,如下图所示。

如何进行RT-Thread中断管理

中断引导程序的主要工作是当发生中断事件时,处理器的硬件会自动将与当前CPU相关的寄存器参数推入中断栈。程序需要调用rt_interrupt_enter()函数给全局变量rt_interrupt_nest加1,用于记录中断的嵌套级别。

用户中断服务程序的主要工作分为两种情况,一种是不切换线程,另一种是切换线程。如果没有线程切换,中断服务程序和中断后续程序完成后,中断的线程将返回。

如果要切换线程,就要调用rt_hw_context_switch_interrupt()函数来切换上下文。该函数主要设置变量rt_interrupt_to_thre。

ad,然后触发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中断相关的应用示例

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

全局中断开关示例,主要是为了验证多线程访问同一个变量时,使用开关全局中断的方式对该全局变量进行临界区保护。

按键中断示例主要是为了验证“上半部分(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.中断服务程序是运行在特权处理模式下的,在这种运行模式里面是不能使用挂起当前线程操作的相关函数的,因为中断服务程序的运行环境里面根本不存在线程。

以上就是如何进行RT-Thread中断管理,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/150148.html

(0)

相关推荐

  • pytorch 训练集尺寸必须一致吗(pytorch如何防止加载模型改变参数)

    技术torch.nn.ModuleList有什么用本篇内容主要讲解“torch.nn.ModuleList有什么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“torch.n

    攻略 2021年12月21日
  • Linux内核Device Tree怎么创建

    技术Linux内核Device Tree怎么创建这篇文章主要讲解了“Linux内核Device Tree怎么创建”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux内

    攻略 2021年11月23日
  • Redis的java客户端Jedis的代码怎么写

    技术Redis的java客户端Jedis的代码怎么写这篇文章将为大家详细讲解有关Redis的java客户端Jedis的代码怎么写,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了

    攻略 2021年10月20日
  • 系统如何获取微信ip地址(如何获取微信ip地址)

    技术如何获取微信服务器IP地址这篇文章将为大家详细讲解有关如何获取微信服务器IP地址,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。如果公众号基于安全等考虑,需要获知微信服务器的IP地址

    攻略 2021年12月22日
  • C++三只小猪谁最重

    技术C++三只小猪谁最重 C++三只小猪谁最重C++选择结构学习小案例#includeiostream
    using namespace std;int main()
    {int A = 0;cout "

    礼包 2021年12月2日
  • Sharding ,分片模式)

    技术Sharding ,分片模式) Sharding (分片模式)Sharding (分片模式)
    副本集可以解决主节点发生故障导致数据丢失或不可用的问题,但遇到需要存储海量数据的情况时,副本集机制就束手

    礼包 2021年11月23日