同事在RTOS临界区嵌套使用栽了跟头~


1

裸机与RTOS的理解

首先这里只针对单核CPU架构的芯片展开讨论,大部分是MCU吧,而多核CPU的讨论相对比较复杂,暂不涉及~

玩RTOS的朋友都知道,裸机与OS的最大区别就是实现多任务的并发,其实你说裸机就不能实现任务的并发吗 ? 这个需要看所站的角度吧,只是说RTOS并发的粒度可以更加细,因为你把裸机的任务拆分成多块运行,其实也是一种并发方式。

从宏观上虽然RTOS的每个任务都是在并发执行,其实微观上还是一条一条指令在顺序执行着,如下图所示:

而对于目前主流的RTOS,如UCOS或者FreeRTOS,所实现的都是多任务,更多的是一种多线程的并发执行而非多进程,所以对应到Linux平台上称他们为thread。

2

并发带来的问题

并发的好处就是能够在更细的粒度来尽可能的提高CPU的利用率,这里不能说使用了多线程就一定能提高,这与你所设计的任务划分和处理有着直接的关系,只能说多线程相比裸机更有这个能力。

而任何事物都有其利弊,多个任务在没有同步处理的情况下,任务之间是无序运行的,无序也就意味着状态的多样性和复杂度。

当然bug菌这里所说的无序是一个相对的过程,比如对于CPU而言,它就是顺序的去执行一条一条的指令,所以在这个层面它是有序的、确定的。

而我们把过程放大,比如执行一条C语言语句,一般它是由多条汇编指令组成,对于目前的抢占式内核,在一段时间内其多个任务就有可能指令交替执行,当这些指令都去操作同一块内存,那么内存的最终结果由于顺序不同而不同,最终难以确定。

状态的不确定就有可能造成异常行为,也就是大家经常遇到的:"怎么跑着跑着就有问题,还没啥规律~","这段代码怎么看也没问题呀~"

所以对比看来RTOS确实会带来编程上的难度~

3

临界区

既然有难度,我们就要解决,把不确定性部分通过一些手段来变得确定,而造成这些不确定因素的动力是什么呢?是中断~

bug菌一直觉得,其实对于裸机而言,如果把中断服务函数看成一个更高优先级的抢占式任务,其实裸机主任务与中断任务就形成了一种两任务的并发,所以中断与任务之间也是有共享问题需要类似处理的。

为了解决这些不确定因素,我们只需要在这段代码区域限制中断的发生即可,这一段区域就是临界区,说得直白点 : 关中断与开中断。

1ENTER_CRITICAL();//进入临界区
2
3//临界区代码
4
5EXIT_CRITICAL();//退出临界区

4

临界区嵌套

临界区的使用没啥可说的,但是在你的代码中怎么加临界区确实一门技巧,可是说很多3~5年的工程师也并不一定处理得好,本文暂不展开,后面bug菌整理以后再分享给大家,今天只聊聊临界区嵌套使用的问题,毕竟很多朋友在这里掉过坑~

参考伪代码:

 1/*********************************************2 * Function: Fuction13 * Description:功能函数4 * Author: bug菌5 ********************************************/6void Fuction1(void)7{8    ENTER_CRITICAL();//进入临界区9
10    //do something~
11
12    EXIT_CRITICAL();//退出临界区
13}
14/*********************************************
15 * Function: Fuction2
16 * Description: 功能函数
17 * Author: bug菌
18 ********************************************/
19void Fuction2(void)
20{
21    ENTER_CRITICAL();//进入临界区
22
23    ......
24    Fuction1();
25
26    ......
27    //do something~
28
29    EXIT_CRITICAL();//退出临界区
30}

这种临界区的使用是很多朋友常犯的错误,当然这里的临界区操作仅仅只是开关中断,许多自己公司写的,或者裁剪的都是这种简约开关中断版本,所以当调用Function1函数以后,后面的代码就不在临界区内了,此时就有可能会存在共享问题。

当然目前的开源OS都会提供一种把相关嵌套标记保存在局部变量中的处理方式,如下代码所示:

 1//来源于ucos源码2#define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR())3#define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr))45/*********************************************6 * Function: Fuction17 * Description:功能函数8 * Author: bug菌9 ********************************************/
