一.概述
RTOS(real time operation system)既实时操作系统。通俗来说,实时操作系统正如一个大管家一般,可以根据任务的要求,进行资源管理,消息管理,任务调度,异常处理等工作。在RTOS支持的系统中,
每个任务均有一个优先级,实时操作系统总是运行处于就绪态且最高优先级的任务,RTOS根据各个任务的优先级及任务状态,动态的切换各个任务,保证对实时性的要求。
实时操作系统允许多个任务同时执行,实际上,一个处理器核心在同一个时刻只能运行一个任务。操作系统中任务调度器的责任就是决定在某个时刻究竟执行哪个任务,任务调度在各个任务之间的切换非常快,给人造成同一时刻能运行多个任务的错觉。故学习实时操作系统的核心,就在于学习其任务调度方式。
二.裸机开发的缺陷
并发性差
程序并发工作效率低是因为在写裸机程序时,不可避免的会在主程序中有超级大的while(1)循环,这里面几乎包含项目的所有业务逻辑。因为每个业务逻辑中会有delay这样的循环等待函数,这样导致了所有业务逻辑几乎都是串行起来工作的。这个时候CPU会有很多时间都浪费在了延时函数里,一直在空转,导致软件的并发效率非常低。
模块化差,代码间耦合度高
从软件工程的角度,我们在做软件开发时,都会强度高内聚,低耦合的原则。而裸机的模块化来发难度非常大,模块间的耦合程度非常高,导致无法在大型项目中使用裸机开发。
还是刚才main函数中大while(1)的例子,可以想象这么多功能都紧紧的拥挤在主函数中,不可拆分,模块化开发困难重重。
举一个非常贴切的例子,在一些使用看门狗的项目中,如果使用delay延时函数,那得注意点,万一延时过长,主函数来不及喂狗,看门狗就被触发了。最后会产生这样一种感觉,一个简简单单的delay还得考虑喂狗功能,裸机开发时操的心太多了,自然无法应用在大型项目中。
生态:
很多高级的软件组件,必须依赖于操作系统来实现,无法在裸机上实现。
实时性差:功能复杂的条件下,实时性无法保证
软件的实时性在一些领域中会有很高的要求,软件的每个步骤必须在指定的时间被触发。工控领域就是最常见到的场景,如果实时性无法保证机械设备就可能无法按照指定的时序要求去动作,以至于发生机械事故,甚至威胁到人的生命,回过头来接着看裸机程序,如果的软件变得庞大时,主程序中那么大的一个while(1)循环,到处都是delay函数,代码耦合性严重,无法保证实时性。
可重复性:软件可重用性差,总是重复早轮子
可重用性与模块化程度有直接的关系,相信大家每个人在工作中都不想做很多重复性的工作,同样在写代码时,也想着今可能少写一些功能相似的代码,但在这个嵌入式碎片化极其严重的时代,各式各样的芯片,想要让同样的代码会过于依赖于底层硬件,重复造轮子的过程也无法避免。
三.操作系统带来的优势
线程的方式进行并发任务处理,解决模块化问题,同时保证实时性。
模块化
使用了操作系统后,整个软件的工作被拆分为多个任务来构成(也会称为线程),每个线程会有自己的独立运行空间,既称为线程堆栈,这时每个线程是你玩你的,我做我的,大家互不干涉,模块化程度得到很好的提高。
并发性
在并发的角度来看,各个线程在使用delay/事件等待这类函数时,会自动的让出CPU的使用权给其他需要的线程,不仅书写delay延时函数操的心少了,整个CPU的利用率也得到了提高,最终提高了并发性。
3.实时性
再来看实时性,像 ucos/RT-Thread 这些 RTOS 本身就被设计为实时的操作系统,各个线程都有不同的优先级别,重要的线程可以设为高优先级,不重要的线程可以降低优先级,做好全局的统筹规划后,这样整个软件的实时性也能得到保证。
4.开发效率
由于操作系统提供了统一的抽象接口层,方便了可重用组件的积累,提高开发效率。
操作系统其实是一群软件大牛们智慧的结晶,他们站在应用软件、底层驱动的开发角度,对很多常见的软件功能进行了封装、抽象,比如:信号量、事件通知、邮箱、环形缓冲区、单向链表/双向链表等等,这些功能拿来即用,对于开发者方便极了
还有一些操作系统,比如:Linux 和我们国产的 RT-Thread ,他们这些系统对碎片化的硬件,统一封装了一套标准的硬件操作接口,一般称为设备驱动框架。这样我们的应用软件工程师,就可以专攻应用的工作,再也不用怕更换硬件,又需要重复造轮子了。
四.操作系统代码框架初识
一个任务管理一个硬件
任务与任务或者任务与中断涉及到数据传输使用消息队列
任务间访问共享资间使用互斥锁
任务的同步使用信号量
标志位的管理使用事件标志组
编写一个专门初始化硬件的任务,该任务可以创建其它任务