一、FreeRTOS介绍
FreeRTOS 是市场领先的嵌入式系统 RTOS,支持 40+ 处理器架构,内存占用小,执行时间快,具有尖端的 RTOS 功能和库,包括对称多处理 (SMP)、支持 IPv6 的线程安全 TCP 堆栈,以及与云服务的无缝集成。它是开源的,并得到积极支持和维护。
源代码可以在官方网址:https://www.freertos.org/,在里面进行下载,我是通过STM32CubeMX进行创建,就不通过移植和解释和了解内核了,有兴趣的可以自己去查资料,本文主要记录FreeRTOS的调用。
二、使用STM32CubeMX创建FreeRTOS项目
首先使用STM32CubeMX创建新项目,选择自己需要使用的芯片,我使用的是STM32C8T6
RCC按我设置就行
SYS设置,如果使用stlink下载或者调试,debug选择Serial Wire,时钟尽量不要选择SysTick和TIM1,SysTick是ARM Cortex-M内核自带的一个简易定时器,像一个“心脏起搏器”,每隔固定时间(通常是1ms)产生一次中断,当使用FreeRTOS后会被系统接管。SysTick作用很重要,一为HAL库提供时间基准二为操作系统提供心跳。而TIM1是高级寄存器,用来作为HAL的计时太过浪费。时基源尽量冲另外的TIm中使用,我选择的是TIM3。
然后更根据自己的使用情况配置相关的引脚
在左侧找到Middleware and Software Packs,选择FreeRTOS,如图所示:
我主频设置的最高,以最高速率运行。大家有需要更具自己的应用场景选择
然后设置一些基础,我就不过多介绍了,可以看我上片文章:https://blog.csdn.net/qq_52684099/article/details/153901792?spm=1011.2124.3001.6209
最后点击右上角的GENERATE CODE生成代码,然后如图直接打开项目就行了:
然后点击编译,基本是0错误0警告
三、FreeRTOS的简单使用和部分代码解释
1. 任务定义
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle; // 任务句柄,用于引用和控制这个任务
const osThreadAttr_t defaultTask_attributes = { // 任务的属性配置
.name = "defaultTask", // 任务名,调试时有用
.stack_size = 128 * 4, // 任务栈大小:128字 * 4字节/字 = 512字节
.priority = (osPriority_t) osPriorityNormal, // 任务优先级:普通优先级
}
(一)其中关于常用优先级结构体定义,后续添加任务更具需求使用,一般使用最多的优先级为以下几个,其他优先级可以去cmsis_os.h文件中看详细的解释。
priority = osPriorityLow; // 最常用的低优先级,一般用于后台任务、数据记录、统计信息
priority = osPriorityNormal; // 默认优先级,最常用,一般用于大部分普通任务、常规功能处理
priority = osPriorityHigh; // 高优先级任务,一般用于用户交互、通信处理、紧急事件
priority = osPriorityRealtime; // 最高优先级,慎用,一般用于电机控制、安全关键功能
(二)任务栈的大小的选择
更具自己的使用场景需要进行大小设置,此展示的为一般大小,已经可以满足大部分场合了。
2、任务添加和任务使用
以下为其中一个示例,比如在一个基础上添加一个led示例:
osThreadId_t ledTaskHandle;
const osThreadAttr_t ledTask_attributes = {
.name = "LedTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
在初始化中添加相关任务
void MX_FREERTOS_Init(void) {
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);//原有任务
/* 创建LED闪烁任务 */
ledTaskHandle = osThreadNew(StartLedTask, NULL, &ledTask_attributes);
// ... 其他代码
}
记得在最后添加多任务函数,一定要记得将函数在init前声明,
void StartLedTask(void *argument)
{
/* 任务主循环 */
for(;;)
{
osDelay(1000); // 延时1秒
}
}
3、freertos.h完整代码示例:
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "tim.h"
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
osThreadId_t ledTaskHandle;
const osThreadAttr_t ledTask_attributes = {
.name = "LedTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
void StartDefaultTask(void *argument);
void StartLedTask(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
void MX_FREERTOS_Init(void) {
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
ledTaskHandle = osThreadNew(StartLedTask, NULL, &ledTask_attributes);
}
void StartDefaultTask(void *argument)
{
for(;;)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 1500);
osDelay(1);
}
}
void StartLedTask(void *argument)
{
for(;;)
{
osDelay(1000);
}
}
(如有问题请指正)
————————————————
版权声明:本文为CSDN博主「爱学习嵌入式的小白」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_52684099/article/details/154174386
|
|