5分钟学习笔记(FreeRTOS)(一) 📅 发布时间:2026/8/29 7:31:56 👁 浏览次数: 学习1.任务状态Running / Ready / Blocked / SuspendedRunning运行态表示当前任务正在占用 CPU 执行。Ready就绪态表示任务已经具备运行条件但是还未被调度器选中执行。由于有更高优先级任务正在运行或者同优先级任务还没轮到它所以暂时没有执行Blocked阻塞态表示任务正在等待某个时间到达或者等待某个事件发生。在阻塞期间任务不占用 CPU也不会被调度器选中运行。等时间到了或者事件发生了任务会重新进入 Ready 状态。等待延时结束等待队列数据等待信号量等待事件组等待任务通知等待互斥量例如例如vTaskDelay(100);任务会阻塞 100 个 tick。注意100 tick 不一定等于 100ms具体取决于系统 tick 周期再比如xQueueReceive(queue, data, 100);如果队列没数据任务会阻塞等待如果 100 个 tick 内还没等到数据就超时退出阻塞。Suspended挂起态表示任务被手动挂起后不会参与调度也不会因为超时自动恢复。只有调用 vTaskResume() 或 xTaskResumeFromISR() 才能恢复到 Ready 状态。2.任务为什么会阻塞因为任务调用了会等待的 FreeRTOS API主动让出 CPU去等待时间、资源或者事件。vTaskDelay();xQueueReceive();xSemaphoreTake();xEventGroupWaitBits();ulTaskNotifyTake();这些函数都可能进入阻塞态总结FreeRTOS任务不是一直占用CPU运行的。当任务需要等待延时、队列、信号量、事件组或任务通知时就会进入阻塞态。阻塞态任务不会消耗CPU调度器会去运行其他Ready任务。等事件发生或者等待超时后该任务再回到Ready态等待调度器重新调度。3. BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE uxStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pxCreatedTask);个人理解pvTaskCode任务函数入口地址任务函数通常是一个无限循环不能直接 return。如果任务不再需要运行应该调用 vTaskDelete() 删除自己。 例如void LED_Task(void *argument) { while(1) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); vTaskDelay(pdMS_TO_TICKS(500)); } }如果任务想删除自己vTaskDelete(NULL);vTaskDelete(NULL)不是删除空任务而是删除当前正在运行的任务自己pcName是任务的名称主要用于1. 调试 2. 任务列表显示 3. FreeRTOS Trace 工具显示uxStackDepth为任务分配的栈深度单位通常是 StackType_t不是字节。在 STM32 上 128 通常约等于 512 字节。注意这是 FreeRTOS 原生 xTaskCreate() 的规则如果用 CMSIS-RTOS 或 CubeMX 配置任务界面里的 stack size 可能按字节理解要看具体接口。pvParameters是传递给任务函数的参数指针。例如uint8_t led_id 1; xTaskCreate(LED_Task, LED, 128, led_id, 2, NULL);任务里接收void LED_Task(void *argument) { uint8_t id *(uint8_t *)argument; while(1) { // 使用 id } }注意如果传局部变量地址要小心变量生命周期。 led_id 是局部变量创建任务的函数退出后这个地址可能失效所以传给任务的参数最好是全局变量、static变量或者长期存在的结构体。uxPriority是任务的优先级数字越大优先级越高pxCreatedTask是一个输出参数用来保存创建成功后的任务句柄。xTaskCreate() 还有一个返回值BaseType_t常见返回值pdPASS任务创建成功 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY内存不足创建失败4.vTaskDelay() 作用vTaskDelay() 用于让当前任务进入阻塞态延时指定的 tick 数。延时时间到后任务从 Blocked 状态回到 Ready 状态延时时间到后任务从 Blocked 状态回到 Ready 状态等待调度器选中后才会重新进入 Running。。它是相对延时适合普通延时如果要实现严格周期任务应使用 vTaskDelayUntil()。5.Delay后任务去哪了任务在 Running 状态调用 vTaskDelay() 后会主动让出 CPU让其他 Ready 任务得到执行机会。本任务会进入 Blocked阻塞态在延时未结束前一直处于阻塞态不参与调度也不占用 CPU。当延时时间到了以后任务会从 Blocked 状态转为 Ready就绪态然后等待调度器调度只有被调度器选中后才会重新进入 Running运行态。总结一句话Running 是正在跑Ready 是能跑但没轮到Blocked 是等时间或事件Suspended 是被手动暂停。