妹子要我教她学RTOS

新来的程序媛

公司招了个程序媛,老大最近赶项目忙的死去活来,没空指导,让我来照顾她,哦,是辅导她做开发。

她刚来那阵,我也没怎么跟她交流过,就打过几次招呼,微笑下点点头之类的。老大最近忙,这次也只是分别跟她、跟我简单提了下这回事,也没正式介绍下。腼腆的我,又不好意思主动找她,她也没有问题主动找我。尴尬得,我心胡乱跳了好几天。程序猿我倒是辅导过几个,但是,妹子还真没有……

终于,有一天快下班了,我还在那里调bug,我背后隐约传来个温柔的声音,“前辈,你好!”我以为不是喊我,我继续调代码……

“你好,前辈!”

我转头看了看,是新来的那个妹子。

“呃……”

于是,她又换了个称呼。

“师兄,你好,不好意思,打扰下你。”

“你好……”

“你今晚有空吗?”

“嗯,什么事?”我慌张的很,内心想难道妹子暗恋我,要约我?

“我看了好几天了,摸不着头脑,我想请教下你RTOS的一些问题……”

“哦,没问题”,我心中窃喜,这是我的强项!

于是,晚上顺理成章地加班了……

“RTOS有什么问题?”我关切地问,又发现我这句话问的不够贴切。

“我以前没用过RTOS……”,她低声说,像是做错事的孩子。

听到这里,我发现我的机会来了……我总结的RTOS干货(广告:关注“嵌入式软件实战派”,获得更多精品干货!),终于派上用场了。


什么是系统

中国著名学者钱学森认为:系统是由相互作用相互依赖的若干组成部分结合而成的,具有特定功能的有机整体,而且这个有机整体又是它从属的更大系统的组成部分。

百度百科

程序里面为什么有个死循环?妹子其实很好奇,但是她没直接问这个问题。

因为,程序员的爱是永恒的,不是随随便便玩两下的,更不是始乱终弃的。当然,这话我也没跟她说。

实现一个产品的功能,是用户随时都能用的,也就是软件是一直就绪候着用户这位大爷的。所以,它处于一直循环状态中,不叫你关机,就一直运行下去,直到永远。

1. 轮询系统

实际上,朴素的系统就很简单,一个死循环就行。

这个就是轮询系统

这是最简单的一种系统,主程序就是一段死循环的代码,在循环中运行多个程序功能(姑且叫它为job),这些job顺序查询各个条件,如果满足就执行相应的操作。这系统实现非常简单,妹子一看就懂了。

但是,这个轮询系统有点死板,对于外面的输入,它只能通过循环里面的job去查询到,万一有一个job干了很多事,运行好慢,那么这个外部输入就处理不及时,影响体验。

那么,中断这个功能就发挥优势了。

2. 前后台系统

在程序运行的过程中,用一些job来处理中断的数据。

这个就是前后台系统

实际上,前后台系统对轮询系统的外部事件的处理做了优化,它是由中断驱动的。主程序依然是一段死循环的代码, 称为后台程序,而所谓的前台,就是中断触发的事件。在后台程序执行的时候,如果有外部事件发生,则前台的中断程序会打断后台程序。

例如,假如把现在的软件开发工作当做是一个后台任务,产品经理突然打电话过来说要该需求,这个就是前台。

做这个举例的时候,我有点激动(一提到该需求就激动,想到处找砖头……),幸好我控制了情绪,幸好妹子还是理解了这个概念。

如果前后台系统的某个job处理事情太慢了,还是会影响其他job的运行啊。

3. 多任务系统

对于前后台系统的问题,人类的追求总是不停歇的,人民群众的智慧也是无穷无尽的。

用多个死循环呗。

从上图可以看出,多任务系统好像是前后台系统的几份拷贝一样,每个task都是一个死循环。这几个task是独立运行的,处理着各自的事情,这些事情也可以简单理解为job1、job2、job3等等。

当中断事件来了,由对应的task去处理,而且可以及时响应。

举个例子,假如当前task1在运行,而更紧急的任务——中断3来了,那么task2会抢占运行(假设优先级比task1的高),及时响应了事件中断。

这个就是多任务系统了。用在嵌入式上,也可以理解为我们常说的RTOS

说到这里,好像系统变得复杂了,看得出,妹子一脸懵逼。她似乎想问,多个死循环怎么运行?


