STM32-FreeRTOS快速学习

定义

FreeRTOS 满足实施系统对任务响应时间的要求。

实时操作系统、轻量级(内核小,只需要几KB的ROM和RAM)、

提供了一些内核功能,如任务管理、时间管理、内存管理和通信机制等。

和裸机的区别

裸机:无操作系统,直接操作系统,缺乏任务调度难以管理多任务。只能顺序执行任务

多任务管理:可以创建多个任务,通过时间片轮转算法进行任务切换。

任务管理

c 复制代码
# 裸机
void music()
void movie()
void main(){
	while(1){
		music();
		movie();
	}
}
# freeRTOS通过时间片轮转算法不断切换任务,实现了音画基本同步,提高了用户体验
void task1(){
	music();
}
void task2(){
	movie();
}
void main(){
	while(1){
		task1();
		taks2();
	}
}

提供内存管理、任务间通信机制

利用CUBMX快速配置FreeRTOS

freeRTOS需要使用systick滴答时钟作为系统提供时基,因此需要更换stm32内核的时基为其他定时器

生成多出的代码

osThreadDef 为FreeRTOS用于定于任务的宏
osThreadDef(name, thread, priority, instances, stacksz)

name为任务的名称,thread为任务的处理函数(函数指针,传入函数名即可),priority为任务的优先级,instances为任务的实例数,stacksz为任务的堆大小 栈

osThreadCreate用于创建任务的函数
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
thread_def为任务定义的指针,argument为传递给任务处理函数的参数

CUBMEX创建了一个默认的任务

在FreeRTOS.init中创建了任务

c 复制代码
  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

也创建了对应的任务处理函数

c 复制代码
/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}
# 上面defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL)中
# 传递参数为NULL,所以这里StartDefaultTask()里的argument也为NULL

手动创建第一个自己的任务

仿照CUBMEX创建的默认任务,在main.c中创建自己的任务,实现每 500ms led闪烁一次

c 复制代码
#导入头文件
#include "FreeRTOS.h"
#include "task.h"

osThreadId myTaskHandle;#任务句柄ID
void myTask1(void const * argument)
{
  for(;;)
  {
	  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	  osDelay(500);//每 500ms LED闪烁一次
  }
}

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  osThreadDef(myTask, myTask1, osPriorityNormal, 0, 128);
  myTaskHandle = osThreadCreate(osThread(myTask), NULL);

堆、栈、FreeRTOS里的任务栈

:操作系统里非常大的一块内存,比如malloc函数就是申请堆里的一块区域使用,不过不free释放,那么申请一块就少一块。

:存储局部变量和函数调用消息的数据结构。栈的大小在程序编译时确定,通常较小。

void func(){
}
int main(void){
	int a=0;
	int b=0;
	func();
	return 0;
}

执行完func()函数如何跳回主函数,这就使用到了栈。

堆的分配是动态的,由人决定;堆的分配是静态的,由编译器自动控制,编译时确定,运行时无法改变。

堆的分配效率低,需要运行时动态分配和释放。栈的分配效率高,由编译器编译时确定分配大小。

FreeRTOS里的任务栈:创建每一个任务都分配了一块栈空间,任务栈的大小在创建任务时指定,任务栈无需我们管理。

FreeRTOSCongfig.h(FreeRTOS的大总管)

该文件主要包含了各种宏定义,有功能宏、API宏...,可以对FreeRTOS灵活配置。详细可参考各种宏的说明

包含任务调度器、内存管理、时间管理、中断处理等方面的配置。

一部分如下图

常用比较重要的6个宏:
configUSE_PREEMPTION定义任务调度器的抢占式调度或者协同式调度。

为 1 时 RTOS 使用抢占式调度器,即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程;为 0 时 RTOS 使用协作式调度器(时间片)高优先级的进程不能中止正在内核中运行的低优先级的进程而抢占 CPU 运行。

configUSE_IDLE_HOOK 定义是否使用空闲任务钩子函数。

configUSE_TICK_HOOK 定义是否使用系统滴答钩子函数。c

configTICK_RATE_HZ 定义是否使用系统滴答频率。

configCPU_CLOCK_HZ 定义系统时钟频率。

configMAX_PRIORITIES 定义系统支持的最大任务优先级。

任务调度算法

多个任务的执行顺序、时间如何确定。

实时系统的调度需求:响应时间要要求、任务优先级、资源利用率。
FreeRTOS的任务调度算法分为抢占式调度算法(优先级抢占式调度算法、时间片轮转调度算法)、非抢占式调度算法(优先级调度算法、先来先服务调度算法)。

优先级抢占式调度算法:任务优先级越高执行的机会越大,相同时执行时间片轮转调度算法。 满足实时操作系统的响应要求、有优先级管理,缺点是优先级低的任务可能被长时间阻塞。

时间片轮转调度算法:每个任务被分配一个时间片,时间片用完后任务被挂起,等待下一次调度。 公平分配CPU时间片、避免优先级低的任务被长时间阻塞。 缺点无法满足实时操作系统的响应要求。

FreeRTOS默认开启优先级抢占式调度算法、时间片轮转调度算法结合使用。

利用CUBMX创建任务

可以看到生成的代码和手动配置的代码一样

相关推荐
日晨难再1 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
PegasusYu11 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
文弱书生65616 小时前
输出比较简介
stm32
黑客呀18 小时前
[系统安全]Rootkit基础
stm32·单片机·系统安全
小A15919 小时前
STM32完全学习——使用SysTick精确延时(阻塞式)
stm32·嵌入式硬件·学习
楚灵魈19 小时前
[STM32]从零开始的STM32 HAL库环境搭建
stm32·单片机·嵌入式硬件
小A15919 小时前
STM32完全学习——使用标准库点亮LED
stm32·嵌入式硬件·学习
code_snow21 小时前
STM32--JLINK使用、下载问题记录
stm32·单片机·嵌入式硬件
youcans_1 天前
【动手学电机驱动】STM32-FOC(8)MCSDK Profiler 电机参数辨识
stm32·单片机·嵌入式硬件·电机控制·foc
YuCaiH1 天前
【STM32】MPU6050简介
笔记·stm32·单片机·嵌入式硬件