10void Fuction1(void)
11{
12    int cpu_sr;
13
14    OS_ENTER_CRITICAL();//进入临界区
15
16    //do something~
17
18    OS_EXIT_CRITICAL();//退出临界区
19}
20
21/*********************************************
22 * Function: Fuction2
23 * Description: 功能函数
24 * Author: bug菌
25 ********************************************/
26void Fuction2(void)
27{
28    int cpu_sr;
29
30    OS_ENTER_CRITICAL();//进入临界区
31
32    Fuction1(void);
33
34    OS_EXIT_CRITICAL();//退出临界区
35
36}

为了更好的理解,我写了一下下面的伪代码,供大家参数~

 1//中断寄存器register原本是1, 向register写0关中断,向register写1开中断23void Fuction2(void)4{5    int cpu_sr1 = 0;67    cpu_sr1   = register; 8    register  = 0; //register == 0;cpu_sr1 == 1;9
10           void Fuction1(void)
11           {
12               int cpu_sr1 = 0;
13
14               cpu_sr2   = register; 
15               register  = 0; //register == 0;cpu_sr2 == 0;
16
17
18               register  = cpu_sr2; 
19               cpu_sr2   = 0;//register == 0;cpu_sr2 == 0;
20           }
21
22    register  = cpu_sr1; 
23    cpu_sr1   = 0;//register == 1;cpu_sr1 == 0;
24
25}

不同的OS可能具体实现有所差异,大体上都一样~

最后

好了,兄弟别下次了,就这次给个吧~~


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465892.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一道内存分配的面试题

这是读者在知识星球上写的面试题我之前写的文章有很完整说过这部分C语言,函数不可返回指向栈内存的指针C 语言内存分配堆和栈的区别(转过无数次的文章)看完上面的文章,我觉得你至少对C语言程序变量内存有一个概念了解了。然后看下…

一道内存分配的面试题后续

昨天写的题目,在VC6.0上面测试一下一道内存分配的面试题结果发现一个问题,发现输出结果竟然没有问题,我很慌,如果这样的输出结果没有问题的话,那肯定是跟我们的理论对不上号的。所以我只能继续调试先把问题抛在printf上…

Qt学习之路(11): MainWindow

尽管Qt提供了很方便的快速开发工具QtDesigner用来拖放界面元素,但是现在我并不打算去介绍这个工具,原因之一在于我们的学习大体上是依靠手工编写代码,过早的接触设计工具并不能让我们对Qt的概念突飞猛进……前面说过,本教程很大程…

要毕业了,我应该做点啥?

这几天是高考的日子,高考结束,也意味着有很多人要离开学校,距离我毕业已经过去很多年了,现在还能记得那些无忧无虑的日子,毕竟人这一辈子,能这么肆无忌惮的时间并不多。最近因为发了几个不错的岗位招聘&…

我那个37岁的大神朋友,后续

还记得我之前写的这篇文章吗?我一个37岁的程序员朋友写这篇文章的时候,我建议我的这个朋友跳槽找更好的工作,可以换个行业,换一个更有钱的领域,做技术不能单单是做技术,需要有点眼光,比如选择行…

扒一扒中断为什么不能调printf

[导读] 大家好,我是逸珺。前面说会写一下Modbus-RTU的实现,写了1000多字了,有兴趣的稍等一下哈。前面在一个群里看到一个朋友在一个串口接收中断里打印遇到了问题,今天聊下这个话题。扒一扒printf 对于单片机中printf到底向哪里打…

躺平,躺下就能赢吗?

之前在群里讨论这个话题,说躺平挺好的,没那么大压力,我也觉得躺平是好事,每个人都要追求理想的权力,那么反过来,每个人也有不追求理想的权力。躺平如果说的好听一些,也可以认为是躺赢&#xff0…

感觉stm32太简单是一种自负吗?

其实简单或者复杂都不重要,重要的是通过STM32我们能学习到什么?做一个键盘/鼠标,可以学习USB协议。做一个联网设备,需要学习以太网,TCP/IP协议的底层实现。做一个无线设备,可能需要学习蓝牙、WIFI或者zigbe…

