FreeRTOS
字数
1006 字
阅读时间
4 分钟
一、任务切换
采用时间片轮转调度算法来实现不同任务之间的并发执行,当任务A被分配到的时间片耗尽,寄存器值都压入栈中,随后寄存器交由任务B在其时间片中使用 
当任务B时间片用尽后同理,任务B将寄存器值入栈,任务A在栈中的指令将会出栈,放回各寄存器中,恢复寄存器值,PC寄存器又回到了上次执行到的位置,在此次分配到的时间片中可以继续执行下面的指令 
二、任务状态
任务状态:用于划定任务的运行分配情况,决定哪个任务可以继续运行,哪个任务不需要运行
- 使用
osThreadNew函数创建任务后,任务会被FreeRTOS自动认为处于就绪态,等待被分配时间片并运行 - 当程序运行了osKernelStart系统内核启动,FreeRTOS就会从就绪态队列中取出一个任务并分配时间片,该任务就进入了
运行态
- 当时间片耗尽,FreeRTOS调度器就会将任务重新放回就绪队列的队尾

- FreeRTOS随后会分配时间片给下一个就绪队列中的任务,使其进入运行态运行

- 当处于
运行态的任务执行到了osDelay延时函数进行延时,即使该任务时间片未耗尽,也会将自己设为阻塞态,让出了CPU资源,调度器就会自动为下一个就绪任务分配时间片 为什么使用osDelay而不使用HAL_Delay,因为osDelay在延时时间内会自动阻塞,让出CPU,而HAL_Dealy则会一直占用CPU来运算比较当前是否到达延时时间

- 处于阻塞态的任务不参与时间片分配,除非延时时间结束,需要运行后续代码,调度器就会将该阻塞任务设置为就绪态,放入就绪队列队尾

- 如果任务需要等到某个输入才能继续执行,则自动阻塞
当该任务获取到了需要的输入数据,或者到了超时时间(任务阻塞时设置,防止死等),则回到就绪态队尾,继续等待时间片 
- 如果任务需要退出任务调度,则可以通过
osThreadSuspend函数进入挂起态,挂起态的任务也可以被其他任务通过使用osThreadResume函数重新启用
接下来看看具体项目

IDLE任务是空闲任务,当没有其他任务需要调度时,FreeRTOS就会自动执行IDLE,进行自动资源整理; Tmr Svc任务是定时器任务,用于处理FreeRTOS的定时器 这两个项目都是由FreeRTOS自动创建的
三、优先级和抢占式调度
FreeRTOS使用的是优先级调度算法,每个任务在创建时被赋予一个固定的优先级,如果低优先级在执行过程中,就绪队列加入了一个高优先级任务,那么高优先级任务可抢占低优先级任务。当多个相同优先级的任务同时就绪时,调度器采用时间片轮询的方式让它们轮流运行。每个任务运行一个固定的时间片(由系统节拍时钟 tick interrupt 定义),时间一到就切换到下一个同优先级任务,以此实现公平的CPU共享。 FreeRTOS的优先级数字越大,优先级越高。 STM32优先级是数字越小,优先级越高。