- 博客(15)
- 问答 (1)
- 收藏
- 关注
原创 T3 从阻塞态移回就绪态,内核立即将 T1 的优先级设置回 2,这时T3不自动抢占吗,为什么还要显式调用taskYIELD()
内核知道状态发生了重大变化(一个高优先级任务 T3 就绪了,且当前任务 T1 优先级降低了),所以它设置一个内部标志位(例如。内部将 T3 移回就绪态,并且 T3 的优先级 (4) 高于当前正在运行的 T1 (此时还是临时的 4,但即将被降级),它模拟了在临界区结束时“立即发生一次中断”的效果,让调度器能马上选择最高优先级的任务(T3)运行。(现在 T1 优先级是 2,T3 优先级是 4 且就绪,T3 绝对应该抢占 T1!即使有更高优先级任务就绪,中断被屏蔽,抢占请求(PendSV挂起)也无法发生。
2025-07-04 15:20:19
716
原创 任务在优先级继承之后恢复基础优先级时机分析
到 T3 的优先级 (4),以防止中等优先级任务(如 T2,优先级 3)造成的“无界优先级反转”。由于 T3 的优先级 (4) 远高于降级后的 T1 (2) 和 T2 (3),调度器紧接着就会选择 T3 运行。内核知道 T1 不再持有该互斥信号量,因此需要将 T1 的优先级恢复到它进入优先级继承状态之前的优先级。释放信号量的操作直接触发了优先级继承的撤销和 T1 优先级的恢复。现在,T1 (优先级 4) 成为就绪态中优先级最高的任务,继续运行。T1优先级为2,T2优先级为3,T3优先级为4。
2025-07-04 14:48:37
320
原创 队列的尾部入队头部出队与先进先出不矛盾解释
FreeRTOS 队列默认是严格的 FIFO(先进先出)数据结构。实现 FIFO 的核心机制正是:写入 (xQueueSend将新数据添加到逻辑尾部 (。读取 (从逻辑头部 (取出并移除最早写入的数据。“写入到尾,读取到头” 是 FIFO 的标准实现方式,两者完全一致且相辅相成。和是提供了额外灵活性的特殊操作,它们的行为偏离了标准的 FIFO。所以,请放心,FreeRTOS 队列通过“尾写入、头读取”完美地实现了您期望的“先进先出”功能!银行的排队规则就是最好的现实模型。
2025-06-30 20:37:43
643
原创 任务句柄或其他句柄本质详解
操作任务状态(如删除、挂起)涉及多个步骤(如从列表移除、状态变更、资源释放)。结构体所在内存区域的数据,从而实现任务删除、挂起等操作。它们接收这把钥匙,在严格受控的环境下(临界区保护、状态机维护、资源管理、调度触发),使用这把钥匙去安全、正确地修改。将任务从它当前所在的列表(就绪列表、阻塞列表、挂起列表、事件列表)中移除(操作。它告诉内核:“你要操作的任务,它的控制信息就存储在这个内存地址开始的地方”。因此,您的理解完全正确:内核正是利用任务句柄(指针)来访问和修改目标任务。来访问结构体的成员。
2025-06-30 20:06:34
704
原创 taskYIELD()函数辨析
是 FreeRTOS 任务主动交出 CPU 控制权的核心机制。强制调度器立即检查是否有其他(更高或同等优先级的)就绪任务需要运行。调用任务保持在就绪态。提高高优先级任务响应性、避免长任务独占 CPU、实现协作式调度、调试。通过设置处理器特定标志(如 PendSV)触发一次软件中断,在中断处理程序中完成实际的上下文切换。调用就是说:“调度器,我现在把 CPU 让出来了,你看看现在谁最该干活,就让谁接着干吧!” 这保证了高优先级任务能及时响应,也使得多个同等优先级任务能公平分享 CPU 时间。
2025-06-30 19:03:05
809
原创 任务入队阻塞到成功入队内核分析
如果 Task B 优先级很高触发了抢占,那么从用户角度看,Task B 似乎是在队列有空间的瞬间“立刻”开始运行了。Task B 在就绪列表中等待,直到下一个调度点(Task A 阻塞、主动让出、时间片耗尽等)被调度器选中时才会运行。内核会设置 Task B 的一个状态标志或返回值,表明其阻塞等待的操作(入队)已经成功完成。当 Task B 恢复运行时,它发现自己等待的入队操作已经由内核在其阻塞期间代为完成并成功,于是它继续执行。Task B 被调度运行时,发现操作已成功,继续执行后续代码。
2025-06-30 18:24:28
1699
原创 关于freeRTOS任务详情函数的辨析
因素第一个代码第二个代码初始化时机过早调用,依赖项未就绪延时后调用,依赖项已初始化统计数据有效性无任务切换,数据无效多次切换后数据有效资源就绪缓冲区/定时器可能未就绪延时确保资源就绪。
2025-06-29 10:47:15
629
原创 while(1)在freeRTOS和裸机中的应用
在嵌入式开发(尤其是基于 FreeRTOS 或其他 RTOS 的系统)中,int main()// 启动调度器(永不返回)// 对应 Arduino 的 loop()// 对应 Arduino 的 setup()xTaskCreate(task1, ...);while (1) { // 必须无限循环。// 若没有 while(1),程序可能崩溃!永不返回),但也不会导致错误,只是冗余代码。),否则程序会跑飞(执行未定义内存区域)。,在中断中触发任务切换,而非依赖。// 以下代码不会执行!
2025-06-23 17:42:22
535
原创 freeRTOS任务句柄和TCB辨析
总结来说,任务句柄是应用程序与 TCB 之间的桥梁,而 TCB 是内核实现任务调度的底层支撑。任务句柄本质是指向 TCB 的指针,但 FreeRTOS 通过句柄抽象了对 TCB 的直接访问,开发者只能通过句柄调用 API(如。作为任务的“标识符”,供应用程序通过 API 操作任务(例如删除、挂起、恢复任务)。// 创建任务时,内核分配TCB,并返回句柄(xHandle指向TCB)// 通过句柄操作任务(内核通过xHandle找到对应的TCB)),此时任务仍会创建(TCB 存在),但无法通过句柄操作该任务。
2025-06-15 22:18:22
1559
原创 freeRTOS列表项(节点)解析
用通俗易懂的语言解释下面这个代码struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue;:告诉编译器“这个变量可能会被意外修改”(比如中断里修改了链表),别做激进的优化。
2025-06-12 20:55:24
730
原创 stm32引脚主功能切换到默认复用功能解析2
/ 浮空输入(仍能切换到USART1_RX)(RX):无论引脚是普通输入还是复用输入,信号都会进入复用器,由外设(如USART)主动读取。(TX):GPIO需要明确知道信号来源是USART(而非GPIO输出寄存器),因此必须配置为复用模式。:浮空/上拉/下拉模式已满足USART对输入信号的要求(如抗噪声、电平稳定性)。这种设计是STM32硬件自动完成的,旨在简化输入功能配置,同时确保信号正确传递。复用功能外设(如USART、SPI等)的输入通道。// 配置PA10(USART1_RX)为浮空输入。
2025-06-07 12:05:17
631
原创 stm32引脚主功能切换到默认复用功能解析1
指引脚除了作为普通GPIO外,还能用于其他外设(如ADC、USART等)。,需要经过GPIO模块的复用器(Multiplexer)切换路径。(如施密特触发器、上下拉电阻等),直接进入ADC模块的模拟输入通道。:信号完全绕过GPIO的数字部分,直接进入模拟域(ADC)。:信号经过GPIO的数字部分,再通过复用器切换到外设。(例如PA0对应ADC1_IN0),但实际配置时需选择。配置的数字外设功能(如USART、SPI)。:模拟信号需要绕过数字部分,因此必须配置为。(如USART、SPI等)。
2025-06-07 12:03:50
286
原创 2.如果访问之后不会自动清除,为什么PR寄存器下面标的是“rc和w1”,rc不是代表访问之后清除吗,为什么是矛盾的
层面EXTI_PR寄存器标准库函数硬件行为支持读清除(rc)和写1清除(w1)忽略rc,仅用逻辑判断清除方式读或写1均可清除必须显式调用设计目的提供硬件灵活性保证代码可控性和兼容性结论矛盾源于硬件特性与软件库设计的取舍,库函数选择牺牲硬件特性以换取更可控的行为。实际开发中应以库函数文档为准,而非完全依赖寄存器手册的标注。
2025-06-04 15:28:29
317
原创 1.EXTI_GetITStatus()函数访问之后,PR寄存器对应的位会被硬件自动清除吗
在STM32的标准外设库(SPL)中,EXTI_GetITStatus()EXTI->PR。
2025-06-04 15:27:31
589
空空如也
51单片机按下亮,松手灭
2022-11-02
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