FreeRTOS学习笔记(二)

📅 2026/7/1 2:30:51
FreeRTOS学习笔记(二)
FreeRTOS学习笔记二在STM32F407ZGT6上实现任务创建和删除前言为什么要引入操作系统在没有操作系统之前编写程序一直使用大while循环的方式来完成检查然后使用中断的方式进行异常处理。然而当任务增多时很难保证高优先级任务如紧急报警能够及时响应。并且随着单片机处理的工作增多while大循环中的控制逻辑越来越复杂到了最后连编写程序的本人也无法修改最后形成了一座shit山。为了解耦不同功能的程序和保证工作完成的实时性引入了操作系统例如freeRTOS。而引入嵌入式操作系统本质上是用“空间换时间”和“用架构换效率”。操作系统如何工作FreeRTOS 作为一个轻量级的实时操作系统RTOS其核心工作机制是围绕任务调度和系统时钟节拍展开的。本篇学习笔记主要围绕任务基础创建和删除展开。什么是任务简要来说任务可以理解为一段拥有自己独立执行环境和上下文的程序代码。打个比方来说如果把 单片机 比作一个厨师那么“任务”就是厨师手里正在做的一道道菜。厨师同一时间只能炒一道菜单核但他可以迅速切换去处理另一道即将出锅的菜任务切换在宏观上看起来就像是同时在做很多道菜一样。​ 开始烧菜时总要先开火菜出锅总要把装盘。在FreeRTOS 中任务的创建和删除就好比开火和装盘。用动态内存分配方法创建任务下面给出一个实例是在之前已经移植了freeRTOS的基础工程上创建两个任务LED0是每秒闪烁1次LED1是每秒闪烁2次。LED0闪烁10次后将LED任务删除让LED1不再闪烁。具体代码如下1.创建任务函数/* Led0Task 任务 配置 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务 */staticvoidLed0Task(void*pvParameters);/* 任务函数 */staticTaskHandle_t Led0TaskHandleNULL;/* 任务句柄 */#defineLed0Task_PRIO4/* 任务优先级 */#defineLed0Task_STK_SIZE128/* 任务堆栈大小 *//* Led1Task 任务 配置 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务 */staticvoidLed1Task(void*pvParameters);/* 任务函数 */staticTaskHandle_t Led1TaskHandleNULL;/* 任务句柄 */#defineLed1Task_PRIO4/* 任务优先级 */#defineLed1Task_STK_SIZE128/* 任务堆栈大小 *//** * brief Led1Task * param pvParameters : 传入参数 * retval 无 */staticvoidLed1Task(void*pvParameters){while(1){LED1_TOGGLE();vTaskDelay(pdMS_TO_TICKS(250));printf(LED1正在以0.5秒周期闪烁\r\n);}}2.定义任务句柄用vTaskCreate()创建任务/** * brief appStartTask * param 无 * retval 无 */voidappStartTask(void){taskENTER_CRITICAL();/*进入临界段关中断*/xTaskCreate((TaskFunction_t)Led0Task,/* 任务函数 */(constchar*)Led0Task,/* 任务名称 */(uint16_t)Led0Task_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)Led0Task_PRIO,/* 任务优先级 */(TaskHandle_t*)Led0TaskHandle);/* 任务句柄 */xTaskCreate((TaskFunction_t)Led1Task,/* 任务函数 */(constchar*)Led1Task,/* 任务名称 */(uint16_t)Led1Task_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)Led1Task_PRIO,/* 任务优先级 */(TaskHandle_t*)Led1TaskHandle);/* 任务句柄 */taskEXIT_CRITICAL();/*退出临界段开中断*/vTaskStartScheduler();/*开启任务调度器*/}3.用vTaskDelete函数释放内存/** * brief Led0Task * param pvParameters : 传入参数 * retval 无 */staticvoidLed0Task(void*pvParameters){uint16_tcnt0;while(1){LED0_TOGGLE();vTaskDelay(pdMS_TO_TICKS(500));printf(LED0正在以1.0秒周期闪烁\r\n);if(cnt10){if(eTaskGetState(Led1TaskHandle)!eDeleted)/*如果没有被删除*/{vTaskDelete(Led1TaskHandle);/*删除LED1闪烁任务*/printf(LED1任务已经被删除\r\n);}}}vTaskDelete(NULL);}main函数/* USER CODE BEGIN Includes */#includeled.h#includefreertos.h#includetask.h#includestdio.h#includefreertos_demo.h/* USER CODE END Includes */***brief The application entry point.*retvalint*/intmain(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */led_init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */appStartTask();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}运行结果/* Infinite loop//USER CODE BEGIN WHILE/while (1){/USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}运行结果 ![任务创建和删除](https://i-blog.csdnimg.cn/direct/18849ae17f874ba99b5b909ea701772c.jpeg#pic_center)