freeRTOS学习笔记
有错误请友好评论指出,查阅后会改正,谢谢。
freeRTOS
前言
记录我自己学习freeRTOS的历程(学习中,缓慢更新)
一、freeRTOS是什么?
RTOS是:RT(Real-Time)实时 OS操作系统 RTOS即实时操作系统。
二、freeRTOS的特点
1.实时性
• RTOS 能够保证重要的任务在规定的时间内得到响应和执行,满足实时系统的要求。
• 这种特性特别适合那些对时间敏感的应用,比如控制系统、医疗设备和航空航天领域
2.任务调度
• RTOS会按照任务的优先级和时间约束来进行调度,确保高优先级的任务比低优先级的任务优先获得CPU资源
• 它支持多种调度算法,例:优先级抢占、轮询等。
3.资源管理
• RTOS能够有效的管理内存、外设和其他系统资源。
• 它提供机制来分配和回收资源,预防死锁和资源竞争等问题。
4.中断管理
• RTOS能够快速响应中断,并且在正确处理中断返回后的任务状态。
• 有助于降低中断延迟,保证系统的实时响应。
5.可预测
• RTOS提供确定性的行为,即相同操作在相同时间内处理完成
• 对于需要基于时间精准控制的应用来说很重要。
6.可扩展与可维护
• RTOS通常是模块化设计,可以根据需要添加或移除任务
• 这样的设计有利于维护和升级,以适应不同需求。
7.可移植
• RTOS提供了标准接口和抽象层,以适应不同的平台
• 可在不同平台是移植运行,降低了开发的成本和维护难度
8.多任务支持
• RTOS中多任务运行,即单处理器可通过设置 短时间片 来“基本”同时完成不同操作。
• RTOS可多任务管理,所以支持任务间的通信和同步机制。
9.安全性
• RTOS具有安全特性,例:隔离机制、访问控制以及加密支持等。
• 对于设计到敏感数据的设备非常合适。
二、freeRTOS的任务
1.任务调度
freeRTOS的调度器会根据不同的调度算法来执行当前任务。
freeRTOS支持三种不同的调度方式:
-
抢占式调度:主要针对优先级不同的任务
-
高优先级任务抢占低优先级任务运行。
-
高优先级任务不停止,低优先级任务无法运行。
-
被抢占CPU的任务会进入就绪态。
-
-
时间片调度:主要针对优先级相同的任务,根据时间节拍切换运行每一个任务。
-
同等优先级任务,按照时间片流转,轮流执行。
-
一个时间片的大小取决于滴答定时器的中断频率
-
任务中途被打断或阻塞,没有用完的时间片不会被使用,再次到该任务执行时,获得新的时间片
-
-
协程式调度:轮询,目前的freeRTOS还支持,但官方已不再维护升级。
2. 任务状态
freeRTOS存在四个任务状态
-
就绪态:正在执行的任务。在stm32中,同一时间 __`仅`__ 一个任务运行。
-
执行态:可以执行,但还没有轮到该任务执行
-
阻塞态:因延时或 __`等待`__ 外部事件发生
-
挂起态:类似暂停,调用函数vTaskSuspend() 进入挂起态,调用解挂函数vTaskResume() 进入就绪态
-
注:仅就绪态可转为执行态,其他状态想运行须先转为就绪态。
其中三种任务状态具有任务列表
-
就绪列表 pxReadyTasksLists[X],X代表优先级
-
阻塞列表 pxDelayedTaskList
-
挂起列表 xSuspendTaskList
三、freeRTOS的移植(更新不完整,持续更新中)
到FreeRTOS官网找到下载图标,下载不带LTS的版本
得到压缩包解压后,一般为以下目录
目录名 | 描述 |
---|---|
FreeRTOS | FreeRTOS内核 |
FreeRTOS Plus | FreeRTOS组件 |
tools | 工具 |
GitHub-FreeRTOS-Home | FreeRTOS的GitHub仓库链接 |
Quick_Start_Guide | FreeRTOS快速入门指南官方文档链接 |
Upgrading-to-FreeRTOS-xxx | 升级指定的FreeRTOS版本的官方文档链接 |
History.txt | FreeRTOS的历史更新记录项目 |
FreeRTOS目录
目录名 | 描述 |
---|---|
Demo | FreeRTOS演示例程 |
License | FreeRTOS相关许可 |
Source | FreeRTOS源码 |
Test | 公用与移植层代码 |
Source目录(必要文件已加红)
目录名 | 描述 |
---|---|
include | FreeRTOS头文件 |
portable | FreeRTOS移植文件 |
croutine.c | 协程相关文件 |
event_groups.c | 事件组相关文件 |
list.c | 列表相关文件 |
queue.c | 队列相关文件 |
stream_buffer.c | 流式缓冲区相关文件 |
tasks.c | 任务相关文件 |
timers.c | 软件定时器相关文件 |
进入
portable目录(目前了解到的是stm系列的MDK开发,故移植这部分文件,后期学会其他的,再更新)
目录名 | 描述 |
---|---|
keil | 指向RVDS文件夹 |
RVDS | 不同内核芯片的移植文件 |
MemMang | 内存管理文件 |
四、freeRTOS的函数
动态创建任务函数
xTaskCreate();
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode, // 指向任务函数的指针
const char *const pcName, // 任务的名称,用于调试和跟踪
const uint16_t usStackDepth, // 任务栈的深度,以 "字" 的数量来指定
void *const pvParameters, // 传递给任务函数的参数
UBaseType_t uxPriority, // 任务的优先级 范围 0 ~ maxSize-1
TaskHandle_t *const pxCreatedTask // 指向一个变量的指针,该变量用来存储新创建任务的句柄,就是任务控制块
);
返回值
类型:通常定义为 typedef signed char BaseType_t;
BaseType_t 是一个枚举类型。
描述:一般来说如果任务成功创建,函数返回 pdPASS;如果失败,则返回 pdFAIL。
此函数创建的任务会立即进入就绪态,由任务调度器运行
- 注:8位系统 一个字=一个字节=8位,32位系统 一个字=四个字节=32位
静态创建任务函数
xTaskCreateStatic();
TaskHandle_t xTaskCreateStatic(
TaskFunction_t pxTaskCode, // 指向任务函数的指针
const char * const pcName, // 任务的名称,用于调试和跟踪 /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth, // 任务栈的深度,以 "字" 的数量来指定
void * const pvParameters, // 传递给任务函数的参数
UBaseType_t uxPriority, // 任务的优先级 范围 0 ~ maxSize-1
StackType_t * const puxStackBuffer, // 任务堆栈大小由用户分配,一般为数组
StaticTask_t * const pxTaskBuffer // 任务控制块指针,任务的句柄
);
返回值
描述:如果任务成功创建,返回句柄;如果失败,表明用户没有返回相应内存,则返回 NULL。
删除任务函数
vTaskDelete();
任务控制块TCB
指定任务的特征、属性等,相当于任务的“身份证”
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; // 任务栈顶指针
ListItem_t xStateListItem; // 任务状态列表项
ListItem_t xEventListItem; // 事件列表项
UBaseType_t uxPriority; // 任务优先级
StackType_t *pxStack; // 任务栈起始地址
char pcTaskName[ configMAX_TASK_NAME_LEN ]; // 任务名字
// 其他成员...
} tskTCB;