- 博客(14)
- 收藏
- 关注
原创 FreeRTOS 启动流程详解:从复位到任务调度
上电 → Reset_Handler → __main → main()│├─ xTaskCreate() → 自动调用 prvHeapInit() 初始化堆├─ 创建空闲任务├─ 创建定时器任务(可选)├─ 关闭中断│ ├─ 配置 SysTick 和 PendSV│ └─ 触发 SVC → 启动第一个任务└─ 调度器运行,永不返回核心要点FreeRTOS 不需要用户显式初始化内核,创建第一个任务时自动完成。空闲任务是系统运行的最低保障,优先级最低。
2026-04-02 23:45:15
461
原创 FreeRTOS 内存管理核心:深入解析 heap_4 实现原理
摘要: FreeRTOS的heap_4内存管理方案通过首次适应算法分配内存,并采用自动合并相邻空闲块的策略减少碎片。其核心是单向链表组织空闲块,每个块包含头部信息用于状态标记。初始化时堆空间布局为单个大空闲块,分配时分割大块,释放时按地址顺序插入并合并相邻块。通过挂起调度器保证操作原子性,提供内存统计功能监控使用情况。相比其他heap方案,heap_4在支持动态分配的同时优化了碎片问题,成为通用嵌入式场景的推荐选择。实际应用中需合理预估堆大小,避免高频分配,并谨慎处理中断中的内存操作。
2026-04-01 23:39:00
643
原创 为什么 SysTick 中断可以直接关中断而不保存状态
SysTick 中断的写法是内核在特定条件下的优化,不是通用规则。用户在写自己的中断服务函数时,仍然必须使用中断版临界段 API,以确保嵌套安全。
2026-03-26 20:43:47
503
原创 FreeRTOS 临界段终极解惑:从零讲起,一次搞懂两个版本
先想象一个场景:你和室友合用一个厨房(共享资源)。你正在切菜(操作数据),突然室友冲进来开始炒菜(任务切换/中断),你的手可能被锅铲碰到,或者他把你切好的菜弄乱了(数据错乱)。进门锁门 → 安心干活 → 开门出去关中断 → 执行关键代码 → 开中断为什么要关中断?因为 FreeRTOS 的任务切换靠中断(SysTick 定时器中断、PendSV 异常)触发。关掉中断,任务切换就被禁了,当前任务可以放心独占 CPU。
2026-03-26 20:06:42
333
原创 FreeRTOS进阶之路:深入理解临界段保护机制
简单来说,临界段就是一段在执行时不能被中断的代码。想象一个全局变量,它就像一个公共靶子。如果多个人(多个任务或中断)同时向它“开枪”(写入数据),我们就无法确定最终是谁命中了靶心(数据最终状态)。为了避免这种混乱,我们必须确保在同一时间,只有一个人能操作这个靶子。在FreeRTOS中,临界段通常用于保护对全局变量的操作。那么,临界段可能被什么打断呢?系统调度:任务切换。外部中断:硬件中断。有趣的是,在Cortex-M内核中,系统调度最终也是通过触发PendSV中断来实现的。因此,
2026-03-25 20:57:11
503
原创 嵌入式必知 | 一张图看懂 Cortex‑M 寄存器组(附汇编实战)
Cortex‑M 的寄存器设计非常规整,每类寄存器都有明确分工。看懂反汇编调试 HardFault编写 RTOS 任务切换优化中断响应编写裸机启动代码有任何疑问或想深入探讨的话题,欢迎在评论区留言!
2026-03-25 18:07:59
589
原创 深挖FreeRTOS任务切换:那些你必须掌握的ARM汇编指令
在定义任务控制块(TCB)或初始化任务堆栈时,会用到一些伪指令和内存操作指令。指令/伪指令作用在FreeRTOS中的应用场景EQU给数字常量设置符号名,类似C语言的#define。用于定义常量,如任务优先级、堆栈大小等。在汇编中可用表示。AREA汇编一个新的代码段或数据段。将汇编代码组织在不同的段中。例如,.text段存放代码,.data段存放数据。EXPORT声明一个标号具有全局属性,可被外部文件使用。汇编函数需要被C文件调用时,必须用EXPORT导出函数名。例如。
2026-03-24 21:17:32
169
原创 xPortPendSVHandler()` 函数详解
保存上文:将当前任务的 r4-r11 手动压入其栈,并将新的栈顶指针保存到 TCB。选择下文:关中断保护全局数据,调用更新,然后开中断。恢复下文:从新任务的 TCB 中获取栈顶指针,恢复 r4-r11,更新 PSP,最后异常返回,硬件自动恢复剩余寄存器。通过这个机制,FreeRTOS 利用 Cortex-M 的 PendSV 实现了高效、可嵌套的任务切换,同时通过 BASEPRI 精细控制中断,保证了硬实时性。
2026-03-24 10:04:08
363
原创 深入理解Cortex-M双栈机制:主栈指针(MSP)与进程栈指针(PSP)
主栈指针(MSP)和进程栈指针(PSP)是Cortex-M内核实现安全、高效任务调度的基石。隔离内核和用户任务的栈空间。利用硬件自动压栈/出栈的特性,简化上下文切换。通过异常返回机制无缝切换任务。理解MSP和PSP的工作原理,是深入掌握RTOS调度器底层实现的关键。希望本文能帮助你更好地理解之前调度器代码中涉及栈操作的部分,从而更自信地编写和调试RTOS应用。《ARM Cortex-M3与Cortex-M4权威指南》(第3章:异常与中断)
2026-03-23 16:59:41
498
原创 手把手教你实现一个RTOS调度器:从启动到任务切换
启动:设置中断优先级 → 获取MSP → 触发SVC → 进入第一个任务。切换:通过PendSV异常,在中断服务中保存当前任务状态、选择新任务、恢复新任务状态。关键寄存器:PSP(进程栈指针)、MSP(主栈指针)、BASEPRI(中断屏蔽)、SCB_VTOR(向量表偏移)。理解这些底层细节,不仅有助于我们更好地使用RTOS,也能在遇到问题时快速定位。希望这篇博客能帮助你把调度器的原理看得更通透。如果你对RTOS的其他组件(如信号量、消息队列)也感兴趣,欢迎留言交流!
2026-03-23 16:45:21
1334
原创 FreeRTOS 在 Cortex-M 上为何将 PendSV 和 SysTick 设置为最低优先级?
FreeRTOS在ARM Cortex-M内核上通过PendSV和SysTick异常实现任务调度和系统时钟。
2026-03-22 21:03:14
342
原创 C 语言中的通用指针类型(void *)
FreeRTOS链表实现中广泛使用void*通用指针类型,以实现类型无关的数据结构。void*允许链表节点存储不同类型的内核对象指针(如任务控制块、定时器等),通过强制转换消除类型不匹配警告。关键宏操作包括:listSET_LIST_ITEM_OWNER将具体指针转为void*存储,listGET_LIST_ITEM_OWNER返回后需显式转换回原类型。指针比较时也使用void*转换,既避免限定符警告又保持代码一致性。这种设计使FreeRTOS能用同一套链表管理多种内核对象,体现了通用性和类型安全性。
2026-03-22 14:38:57
306
原创 宏展开中的副作用问题
C语言宏定义中的副作用问题源于宏的简单文本替换机制,可能导致带有副作用的表达式被多次求值。以FreeRTOS的listGET_OWNER_OF_NEXT_ENTRY宏为例,通过将参数赋给const局部变量,既避免了多次求值带来的副作用问题,又增强了代码安全性和可读性。编写宏时,对可能产生副作用的参数应先保存到临时变量再使用,这是防御性编程的重要实践。
2026-03-21 17:15:37
453
原创 FreeRTOS节点带参宏函数
这些宏共同构成了 FreeRTOS 中高效、简洁的链表操作接口。它们被广泛用于任务调度、延时管理、事件处理等核心模块中。通过内联宏的方式,既保证了代码的紧凑性,又避免了函数调用的开销,符合嵌入式实时系统对性能和资源的要求。
2026-03-21 16:52:50
715
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