耗时两年,19岁小伙采用230片纯74逻辑芯片搭建出32位处理器!可玩贪吃蛇

从设计 CPU、制作原型机、最终成品到软件编程,19 岁极客小伙用了整整两年的时间。RISC-V 是一个基于精简指令集(RISC)原则的开源指令集架构(ISA),它是对应开源软件运动的一种「开源硬件」。该项目于 2010 年…

VC++ 6.0 与VS2008 C++ DEBUG工具(Windows)介绍

在VC 6.0 里面,debug工具有这些: 请看大图展示: 这里面几个工具都是经常用到的。比如:上下文信息,可以查看当前变量的值和地址Memory: 可以输入地址查看里面的内容。对调试和检查指针特别有用。 在vs2008里…

数组与指针不能混用的情况

扫描二维码获取更多精彩嵌入式杂牌军编辑|追梦星空公众号|嵌入式杂牌军✎ 编 者 悟 语正当性的出发点应该是少目的性、不带偏见、以尊重为前提的多方考虑。文 章 导 读C中的数组有能混用的情况,有不能混用的情况,今天就带小伙伴们探究一下!阅…

[CTO札记]盛大游戏上市,是对《文化产业振兴规划》的响应

重要国策《文化产业振兴规划》于9月26日正式对外公布。巧合的是,就在前一天(9月25日 ),盛大游戏(SDG)成功在NASDAQ上市,并且创下了美股IPO规模之最(10亿美元)。1&#xf…

Linux内核入门之路 (非广告)

笔者从开始接触 Linux 内核应该有 4 ~ 5 年了,虽然不敢说非常了解 Linux 内核,但起码也有了点眉目。所以,本文主要想分享一下我的 Linux 内核入门之路,如果对大家有帮助的话,希望能够转发一下,帮助更多想学…

万能红外遥控开发

下班刚回到家,天气很热~空调遥控器呢?找不到!躺平不想动~风扇遥控器呢?找不到!想看电视,不想动~电视遥控器呢?找不到!好不容易找到了,遥控器没电?崩溃&#x…

[Lydsy1805月赛] 对称数

挺不错的一道数据结构题QWQ。 一开始发现这个题如果不看数据范围的话,妥妥的树上莫队啊23333,然鹅10组数据是不可能让你舒舒服服的树上莫队卡过的23333 于是想了想,这个题的模型就是,把u到v链上的权值出现奇偶次的01串搞出来&…

linux下被遗忘的gpio_keys按键驱动

我们新项目硬件设计上使用gpio口做按键,所以我就需要搞定这个驱动,本来想自己写一个gpio口的按键驱动,然后看了下内核下面的代码,已经有现成的了。Linux内核下游很多很多的现成驱动,只要你想得到的,基本都是…

如何通过审计安全事件日志检测密码喷洒(Password Spraying)攻击

许多渗透测试人员和攻击者通常都会使用一种被称为“密码喷洒(Password Spraying)”的技术来进行测试和攻击。对密码进行喷洒式的攻击,这个叫法很形象,因为它属于自动化密码猜测的一种。这种针对所有用户的自动密码猜测通常是为了避…

单片机编程技巧—状态机编程

摘要:不知道大家有没有这样一种感觉,就是感觉自己玩单片机还可以,各个功能模块也都会驱动,但是如果让你完整的写一套代码,却无逻辑与框架可言,上来就是开始写!东抄抄写抄抄。说明编程还处于比较…

啥叫旁路电容?啥叫去耦?可以不再争论了吗

1. 旁路和去耦先谈两个比较重要的概念:旁路电容(Bypass Capacitor),去耦电容(Decoupling Capacitor)。只要是设计过硬件电路的同学肯定对这两个词不陌生,但真正理解这两个概念的可能并不多。我刚毕业时就问过我的师傅,为什么总是在…

H5活动产品设计指南基础版

本文来自 网易云社区 。 H5一般页面不会很多,看似简单,实际上会有很多细节需要注意,我自己在做过了几个H5之后,发现了一些常犯的问题,做了小结,希望给新开始做H5的产品相关的同学提供一些帮助。 首先说说一…