自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Rach的博客

Rach的博客

  • 博客(92)
  • 收藏
  • 关注

原创 5.0. 最终综合实战项目 - 模块化IoT传感器节点

定义了系统的“血液”,所有模块通过这个标准化的血液进行交流。将应用逻辑与具体传感器硬件完全解耦。每个模块都有清晰的、单一的职责(Logger负责日志,CliManager负责命令处理)。我们广泛使用了class、继承、多态(ISensor)、封装(所有模块)和设计模式(Logger的单例)。我们拥抱了enum class等现代工具来提升代码的安全性和表达能力。这个框架已经为下一节的编码实现做好了充分准备。

2025-08-13 16:08:32 1384 1

原创 4.4b. 模板方法模式 (Template Method Pattern) 应用

这是我们驱动框架的核心,定义了通用的基类。// 抽象基类 (AbstractClass)public:// 1. 公共的、非虚的模板方法 (Template Method)// 使用 C++11 'final' 关键字确保子类不能重写这个固定的算法流程。// --- 算法骨架 ---powerOn();// 通用步骤if (checkDeviceID()) { // 通用步骤// 可变步骤 (由子类实现)// 通用步骤// 可变步骤 (由子类实现)// 通用步骤} else {

2025-08-12 18:17:11 444

原创 4.4a. 模板方法模式 (Template Method Pattern) 概念

模板方法模式通过C++的继承和虚函数机制,将一个算法中不变的部分和可变的部分分离开来。负责定义模板方法 (Template Method)。这个方法是一个具体的、不可被重写的函数,它定义了算法的整体骨架,并按照固定的顺序调用一系列的“原始操作”。负责声明一个或多个原始操作 (Primitive Operations)。这些操作通常是protected的virtual函数,它们是算法骨架中可变的“插槽”。它们可以是纯虚函数(强制子类实现),也可以是提供了默认行为的虚函数(允许子类选择性地重写)。

2025-08-12 18:15:17 746

原创 4.3b. 单例模式 (Singleton Pattern) 应用

在教程 4.3a 中,我们从理论上剖析了单例模式的实现机制、C++11的现代化改进(Meyers’ Singleton),以及它在软件架构中因引入全局状态而引发的争议。。在任何复杂的嵌入式系统中,我们都需要一个统一的日志出口。让系统中的任何模块、任何任务都能方便地记录信息,对于调试和状态监控至关重要。单例模式为此提供了一个简单直接的解决方案。我们将使用函数内的静态局部变量来实现单例,确保其无堆分配且线程安全。在RTOS环境下,我们将使用FreeRTOS的互斥锁来保护日志缓冲区的并发访问。

2025-08-12 18:12:25 889

原创 4.3a. 单例模式 (Singleton Pattern) 概念

单例模式保证一个类只有一个实例,并提供一个全局访问点。在C++11及以后,是最安全、最高效的实现方式,它避免了动态内存和线程安全问题。单例模式因其引入全局状态隐藏依赖和降低可测试性而备受争议。在嵌入式系统中,它可以被审慎地用于封装真正全局唯一的硬件或服务,但开发者必须警惕其带来的架构问题。依赖注入是一个更现代、更灵活的替代方案,它通过显式传递依赖关系,构建出更清晰、更易于测试的系统。

2025-08-12 18:10:27 620

原创 4.2b. 观察者模式 (Observer Pattern) 应用

在教程 4.2a 中,我们从理论上剖析了观察者模式如何通过“主题”与“观察者”的分离,来实现模块间的松耦合。现在,我们将这一强大的设计模式付诸实践,解决嵌入式开发中最常见的需求之一:一个数据源的变化需要通知多个独立的业务逻辑模块。本教程将引导您构建一个 温度监控系统。其中:一个 类作为 具体主题 (Concrete Subject),负责模拟温度变化。多个不同的模块,如 和 ,将作为 具体观察者 (Concrete Observers),对温度变化做出各自的响应。最关键的是,我们将严格遵循嵌入式开发准则

2025-08-12 18:07:59 479

原创 4.2a. 观察者模式 (Observer Pattern) 概念

