【原创文字】关于实时操作系统的话题(上)

今天有位朋友私信我,和我讨论了一些关于实时操作系统的话题。讨论结束后,我针对这个话题具体写了些关于实时操作系统的文字,分享给大家,希望可以对大家有帮助。
两个问题
首先,让自己回想一个操作系统,然后闭上眼睛,大家脑海中是不是都出现了这样的画面?
这是一个操作系统,确确实实的操作系统,然而你看到的这个桌面,图标,还有各种展示在你眼前的画面,并不是一个操作系统,准确的说这些东西只不过是一个叫做“用户界面”的东西,它是操作系统用来将计算机内部各种软件需要显示出来的内容展现在你眼前的。所以大家需要知道的是,用户界面,窗体程序等并不是操作系统,哪怕一个STM32单片机逻辑程序运行,只要你数据结构和算法写得好,完全可以复制出来一个这种菜单切换的界面。讲到这里,先完成我们的第一步,脱开操作系统界面这一层伪装的外衣。
接着,自己再思考一个问题,如果哪天全世界windows,Linux,osx等操作系统的所有代码突然没了,那么我们手中的计算机还有没有办法运行?
这时候有些朋友可能会想了,如果没有了这些操作系统,那么电脑不是机都开不了了吗,还怎么去玩英雄联盟,怎么去写PPT,Edward还怎么去更新公众号?但是真的是这样吗?
要回答这个问题,大家先了解下世界上到底是第一台计算机先被发明出来还是第一个操作系统先问世。这个问题并不是“先有鸡还是先有蛋”这样子的哲学问题,因为世界上科技的发展永远都是呈现出“硬件先于软件,软件推动硬件发展”这样子一个规律的,当然这个规律是我自己总结的,不过说起来确实是那么一回事。大家先回想下自己手中的手机,早些年的大哥大,二哥大,爱立信,摩托,诺基亚等,都是一个个拼自己手中的硬件科技,直到有天出现了IOS和安卓,随着安卓操作系统越来越大,各大手机厂商的硬件不断地被软件催促着,今年865,明年875,今年十核,明年一百核。
计算机的软件和硬件关系也是一样,20世纪40年代,那个大家伙计算机问世,从今往后的30年时间内,都是硬件在不断地迭代发展,直到大规模和超大规模集成电路在计算机系统中的使用,促使了世界上第一个现代化的操作系统,也就是我们常说的UNIX诞生,此后的时间内,就变成了软件的扩张性需求,促进了硬件的发展。那上面的问题也就好回答了,如果没有了这些操作系统,我们的硬件肯定还是可以运行,我们以前的硬件上可能有操作系统,应用软件,驱动等而没有了操作系统之后,想要用word的时候,就插入一张word的磁盘,想要用excel的时候,就插入一张excel的磁盘。这是不是就类似于我们现在使用的单片机了?同一时间内,永远执行着一个“while(1)”循环。
桌面操作系统
以上两个问题作为铺垫后,我们下面的内容开始正式进入主题。
嵌入式实时操作系统,俗称“RTOS”,一般运行在单片机平台上面,相比于一些操作系统特性比较健全的桌面式操作系统来说,RTOS简单地都不像是一个操作系统,它更像是一个有实时特性的操作系统内核。
抛开“嵌入式实时”这几个字不说,我们先来看看一个操作系统它具有哪些好处。
计算机上面使用操作系统的好处主要有以下几点:
(1)    多任务,这是操作系统最大的好处,它可以充分发挥出CPU的特性,让原本只可以处理单个任务的CPU,看上去可以同时执行多个任务。比如你上C语言课程的时候,可以打开电脑,欣赏美妙的音乐。这种多任务的实现,其实是基于操作系统内核中的分时调用机制的,即将CPU的处理资源(主要是时间资源)分成多个碎片,每个时间片都会分配到每个运行的任务上面,这就类似于我们在做数码管动态刷新的程序一样,只要刷新够快,给人的感觉就是同时进行的。这也就是为什么当你的电脑软件同时开启过多,会造成假死的原因。
(2)    硬件抽象化,操作系统发展的这个趋势,绝对是造福于程序员的事情,如果说计算机还是停留在单片机时代的驱动和功能代码一团糟的时代,那么现在一些做前端的程序员恐怕就不是掉头发这么简单了,说不定头皮都掉下来了。正是因为操作系统将目前主流的硬件都抽象成了一个个软件对象,因此程序员在操作系统上面写软件的时候无需过多地考虑硬件驱动了。
(3)    内存管理,这个又是操作系统给程序员的福利了,有了各种虚拟内存技术,内存管理技术,我们在编程的时候就不需要考虑内存溢出,内存分配,内存释放等问题了。
(4)    促进软件行业的蓬勃发展,这个还真的没法想象,万一当时操作系统没有被发明出来,到底会不会出现这么多如Java,Python,C#等优秀的编程语言。
(5)    安全,这个安全是个相对来说的话题,我们这里就不讨论了。
以上这么多,就是一个操作系统可以带给用户的便捷性。一般一个操作系统的层级结构是这样的。
实时操作系统
接下来,来看看什么是实时操作系统。大家如果写单片机程序的时候,是不是都会喜欢在while(1)这个死循环里面运行状态机?然后以每个定时周期去调用某一个具体的函数?其实RTOS的多任务也是一样的机制,你可以独立地将每个任务需要运行的内存空间定义出来,每次MCU将这些任务里面的函数执行完成一次之后,便可以将这个任务进行阻塞,以释放MCU的资源。实现这一调度功能,主要有以下两种方法:
1.时间片轮转法
1) 基本原理
在早期的时间片轮转法中,系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU 分配给队首进程,并令其执行一个时间片。时间片的大小从几ms 到几百ms。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便跟据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就可以保证就绪队列中的所有进程在一给定的时间内均能获得一时间片的处理机执行时间。换言之,系统能在给定的时间内响应所有用户的请求。
2.多级反馈队列调度算法
前面介绍的各种用作进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程,而且如果并未指明进程的长度,则短进程优先和基于进程长度的抢占式调度算法都将无法使用。而多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。在采用多级反馈队列调度算法的系统中,调度算法的实施过程如下所述。
(1) 应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。例如,第二个队列的时间片要比第一个队列的时间片长一倍,……,第i+1个队列的时间片要比第i个队列的时间片长一倍。
(2) 当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n 队列便采取按时间片轮转的方式运行。
(3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。如果处理机正在第i队列中为某进程服务时,又有新进程进入优先权较高的队列(第1~(i-1)中的任何一个队列),则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回到第i队列的末尾,把处理机分配给新到的高优先权进程。
实时操作系统区别于桌面操作系统的另一个方面,在于其实时性的实现,一个操作系统的实时性是基于以下三个方面去实现的:
1)高精度计时系统
计时精度是影响实时性的一个重要因素。在实时应用系统中,经常需要精确确定实时地操作某个设备或执行某个任务,或精确的计算一个时间函数。这些不仅依赖于一些硬件提供的时钟精度,也依赖于实时操作系统实现的高精度计时功能。
2)多级中断机制
一个实时应用系统通常需要处理多种外部信息或事件,但处理的紧迫程度有轻重缓急之分。有的必须立即作出反应,有的则可以延后处理。因此,需要建立多级中断嵌套处理机制,以确保对紧迫程度较高的实时事件进行及时响应和处理。
3)实时调度机制
实时操作系统不仅要及时响应实时事件中断,同时也要及时调度运行实时任务。但是,[3]  处理机调度并不能随心所欲的进行,因为涉及到两个进程之间的切换,只能在确保“安全切换”的时间点上进行,实时调度机制包括两个方面,一是在调度策略和算法上保证优先调度实时任务;二是建立更多“安全切换”时间点,保证及时调度实时任务。
(0)

相关推荐