目录
一、为什么要学习FreeRTOS
二、前言------从0到1认识FreeRTOS
1、逻辑系统与多任务系统
1.1、裸机系统:裸机系统通常分成轮询系统和前后台系统
1.2、多任务系统
2、数据结构-列表与列表项
三、任务
3.1基本属性
3.1.1任务栈
3.1.2任务控制块
3.1.3任务成员
3.2状态
四、机制
4.1任务优先级
4.1.1高优先级抢占低优先级
4.1.2时间片
4.2任务调度器
4.3临界段的保护
4.4空闲任务与阻塞延时
五、API函数
写这篇文章的目的有两个。1、方便初学者快速的入门;2、对自己这一阶段的学习进行一个阶段性的小结。
因为笔者也不过是个短时间的初学者,难免会有疏漏和差错,仅供参考。同时也欢迎大佬批评指教。不吝赐教 。
一、为什么要学习FreeRTOS
当我们进入嵌入式这个领域的时候, 往往首先接触的都是单片机编程, 单片机编程又
首选 51 单片机来入门。 这里面说的单片机编程通常都是指裸机编程,即不加入任何 RTOS
(Real Time Operating System 实时操作系统) 的程序。在裸机系统中,所有的程序基本都是自己写的, 所有的操作都是在一个无限的大循环里面实现。现实生活中的很多中小型的电子产品用的都是裸机系统, 而且也能够满足需求。
但是为什么还要学习 RTOS 编程,偏偏还要整个操作系统进来。一是项目需要,随着产品要实现的功能越来越多,单纯的裸机系统已经不能够完美地解决问题,反而会使编程变得
更加复杂,如果想降低编程的难度, 我们可以考虑引入 RTOS 实现多任务管理, 这是使用
RTOS 的最大优势。二是学习的需要,必须学习更高级的东西,实现更好的职业规划,为
将来走向人生巅峰迎娶白富美做准备,而不是一味的在裸机编程上面死磕。作为一个合格
的嵌入式软件工程师,学习是永远不能停歇的事,时刻都得为将来准备。书到用时方恨少,
我希望机会来临时你不要有这种感觉。
二、前言------从0到1认识FreeRTOS
1、逻辑系统与多任务系统
1.1、裸机系统:裸机系统通常分成轮询系统和前后台系统
1.1.1轮训系统
轮询系统即是在裸机编程的时候,先初始化好相关的硬件,然后让主程序在一个死循环里面不断循环,顺序地做各种事情,轮询系统是一种非常简单的软件结构,通常只适用于那些只需要顺序执行代码且不需要外部事件来驱动的就能完成的事情。如果只是实现 LED 翻转,串口输出,液晶显示等。
这些操作,那么使用轮询系统将会非常完美。但是,如果加入了按键操作等需要检测外部信号的事件,用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。当一个按键事件发生时,程序刚好运行到一个函数,要命的是这个函数要执行的时间还很久,久到按键释放之后都还没有执行完毕,那么按键时间就会丢失。可以看见轮训系统只适合顺序执行的功能代码。
1.1.2前后台系统
相比轮询系统,前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台, main 函数里面的无限循环我们称为后台。
在顺序执行后台程序的时候,如果有中断来临,那么中断会打断后台程序的正常执行流,转而去执行中断服务程序,在中断服务程序里面标记事件,如果事件要处理的事情很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台程序里面处理。虽然事件的响应和处理是分开了,但是事件的处理还是在后台里面顺序执行的,但相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力。在大多数的中小型项目中,前后台系统运用的好,堪称有操作系统的效果。
1.2、多任务系统
相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。在多任务系统中, 任务跟中断一样,也具有优先级,优先级高的任务会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的任务的优先级足够高,就会立马得到响应。相比前后台系统,多任务系统的实时性又被提高了。
相比前后台系统中后台顺序执行的程序主体,在多任务系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为任务。每个任务都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流,不用担心每个功能模块之间是否存在干扰。加入了操作系统,我们的编程反而变得简单了。整个系统随之带来的额外开销就是操作系统占据的那一丁点的 FLASH 和 RAM。现如今,单片机的 FLASH 和 RAM 是越来越大,完全足以抵挡 RTOS 那点开销。
无论是裸机系统中的轮询系统、前后台系统和多任务系统,我们不能一锤子的敲定孰优孰劣,它们是不同时代的产物,在各自的领域都还有相当大的应用价值,只有合适才是最好。
2、数据结构-列表与列表项
在 FreeRTOS 中存在着大量的基础数据结构列表和列表项的操作,要想读懂 FreeRTOS的源码或者从 0 到 1 开始实现 FreeRTOS,就必须弄懂列表和列表项的操作。在FreeRTOS中的列表就等同于C语言中的链表。
链表作为 C 语言中一种基础的数据结构,在平时写程序的时候用的并不多,但在操作系统里面使用的非常多。链表就好比一个圆形的晾衣架, 具体见图, 晾衣架上面有很多钩子,钩子首尾相连。链表也是,链表由节点组成,节点与节点之间首尾相连。晾衣架的钩子本身不能代表很多东西,但是钩子本身却可以挂很多东西。同样,链表也类似,链表的节点本身不能存储太多东西,或者说链表的节点本来就不是用来存储大量数据的,但是节点跟晾衣架的钩子一样,可以挂很多数据。
链表又分为单向链表和双向链表
单向链表
双向链表
对于链表的操作无非就是增删改查,这里不过多讲解。
链表与数组的对比
在C语言中,链表和数组确实很像。但是二者又完全不同
链表是通过节点把离散的数据链接成一个表,通过对节点的插入和删除操作从而实现对数据的存取。而数组是通过开辟一段连续的内存来存储数据,这是数组和链表最大的区别。 数组的每个成员对应链表的节点,成员和节点的数据类型可以是标准的 C 类型或者是用户自定义的结构体。数组有起始地址和结束地址,而链表是一个圈,没有头和尾之分,但是为了方便节点的插入和删除操作会人为的规定一个根节点。