RTOS怎么工作的

RTOS里面的任务(Task),从宏观上看,是独立的,他们各自干各的,但是,从微观上(虽然有点不恰当,姑且用宏观/微观的概念来解释)不是,对于单核的CPU,这些task可以说是“分时复用”的,也就是说,CPU一会运行一下task1,一会又切换到task2去运行,一会又切换到task3……而CPU运行很快,让你感觉不到它在切换和停留,感觉起来各个task就是各自干各自的。

那,这是怎么做到的呢?妹子听我说着,满怀期待的样子。

1. 时钟节拍

引入一个概念,“时钟节拍”或者叫“时间节拍”或“时间片”。在电子的世界了,软件的运行并非是连续的,而是由一个小小的时间片驱动着运行。就像,现实世界是连续的,而软件的世界是离散的,是由一个个小片段组成的。

时钟节拍是多任务系统的基础, 它指明了把处理器时间以某个频率分割成固定长度的时间片段。这个时间片段,就是RTOS运行的时间尺度。这些时间片,基于硬件的,准确说是基于芯片的时钟模块的定时器中断。每次时间片切换,OS都会检测到,并判断当前是继续当前的任务,还是要切换到其他任务运行。

2. 多任务机制

不管怎么耍,CPU的固定一个时刻,只能是运行着一个task,就像齐天大圣什么个七十二变,实际上只有一个真身。

什么时间片由哪个task运行,这个才是OS核心的内容。实际上这是个复杂的事情。为了讲明白这个东西,我只好抽象地讲解。这几涉及到另外几个概念了,如上下文(Context)、任务状态、任务切换、系统调度等。

每个task正在CPU上运行的时候,OS的堆栈是会记录着当前运行的位置,还记录着上一个task是在哪个位置被切换过来的。这些记录的信息就是上下文。

我在讲解的时候,时不时转头看下妹子,妹子也是使劲地点头,好像很佩服的样子……

而这些上下文是怎么记录的呢?

从单纯的MCU程序运行来看,这些信息是存放在一系列寄存器中的,例如R0,R1,R13等等,其中还有几个特殊的寄存器,如SP指针,PC指针等。

这好像绕到了MCU底层的东西去了,生怕妹子听不懂,我就尽量避开了,但是必要的地方还是会提到。

这一系列的内容,OS就会用一个堆栈(准确说是OS的栈)来存放着,每个task都有一个单独的栈,存放着自己的task的上下文信息,就像MCU里面寄存的快照一样,当然,还存放着自己task里面的其他信息,例如局部变量等。当CPU要切换的时候,就会把这些栈信息提取出来用。

这个过程有点复杂,我没绕进去,后面有机会再细讲,这些信息怎么存进来,又怎么提取出来使用的。(广告:关注“嵌入式软件实战派”,获得更多RTOS知识!)

那么,CPU怎么知道某个时刻要切换到某个task运行的呢?妹子疑惑地问。

这就靠OS里面的状态管理了,也就是前面提到的任务状态。一般情况下,RTOS都会有几个不同的状态,如运行状态(Running State)、就绪状态(Ready State)、挂起状态(Suspend State),还有阻塞状态(Blocked State)等等,当然还有些其他的状态来处理其他特殊的情况。例如下图的FreeRtos的状态切换。

当然,这里面还涉及到Task的优先级(Priority),其决定哪个task的优先级更高,给更多的机会切换到这个task运行。

……

我还要继续讲下去的时候,妹子突然跟我讲,太多概念了,越来越复杂了,怕一下子消化不了。

我停顿了下,看了看我电脑的右下角,原来时间很晚了……

我于是跟她说,要不下次再讲吧,有任何疑问可以随时来找我等等的话。

于是,她起身离开,顺便还关心的问,“你也要下班了吧!”

我突然想起我的bug还没接完,我只是对她笑了下。

她收起了她的东西,好像有点犹豫的样子,还在办公室晃荡了两圈,然后慢慢地离开了。

过了一会,我才发现,前面几排的小伙伴已经下班了,其上面的灯管已经关了,月光从窗外透进来,格外的美。我的座位还留着妹子淡淡的芬芳……

不对,她是不是等我一起下班?于是我冲出了办公室……

猜你喜欢

转载自blog.csdn.net/usstmiracle/article/details/108248473
今日推荐