<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Freertos 学习 on Mortal</title><link>https://041101.xyz/categories/freertos-%E5%AD%A6%E4%B9%A0/</link><description>Recent content in Freertos 学习 on Mortal</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>Mortal © 2026</copyright><lastBuildDate>Sat, 28 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://041101.xyz/categories/freertos-%E5%AD%A6%E4%B9%A0/index.xml" rel="self" type="application/rss+xml"/><item><title>freertos学习</title><link>https://041101.xyz/p/freertos%E5%AD%A6%E4%B9%A0/</link><pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate><guid>https://041101.xyz/p/freertos%E5%AD%A6%E4%B9%A0/</guid><description>&lt;h1 id="1基本概念"&gt;1.基本概念
&lt;/h1&gt;&lt;h2 id="一内核kernel"&gt;一、内核（Kernel）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;管理所有任务、分配 CPU 资源、处理中断、提供系统 API（如任务创建 / 延时 / 队列）&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;可以实现抢占式，&lt;code&gt;configUSE_PREEMPTION=1&lt;/code&gt; 开启&lt;/li&gt;
&lt;li&gt;可裁剪通过 &lt;code&gt;FreeRTOSConfig.h&lt;/code&gt; 宏定义开启/关闭，适配不同的mcu&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="二任务task"&gt;二、任务（Task）
&lt;/h2&gt;&lt;p&gt;RTOS中最小执行单元，对应独立的、无限循环的C函数，实现一个具体的业务功能&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;void vTaskUART(void *pvParameters)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; for(;;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;多状态切换&lt;/strong&gt;：任务在运行过程中会被内核切换为不同状态，核心状态有 4 种&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;运行态&lt;/strong&gt;：当前正在占用 CPU 执行的任务（同一时间只有一个任务处于运行态）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;就绪态&lt;/strong&gt;：任务已准备好执行，等待 CPU 资源（如你的串口任务被唤醒后，进入就绪态立即抢占 CPU）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阻塞态&lt;/strong&gt;：任务因等待某个事件而暂停（如&lt;code&gt;vTaskDelay&lt;/code&gt;延时、&lt;code&gt;xQueueReceive&lt;/code&gt;等待队列数据），不占用 CPU；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;挂起态&lt;/strong&gt;：任务被手动挂起（&lt;code&gt;vTaskSuspend&lt;/code&gt;），需手动恢复（&lt;code&gt;vTaskResume&lt;/code&gt;），同样不占用 CPU。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="三任务控制块tcb---task-control-block"&gt;三、任务控制块（TCB - Task Control Block）
&lt;/h2&gt;&lt;p&gt;为每个任务分配一个结构体，存储任务的核心信息，内核通过操作TCB来管理任务(创建、调度、切换、删除)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;typedef struct tskTaskControlBlock {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; StackType_t *pxTopOfStack; // 任务栈的栈顶指针（核心，任务切换的关键）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ListItem_t xStateListItem; // 任务状态链表项（用于将任务加入就绪/阻塞/挂起链表） UBaseType_t uxPriority; // 任务的优先级（0~configMAX_PRIORITIES-1）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; char pcTaskName[ configMAX_TASK_NAME_LEN ]; // 任务名称（如你的&amp;#34;LED_Task&amp;#34;）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 其他：栈大小、任务编号、队列/信号量等待信息等
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;} tskTCB;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="核心作用"&gt;核心作用
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;存储任务状态&lt;/strong&gt;：通过&lt;code&gt;xStateListItem&lt;/code&gt;将任务挂载到内核的&lt;strong&gt;就绪链表 / 阻塞链表 / 挂起链表&lt;/strong&gt;，调度器只需遍历链表即可找到待执行的任务；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记录运行环境&lt;/strong&gt;：&lt;code&gt;pxTopOfStack&lt;/code&gt;保存任务栈的栈顶地址，&lt;strong&gt;任务切换的核心就是保存 / 恢复栈顶指针&lt;/strong&gt;（CPU 的寄存器值会压入任务栈，栈顶指针记录压栈位置）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标识任务属性&lt;/strong&gt;：优先级、任务名称、栈大小等，为调度器的调度决策提供依据。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="四栈stack"&gt;四：栈（STACK）
&lt;/h2&gt;&lt;p&gt;为每一个任务分配独立的RAM空间，存储局部变量、CPU寄存器值、函数调用返回地址&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现任务切换&lt;/strong&gt;：这是栈最核心的作用！当高优先级任务抢占低优先级任务时，内核会将当前 CPU 的所有寄存器值（如 PC、R0-R15）压入被抢占任务的栈中，并将栈顶指针更新到 TCB 的&lt;code&gt;pxTopOfStack&lt;/code&gt;；当被抢占任务再次执行时，内核会从栈中&lt;strong&gt;恢复所有寄存器值&lt;/strong&gt;，让任务从被打断的位置继续执行，实现 “无缝切换”。&lt;/p&gt;
&lt;h2 id="五优先级priority"&gt;五、优先级（Priority）
&lt;/h2&gt;&lt;h3 id="freertos-优先级的核心规则"&gt;FreeRTOS 优先级的核心规则
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;抢占式调度核心&lt;/strong&gt;：&lt;strong&gt;当一个高优先级任务进入就绪态时，调度器会立即暂停当前正在执行的低优先级任务，将 CPU 切换给高优先级任务&lt;/strong&gt;（这就是你代码中串口任务能打断数据处理 / LED 任务的根本原因）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;同优先级任务调度&lt;/strong&gt;：若多个任务优先级相同，FreeRTOS 会采用&lt;strong&gt;时间片轮转调度&lt;/strong&gt;（需开启&lt;code&gt;configUSE_TIME_SLICING=1&lt;/code&gt;），每个任务分配固定的 CPU 时间片，轮流执行；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优先级范围&lt;/strong&gt;：由&lt;code&gt;FreeRTOSConfig.h&lt;/code&gt;的&lt;code&gt;configMAX_PRIORITIES&lt;/code&gt;定义，建议按实际需求配置（无需配置过大，否则会占用更多内核 RAM）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;空闲任务优先级&lt;/strong&gt;：FreeRTOS 会自动创建一个&lt;strong&gt;空闲任务（idle task）&lt;/strong&gt;，优先级为 0（最低），当系统中所有任务都处于阻塞 / 挂起态时，调度器会执行空闲任务（防止 CPU 空转）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="六调度器scheduler"&gt;六、调度器（scheduler）
&lt;/h2&gt;&lt;p&gt;根据任务的优先级和TCB状态来决定哪个任务获得CPU执行权&lt;/p&gt;
&lt;h3 id="调度器的类型freertos-支持"&gt;调度器的类型（FreeRTOS 支持）
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;抢占式调度器&lt;/strong&gt;：&lt;code&gt;configUSE_PREEMPTION=1&lt;/code&gt;开启，是嵌入式实时开发的&lt;strong&gt;主流选择&lt;/strong&gt;，高优先级任务可随时抢占低优先级任务，保证实时性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协作式调度器&lt;/strong&gt;：&lt;code&gt;configUSE_PREEMPTION=0&lt;/code&gt;开启，任务不会被主动抢占，需任务主动调用&lt;code&gt;taskYIELD()&lt;/code&gt;让出 CPU，实时性差，适合对实时性要求低的场景。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="2-常用函数"&gt;2. 常用函数
&lt;/h1&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;函数名&lt;/th&gt;
&lt;th style="text-align: center"&gt;参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTaskCreate()&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTaskCreate(Func, &amp;quot;name&amp;quot;, stack, pvParameters, priority, Handle);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskStartScheduler&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskStartScheduler()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelete&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelete(Handle)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskSuspend&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskSuspend(Handle)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskResume&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskResume(Handle)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTaskGetHandle&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTaskGetHandle(name)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelay()&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelay(pdMS_TO_TICKS(time));&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelayUntil()&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vTaskDelayUntil(&amp;amp;pretime,delaytime);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueCreate()&lt;/code&gt;&lt;br&gt;队列创建&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xADCQueue = xQueueCreate(10, sizeof(float));&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueSend()&lt;/code&gt;&lt;br&gt;队列发送&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueSend(xADCQueue,&amp;amp;voltage,pdMS_TO_TICKS(50))&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueReceive()&lt;/code&gt;&lt;br&gt;队列接收&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueReceive(xADCQueue,&amp;amp;voltage,portMAX_DELAY)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;uxQueueMessagesWaiting()&lt;/code&gt;&lt;br&gt;队列数目查询&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;uxQueueMessagesWaiting(adc_voltage_queue)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreCreateBinary&lt;/code&gt; &lt;br&gt;二值信号量&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xBinarySemaphore = xSemaphoreCreateBinary();&lt;/code&gt; &lt;br&gt;必须手动调用Give函数启用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreCreateCounting&lt;/code&gt; &lt;br&gt;计数信号量&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreTake&lt;/code&gt; &lt;br&gt;获取令牌，获取后从1-0&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreTake(句柄,portMAX_DELAY)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreGive&lt;/code&gt;&lt;br&gt;释放令牌，成功后获取后从0-1&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreGive(xBinarySemaphore);//释放&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreGiveFromISR&lt;/code&gt;&lt;br&gt;中断释放令牌&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreCreateMutex&lt;/code&gt;&lt;br&gt;创建互斥量(获取和释放同上)&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreCreateMutex&lt;/code&gt;&lt;br&gt;避免优先级反转，自动启用需要手动释放&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xQueueSendFromISR()&lt;/code&gt;&lt;br&gt;中断中队列入队&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xSemaphoreGiveFromISR()&lt;/code&gt;&lt;br&gt;中断中释放信号量 / 互斥量&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;portYIELD_FROM_ISR()&lt;/code&gt;&lt;br&gt;中断中触发任务调度&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xEventGroupCreate()&lt;/code&gt;&lt;br&gt;创建事件组&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xEventGroupSetBits()&lt;/code&gt;&lt;br&gt;设置事件位&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xEventGroupWaitBits()&lt;/code&gt;&lt;br&gt;等待事件位&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xEventGroupClearBits&lt;/code&gt;&lt;br&gt;清除事件位&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerCreate()&lt;/code&gt;&lt;br&gt;创建定时器&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerCreate( &amp;quot;名称&amp;quot;, 定时时长, pdTRUE,pvTimerID 回调函数 ;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerStart()&lt;/code&gt;&lt;br&gt;启动定时器&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerStart(名称, 0);&lt;/code&gt;&lt;br&gt;第二位0表示立即开始&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerStop()&lt;/code&gt;&lt;br&gt;停止定时器&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTimerReset()&lt;/code&gt;&lt;br&gt;重置定时器&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;vApplicationStackOverflowHook()&lt;/code&gt;&lt;br&gt;栈溢出钩子函数&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;portYIELD_FROM_ISR&lt;/code&gt;&lt;br&gt;中断中唤醒高优先级任务&lt;/td&gt;
&lt;td style="text-align: center"&gt;一般用于中断处理后加上&lt;br&gt;xHigherPriorityTaskWoken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;uxTaskGetStackHighWaterMark&lt;/code&gt;&lt;br&gt;空闲任务剩余栈大小&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;code&gt;xTaskGetTickCount&lt;/code&gt;&lt;br&gt;获取当前tick数&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="3标准流程"&gt;3.标准流程
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;中断里在执行完代码后立即按照任务优先级执行：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 典型用法
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BaseType_t xHigherPriorityTaskWoken = pdFALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 初始化为“未唤醒高优先级任务”
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 在ISR中释放信号量，函数会修改 xHigherPriorityTaskWoken 的值 xSemaphoreGiveFromISR(Handle, &amp;amp;xHigherPriorityTaskWoken);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 根据标记判断是否需要立即切换任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h1 id="4工程步骤"&gt;4.工程步骤
&lt;/h1&gt;&lt;p&gt;划分任务（按功能 + 优先级）→ 确定同步 / 通信方式 → 分配栈大小和优先级 → 编写业务逻辑 → 调试排错。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;整理&lt;strong&gt;FreeRTOS 核心知识框架&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;plaintext&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FreeRTOS核心
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 任务管理：创建/删除/挂起/恢复 + 调度器（抢占式/时间片）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 通信同步：队列（数据传输）、信号量（同步/计数）、互斥量（互斥+优先级继承）、事件组（多条件同步）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 时间管理：vTaskDelay()/vTaskDelayUntil()、软件定时器
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─ 中断管理：FROM_ISR API、中断优先级配置、portYIELD_FROM_ISR()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>freertos源码学习</title><link>https://041101.xyz/p/freertos%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0/</link><pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate><guid>https://041101.xyz/p/freertos%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0/</guid><description>&lt;h1 id="1列表listc"&gt;1.列表(list.c)
&lt;/h1&gt;</description></item></channel></rss>