RTOS概念
RTOS 全称是 Real Time Operating System,中文名就是实时操作系统,提供了任务调度、内存管理、中断处理等功能。
1. 任务调度:裸机编程需要手动调
度任务,而RTOS提供自动的任务调度器。
2. 硬件管理:裸机编程需要开发者手动管理硬件资源,RTOS提供了抽象接口,简化了硬件管理。
3. 复杂性:裸机编程相对较复杂,需要深入了解硬件细节。RTOS提供了更高层次的抽象,简化了开发流程。
这些目前看不懂,先往后学,等学着学着就理解了。了解就行
FreeRTOS优势
FreeRTOS是一款受欢迎、广泛应用于嵌入式系统的RTOS,其开源、轻量级、可移植的特点使其成为许多嵌入式开发者的首选,主要优势如下:
- 开源和免费:FreeRTOS是一款开源的RTOS,采用MIT许可证发布,可以免费使用、修改和分发。
- 轻量级设计:FreeRTOS注重轻量级设计,适用于资源受限的嵌入式系统,不占用过多内存和处理器资源。
- 广泛应用:FreeRTOS在嵌入式领域得到广泛应用,包括工业自动化、医疗设备、消费电子产品、汽车电子等。
- 多平台支持:FreeRTOS的设计注重可移植性,可以轻松地移植到不同的硬件平台,支持多种处理器架构。
- 丰富的功能:提供了多任务调度、任务通信、同步等功能,适用于复杂的嵌入式应用场景。
任务调度
一个处理器核心(CPU)在某一时刻只能运行一个任务,如果有多个任务,那CPU该执行哪一个呢?这就是调度器的作用。
这就好比排队买奶茶,一个人相当于一个任务,做奶茶相当于CPU正在执行任务,这里假设只有一个人做奶茶的情况,也就是一个CPU。
店里没人,一个人去买奶茶,那店员则可以直接做。
很多人去买奶茶,这个时候就需要排队,不然谁都能插队了这个时候谁受得了。
排队就是一种调度算法,先来先服务。
假如奶茶店实行会员制,有会员vip可以插队,这就相当于它的优先级高,可以插队先做奶茶也就是先执行任务。
这种插队规则,也就是抢占式调度,优先级高的,先执行任务(VIP)。
操作系统中任务调度器的责任就是决定在某一时刻要执行哪个任务。
FreeRTOS 支持三种任务调度方式:
- 抢占式调度
- 时间片调度
抢占式调度
主要是针对优先级不同的任务,每个任务都有一个优先级,优先级高的任务可以抢占优先级低的任务。
1、创建三个任务:Task1、Task2、Task3
2、Task1、Task2、Task3的优先级分别为1、2、3;
3、在FreeRTOS中任务设置的数值越大,优先级越高,所以TASK3的优先级最高。
1、首先Task1在运行中,t1时刻Task2就绪了,在抢占式调度器的作用下Task2会抢占Task1,此时CPU执行Task2。就绪简单理解为,什么都准备好就差CPU了,万事俱备只欠东风。
2、Task2运行过程中,t2时刻,Task3就绪了,在抢占式调度器的作用下Task3会抢占Task2的运行。
3、Task3运行过程中,t3时刻Task3阻塞了(系统延时或等待信号量等),此时就绪态中,优先级最高的任务Task2执行。阻塞简单理解为,用上述奶茶的例子,做奶茶突然差了一种材料,得等材料到了才能继续做奶茶
4、t4时刻,Task3阻塞解除了(延时到了或者接收到信号量),此时Task3恢复到就绪态中,抢占TasK2的运行。(阻塞解除指的是奶茶材料来了,店员继续做奶茶)
时间片调度
主要针对优先级相同的任务,当多个任务的优先级相同时,每个任务执行一个时间片,如果有其他同优先级的任务等待执行,则切换到下一个任务。
同等优先级任务轮流地享有相同的 CPU 时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick 中断周期。
1、首先Task1运行完一个时间片后,切换至Task2运行
2、Task2运行完一个时间片后,切换至Task3运行
3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等),此时直接切换到下一个任务Task1
4、Task1运行完一个时间片后,切换至Task2运行
时间片调度公平地、轮流地为各个任务服务,让每一个任务在一定时间间隔内都可以得到相应。
注意:
- 一个时间片大小,取决为滴答定时器中断周期
- 注意没有用完的时间片不会再使用,下次任务Task3得到执行,还是按照一个时间片的时钟节拍运行
任务状态
FreeRTOS中任务共存在4种状态
- 运行态
正在执行的任务,该任务就放处于运行态 - 就绪态
如果该任务已经能够被执行,但当前还未被执行,就差CPU,那么该任务处于就绪态 - 阻塞态
如果一个任务因延时或等待外部事件发生,那么这个任务就处于阻塞态 - 挂起态
类似暂停,调用函数vTaskSuspend0进入挂起态,需要调用解挂函数VTaskResume()可以进入就绪态。
其他状态很容易理解,但为什么要有挂起状态呢?
在于暂时停止进程的执行,以便于系统进行资源管理和调度,或者为了释放资源或优化系统性能。
1.系统有时可能会出现故障或某些功能受到损坏,这时就需要暂时将系统中的进程挂起,以便于系统故障消除后,再将这些进程恢复到原来状态。
2.用户检查自己作业的中间执行情况和中间结果时,应同预想想法不符而产生后,这时用户要求挂起进程,以便进行某些检查和改正。
3.系统中有时负荷过重(进程数过多),资源数相对不足,从而造成系统效率下降。此时需要挂起一部分进程以调度系统负荷,等系统中负荷减轻后在恢复被挂起进程的执行。
4.在操作系统中引入了虚拟存储管理机术后,需要区分进程是驻留在内存还是外存,此时可以用挂起表示驻留在外存。
这四种状态中,除了运行态(32单片机,同一时刻只能执行一个任务),其他三种任务状态的任务都有其对应的任务状态列表:
- 就绪列表:pxReadyTasksLists[x],其中x代表任务优先级数值。
- 阻塞列表:pxDelayedTaskList。
- 挂起列表:xSuspendedTaskList。
注意:
- 只能从就绪态–>运行态(简单理解,阻塞态和挂起态都是因为任务有事才变为的状态,事情还没处理完就直接运行,这不太好吧)
- 其他状态的任务想运行,必须先转变成就绪态
就绪列表中,如果在32位的硬件中,会保存一个32位的变量,代表0-31的优先级。当某个位,置一时,代表所对应的优先级就绪列表有任务存在。
就绪列表怎么理解呢?
相当于一个数组,里面有32个元素,每个元素是一个链表,链表上的每一个节点是一个任务。
机器想要找到优先级高的,只需要从高位开始找哪一个为1,找到哪一个为1,就可以找到对应的数组元素,就可以找到链表,然后执行该链表里的任务。