- 博客(56)
- 收藏
- 关注
原创 cpu异常中断(2)
内核里面的cpu主要通过D-Bus,I-Bus,S-Bus与外设沟通,其中S-Bus是主要用来访问外设的当我们访问一个外设地址时,数据会从cpu然后通过S-Bus再到AHB总线矩阵,经过某些处理到达APB(挂载着外设)但APB_BUS也不知道这个地址是什么,只有cpu知道,然后被转译到apb,只知道在自己总线上寻址访问,(后续需要联通从memory map ->图示->bootloadr->再到bus总线->芯片架构)
2025-12-12 19:45:21
1220
1
原创 mcu启动流程
STM32 启动流程的核心是地址映射机制与启动介质选择,通过硬件配置(BOOT 引脚)和软件初始化(堆栈、数据段搬运),最终引导 CPU 执行用户程序。整体流程可概括为:复位→地址重映射→堆栈初始化→数据段搬运→执行用户代码。通过上文的Boot ROM与Boot Loader我们知道:Boot ROM会读取Boot引脚的电平配置来选择启动方式。
2025-12-12 19:38:16
1383
原创 CPU中断异常
中断向量表是存储中断服务程序入口地址的连续内存区域,“圆整” 指将其起始地址对齐到特定的字节边界(如 256 字节、1024 字节等),本质是地址对齐(Address Alignment)。假设内部异常中断加上外部中断有103个,每个占四字节,则需要412个字节,圆整就需要2的整次幂,则需要取512字节。
2025-12-09 23:03:27
785
原创 pendsv任务切换
在.bss段分配了FREERTOS的栈堆空间(在系统里面uc heap数组大小)大小所有创建的任务 如任务一的栈和tcb也在里面,还有队列等也会创建在里面在操作栈的时候就用到了我们的psp指针。
2025-12-09 23:01:24
327
原创 dma的深层次理解和实战
HAL 库将「串口的回调函数」通过绑定到 DMA 句柄,本质是为了:让 DMA 这个 “通用搬运工” 知道「搬完后该通知谁」;让 UART 这个 “外设” 只关心「自己的业务逻辑」,不用管 DMA 怎么工作;让中断处理流程「统一化」,降低开发复杂度(你不需要为每个外设写一套 DMA 中断逻辑)。这种设计模式,正是嵌入式开发中「分层设计」和「单一职责原则」的体现 ——底层负责硬件操作,上层负责业务逻辑,中间通过回调函数解耦,让代码更清晰、更易于维护。
2025-12-03 16:31:24
1281
原创 函数调用栈和fault analyzers
一般来说 错误类型就是以下四种 而最常见的是:Hardfault在 ARM Cortex-M 系列处理器(如 STM32 芯片)中,是一种,当处理器检测到无法被其他异常(如总线故障、用法故障)处理的错误时,会触发该异常。
2025-12-03 16:16:15
953
原创 任务切换时机和队列唤醒机制(isr)
任务切换不会自动发生,而是需要等到特定的调度触发条件满足时,才会进行任务切换判断—— 这是 FreeRTOS 按需调度机制的核心,也是平衡系统效率与实时性的关键设计。
2025-11-27 21:18:55
1210
原创 队列传输的函数应用原理(拷贝原理)
1.当我们用这个函数的时候,要传入一个变量的地址,此时我们要传入一个指针,此时传进去的是 变量的首地址在函数参数就会定义一个指针变量 并且将变量的地址赋值给指针2.从xqueuesend函数进去后 会调用如上所示的一个copy函数,把地址里面的数据拷贝进去3.此时就会将变量数据拷贝到由freertos维护的队列区域(全局变量的句柄的空间)
2025-11-16 22:53:18
633
原创 printf线程问题
串口(UART)硬件的发送过程是 “字节级串行”:需先将数据写入发送寄存器(TDR),硬件再逐位移位发送,发送完成后由状态寄存器(SR)的。线程安全的核心是 “多线程并发访问共享资源时,结果与单线程执行一致”。HAL 库串口驱动会维护全局状态变量(如。之所以线程不安全,根源在于其依赖的。),用于标记串口当前状态(位(发送寄存器为空)标记。
2025-11-01 22:31:50
705
原创 嵌入式项目代码架构与分层笔记
解耦是指降低程序模块间的依赖关系,使每个模块独立完成自身功能,模块间仅通过标准化接口交互,不涉及内部实现细节。稳定性:层间隔离,单一模块故障影响范围可控。可维护性:模块职责清晰,问题定位、修改更高效。可移植性:更换芯片时仅需修改 Driver 层、BSP 层,上层代码无需改动。开发效率:模块化复用,减少重复开发,支持团队并行协作。
2025-10-31 23:23:31
1246
原创 汇编与底层编程笔记
字节序是计算机存储多字节数据时的字节排列规则,核心解决 “高字节与低字节对应哪个内存地址” 的问题,以十六进制数0x12345678为例(注:1 个十六进制位占 4bit,1 字节 = 8bit,因此该数可拆分为 4 个独立字节)。
2025-10-20 21:20:25
1481
原创 ARM 架构核心知识笔记(整理与补充版)
arm;原伪指令:LDR R0, =0x12345678(非合法立即数);编译器处理步骤:;1. 在程序数据段用DCD指令定义该数值(存入内存)内存地址假设为0x20000000;2. 替换为原生LDR指令(从内存读取该数值到R0)offset = 0x20000000 - PC当前值(由链接器计算)
2025-10-19 16:21:59
1954
1
原创 C++ 多态核心知识点笔记(整理与补充)
多态的实现需满足两个强制条件,核心依赖 “虚函数” 机制,以下结合代码详细说明。被virtual关键字修饰的类成员函数,称为虚函数。其作用是允许派生类重写该函数,为多态提供基础。cpp运行// 基类:Person(普通人)public:// 定义虚函数:买票(全价)cout << "买票-全价" << endl;基类虚函数返回基类对象的指针 / 引用,派生类虚函数返回派生类对象的指针 / 引用(派生类与基类需有继承关系),仍构成重写,称为 “协变”。
2025-10-18 17:21:37
1273
原创 C++ 继承笔记
若子类与基类存在同名成员(变量或函数),子类成员会 “屏蔽” 基类同名成员的直接访问,需通过基类名::成员名显式访问基类成员。cpp运行public:// 基类拷贝构造public:int No;// 派生类显式拷贝构造:调用基类拷贝构造// 调用派生类拷贝构造// 输出顺序:// Person copy constructor(先拷贝基类)// Student copy constructor(再拷贝子类)return 0;
2025-10-17 15:53:10
1287
1
原创 C++ 类与对象(下篇)笔记整理
若成员是自定义类型(如类 A),且该类没有默认构造函数(即必须传参才能构造),则必须在初始化列表中给该成员传递构造参数。cpp运行// 类A:无默认构造函数(只有带参构造)class A {private:int _a;public:A(int a) : _a(a) {} // 带参构造,无默认构造// 类B:包含A类型成员,必须用初始化列表初始化_aobjclass B {private:A _aobj;
2025-10-14 22:36:04
1741
原创 类与对象(中)笔记整理
构造函数:初始化对象析构函数:清理对象资源拷贝构造函数:用已有对象初始化新对象赋值运算符重载:已有对象间的赋值取地址运算符重载:获取对象地址const 取地址运算符重载:获取 const 对象地址默认成员函数的核心特点:仅当用户未显式定义对应函数时,编译器才会生成;若用户显式定义,编译器则不再生成。
2025-10-13 21:38:29
1158
原创 C++ 类与对象(上)笔记(整理与补充)
类是 “成员变量”(描述对象属性 / 状态)与 “成员方法”(描述对象行为 / 操作)的集合,是封装思想的直接体现。为保证代码模块化与可维护性,C++ 中类的声明与定义声明(Declaration):放在.h(头文件)中,仅告知编译器 “类的结构”(包含哪些成员变量、成员方法的签名),不涉及具体实现。定义(Definition):放在.cpp(源文件)中,实现.h中声明的成员方法(填充函数逻辑)。声明是 “向编译器承诺某个实体的存在”,仅告知实体的 “名称与签名”,不分配内存或填充实现逻辑。
2025-10-10 23:08:04
1004
原创 C++ 核心基础知识点笔记
函数重载的核心条件:同一作用域内,函数名相同,但参数列表(参数的类型、个数、顺序)至少有一项不同。返回值类型不同不能作为重载的判定依据。示例:cpp运行// 以下三个add函数构成重载(参数列表不同)int add(int a, int b) { // 参数:int, intdouble add(double a, double b) { // 参数:double, double(类型不同)
2025-10-10 03:00:00
718
原创 cpu占用优化
我们需要比Tick更快的时钟,比如Tick周期时1ms,我们可以使用另一个定时器,让它发生中断的周期时0.1ms甚至更短。在FreeRTOS中,我们也可以查看任务使用CPU的情况、使用栈的情况,然后针对性地进行优化。很不精确,因为有更高优先级的任务就绪时,当前任务还没运行一个完整的Tick就被抢占了。对于同优先级的任务,它们按照时间片轮流运行:你执行一个Tick,我执行一个Tick。原理是:从栈底往栈顶逐个字节地判断,它们的值持续是0xa5就表示它是空闲的。这就是查看"任务的统计"信息。
2025-10-05 00:30:00
1224
原创 FreeRTOS 栈空间精细调整与监控技术笔记
栈空间精细调整是嵌入式系统开发中的关键技能。通过:理解栈填充机制熟练使用高水位线检测函数结合实际监控数据建立系统化的优化策略可以构建出既节省内存又稳定可靠的FreeRTOS应用程序。
2025-10-03 00:30:00
901
原创 FreeRTOS临界区保护与资源管理机制详解
临界区是指必须独占式访问的代码段,通常涉及多个任务或中断都可能使用的共享资源(全局变量、链表、外设等)。如果被打断,可能导致数据损坏或状态混乱。队列使用关中断:操作快速,需要在ISR中使用事件组使用关调度器:操作可能较慢,主要在任务中使用,通过守护任务处理ISR请求高优先级中断:通过设计约束确保不访问受保护资源这种分层保护策略确保了系统的可靠性和实时响应能力,体现了嵌入式系统设计的精细权衡。
2025-09-29 04:00:00
1112
原创 中断管理(Interrupt Management) - 整理笔记
CPU跳到固定地址(中断向量)执行代码:保存被打断任务的运行环境(寄存器值等):分辨中断类型,调用对应的ISR函数:恢复任务运行环境,继续执行原任务或更高优先级任务。
2025-09-28 04:00:00
1003
原创 FreeRTOS 任务通知(Task Notification)详解
任务通知是 FreeRTOS 中一种高效的进程间通信机制,它直接通过任务控制块(TCB)进行通信,无需创建额外的通信对象。B 不会被立即唤醒,但当 B 被其他方式唤醒后,如果调用等待通知函数,会立即接收通知。:ISR 没有任务结构体,无法接收任务通知(但 ISR 可以发送通知给任务)任务通知:直接通过任务本身的 TCB 进行通信,无需额外结构体。:通知值存储在目标任务 TCB 中,只有该任务能访问。使用任务通知时需要仔细管理通知状态,避免数据丢失。:在接收到通知并保存值后,清除通知值的指定位。
2025-09-26 01:30:00
1468
原创 FreeRTOS 事件组详解
0x05, // bit0和bit2。pdFALSE, // 等待任意位。pdTRUE, // 退出时清除。pdTRUE, // 等待所有位。pdTRUE, // 退出时清除。pdFALSE, // 或关系:任意位为1即可。pdTRUE, // 退出时清除事件。xBitsToWaitFor, // 等待的位。pdTRUE, // 与关系:所有位必须为1。信号量被获取后减少)pdTRUE, // 清除事件。
2025-09-25 02:00:00
1362
原创 FreeRTOS 信号量与互斥量详解
需要保护共享资源,防止同时访问?✅ 使用互斥量(特别是有优先级差异时)需要任务间事件通知?✅ 使用二进制信号量需要管理有限数量的相同资源?✅ 使用计数型信号量有"谁获取,谁释放"的所有权概念 → 互斥量无明确所有权概念 → 二进制或计数型信号量核心原则:互斥量用于互斥,信号量用于同步和计数。
2025-09-24 18:21:40
1672
原创 FreeRTOS 队列集(Queue Set)机制详解
高效等待多数据源:一个任务可阻塞等待多个队列/信号量,避免轮询消耗 CPU。解耦生产与消费:数据生产者(硬件驱动、中断)与消费者(任务)通过队列集间接通信,提高模块化程度。简化事件处理逻辑:无需复杂的状态机或多个任务分别阻塞,统一由队列集调度。
2025-09-21 23:16:37
1605
原创 RTOS队列(创建 发送和接送任务函数)机制以及任务状态与链表管理详解
队列操作是原子性的和在执行期间不会被中断任务状态转换运行态 → 阻塞态:当任务等待队列操作时阻塞态 → 就绪态:当队列条件满足时(有数据/有空间)就绪态 → 运行态:被调度器选中时优先级影响高优先级任务可以抢占低优先级任务当队列操作使高优先级任务就绪时,会立即发生抢占链表管理RTOS通过将任务移动到不同的链表来管理任务状态这种机制确保了高效的任务调度和同步这个机制使得RTOS能够高效地管理多个任务,确保高优先级任务及时响应,同时低优先级任务在系统空闲时也能得到执行。
2025-09-19 01:02:19
962
原创 FreeRTOS 队列机制详解:阻塞、唤醒与任务同步
队列(Queue)是 FreeRTOS 中实现任务间通信与同步的核心机制之一。它允许任务以线程安全的方式传递数据,并内置阻塞与唤醒机制,能有效协调生产者与消费者任务之间的执行节奏,提高 CPU 利用率。阶段任务B(消费者)RTOS & 队列任务A(生产者)初始调用队列为空阻塞进入阻塞态,不占用 CPU将B加入等待接收列表正常运行触发持续阻塞A写入数据,RTOS检查等待列表调用唤醒被标记为“就绪”将B移回就绪列表继续运行运行被调度执行,成功取出数据数据从队列中移除。
2025-09-18 23:18:42
1102
原创 同步与互斥学习笔记
原子操作:某些架构提供原子指令(如),可避免数据竞争;临界区保护:使用开关中断、调度器锁、互斥量等方法保护共享资源;任务通信机制:除了全局变量,还可使用队列、事件组、信号量等进行任务间同步与通信;内存屏障:在多核系统中,可能需要使用内存屏障指令确保内存访问顺序。(见原笔记中的图片,图示展示了同步与互斥的机制和资源访问流程)
2025-09-17 23:23:14
688
原创 两个delay函数
特性延时类型相对延时绝对延时周期稳定性受执行路径影响严格周期适用场景非精确延时精确周期任务参数含义延时 tick 数上一次唤醒时间和周期。
2025-09-17 17:45:41
801
原创 RTOS 任务状态与调度机制详解
Running(运行态):任务正在 CPU 上实际执行。单核系统中同一时刻最多只有一个任务处于运行态。Ready(就绪态):任务已具备执行条件,等待被调度器选中并获得 CPU 使用权。Blocked(阻塞态):任务因等待外部事件(如延时、信号量、消息等)而无法继续执行,主动让出 CPU。Suspended(挂起态):任务被强制暂停,不参与任何调度,必须显式恢复才能回到就绪态。状态是否消耗 CPU是否参与调度进入原因离开条件Running是不适用被调度器选中时间片到/被抢占/主动阻塞。
2025-09-16 23:41:58
1625
原创 RTOS创建任务简要要求
c// 1. 定义任务函数(形参为 void*)// 将 void* 转换为实际类型(例如 int*)while(1) {// 使用参数printf("任务参数:%d\n", *param);// 延时 1s代码解析任务函数使用无限循环保持任务持续运行通过类型转换将通用指针转换为具体类型指针使用实现周期性任务执行。
2025-09-16 17:01:30
302
原创 栈大小计算
项目说明栈空间组成局部变量 + 寄存器保存 + 调用参数 + 对齐开销寄存器保存R4–R11 + LR(若发生嵌套调用)调用者保存寄存器R0–R3、R12、LR(一般情况)被调用者保存寄存器R4–R11栈计算示例层数 × 保存寄存器数 × 4 字节。
2025-09-15 22:25:03
1304
原创 rtos初任务
RTOS 中,,其核心由「任务函数」「任务栈」「优先级」三大要素支撑,且依赖「任务控制块(TCB)」管理任务状态。以下结合 FreeRTOS 的任务创建函数,梳理关键逻辑。
2025-09-14 23:37:27
666
原创 关于rtos的栈和堆
如果大家共用一个办公桌(栈),那么A员工离开时,他的文件(局部变量)会被B员工的文件覆盖,全乱套了。经理(调度器)让谁工作,就把谁的档案柜搬到办公桌旁,他用完离开后,经理再把他的柜子搬走,换上下一个人的。为每个任务提供了私有的内存空间,用于存储其自身的局部变量、函数调用链,确保了任务间的完全隔离和数据安全。这样,下一个任务就能无缝地继续运行,仿佛从未被中断过,它的所有局部变量也都在它自己的栈中完好无损。独立的栈将问题隔离在单个任务内,一个任务的崩溃不会直接影响其他任务或内核,增强了系统的可靠性。
2025-09-14 21:34:37
1646
原创 对汇编的初理解
这是一段典型的 **“函数内数据处理流程”**,核心逻辑是:先 “备份重要数据”→ 准备临时空间 → 取数据计算 → 存结果 → 最后 “恢复原始数据并返回”。整个过程用栈(RAM)作为 “临时仓库”,用寄存器(CPU 内)作为 “快速运算工具”,既保证了计算的高效性,又避免了数据被意外覆盖,最终安全返回。
2025-09-12 01:16:20
1202
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