观察者模式是一种强大的行为设计模式,其核心是实现主题与观察者之间的松耦合。它使得一个主题的状态变更可以透明地、自动地通知到任意数量的、对该状态感兴趣的观察者模块。它是C语言回调模式的类型安全、面向对象的演进,也是发布-订阅模式的一种轻量级、直接的实现。在嵌入式C++中实现时,必须:使用静态数组 (std::array来管理观察者列表,避免堆分配。使用互斥锁 (Mutex)来保证对观察者列表访问的线程安全。在下一篇教程 4.2b。

2025-08-12 18:06:20 799

原创 4.1b. 状态机模式 (State Pattern) 应用

在教程 4.1a 中,我们从理论上剖析了状态模式如何通过将状态封装成对象,来构建高内聚、低耦合的系统。现在,我们将这一强大的设计模式付诸实践,解决嵌入式开发中最核心的逻辑控制问题。本教程将引导您使用状态模式,构建一个模块化的。我们将彻底告别C语言中庞大的switch语句,转而为每个状态(空闲洗涤漂洗等)创建一个独立的类。最关键的是,我们将解决状态模式在嵌入式应用中的核心挑战——动态内存。通过技术,我们将在编译时就创建好所有状态对象,确保状态机在运行过程中newdelete,从而实现完全的内存确定性。

2025-08-12 18:04:14 790

原创 4.1a. 状态机模式 (State Pattern) 概念

状态机模式通过将每个状态封装成一个独立的对象,将C语言中庞大、集中的状态机逻辑,重构为一系列高内聚、低耦合、可互换的状态类。它完美地遵循了开闭原则,使得添加新状态变得异常简单,而无需修改现有代码。虽然其标准实现依赖虚函数和动态内存,但在嵌入式系统中,我们可以通过预先实例化所有状态对象(状态单例)的方式来完全规避堆分配,使其成为一个安全、确定且强大的架构工具。在下一篇教程 4.1b中,我们将从零开始,完整地实现一个基于状态模式的、无动态内存分配的洗衣机控制器,亲身体验这一高级设计模式的威力。

2025-08-12 17:58:22 777

原创 3.4b. 定制STL - 静态分配器 (Customizing STL - Static Allocators) 应用

来使。

2025-08-11 18:38:04 668

原创 3.4a. 定制STL - 静态分配器 (Customizing STL - Static Allocators) 概念

分配器 (Allocator)是一个C++类模板,它封装了内存的分配和释放策略。每一个标准的STL容器,其模板参数列表中都包含一个可选的分配器类型。以template<class T,class Allocator = std::allocator<T> // 默认的分配器T: 容器中存储的元素类型。Allocator: 负责为这些T类型的元素提供内存的类。这个Allocator参数就是我们能够介入并改变内存行为的关键。STL容器的分配器 (Allocator)

2025-08-11 18:32:40 943

原创 3.3b. STL算法 (STL Algorithms) 应用

在教程 3.3a 中,我们从理论上剖析了STL算法如何通过迭代器与容器解耦,从而提供一套标准、高效且富有表现力的操作集合。。本教程将引导您构建一个。我们将从一个由std::array定义的、模拟ADC采样值的原始数据缓冲区开始,使用多种STL算法来执行常见的分析任务,例如查找极值、数据筛选、单位转换和排序。如何用std::sort等算法替代手写循环,让代码直接表达“做什么”而非“怎么做”。如何使用Lambda表达式就地定义复杂的筛选和转换逻辑,使代码更简洁、更内聚。体验STL算法如何通过迭代器,与。

2025-08-11 18:27:29 968

原创 3.3a. STL算法 (STL Algorithms) 概念

STL算法通过迭代器与数据容器解耦,提供了一套标准、高效、类型安全的操作集合。相比手写循环,STL算法在正确性、可读性和性能上通常具有明显优势。在嵌入式系统中,其主要成本是代码膨胀,因为模板会为每个使用的类型实例化一份代码副本。Lambda表达式与STL算法的结合,是现代C++中编写优雅、高效数据处理逻辑的典范。在下一篇教程 3.3b中,我们将把这些概念付诸实践,使用std::arraystd::span和STL算法库来安全、高效地处理一个传感器数据缓冲区。

2025-08-11 18:26:56 772

原创 3.2b. STL容器 - 认知与选择 (STL Containers - Know and Choose) 应用

其中,std::array作为C风格数组的类型安全替代品,以及std::span作为处理连续内存视图的终极解决方案,是我们的首选工具。本教程将把这一准则付诸实践。我们将构建一个模拟的协议解析器,它从一个由DMA填充的固定大小缓冲区中读取数据。std::array如何使用std::array来定义一个固定大小、内存布局与C数组完全兼容的DMA缓冲区。std::span如何使用std::span作为函数参数,以类型安全、边界明确的方式传递数据缓冲区,彻底告别C语言中这种易错的模式。

2025-08-11 18:26:15 839

原创 3.2a. STL容器-认知与选择 (STL Containers - Know and Choose) 概念

类别容器内存模型嵌入式建议🟢绿灯std::arraystd::span栈 / 静态(无堆)强烈推荐,优先使用🟡黄灯默认堆谨慎使用,必须配合自定义静态分配器🔴红灯std::liststd::mapstd::set默认大量堆分配通常应避免,寻找基于数组的替代方案STL不是一个非黑即白的工具。作为一个专业的嵌入式C++开发者,我们的任务是理解每个组件的成本,并从中(精心挑选) 那些符合嵌入式系统核心约束(内存确定性、性能可预测性)的“零成本”或“可控成本”的抽象。

2025-08-11 18:25:28 824

原创 3.1b. 模板基础 (Template Basics) 应用

在教程 3.1a 中,我们从理论上剖析了模板如何通过编译期代码生成,来实现类型安全、零运行时开销的泛型编程。。回想一下我们在C语言教程中实现的环形缓冲区:它功能强大,但存在一个根本性缺陷——它只能处理uint8_t类型的数据。如果我们想创建一个用于存储float或者结构体的环形缓冲区,就必须复制整个模块的代码并手动修改所有类型定义,或者退回到使用不安全的void*指针。本教程将引导您使用来一劳永逸地解决这个问题。我们将构建一个泛型的RingBuffer类,它可以被实例化来处理。

2025-08-11 18:24:16 879

原创 3.1a. 模板基础 (Template Basics) 概念

模板是C++实现泛型编程和编译期多态的核心机制。它不是代码,而是代码的蓝图,编译器通过实例化的过程为其生成类型专属的代码。模板提供了零运行时开销的抽象,性能极高,但代价是可能导致代码膨胀,增加Flash占用。函数模板用于通用算法,类模板用于通用数据结构,它们是构建类型安全、可复用嵌入式组件的强大工具。在下一篇教程 3.1b中,我们将从零开始,实现一个模块化的、泛型的模板类,亲身体验模板在构建可复用数据结构时的巨大威力。

2025-08-11 18:23:32 1153

原创 2.4. 其他关键C++11特性

本节介绍的四个C++11特性,虽然不像智能指针或移动语义那样从根本上改变大型架构,但它们是构成现代、高质量C++代码的“细胞”。在编译期发现更多的错误,让代码的意图更清晰,让程序员的生活更轻松。并且,这一切都严格遵循零成本抽象原则,完全适用于对性能和内存要求苛刻的嵌入式系统。

2025-08-10 17:55:39 622

原创 2.3b. Lambda表达式 (Lambda Expressions) 应用

在教程 2.3a 中,我们从理论上剖析了Lambda表达式如何通过捕获列表,以类型安全的方式在就地定义的匿名函数中访问外部状态。。本教程将引导您构建一个简单的、非抢占式的。这个服务允许系统的任何部分注册一个在未来某个时间点被执行的动作。我们将对比C++ Lambda与传统C语言回调的实现差异,以突显Lambda在类型安全、代码局部性和简洁性方面的巨大优势。如何使用作为一种通用的、类型安全的回调容器,来存储和调用Lambda表达式。如何通过值捕获 ([=]) 和引用捕获 ([&]

2025-08-10 17:54:34 673

原创 2.3a. Lambda表达式 (Lambda Expressions) 概念

Lambda表达式是一种用于在代码中就地 (inline)定义一个匿名函数对象 (anonymous function object)的简洁语法。它没有正式的函数名。它可以直接在需要一个函数的地方(例如,作为另一个函数的参数)进行定义。编译器会为每个Lambda表达式生成一个唯一的、无名的struct或class,该类重载了operator()(函数调用操作符)。这使得Lambda表达式的实例可以像函数一样被调用。Lambda表达式是在C++中创建匿名、内联函数对象的现代、简洁语法。其核心优势在于。

2025-08-10 17:53:28 914

原创 2.2b. 右值引用与移动语义 (Rvalue References & Move Semantics) 应用

在教程 2.2a 中,我们从理论上剖析了移动语义如何通过“窃取”资源而非“复制”资源,来消除临时对象带来的性能开销。。Message这个类封装了一个来自的数据缓冲区,并为其实现了一套完整的构造/析构/赋值规则,包括拷贝和移动两种语义。一个生产者任务将创建并填充Message对象,然后通过FreeRTOS队列将其发送给一个消费者任务。我们将通过在拷贝和移动构造函数中添加打印语句,清晰地观察到std::move如何将昂贵的操作,转变为几乎零成本的操作。

2025-08-10 17:52:56 529

原创 2.2a. 右值引用与移动语义 (Rvalue References & Move Semantics) 概念

在C++98/03时代,一个常见的性能陷阱是函数返回大型对象。在这个过程中,1024字节的数据被,并伴随着两次堆内存分配。对于嵌入式系统来说,这种开销是不可接受的。我们真正想要的,不是创建一个副本,而是将内部创建的那个缓冲区的直接“转移”出来。C++11通过引入和,完美地解决了这个问题。

2025-08-10 17:52:18 1254

原创 2.1b. 智能指针与所有权 (Smart Pointers & Ownership) 应用

这是本教程的核心。我们定义Packet类,并为其创建一个专门的。private:public:// --- 自定义删除器 (Custom Deleter) ---// --- 类型别名 (Type Alias) ---// 定义一个特殊的 unique_ptr 类型,它绑定了我们的自定义删除器// --- 工厂函数 (Factory Function) ---// 这是创建Packet对象的唯一入口。

2025-08-10 17:51:40 861

原创 2.1a. 智能指针与所有权 (Smart Pointers & Ownership) 概念

C++从C语言继承了以及与之配套的手动内存管理函数new和delete。这套机制虽然灵活,但也带来了与mallocfree忘记调用delete。在内存被delete后,依然尝试使用指向它的指针。对同一个指针调用两次delete。这些问题在复杂的、具有多个退出路径的程序中层出不穷,是导致系统不稳定的主要根源。为了解决这个世纪难题,C++引入了一个强大的编程概念——,并通过这一工具将其付诸实践。

2025-08-10 17:50:39 882

原创 1.2b. 继承与多态 (Inheritance & Polymorphism) 应用

我们首先定义一个抽象基类IODevice,它代表了所有I/O设备都必须遵守的通用接口。// 1. 定义一个抽象基类 (Abstract Base Class)public:// 2. 纯虚函数 (Pure Virtual Functions) 定义了接口// 它们没有实现,强制所有派生类必须提供自己的版本。// 3. 黄金法则:基类如果有多态行为,其析构函数必须是虚函数!// 这确保了通过基类指针删除派生类对象时,能正确调用派生类的析构函数。

2025-08-09 21:17:44 411

原创 1.2a. 继承与多态 (Inheritance & Polymorphism) 概念

有时,我们希望定义一个纯粹的接口,基类本身不提供任何有意义的实现,而是强制所有子类必须提供自己的实现。这通过纯虚函数 (Pure Virtual Function)来实现。public:// 纯虚函数:以 '= 0' 结尾// 虚析构函数:重要!任何包含至少一个纯虚函数的类,都成为一个抽象基类。你不能创建一个抽象基类的实例 (会导致编译错误)。它只能作为基类被继承。任何从Sensor派生的子类,必须提供函数的具体实现,否则它自己也将成为一个抽象类。为什么需要虚析构函数?

2025-08-09 21:16:59 1037

原创 1.1b. 封装 (Encapsulation) 应用

在教程 1.1a 中,我们从理论上剖析了封装如何通过class、访问控制和构造/析构函数,来构建比C语言struct更安全、更内聚的对象。。我们将告别C语言中“数据结构+全局函数”的分离模式,转而创建一个GpioPin类。这个类将把一个GPIO引脚所需的所有状态(端口地址、引脚号)和行为(设置模式、置高、置低、读取)在一个独立的、自洽的单元中。设计并实现一个GpioPin类,对外暴露清晰的公共接口,对内隐藏底层的寄存器操作细节。

2025-08-09 21:16:26 370

原创 1.1a. 封装 (Encapsulation) 概念

封装是面向对象编程的第一大支柱,它通过class将C语言中松散的数据和函数,整合成一个高内聚、低耦合的逻辑单元。将数据(状态)和方法(行为)捆绑在一起。使用 public定义稳定接口,使用 private隐藏实现细节,保护内部状态。通过构造函数保证对象的有效初始化,通过析构函数保证资源的自动释放(RAII在嵌入式开发中,封装的意义尤为重大。它让我们能够创建出像GpioPinI2CDeviceTimer这样的硬件抽象层(HAL),这些抽象层接口清晰、使用安全、内部实现与上层应用完全隔离。

2025-08-09 21:15:45 1223

原创 0.3. 构建与互操作 (Build & Interoperability)

在嵌入式世界中,一个纯粹的C++项目是极其罕见的。绝大多数MCU的硬件抽象层(HAL)、实时操作系统(RTOS,如FreeRTOS)、以及历史悠久的协议栈都是用纯C语言编写的。我们可能希望在一个现有的、稳定的C语言项目中,逐步引入C++来编写新的业务逻辑,以利用其更强大的抽象能力。因此,深刻理解如何构建一个C与C++混合的项目,并确保两者之间能够正确、高效地相互调用,是每一位嵌入式C++开发者的基本功。本教程将为您揭示这背后的编译器魔法,并提供一套标准的实战解决方案。

2025-08-09 21:14:49 876

原创 0.2. RAII原则:嵌入式C++的基石 (Resource Acquisition Is Initialization)

无论是malloc后的freefopen后的fclose,还是获取互斥锁后的释放,程序员都必须在代码的每一个可能的退出路径上,确保资源被正确释放。正如我们在C教程1.2节的“函数单一出口”示例中所见,这种手动管理极易出错,是导致内存泄漏、资源死锁等顽固bug的主要根源。C++通过一个强大而优雅的设计原则,从根本上解决了这个问题。这个原则就是,直译为“资源获取即初始化”。将资源的生命周期与一个栈上对象的生命周期绑定。在对象的中完成。在对象的中完成。

2025-08-09 21:14:12 1071

原创 0.1. C++不仅仅是 更好的C (C++ is More than a better C)

抽象?封装?这听起来会增加开销!我的MCU只有32KB的RAM!”——这是每一个嵌入式C开发者转向C++时最合理的担忧。然而,C++语言的核心设计哲学正是为了打消这个疑虑,即零成本抽象。(你没用到的功能,你无需为其付出任何代价。更进一步:你所用到的功能,其性能与你自己手写的高度优化的C代码相比,不相上下。— Bjarne Stroustrup (C++之父)这意味着,C++提供的类、模板、Lambda等高级抽象工具,其目标是在编译期。

2025-08-09 21:13:29 803

原创 0.0. 嵌入式C++进阶知识树 - 目录 (基于C++11)

构造函数 (Constructors) 与析构函数 (Destructors) 的核心作用。如何通过“窃取”资源而非“复制”资源,实现消息、缓冲区等对象在任务间传递的极致性能。模板的编译期多态与代码膨胀 (Code Bloat) 问题分析。学习如何编写一个自定义的STL分配器,使其从我们C教程中实现的。编译器与C的差异:名称修饰 (Name Mangling)。函数模板与类模板:编写泛型、类型安全的代码。(虚函数表) 的内存开销与性能成本分析。) 与多态:实现统一接口下的不同行为。

2025-08-09 21:11:34 1579

原创 6.2 多通道数据采集与命令处理系统 具体实现

在教程 6.1 中,我们搭建了“多通道数据采集与命令处理系统”的完整框架,定义了所有模块的接口和核心数据结构。现在,是时候填充这些框架,编写出能够驱动系统运行的实际代码了。本教程将提供所有模块的完整.c文件实现。我们将从最底层的工具模块(日志器)开始,逐步构建到核心的业务逻辑(主控制器、CLI管理器),最后完成顶层的多任务调度。您将亲眼见证,一个复杂的嵌入式系统是如何由一个个高内聚、低耦合的模块协同工作而成的。

2025-08-04 11:16:34 1006

原创 6.1 多通道数据采集与命令处理系统 框架设计

通过定义以上头文件,我们已经成功地搭建起了整个固件的架构。高层模块(如)和底层模块(如adc_task)都不直接相互依赖,它们都依赖于一个共同的抽象——。这使得系统高度解耦。每个.h文件都定义了“做什么”(What),而将“怎么做”(How)的细节留给了.c文件。例如,没有暴露任何关于哈希表的细节,调用者无需关心其内部实现。整个系统的行为将由在中定义的事件消息来驱动,而不是通过复杂的函数调用链。这个坚实的框架为我们下一节的编码实现铺平了道路。

2025-08-04 11:15:13 714

原创 6. 最终综合实战项目 - 模块化固件架构

在开始最终项目之前,让我们简要回顾一下整个知识树的核心脉络:第一、二章 (基础与基本类型):我们确立了嵌入式C编程的基石:内存安全 与 行为确定性。我们学习了内存的五大区域,理解了MISRA C等编码规范的重要性,并掌握了为何必须使用 <stdint.h> 和 <stdbool.h> 中的固定宽度类型来编写可移植、无歧义的代码。第三章 (复合数据类型):我们掌握了构建复杂数据模型的工具。指针 用于高效的内存访问和参数传递;数组 和 字符串 用于处理连续数据和文本;

2025-08-04 11:14:03 735

原创 5.2.3. 图在嵌入式中的应用

在前面的章节中,我们学习了如何用代码来表示一个图,并如何系统性地遍历它。现在,我们将利用这些基础,解决一个更具挑战性也更具实用价值的问题:在一个复杂的网络中,如何找到从A点到B点的“最佳”路径?一个传感器节点如何通过最少的跳数或最可靠的链路,将数据传送到网关?在一系列有依赖关系的任务中,完成一个最终目标所需的最短关键路径是什么?一个网络数据包应该经过哪些路由器才能最快地到达目的地?本教程将以为背景,引导您实现解决此类问题的经典算法——。来表示一个带权重的网络拓扑。

2025-08-04 11:13:22 832

原创 5.2.2. 图的遍历

在教程 5.2.1 中,我们学习了如何用邻接矩阵和邻接表来表示一个图。仅仅表示图是不够的,我们还需要一套系统性的方法来访问图中的所有顶点,这就是。图的遍历是解决路径查找、连通性分析、拓扑排序等众多高级图问题的基础。一种“不撞南墙不回头”的探索策略,它会尽可能深地沿着一条路径前进,直到无法再前进时才回溯。我们将使用我们之前构建的来实现一个安全的迭代版本。一种“层层推进”的探索策略,它会先访问所有距离起点最近的邻居,然后再逐层向外扩展。我们将使用我们之前构建的来实现其核心的队列逻辑。

2025-08-04 11:12:14 745

原创 5.2.1. 图的表示方法

在教程 5.2 中,我们从理论上剖析了图的两种主要表示法:邻接矩阵和邻接表,并分析了它们在空间和时间复杂度上的权衡。现在,我们将把这些理论蓝图转化为坚实的代码。本教程将引导您完成两个独立的、模块化的图ADT实现,两者都严格遵循嵌入式开发的内存安全原则(即malloc体验其O(1)的边查找速度和直观的实现方式。实践如何结合来构建一个空间效率极高的图表示,这对于稀疏图是至关重要的。最后,我们将通过一个统一的测试用例来对比这两种实现,让您在实践中深刻理解它们各自的优劣和适用场景。

2025-08-04 11:11:31 332

原创 5.2. 图 (Graphs)

图是用于表示多对多关系的终极数据结构,比树更为通用。在C语言中,图主要通过邻接矩阵或邻接表来实现。对于内存受限的嵌入式系统,邻接表通常是更优的选择。DFS和BFS是图的两种基本遍历算法,是解决路径查找、排序和网络问题等众多图算法的基础。图为嵌入式系统中的网络路由、任务依赖、资源管理等复杂问题提供了强大的数学模型和算法基础。实现图结构时,必须采用静态内存分配策略,以保证系统的确定性和稳定性。在接下来的5.2.x。

2025-08-04 11:10:47 886

原创 5.1.4b. 设备树 (Device Tree) 应用

在教程 5.1.4a 中,我们理解了设备树(Device Tree)作为一种硬件描述语言,如何将硬件信息与操作系统内核解耦。为一个假想的、但贴近现实的嵌入式开发板my-board创建硬件描述。使用标准的设备树编译器(DTC)将人类可读的源文件转换为机器可读的二进制格式。我们将编写一个C程序,使用标准的libfdt库来加载和解析我们生成的.dtb文件,并从中提取出具体的硬件配置参数,就像一个真正的设备驱动所做的那样。

2025-08-03 22:48:36 614

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除