欢迎光临散文网 会员登陆 & 注册

使用RTOS做单片机开发有什么优势

2020-09-15 23:49 作者:奥大梨呀  | 我要投稿


    随着单片机性能的提高,逐渐诞生了一些轻量级的操作系统,可以在MCU上运行,这样的操作系统被称为实时操作系统(Real Time Operating System),简称RTOS。尽管RTOS如此的轻巧(一些RTOS裁剪过后仅10几KByte),但“麻雀虽小,五脏俱全”。操作系统所包含的基本元素RTOS都具备,比如任务调度、信号量、消息队列等。那么在程序开发时使用RTOS有什么优势呢,就以笔者的亲身经历来介绍吧。由于笔者接触到的第一个RTOS是uCOS-III,常用的也是这款RTOS,因此本文主要以uCOS-III为例子来介绍RTOS的优势。

    首先先简述一下裸机的开发方式,一般情况下一个裸机程序通常分为两个部分,一个大循环和若干个中断服务程序,也称为前后台系统,其中前台指的是各种中断所执行的任务,一般是设置一些标志位。而后台则是一个无限循环,主要根据标志位来执行相关的任务,以及管理系统的资源。

 

前后台系统简单模型

    在前后台系统下,所有的任务的优先级是平等的,且是以FIFO的方式排列。也就是说,后面的任务必须等待前面的任务都完成之后才可以执行。在前后台系统下,实时性非常差,而且随着任务数量的增多,实时性会愈差。就好像我们上课时突然内急(非常急),需要立刻去WC,但是却不得不等到下课。这种情况下大概率会发生什么样的事情相信大家应该也猜得到吧。在程序上表现出来可能就是数据丢失,或者响应慢(比如步进电机过冲)等效果了。

    尽管也可以利用定时器等手段去手动分配时间片来增强实时性,但这样的方法容易造成程序的高度耦合,与程序开发的“高内聚,低耦合”相悖,这样的代码肯定是很难管理和维护的。笔者在厂里修改一个别人写的程序时(主要是添加功能),亲切的体会到了这一点。 该代码是一个非常标准的前后台系统,其中还利用定时器划分了一些时间片来执行相关任务。可仅仅在main函数所在的C文件中就定义了十几个flag标志变量,笔者在读代码时也是花费了不少功夫。再加上一些外设在大循环和定时器中断中都有可能被访问,协调不好就容易造成错误。

    再说说RTOS。在RTOS下进行程序开发,每个任务都是独立运行的一个有限次或无限次循环,一般情况下不会互相影响(除非栈溢出等因素),因而很容易管理和维护。每个任务都可以设置优先级,RTOS的内核大多都是可抢占式的。高优先级的任务一但就绪就可以夺走低优先级任务的CPU使用权,实时性相比于前后台系统大幅度提高。而且RTOS会提供一些内核对象供用户使用,比如信号量,常用作任务同步和共享资源保护等。

抢占式内核任务调度模型

 

下图就是一个在uCOS-III操作系统下让LED以500ms的周期闪烁的任务。

 

LED闪烁任务

    当然,RTOS还包含任务休眠的机制,比如当一个任务需要等待某个发生频率不高的事件时(如按键按下,或者延时一段时间),就可以令这个任务暂时休眠,休眠的任务不会再占用CPU的时间,待事件发生时(按键按下,或者延时时间到),将这个任务唤醒即可。不需要像前后台系统那样,需要不断地查询标志位。

下图就是利用任务内建消息队列和休眠机制来进行任务间通信的例子。

 

任务内建消息队列实现任务间通信

    如果利用操作系统中的进程和线程的概念来类比RTOS,那么整个程序可以看成一个进程,每个任务可以看成是线程。因为整个程序包含且管理所有的系统资源,而每个任务仅包含自己的栈空间,共享系统资源,CPU在任务之间进行调度。这不正是符合进程和线程的概念吗。因此在RTOS中,任务也被称为线程。

    再用信号量举两个例子。信号量做任务同步就好比泡咖啡,首先肯定要烧水,泡咖啡肯定是需要等待水烧开才可以进行,因此在水没烧开之前。泡咖啡可以暂时放着不管,对应的就是请求信号量(请求一杯泡咖啡用的开水),请求不到而暂时休眠任务。当水烧开时,水壶开关断开,我们听到开关断开的声音后,就会拿开水去泡咖啡,对应的就是释放一个信号量(把一杯开水拿过来),然后操作系统会唤醒先前休眠的任务(泡咖啡),在没有其他更高优先级任务的时候,就会执行这个任务(泡咖啡)。这样就实现了一个任务之间同步的效果。

    而共享资源的保护就好比一个公厕,每次只能进去一个或若干个人,进去的人会将门锁上,对应的就是请求信号量,当公厕人满了之后,后面的人肯定就不能进去了,对应的就是其他任务请求不到信号量。那么外面的人就需要等待有人出来才能进去,对应的就是正在使用共享资源的任务释放信号量(厕所里的人开门出来)。这样也就实现了对共享资源的保护了。

    我们现在再从RTOS的角度看刚才笔者所说的例子。如果采用RTOS,那么只需要创建若干个任务,任务之间使用消息队列进行通信或者信号量同步,使用信号量或者互斥锁对共享资源进行保护,再设置每个任务的优先级,让重要且紧急的任务可以第一时间得到执行。这么看来,明显降低了程序的耦合性,程序就好管理多了。而且后期添加功能也很方便,只需要再创建任务即可。

    当然,RTOS的优势还不止如此,笔者如今做MCU项目时基本上都采用RTOS进行程序开发。在能够熟练使用RTOS提供的内核对象进行程序开发后,你会发现,其实采用RTOS开发的难度会远低于裸机开发,随着项目复杂度的提高,RTOS带来的优势将会更明显。

    在现在这个时代,一个合格的单片机工程师通常都要求至少需要掌握一款RTOS。毕竟,这是单片机开发的发展趋势。而且根据笔者的学习经验,掌握RTOS的相关知识对往后学习Linux开发(驱动或应用)有着非常大的帮助,在学习Linux开发时会感觉到非常亲切,容易上手而且更有学习动力。

    当然也不是非得使用RTOS不可,一切均要视具体项目而定。笔者这里只是说明了RTOS相比裸机开发的一些优势。

    以上内容为笔者个人拙见,若有不合理之处还请批评指正。


使用RTOS做单片机开发有什么优势的评论 (共 条)

分享到微博请遵守国家法律