- 博客(25)
- 收藏
- 关注
原创 Android 系统源码阅读与编译构建实战指南
对于 Android 系统开发者而言,AOSP 源码仓库体量极为庞大(通常数十 GB,包含数百万个文件)。在服务器环境或本地性能受限的机器上,使用 Android Studio 或 VS Code 打开整个源码树往往会带来灾难性的体验:相比之下,Vim + ctags 的组合是一种轻量级且高效的 “终端原生” 阅读方案。它无需图形界面,无需等待数小时的全量索引,只需在特定子目录下快速生成 文件,即可实现毫秒级的符号跳转。这种工作流尤其适合在内核层、HAL 层、Native 层进行快速的逻辑追踪与代码考古。
2026-04-16 19:54:25
92
原创 Android 与 Linux 对比
Android 其实就是跑在 Linux 内核上面的一个 Linux 应用,只不过这个应用极其复杂,内部塞了一个虚拟机(ART),并管理着所有其他应用。这个“复杂应用”的名字可以叫做“Android 用户空间软件栈”。它启动后,会创建等进程,然后不断孵化出新的进程来运行微信、淘宝、抖音等 App。从 Linux 内核的视角看,这些 App 进程与普通的grep进程没有本质区别 —— 它们都拥有 PID、内存映射、文件描述符,只是它们内部的执行逻辑是 DEX 字节码。Android 的架构。
2026-04-16 14:14:09
563
原创 C++组合(Composition)与委托(Delegation)
关系has-a(拥有)。组合表示“整体-部分”的关系,部分属于整体。生命周期:部分对象的生命周期与整体对象严格一致。整体创建时部分也被创建,整体销毁时部分也销毁。实现方式:通常将部分对象作为整体的成员变量(不是指针或引用),直接在构造函数中初始化。耦合度:高耦合。整体直接依赖具体的部分类,不能轻易替换为其他类型的部分。灵活性:低。组合关系在编译时就已经确定,运行时无法改变部分对象的类型或实例。关系use-a(使用)。委托表示“一个对象将某些工作转交给另一个对象去做”。生命周期:委托者不负责。
2026-04-15 08:39:01
446
原创 C++ 继承、多态与虚函数
虽然纯虚函数 = 0 声明,但可以为其提供一个实现(在类外定义)。派生类必须重写它,但可以在重写函数中显式调用基类版本。不过这种用法很少见。public:} // 提供实现public:// 调用基类实现概念关键字 / 语法核心要点继承复用基类代码,注意访问控制与构造/析构顺序访问控制publicprotectedprivate影响派生类内外对基类成员的可见性,private继承几乎不用虚函数支持多态,允许派生类重写重写override(C++11)
2026-04-14 11:45:19
422
原创 C++ const 用法
使用const定义不可修改的常量。// x 的值不可改变// x = 200;// 错误用法含义能否修改const T x;常量变量否常量引用不能通过引用修改const T* p;指向常量的指针不能通过p修改指向的内容T* const p;常量指针不能改变p的指向指向常量的常量指针两者都不能改const成员函数不修改对象状态(除mutable非mutable成员只读const对象只能调用const成员函数同上可在const函数中修改任意位置均可。
2026-04-14 11:44:48
185
原创 C++ 静态数据成员与静态成员函数
静态数据成员必须在类内声明,在类外(文件作用域)定义并初始化(除静态常量整型成员外)。定义时不需要重复static关键字,但需要加上类名和作用域运算符。public:// 静态成员函数声明private:// 静态数据成员声明(引用性声明)#endif// 静态数据成员定义性声明,在文件作用域初始化++count_;--count_;特性静态数据成员非静态数据成员存储位置全局数据区,独立于对象每个对象各自的内存空间初始化类外定义时初始化,仅一次。
2026-04-13 17:17:35
324
原创 Linux Pinctrl 子系统详解
Linux Pinctrl子系统通过标准化的服务端/客户端模型,将引脚配置从硬件细节中抽象出来。芯片厂商实现+ ops,并注册控制器。设备树编写者在客户端节点中声明和。内核Pinctrl Core在设备probe前自动解析设备树,调用驱动回调完成硬件配置。驱动开发者也可以在运行时调用动态切换状态(如电源管理)。这种设计极大简化了驱动开发,避免了引脚配置冲突,是Linux SoC支持中的关键基础设施。理解Pinctrl,对于阅读和编写嵌入式Linux板级支持包(BSP)至关重要。
2026-04-13 13:53:14
838
原创 C++ 嵌套类与局部类
嵌套类的成员函数可以在类体外定义,但需要使用两层作用域限定外围类::嵌套类::函数名。public:public:// 声明// 声明// 在外部定义嵌套类的成员函数// 也可以分多行定义in.func1();// 输出:Inner::func1 defined outsidein.func2();// 输出:Inner::func2return 0;局部类的所有成员函数必须在类体中定义(不能在外面单独定义),因为函数外部无法访问局部类的名字。public:// 定义在类体内。
2026-04-08 23:35:45
354
原创 C++ 类的初始化与相互包含
构造函数冒号后面、函数体之前的部分,用于直接初始化成员变量。int age;public:Student(const string& n, int a) : name(n), age(a) { // 初始化列表// 函数体初始化相关概念关键点成员初始化列表const、引用、无默认构造的成员必须用;顺序按声明,不按列表包含关系循环依赖用指针/智能指针;初始化顺序:基类 → 成员(声明序)→ 构造函数体数组/vectorC++11 类内初始化;构造函数中可用列表或循环委托构造。
2026-04-07 11:37:24
167
原创 C++ 引用
int a = 5;// 正确// 错误:必须初始化假设MyString没有移动构造函数,只有拷贝构造函数(通常由编译器自动生成,会拷贝vector的所有元素)。// 拷贝:会把 a.data 的 5 个字符逐个复制到新内存拷贝完成后,a和ba.data 指针 → [H][e][l][l][o] (堆内存 A)b.data 指针 → [H][e][l][l][o] (堆内存 B,内容相同)如果a马上就要被销毁(例如作为函数返回值),那么堆内存 A 将被释放,白白浪费了复制和释放的开销。移动语义。
2026-04-07 09:45:50
261
原创 GPIO子系统笔记
GPIO 的全称是(通用输入输出),它是一种软件运行期间可以动态配置和控制的通用引脚。通用性:同一个引脚可以用于不同功能(输入、输出、中断等)。输入输出:既能读取外部信号(如按键状态),也能输出高低电平(如控制 LED)。初始状态:所有 GPIO 在上电后默认处于输入模式,可通过软件配置上拉/下拉、驱动强度等。假设我们有一个 GPIO 引脚(例如GPIO1_A0),需要能够在 GPIO 功能和 I2C3_SDA 功能之间动态切换。和"func_i2c"。/ {
2026-04-02 15:42:25
392
原创 Linux Platform 虚拟总线驱动模型
/ 定义内存资源:起始地址 0xfd60004,大小 4 字节0xfd60004// 定义中断资源:中断号 23// 初始化硬件、注册设备等return 0;// 释放资源return 0;{ },.name = "my_driver", // 用于名称匹配.of_match_table = of_match_ptr(my_of_ids), // 设备树匹配表},.id_table = my_ids, // 可选 ID 表函数功能根据节点名称查找设备树节点。
2026-04-01 17:24:40
662
原创 Linux 内核中断笔记
机制上下文可睡眠并发特性适用场景软中断软中断上下文(原子)否同种可多 CPU 并发,需锁高性能网络、块设备tasklet软中断上下文否同种单 CPU 串行,无锁简单设备驱动,中等耗时工作队列(传统)进程上下文是单 CPU 串行,低并发耗时任务,可睡眠CMWQ进程上下文是动态线程池,高并发现代驱动推荐中断线程化进程上下文(内核线程)是每中断独立线程实时性要求高的系统选择建议极短、不可睡眠的任务:直接在上半部完成。稍长但不可睡眠:使用 tasklet。
2026-03-31 15:50:48
593
原创 V4L2 的 ioctl 调用流程
通过追踪,我们可以看到 Linux 内核中 VFS 层、V4L2 框架层、主机驱动与子设备分离架构,以及总线模型的经典配合。这种高度抽象的设计虽然增加了代码的调用深度,但换来的是极佳的代码复用性和系统稳定性。
2026-03-24 17:20:26
483
4
原创 Linux模块化编程基础
驱动模块传参允许在加载模块时动态传递参数,例如配置串口的波特率,从而避免重新编译模块,提高调试效率。核心宏:参数说明:实验代码 ():加载示例:1.2 内核模块符号导出内核模块之间是相互独立的,一个模块无法直接访问另一个模块的函数或变量。通过符号导出,可以将模块中的函数或变量导出到公共内核符号表中,供其他模块使用。导出宏:实验代码:导出模块 (math.c):使用模块 (hello.c):Makefile (同时编译两个模块):1.3 内核模块详细加载/卸载过程KO文件格式: 内
2026-03-23 13:42:38
584
原创 T113S3系统移植(基于T113S3 TinaSDK5.0V1.2)
通过上述四个核心阶段的深度拆解与实战,我们完成了一块基于 T113-S3 芯片的新主板从“点亮”到“完全可用”的全链路移植闭环。向下扎根(底层破冰):理清了 SPI NAND 的启动逻辑,精准配置了 U-Boot 与 Linux Kernel 的软硬件交接点(FEX 与 DTS),并成功完成了 FL7707 MIPI 屏幕等非标外设的驱动级移植与时序同步。向上生长(系统重构):通过果断剥离 OpenWrt 黑盒的procd,换用线性可控的框架,彻底接管了系统的启动生命周期。
2026-03-19 16:09:28
1019
原创 全志 Tina Linux 开发:ADB 权限问题与 gpio-keys 按键调试
学会利用dmesgudevadm和下的节点去探听底层的真实声音,所有的 BUG 最终都会无处遁形。
2026-03-18 11:32:12
386
原创 文件持久化和OSAL接口封装架构
OSAL 是操作系统抽象层(Operating System Abstract Layer)的缩写。在嵌入式开发中,系统可能会面临跨平台的需求。例如,当前项目在 Linux 系统下运行,创建线程使用的是。但如果将来项目需要移植到 FreeRTOS 上,它的任务创建函数变成了。如果没有抽象层,我们就需要全局搜索并修改所有调用了的业务代码,不仅工作量大而且极易引入 Bug。因此,我们通过搭建 OSAL 层,让应用层统一调用类似的抽象接口。更换系统时,只需重写这个接口的底层实现即可,实现完美解耦。
2026-03-17 10:39:03
506
原创 进程间通信IPC
Ctrl+CSIGUSR1信号量初始值作用sem_writer1相当于“令牌”。Writer 拿到令牌后写入,写完不归还给自己,而是给 Reader。sem_reader0相当于“通知”。当其 > 0 时,Reader 知道数据准备好了,读完后把“令牌”还给 Writer。**掌握这些底层机制,不仅是为了编写更高效的代码,更是为了在面对复杂的系统架构设计时,能够从容不迫地选择出那把最合适的“钥匙”。**希望这篇指南能成为你 Linux 编程之路上的垫脚石。
2026-03-10 16:26:39
465
原创 Linux 内核与驱动调试指南
优秀的驱动开发工程师不仅需要具备扎实的内核源码阅读能力,更需要建立体系化的排错思维。从printk的日志流分析,到devmem与i2c-tools的底层硬件验证,再到Ftrace与Crash的纵深剖析,灵活组合并运用上述调试工具链,将显著提升嵌入式 Linux 平台的系统开发与维护效率。
2026-03-08 21:44:52
621
原创 为什么不能在Linux消息队列中传指针?深入理解IPC、浅拷贝与虚拟内存
摘要: Linux进程间通信(IPC)中直接传递带指针的结构体会导致段错误。这是因为消息队列只进行浅拷贝,复制指针值而非指向的数据。而不同进程的虚拟内存空间隔离,使得接收方无法访问发送方的指针地址。解决方案是:1) 改用固定大小数组替代指针;2) 传递文件描述符而非内存指针;3) 使用共享内存配合同步机制。开发者必须理解操作系统的虚拟内存机制,避免跨进程传递无效内存地址。
2026-03-05 00:10:15
521
原创 深入理解Linux进程间通信:普通文件与流文件的底层读写差异
Linux系统中,普通文件和流文件(如管道)在进程间通信时存在关键差异。当父子进程通过fork()共享同一个文件描述符时,它们会共享底层文件表项中的文件偏移量(f_pos),导致父进程写入后子进程必须使用lseek重置偏移量才能读取数据。而非亲属进程独立打开同一文件时,内核会创建不同的文件表项,各自维护独立的偏移量,因此不需要lseek操作。理解这种底层机制对开发可靠的多进程应用至关重要,特别是在处理进程间通信和状态同步时。
2026-03-04 23:35:01
530
原创 VSCode + SSH 构建 Linux 远程 C 语言开发环境
通过上面三个简单的例子,我们可以看到:在 VSCode 远程环境中,从多文件管理、到底层 API 的智能补全,再到集成 AI 助手自动生成代码,整个开发体验得到了质的飞跃。Linux C 语言开发中,有大量重复性的结构体定义或模板代码,现在完全可以交给 AI 来完成。
2026-03-03 22:03:19
466
原创 GCC 交叉编译与链接技术笔记
不是的,如果代码在其他系统上运行,且没有相应的库时,解决办法就是使用静态库。程序只有经过编译才能够运行,虽然ARM 板性能越来越强,可以认为 ARM 板就相当于一台 PC,但它的性能再强也强不过 PC 机,在对上万个文件工程同时编译的话用arm可太浪费时间了,所以更多时候我们是在 PC 机上开发、编译程序,再把这个程序下载到 ARM 板上去运行。在链接阶段中,所有对应于源程序的.o文件,“-l”选项指定的库文件,无法识别的文件名(包括指定的“.o”目标文件和“.a”库文件)按命令行中的顺序传递给链接器。
2026-03-02 21:40:54
588
原创 ARMv7 架构的简单介绍
IMX6UL 使用 Cortex-A7 架构,简单介绍一下 Cortex-A7 架构的基础知识,如运行模式、切换模式、寄存器组等Cortex-A7 架构的运行模式有 9 种,分别为 User、Sys(System)、FIQ、IRQ、ABT(Abort)、SVC(Supervisor)、UND(Undef)、MON(Monitor)、Hyp 模式。除了 User 模式属于非特权模式,其它 8 种处理器模式都是特权模式,运行模式可以通过软件进行任意切换,也可以通过中断或者异常来进行切换。
2026-03-02 21:03:23
695
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