sparrow是笔者开发的一款极小型RTOS,代码仅有400行,但是作为一个RTOS内核,笔者认为它是合格的,读者可以将它看成是一个mini版本的FreeRTOS内核,它实现了动态内存管理、阻塞延时、多线程、临界区、优先级、低功耗空闲任务等功能,与FreeRTOS内核相比,它的遗憾是同优先级(时间片)没有实现。
可能读者有些难以置信,要知道FreeRTOS仅仅包括内核和队列、信号量这些应用就有两万行左右的代码,单把内核拿出来,里面的一个tasks.c文件就有五六千行,甚至不说多线程了,光一个heap4.c文件实现动态内存管理就远远超过400行了。sparrow单凭400行代码完成动态内存都够呛,怎么可能完成这一庞大的任务呢?
请听笔者细细解释,FreeRTOS作为一个开源且被大量商用的RTOS,可不仅仅是实现功能就够了,它还要根据不同的应用场景选择同一种功能的不同形式,例如:创建任务就包括动态内存创建任务和静态内存创建任务。更别说,为了提供足够的稳定性,FreeRTOS更是在大量的关键代码处添加assert(断言)来判断一些内存溢出问题或者其他问题,例如在我们使用pvPortMalloc时,它还要判断传入pvPortMalloc的申请值是否大于0,这是为了稳定性而做出的让必要牺牲。
但是,笔者的Sparrow作为一个学习用途的极微型RTOS,它的目的是为了方便读者学习RTOS内核的本质,学习操作系统、arm架构以及gnu c等知识,所以它的要求就是实现基本的功能,以及:能跑就行!
不过极度的简洁是有代价的,要知道实现一个链表以及基本的增删查改操作,就要超过四百行代码了,为此,笔者决定直接放弃链表,所以,同优先级的时间片是无法实现了。
现在笔者将sparrow和FreeRTOS内核进行对比:
FreeRTOS内核基本功能:多线程、多优先级、临界区、自定义空闲任务、阻塞延时、动态内存管理、同优先级下的时间片
sparrow基本任务:多线程、多优先级、临界区、自定义空闲任务(默认是进入低功耗模式)、阻塞延时、动态内存管理
现在对各个子模块功能进行对比:
多线程:sparrow最大支持32个线程,FreeRTOS可自定义最大个数,且远远超过sparrow。
多优先级:sparrow使用arm架构提供的指令获得最高优先级,只有一种调度算法,而且依赖于arm架构,FreeRTOS提供多种调度算法查找最高优先级,不依赖具体架构。
临界区:FreeRTOS内核的临界区有多种版本,例如带中断保护版本和不带中断保护版本,Sparrow只有一种,使用方法与FreeRTOS带中断保护版本相同,但是在临界区代码中加入了一层保护。因为FreeRTOS的临界区并不是强制性的原子操作,有被打断的风险,甚至临界区的建立都可能被打断。Sparrow的创建临界区的代码执行是原子性的,但是临界区的区域与FreeRTOS相同,是可选择性屏蔽中断的。
自定义空闲任务:该任务是RTOS无其他任务就绪时才运行的任务,两种RTOS的空闲任务都是可自定义的,所以没什么区别。
阻塞延时:sparrow在任务查找任务延时是否到时间,选择的是遍历全部优先级,而FreeRTOS只对加入延时列表的任务进行遍历,更加灵活。
动态内存管理:sparrow的内存管理算法与FreeRTOS的heap4.c采用的策略是一模一样的,都是小内存管理算法。FreeRTOS因为加入大量assert防止内存溢出等等问题,更加稳定。
任务的挂载:FreeRTOS采用链表挂载任务控制块,而sparrow使用数组并使用任务优先级作为数组下标查找任务,更加简洁。
以上就是两者对比,其实也没啥可比性, 因为sparrow的简洁性和可学习性才是首要目标,而不是功能性。
sparrow源码地址:skaiui2/SKRTOS_sparrow at source (github.com)