RTOS实时操作系统(0):初步认识与对专业名词的分析
前言
好的,那么这里是博主的一些事先声明和对各位可能会有的问题的预解答,还有就是免责声明。
首先,本文基于博主对实时操作系统,也就是RTOS(Real Time Operate Syetem)已有的理解进行的总结和思考,内容不保证完全正确,而且因为每个人理解的深度不同,可能会有些地方存在错误,或者说有讲的不够细致的部分,如果有问题,欢迎各位来评论探讨,只要博主看到,都会尽力回复。
然后讲些废话吧,看过博主前边的小作文的,应该知道博主现在在学习RTOS和硬件的基础操作,目标是把驱动开发做成艺术,短期目标自己写一个类似于hal库或者标准库这样的库函数出来。虽然听起来可能有点吃力或者很费力不讨好吧,但我还是想尽可能地让自己做到深入,做到规范,所以不定期地用博客的形式记录下自己的思考和理解。如果有问题,欢迎随时提问和交流,博主也非常期待和各位技术大佬进行更加深入的交流和学习,也希望各位看完我的文章能有一些自己的思考或者启发。本篇对于好多大佬可能都是洒洒水、不屑于提及的内容,所以主要也是给各位刚学的萌新用来补盲或者说有一点简单了解的,也作为我的学习笔记记录一下。
本文基于博主读考林著、清华大学出版社译制的《嵌入式实时操作系统·理论基础》进行编写,由于是翻译的版本所以个人认为好多地方可能存在翻译问题导致表达并不像原文那样准确,于是基于博主自己的理解和思考再输出一遍。而且强调一点,博主并不喜欢在本来就很抽象的内容上随意地使用比喻进行具象化。因为好多内容如果你对程序设计有一定理解,我认为直接讲抽象的概念你会更加直接且没有任何错误引导地学会学准确,而随便地使用比喻,你可能更多记住的是人家的比喻,尤其是当理解本身就存在偏差的时候使用比喻就更容易跑偏了。这样的方式虽然可能在学习的过程中很痛苦,要绞尽脑汁地想,但是一旦理解了,印象也会更加深刻。这也算是本人对学习上的一些理解,具体情况因人而异。所以博主会在自己比较有把握的时候使用简单的比喻和类比,在不确定的时候就尽可能抽象概念带过了,或者说先讲抽象的概念,最后讲一点博主自己理解的比喻来类比。
我认为,要学实时操作系统,首先要对这个名字每个字都是什么意思有基本的了解。操作系统这个概念很庞大要讲清楚并不轻松,我们可以理解成这就是一套软件,他让我们可以不用对着电脑里的每个零件进行操作,提供了使用高级高效的编程语言编写程序的客观条件和基础。而操作系统的诞生就是为了让我们的代码能够更加精巧,更加准确地运行,好的操作系统应该满足使用更少的硬件资源去运行更加复杂的程序。
程序和资源的联系
首先,只要学习过嵌入式或者单片机我们就知道,对于源码只需要编译,然后将编译后的产物烧录到硬件上,他就会按照我们代码规定的顺序和方式去执行。也就是说,程序的执行,需要相应的内存、时间以及可用的CPU,也就是我们所说的资源。
什么是task
如果你学习过单片机比如stm32,那么你应该会经常遇到一种情况,我们会将我们的业务逻辑放在main中的一个while循环里来不断地执行,对于较为简单的操作,基本一个while循环中就可以满足我们的所有需求了。我们可以将任务非常粗暴地塞到这个while中执行,因为我们只有这些任务,而且都在while循环的逻辑中满足和实现了。
而在需求更为复杂的时候,我们经常会面临这样一种情况,由于我们会用到大量的硬件和外设去实现更为复杂的功能,所有功能已经不能再简单地耦合和绑定了,我们会明确地列出需求1,需求2,需求3,这里边每一个需求都可以单独拿出来用一个while循环来跑,而且他们由于需求的复杂性以及程序的要求,已经不能够将他们简单地放在一个while循环里跑了。如果强制放在一起,要么会导致需求无法实现,要么会导致性能和效率极其低下。那么我们就要跳脱出裸机开发的思维,用更高一层的角度来看这个问题,可不可以让这几个需求不在一个while里,我们多几个while循环,让这些个while循环按照我们想要的方式合理地使用我们有限的资源呢?而对于我们的每一个需求,也就是每一个while中的执行的内容,我们称为一个"task",也就是操作系统中的任务。
并发和并行
首先我们来讲并行。
并行
对于每个task,在实际运行时都需要开辟自己的线程,比如我们看cpu参数的时候经常会看到,这个cpu是多少多少线程,那个cpu是多少多少线程,有多少线程就代表它可以同时执行多少个任务,而对于裸机程序,我们只有一个while循环,也就是说在不引入操作系统的情况下,裸机程序就是一个单线程程序。
最理想的情况就是,当我们有这么多个task,那么最理想的情况肯定就是说我们让他们都运行,我才不想管什么复杂的时间管理和资源管理,既然有这么多任务,我就多给他们一些资源嘛,我每个task都分配一个线程给他,大家不需要争抢,在自己的线程上就有序地把任务跑就好了嘛。这种方式就叫做并行,资源足够充足,每个程序都能分配足够的资源和线程来完成任务。
并发
但是对于嵌入式编程来说,最明显的一点,就是我们所拥有的内存可能会很小,我们的cpu性能并不会非常强大,往往没有那么多线程提供给我们使用。那么问题就来了,我又没有那么多线程,又想让我的每个任务能够运行下去。你说这太难为人了,巧妇难为无米之炊啊,都没这些个线程你让我怎么跑嘛,跑不了啊。
所以我们就要跳脱出这个思维,所有程序同时执行,那肯定是执行不了的,但是能不能让每个task只执行一段时间,然后让他退下去,换其他task上来用资源执行一会,然后再换下去换下一个task上来,几个task共用一个线程来跑起来呢?这样大家都能在这样有限的资源下运行起来,只不过是没有原来高效而已。
这种设计就叫并发,由于嵌入式设备小巧集成和定制化,所以并行的情况并不多见,为了追求极致的资源利用和集成,我们会很经常地用到并发。
而对于这种让每个task占据一段时间和资源来运行的方式也叫分时处理。
对于分时这个词博主第一次听觉得很奇怪,什么是分时,当时并不能直接从字面上很好地理解。后来看到分时的英文Time share,用英文来理解就很直观了,所谓分时,就是将时间分享出来,把原本整块的时间线切成片来使用。
而时间片切下来后会分给许多task,每个task按照调度器的安排,在轮到他的时间片的时候就可以占用系统资源执行自己的任务了。
实时和分时
好,那么我们已经分清楚了并行和并发,那么什么是实时和分时呢?
我们先讲结论,实时和分时都是并发的基础上才有的,而且都采用时间片的处理方式,但是实时操作系统对实时性要求更高,分时操作系统对task公平性和进程吞吐量更加友好。
对于并行,我们不需要进行过多的管理,每个task都有自己的资源和不限制的时间,这种情况不需要管理,大家都很富裕。
而对于并发的情况下,就需要引入新的概念,也就是进程的调度和时间片的分配。
分时操作系统
分时操作系统更加在乎公平性和平衡性,提高同一时间内的进程的吞吐量,所以会相对均匀地给每个task都分配上时间,保证每个task都不会等待太久不被执行。
分时操作系统下,所有task虽然不能说是众生平等享受同样的待遇,但是每个task都有最基本的“人权”,要保证每一个正在执行的task都会在一定时间内会被执行一次,可能执行的慢一点,但是一定会执行,不会因为某些进程很紧急,就选择“饿死”其他进程,优先让高优先级进程占据所有资源。
这样的分配,从用户的角度上来看,就是所有的进程都在“同时”跑。人的感官是有延迟的,如果大家都在跑,但是每个进程只延迟零点几秒,那对于用户来说,整个系统给人的感觉都还是很快的,我的前端界面在运行的同时后端程序也没落下,感觉大家都在运行。
但是这样的设计初衷就会导致他的结构一定还是很复杂和庞大的,那么对于资源和算力就仍旧还有很大的要求和开支,这也是无法避免的,比如常见的分时操作系统有Linux、Windows等,都是些较为大型的操作系统。
实时操作系统
而对于实时操作系统来说,比如FreeRTOS,通常用在更为小型的单片机上,这类设备最大的特点就是资源会少很多,处理器性能会低很多,对于复杂的任务需求,他们根本满足不了并行所需要的资源开销。而嵌入式开发中的任务往往要结合具体硬件去进行数据采集和快速地响应,对于一些具体情境下的处理要做到高效精准。
举一个比较常见的例子就是我们常见的汽车上,其中刹车,气囊,转向等操作控制都是由一些单片机来实现相应操作的。那么对于这种情况我们可以简单地试想一下,如果还让他们和其他的音响,导航或者别的外设来按照分时操作系统共享时间片,那一定是非常危险的。
对于极端情况,这些紧急事件的处理优先级无疑应该排到最高,而且不能再遵守分时操作系统大家都不能“饿死”,都要享受“人权”的方式了。而是宁可饿死其他task,也要保证紧急task能够以最快,最准确,最保险的方式快速响应以确保他的实时性得以满足。
所以说对于实时操作系统,由于使用场景不同,实时操作系统更注重“实时性”,有着自己的中断和优先级处理准则,其核心准则是为了实现遇到紧急或者高优先级事件时能够做到高实时性处理和响应,所以极端情况会阻塞其他task来优先服务紧急和高优先级事件。
后记
对于实时操作系统和分时操作系统,他们没有本质的好与坏,也没有高级与低级之分,他们只是在不同的使用场景下各自发挥自己的特长和功能,要如何使用全凭设计师自身的设计
那么本篇的技术内容就结束了,主要也是分享一下博主看书的收获,目前看了一章多点,只能简单理解到这个程度,后续有新的理解也会考虑更新或者放在新的博客中进行补充,也欢迎各位有什么问题都来提问。
更多推荐


所有评论(0)