高级嵌入式Linux开发板学习教程
文章平均质量分 94
charlie114514191
我是一个普通的嵌入式软件程序员,喜欢研究Linux(应用层跟内核从都有粗浅的涉略),单片机,操作系统和计算机体系架构等内容,目前是一枚普通的本科生。
笔者是一个朴素的开源主义者,我坚信代码和知识没有壁垒,也不应该有壁垒所在,任何人都应该平等的获取到所有的知识。笔者力所能及的将自己的代码项目开源到Github
笔者的github:https://github.com/Charliechen114514
笔者的私人博客(旧):https://charliechen114514.github.io/
笔者的私人博客(新):https://www.charliechen114514.tech/
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
RK3506主线U-Boot移植实战:跨过闭源RKbin的三道坎 开源项目rk-forge成功在冷门芯片RK3506上运行主线U-Boot(2026.07-rc4),核心突破在于与闭源启动组件(rkbin)的适配过程。文章揭示了三个关键技术点: FIT镜像结构复刻:必须严格仿照厂商FIT格式(optee@0x1000 + uboot@0x200000),仅替换U-Boot二进制,否则SPL会因结构不匹配报错; 地址对齐陷阱:主线U-Boot的TEXT_BASE(0x800000)与厂商预设(0x200000原创 2026-06-26 09:31:18 · 563 阅读 · 0 评论 -
嵌入式Linux:按键消抖与内核同步:从消抖算法到自旋锁/等待队列一次讲透
嵌入式Linux按键驱动:消抖与同步机制详解 本文深入探讨了嵌入式Linux下按键驱动的两个核心技术:按键消抖算法和内核同步机制。文章首先介绍了消抖的核心思想——延时20ms等待机械抖动结束,然后详细分析了工作队列处理函数的实现步骤: 使用msleep_interruptible(20ms)等待抖动稳定 读取GPIO稳定状态 通过状态比较过滤无效抖动 更新状态并唤醒等待队列 统计抖动次数验证消抖效果 文章还解释了为何使用schedule_work而非schedule_delayed_work,并提供了完整的原创 2026-06-25 20:06:07 · 165 阅读 · 0 评论 -
.img / .iso / .tar.gz / .ext4 到底谁是谁?一张表理清嵌入式打包与镜像格式
本文通过一张表格梳理了嵌入式开发中常见的打包与镜像格式(如.img、.iso、.tar.gz、.ext4等)之间的区别。核心观点是:能直接dd烧录整盘的只有整盘镜像(.img/.iso),其他格式需区分对待。文章将这些格式分为四类:整盘镜像(关心磁盘布局)、文件系统镜像(如ext4)、文件归档(如tar/zip)和启动专用二进制(如zImage)。重点强调了不同格式所处的层级关系及对应的操作方法,帮助开发者准确识别和使用各类文件格式。原创 2026-06-20 10:40:22 · 218 阅读 · 0 评论 -
嵌入式Linux:镜像、分区与文件系统:.img 到底是什么
本文解释了.img文件的本质与结构,它不是简单的文件夹压缩包,而是整块存储设备的完整镜像。文章通过分层结构阐述其组成:整盘设备包含分区表(如MBR),分区表下划分多个分区(如boot和rootfs分区),每个分区内建有文件系统(如ext4),文件系统里存放具体文件。重点区分了U-Boot(直接写入磁盘raw区域)与内核文件(存放在boot分区)的不同层级,并说明为何完整镜像必须写入整盘设备而非分区。最后指出理解这些层级关系对正确操作镜像文件至关重要。原创 2026-06-19 09:32:40 · 613 阅读 · 0 评论 -
Linux 工作队列:把中断里做不了的事推迟到进程上下文
文章摘要:本文介绍了Linux内核中工作队列的工作原理及其在中断处理中的应用。工作队列用于将中断上下文中无法执行的耗时操作(如延时、睡眠等)推迟到进程上下文执行。作者通过按键消抖的实际案例,阐述了中断上下文的限制(不能睡眠、不能调用可能睡眠的API),并详细讲解了工作队列的API使用(INIT_WORK、schedule_work等)、处理函数编写技巧(container_of宏使用)以及调试方法。文章还对比了工作队列与定时器的适用场景,并提供了选择指南。最后强调了工作队列是解决"中断上下文不能睡眠"问题的原创 2026-06-16 09:44:10 · 183 阅读 · 0 评论 -
嵌入式Linux驱动开发——从轮询到中断
文章摘要 本文介绍了嵌入式Linux驱动开发中从轮询到中断的升级过程。轮询方式存在CPU占用高、响应延迟不可控等问题,而中断方式通过硬件通知机制实现了高效的事件驱动。文章重点阐述了中断处理的核心思想,包括上下半部机制和工作队列的应用,特别针对按键抖动问题提出了延时读取的解决方案。通过对比轮询与中断方式的性能差异,展示了中断在响应速度、CPU占用和功耗方面的优势。文章还详细解析了驱动结构和工作流程,帮助读者理解从用户空间到硬件再返回的完整数据通路。原创 2026-06-13 09:38:31 · 226 阅读 · 0 评论 -
嵌入式Linux实战:GPIO 输入机制 - 配置和读取那些事儿
本文详细介绍了嵌入式Linux中GPIO输入机制的配置和读取方法。主要内容包括: GPIO输入/输出API对比,展示如何使用Descriptor API进行配置和操作 GPIO输入模式的初始化流程,包括设备树解析、GPIO申请和方向设置 GPIO物理电平与逻辑值的转换机制,解释GPIO_ACTIVE_LOW的处理过程 内核源码分析,展示gpiod_get_value()的内部实现 托管资源(devm_)机制的优势和使用方法 核心API总结:获取、读取和释放GPIO的完整流程 文章强调Linux GPIO子系原创 2026-06-12 08:57:44 · 342 阅读 · 0 评论 -
嵌入式Linux驱动:GPIO 按键驱动 - 我们终于要从输出走向输入了
本文介绍了嵌入式Linux中GPIO按键驱动的开发要点。作者通过对比输出和输入设备的本质区别,指出按键驱动的核心挑战在于被动响应机制。文章详细分析了按键驱动需要解决的三个关键问题:检测时机、按键抖动和CPU占用率。作者建议采用循序渐进的学习路径,先掌握轮询方式再过渡到中断方式。硬件方面描述了按键的典型电路连接(上拉电阻+低电平触发),并通过设备树配置示例说明了GPIO_ACTIVE_LOW参数的重要性。本文为开发可靠的按键驱动提供了实用指导,特别适合嵌入式Linux驱动初学者。原创 2026-06-11 09:17:22 · 207 阅读 · 0 评论 -
嵌入式Linux开发——烧写你的镜像:存储介质基础 - 先分清 SD、eMMC 和块设备
本文介绍了嵌入式Linux开发中SD卡和eMMC两种存储介质的基础知识,重点讲解了块设备的概念和使用方法。主要内容包括: SD卡和eMMC的区别:SD卡可拔插,eMMC焊在板子上需通过UMS模式烧录 Linux块设备的概念:整盘设备(/dev/sdb)与分区设备(/dev/sdb1)的区别 镜像烧录原则:完整.img镜像必须写入整盘设备,不能写入分区 设备命名规则:主机与开发板上的不同命名方式(/dev/sdX vs /dev/mmcblkX) 设备识别方法:使用lsblk命令前后对比,或在U-Boot中使原创 2026-06-10 08:39:52 · 585 阅读 · 0 评论 -
从0开始理解Linux时间管理:jiffies到hrtimer的演进
Linux时间管理演进:从jiffies到hrtimer 摘要 本文深入探讨了Linux内核时间管理机制的演进,重点比较了jiffies和hrtimer两种时间管理方式。文章首先介绍了jiffies作为内核基础"心跳计数器"的原理,分析了HZ参数对时间精度和系统开销的影响,并详细讲解了jiffies的回绕问题及解决方案。随后,文章重点介绍了Linux 7.0中定时器(timer_list)的重大改进,包括API变化、新增标志位及正确使用方法。通过新旧API对比,展示了从传统jiffies定时器到现代高精度定原创 2026-06-07 10:28:18 · 245 阅读 · 0 评论 -
嵌入式Linux实战——信号量与互斥体:会睡觉的锁
上一节我们讲了自旋锁,那个让CPU「傻傻空转」的锁。如果临界区很长,等待的CPU就浪费很多时间在空转上。不能在临界区里睡觉。这意味着你不能在锁里调用任何可能阻塞的函数——不能拷贝用户空间数据,不能用GFP_KERNEL分配内存,不能等待硬件响应。那怎么办?会让等待者睡觉的锁。信号量(Semaphore)和互斥体(Mutex)。所有权:互斥体有「所有者」的概念。只有获取锁的线程才能释放锁递归检测:同一个线程不能递归获取同一个互斥体(除非显式初始化为可递归)调试支持。原创 2026-06-06 07:41:42 · 233 阅读 · 0 评论 -
嵌入式Linux——为什么你的内核会死锁
上一节我们聊了原子操作,最后提到了这种「先到先得」的逻辑。这其实就是一个最简单的自旋锁原型。如果你能理解「如果位已经被置1了,我就得在循环里一直等到它变0」,那你其实就已经理解了自旋锁的一半了。这一节,我们要把这半个位,扩展成一个内核正式承认的「锁」。老实说,自旋锁是我踩坑最多的地方。第一次用的时候,我以为「不就是加锁解锁吗」,结果系统直接死锁。第二次用的时候,我以为「这次我注意了,不在锁里睡觉」,结果系统还是死锁了。第三次,我终于理解了——自旋锁不是玩具,它有它的脾气。Linux内核用。原创 2026-06-05 09:14:23 · 237 阅读 · 0 评论 -
原子操作实战指南:Linux内核7.0最轻量的并发控制
a = 3怎么用?首先定义原子变量。atomic_t a;/* 定义一个原子变量 a */通常我们在定义的时候就要给它赋个初值,这时候要用专用宏/* 定义 b 并初始化为 0 *//* 静态初始化 *//* 或者动态初始化 *//* 运行时设置 */原创 2026-06-02 07:30:30 · 172 阅读 · 0 评论 -
从0开始理解Linux内核并发:多核时代的生存法则
老实说,当我第一次在代码里遇到并发bug的时候,我是真的懵了。不是因为代码有多难理解——那只是几个全局变量和一个简单的计数器——而是因为这个问题完全不可复现。开发环境跑得好好的,到了用户手里就莫名其妙崩溃;调试了一百次都没问题,第一百零一次,因为timing的微小差异,系统崩了。这类bug最折磨人的地方在于它的「幽灵性」。你调了一整天,什么都查不出来,准备下班的时候,它又出现了。你开始怀疑人生,怀疑CPU,甚至怀疑是不是量子力学在作祟。但当你真正理解了并发之后,你会发现这一切都有迹可循。原创 2026-05-29 08:04:07 · 678 阅读 · 0 评论 -
嵌入式Linux驱动开发——设备树中的 GPIO 配置实战
本文介绍了嵌入式Linux驱动开发中设备树的GPIO配置方法。主要内容包括: GPIO控制器节点定义的关键属性 GPIO属性的两种写法:单数形式(xxx-gpio)和复数形式(xxx-gpios) GPIO引用的标准格式及标志位说明 驱动代码解析GPIO的两种API方法 检查GPIO引脚冲突的实用方法 完整的设备树配置示例 其他外设(SD卡、I2C)的GPIO使用示例 文章特别强调了复数形式(xxx-gpios)是内核推荐写法,并详细解释了GPIO_ACTIVE_LOW和GPIO_ACTIVE_HIGH的区原创 2026-05-27 09:33:46 · 690 阅读 · 0 评论 -
嵌入式Linux驱动开发——GPIO 子系统架构深度解析
嵌入式Linux GPIO子系统架构解析 本文深入剖析了嵌入式Linux中的GPIO子系统架构。GPIO子系统采用分层设计,上层提供统一API接口,下层对接不同硬件平台,实现了硬件无关的GPIO操作接口。 核心内容包括: GPIO子系统分层架构:应用层→核心层→控制器驱动层→硬件层 关键数据结构gpio_chip及其操作方法 i.MX平台GPIO控制器驱动实现细节: 硬件描述结构mxc_gpio_hwdata 端口结构mxc_gpio_port 设备树匹配机制 驱动probe函数初始化流程 该设计使上层驱动原创 2026-05-26 06:52:02 · 614 阅读 · 0 评论 -
嵌入式Linux驱动开发——Pinctrl 子系统架构深度解析
本文深入解析了Linux内核中的Pinctrl子系统架构,将其比喻为"翻译官、复用管理员、电工"三重角色。文章从硬件到软件的桥梁作用入手,详细介绍了Pinctrl子系统如何将设备树配置转换为硬件寄存器操作、统一管理引脚复用以及配置电气特性。核心内容包括:1) 关键数据结构如pinctrl_pin_desc、imx_pin和pinctrl_dev;2) 三个核心操作结构体(pinctrl_ops、pinmux_ops、pinconf_ops)的功能实现;3) 具体实现流程,如imx_dt_node_to_ma原创 2026-05-23 07:40:30 · 444 阅读 · 0 评论 -
嵌入式Linux驱动开发——开始pinctrl之前,快速回顾i.MX 6ULL 引脚复用与 GPIO 硬件原理
本文介绍了i.MX 6ULL芯片的引脚复用与GPIO硬件原理。主要内容包括: 引脚复用概念:一个物理引脚可配置为多种功能(如UART、SPI、I2C等),通过IOMUXC控制器选择功能模式。 引脚配置: MUX寄存器选择引脚功能模式(如GPIO模式为ALT5) PAD寄存器配置电气特性(驱动强度、上下拉电阻、速率等) GPIO模块控制: 每个GPIO模块最多控制32个引脚 关键寄存器:DR(数据)、GDIR(方向)、PSR(状态)等 通过设置GDIR方向寄存器配置输入/输出模式 文章强调理解硬件原理对开发L原创 2026-05-23 07:22:51 · 368 阅读 · 0 评论 -
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
嵌入式Linux驱动开发:从寄存器操作到pinctrl/gpio子系统 本文探讨了嵌入式Linux驱动开发的演进过程,从直接操作寄存器的方式逐步过渡到使用pinctrl和gpio子系统。传统方法存在硬编码地址、配置步骤繁琐、代码复用性差等问题。Linux内核通过"分离与分层"的设计理念,将硬件操作与驱动逻辑解耦: pinctrl子系统:负责引脚复用和电气特性配置 gpio子系统:提供统一的GPIO控制接口 这种架构使驱动开发者无需关心底层寄存器细节,只需通过设备树获取配置信息并调用标准API。文章通过LED原创 2026-05-20 08:23:04 · 904 阅读 · 0 评论 -
嵌入式Linux嵌入式Linux驱动开发:设备树驱动改造——从硬编码到设备树的实战之旅
本文介绍了将硬编码Linux驱动改造为设备树驱动的实战过程。通过渐进式重构方法,分步骤完成驱动改造:添加设备树头文件、定义节点路径、查找设备节点、读取设备属性等。重点讲解了设备树API的使用技巧和常见错误处理,如of_find_node_by_path查找节点、of_property_read_string读取属性等。文章强调保持硬件抽象层接口不变,通过小步验证确保改造过程可控。配套开源项目提供了i.MX平台的主线内核移植和设备树驱动实现,适合嵌入式开发者学习参考。原创 2026-05-18 10:31:21 · 528 阅读 · 0 评论 -
嵌入式Linux嵌入式Linux驱动开发:板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环
本文介绍了嵌入式Linux驱动开发中设备树(DTS)的实际操作流程,重点演示了从修改设备树到点亮LED的完整闭环开发过程。主要内容包括: 环境准备:确认开发板型号,定位板级DTS文件,理解.dtsi、.dts和.dtb的区别,强调备份的重要性。 DTS文件编写:详细讲解如何根据芯片手册确定寄存器地址,编写LED设备节点,包括节点命名规则、属性设置和寄存器映射方法。 DTB编译:介绍手动编译和构建脚本两种方式,以及通过反编译验证DTB正确性的方法。 驱动开发:概述驱动代码结构,说明如何从设备树中提取硬件信息并原创 2026-05-18 10:25:14 · 564 阅读 · 0 评论 -
嵌入式Linux驱动开发 —— 从 DTS 到代码的桥梁与简单OF系列API
嵌入式Linux驱动开发:设备树与OF API实践指南 摘要 本文深入探讨了嵌入式Linux驱动开发中设备树(DTS)与OF API的实际应用。主要内容包括: 设备树历史背景:从PowerPC的Open Firmware起源到ARM架构的强制采用,解释了为什么内核API使用"OF"前缀而非"DT"。 核心数据结构: device_node:表示设备树节点,包含父子节点关系 property:存储节点属性值 resource:统一描述硬件资源 关键API功能: 节点查找(of_find_node_by_pat原创 2026-05-16 09:00:40 · 592 阅读 · 0 评论 -
嵌入式Linux驱动开发——设备树语法与编译工具——读懂这张“藏宝图“
本文介绍了嵌入式Linux设备树开发的核心概念与工具。首先讲解了DTC编译器如何将.dts文本转换为.dtb二进制文件的过程,包括词法分析、语法分析和代码生成三个阶段。接着详细解析了设备树语法规则,重点阐述了节点命名、标签引用机制以及常见属性类型(字符串、数值、引用等)。文章还列举了标准属性如compatible、status、reg等的作用和使用场景,帮助开发者理解设备树如何描述硬件配置并与内核驱动匹配。通过掌握这些基础知识,开发者能够准确解读和修改设备树文件,为嵌入式系统硬件配置提供灵活支持。原创 2026-05-14 12:23:59 · 388 阅读 · 0 评论 -
如何开始嵌入式Linux的学习呢?
摘要: 本文系统介绍了嵌入式Linux与单片机开发的核心区别,为初学者提供清晰的学习路线图。作者指出嵌入式Linux本质上是完整的Linux操作系统运行在特定硬件平台上,与单片机开发存在四大关键差异:1)复杂的启动链条(U-Boot→内核→RootFS);2)驱动与应用分离的开发模式;3)基于日志和虚拟内存的调试方式;4)交叉编译工具链的配置要求。项目采用分层架构组织教程,从工具链、U-Boot、Linux内核到根文件系统逐步深入,帮助开发者理解嵌入式Linux的系统级开发思维。文章特别强调从裸机开发过渡到原创 2026-05-13 09:58:45 · 1001 阅读 · 0 评论 -
嵌入式Linux开发——设备树简介 - 给硬件画张像
本文介绍了嵌入式Linux开发中的设备树技术。文章从Linus Torvalds对ARM内核源码膨胀的不满切入,解释了传统硬编码方式的弊端:代码重复、维护困难、编译效率低。设备树的本质是将硬件描述从代码中分离出来,形成树状结构的"硬件说明书"(DTS文件),其中.dts描述板级信息,.dtsi描述SOC级信息。相比传统方式,设备树使驱动代码更通用,硬件变更只需修改设备树文件而无需重新编译驱动。作者建议通过实践来掌握设备树,从基础语法开始逐步构建知识体系,强调"少讲理论,多写代码原创 2026-05-12 08:34:06 · 375 阅读 · 0 评论 -
嵌入式Linux驱动开发——驱动错误处理模式 - 当资源分配失败时该怎么办
本文介绍了嵌入式Linux驱动开发中的错误处理模式,重点讲解了两种核心方法: 错误指针机制:使用ERR_PTR()、PTR_ERR()和IS_ERR()宏来处理需要同时返回指针和错误码的情况,通过内核地址空间的保留区域编码错误信息。 goto错误处理模式:通过逆序清理的方式管理资源释放,使用goto语句简化错误处理流程。这种模式相比传统的if-else嵌套更加清晰可靠,避免了重复的清理代码。 文章通过具体代码示例展示了如何在实际驱动开发中应用这些技术,包括设备号申请、cdev添加、类创建和设备创建等步骤的完原创 2026-05-08 10:08:54 · 589 阅读 · 0 评论 -
嵌入式Linux驱动开发——class 和 device 模型 - 自动创建设备节点的幕后机制
嵌入式Linux驱动开发摘要 本文介绍了Linux驱动开发中自动创建设备节点的机制,重点解析了class和device模型的工作原理: 背景问题:传统手动mknod方式繁琐,现代Linux通过udev/mdev自动管理设备节点 核心机制: sysfs作为内核与用户空间的桥梁,/sys/class目录组织设备类别 驱动通过class_create()创建设备类 device_create()在类下创建设备,触发uevent事件 用户空间udev/mdev监听事件并自动创建/dev节点 关键API: class原创 2026-05-07 09:20:35 · 322 阅读 · 0 评论 -
Linux 字符设备驱动:cdev、设备号与设备模型
Linux字符设备驱动核心概念摘要 本文深入讲解了Linux字符设备驱动的三个核心组件: cdev结构体:字符设备的核心数据结构,包含kobject对象、模块所有者指针、文件操作集和设备号等信息。重点强调了owner字段防止模块意外卸载的作用。 设备号管理:详细解析了dev_t类型的32位结构,包含12位主设备号和20位次设备号。介绍了MKDEV、MAJOR和MINOR三个关键宏的使用方法,以及动态分配和静态注册设备号的区别。 操作函数:讲解了cdev_init()初始化、cdev_add()注册和cdev原创 2026-05-02 10:03:01 · 583 阅读 · 0 评论 -
嵌入式C++实践开发第21篇(单片机实践):按钮输入 —— 硬件原理、消抖与HAL API
本文介绍了嵌入式C++中按钮输入的硬件原理与软件实现。硬件方面采用STM32F103C8T6开发板,通过PA0引脚连接按钮到GND,利用内部40kΩ上拉电阻实现默认高电平。按下按钮时产生82.5μA的小电流,对系统影响可忽略。重点分析了机械按钮的抖动问题,实测抖动持续时间约5-20ms,可能导致多次误触发。软件解决方案提出三种渐进式消抖方法:阻塞延时、非阻塞时间戳和状态机方案。最后对比了GPIO输入与输出API的差异,详细说明了输入模式的初始化配置参数。文章强调从理论到实践的渐进式学习方法,配套开源项目可供原创 2026-05-02 09:52:03 · 514 阅读 · 0 评论 -
嵌入式Linux驱动开发——新字符设备驱动 API 概览
本文介绍了嵌入式Linux驱动开发中新字符设备驱动API的优势和使用方法。主要内容包括: 老API存在的问题:资源霸占(占用过多设备号)、设备号冲突、需手动创建节点等。 新API的设计理念:按需分配资源,采用"领号-填表-进门"的三步注册流程。 新API实现方式: 动态/静态分配设备号 初始化cdev结构体 自动创建设备节点 新API的优势: 资源利用率高 避免设备号冲突 自动化程度高 可扩展性强 符合现代内核规范 适用场景建议:老API适合快速原型开发和学习,新API适合生产环境和复杂原创 2026-05-01 07:58:37 · 615 阅读 · 0 评论 -
嵌入式Linux驱动开发——一口气了结老字符设备——字符设备驱动完整指南 - 从硬件抽象到部署实战
本文介绍了嵌入式Linux字符设备驱动的分层设计方法,重点讲解了硬件抽象层的实现。作者通过LED控制驱动示例,展示了如何将寄存器操作、GPIO配置等硬件相关代码封装成清晰的接口(初始化、状态设置/获取),与字符设备层解耦。文章详细解析了寄存器映射、时钟使能、GPIO配置等关键步骤的实现技巧,并强调了调试信息打印、参数校验等工程实践要点。这种分层设计提高了代码的可维护性和可移植性,硬件变更时只需修改抽象层而无需改动上层逻辑。原创 2026-04-30 13:35:37 · 384 阅读 · 0 评论 -
嵌入式Linux驱动开发(8)——内存映射 I/O - 别拿物理地址当指针用
本文介绍了嵌入式Linux驱动开发中内存映射I/O的正确使用方法。文章首先指出在Linux环境下直接使用物理地址会导致内核panic的问题,解释了虚拟地址空间和MMU的作用。重点讲解了ioremap()的工作原理,包括虚拟地址分配、页表映射建立、设备寄存器访问特性等,并强调必须使用writel()/readl()而非直接指针访问。文章还分析了内存屏障的必要性和实现机制,最后给出LED驱动中的实际应用示例。通过本文,读者可以理解Linux下安全访问硬件寄存器的完整机制。原创 2026-04-29 08:47:53 · 476 阅读 · 0 评论 -
嵌入式Linux驱动开发(7) 从虚拟设备到真实硬件 —— LED驱动硬件基础
本文介绍了从虚拟设备转向真实硬件开发的关键步骤,以i.MX 6ULL开发板的LED驱动为例,详细讲解了GPIO硬件控制原理。内容包括:实验环境搭建(开发板型号、内核版本、LED连接方式)、GPIO工作原理(时钟使能、引脚复用、方向配置)、寄存器地址查询方法(参考手册使用技巧)、引脚复用与电气特性配置(MUX和PAD寄存器详解),以及时钟控制的关键细节。文章强调理解硬件原理的重要性,并预告了后续将讨论ioremap()和内核内存管理机制。所有代码和教程已开源,适合嵌入式开发者学习真实硬件驱动开发。原创 2026-04-28 08:48:33 · 310 阅读 · 0 评论 -
嵌入式Linux开发(6)——老API字符设备驱动 - 从零开始踩坑实录
本文介绍了使用Linux老API(register_chrdev)开发字符设备驱动的实践过程。作者从最简单的虚拟字符设备入手,避免了硬件相关的复杂性,专注于驱动核心概念。通过一个基础版本实现,展示了file_operations结构体的关键操作(open、read、write、release)和模块加载/卸载流程。但在实际运行时发现缓冲区溢出问题,原因是用户空间请求的读取大小(4096字节)超过了驱动预设的缓冲区大小(100字节)。这一实践过程凸显了内核编程中内存管理和边界检查的重要性,为后续驱动开发提供了原创 2026-04-23 07:01:07 · 449 阅读 · 0 评论 -
嵌入式Linux开发(6-前置)——IDE 配置指南 - VSCode + clangd 驱动开发环境搭建
本文介绍了如何在VSCode中配置clangd来搭建嵌入式Linux驱动开发环境。主要内容包括:1) 确认clangd插件和内核源码环境准备就绪;2) 理解clangd通过.clangd配置文件和compile_commands.json获取编译信息;3) 利用Linux内核构建系统自动生成compile_commands.json的原理和方法;4) 项目已配置好的.clangd文件如何正确指向内核编译数据库;5) 验证配置正确性的方法和常见问题解决方案。通过这套配置,开发者可以获得精确的代码补全、跳转和参原创 2026-04-23 06:51:32 · 891 阅读 · 0 评论 -
嵌入式Linux模块开发(5)——内核调试技术
本文介绍了嵌入式Linux内核调试的核心技术,重点讲解了dmesg工具的使用技巧、内核日志级别控制、动态调试方法以及常见问题排查流程。文章强调dmesg是内核调试最重要的工具,详细演示了如何通过管道、grep等命令高效查看日志;深入解析了日志级别机制及其对调试输出的影响;详细介绍了动态调试的强大功能,包括运行时精确控制调试打印;最后总结了模块加载失败、设备不工作、系统崩溃等常见问题的系统化排查方法。这些技术能帮助开发者快速定位和解决内核驱动开发中的各类问题。原创 2026-04-22 06:46:39 · 715 阅读 · 0 评论 -
嵌入式Linux驱动开发(4)——内核打印详解
本文深入探讨了嵌入式Linux内核驱动开发中的打印调试技术。主要内容包括:1)内核特有的printk系统与用户空间printf的区别;2)8级日志级别的定义和使用场景;3)现代pr_*宏系列的优势和使用技巧;4)pr_fmt宏实现统一前缀的方法;5)高级打印功能如_once、_cont和_ratelimited;6)动态调试控制通过模块参数实现;7)内核日志级别配置与DEBUG宏的条件编译;8)dmesg工具的高级用法;9)常见错误与最佳实践。文章通过实际代码示例展示了不同日志级别的输出效果,并提供了调试复原创 2026-04-20 08:33:42 · 520 阅读 · 0 评论 -
嵌入式Linux驱动开发(3)——内核模块机制 - Linux 的插件系统
本文介绍了Linux内核模块机制,包括模块的概念、生命周期、加载卸载流程及开发注意事项。主要内容涵盖: 模块是Linux内核的动态插件系统,支持运行时加载卸载而无需重启系统 模块生命周期包括编译、加载、运行和卸载四个阶段 模块通过module_init和module_exit宏定义入口和出口函数 模块参数机制允许运行时配置,通过sysfs可动态调整 引用计数机制防止模块被误卸载,确保使用安全 模块元数据和版本控制(vermagic)是开发中的重要考虑因素 该机制极大提升了驱动开发效率,是Linux驱动开发的原创 2026-04-19 08:55:26 · 358 阅读 · 0 评论 -
嵌入式Linux驱动开发指南02——内核空间基础与硬件访问
本文介绍了嵌入式Linux驱动开发中的内核空间基础与硬件访问机制。文章首先对比了裸机编程与Linux环境下硬件访问的根本区别,指出Linux通过MMU将物理地址与虚拟地址隔离,开发者无法直接操作硬件寄存器。随后详细讲解了Linux的内存空间划分,包括用户空间(0-3GB)和内核空间(3-4GB)的不同权限与功能,并阐述了系统调用作为用户程序访问硬件的唯一合法途径。最后解释了MMU的工作原理,包括地址翻译机制和TLB缓存的作用,强调了在Linux环境下必须通过内核提供的ioremap等机制才能访问硬件寄存器。原创 2026-04-18 09:46:52 · 398 阅读 · 0 评论 -
嵌入式Linux驱动教程01——字符设备驱动简介
本文介绍了Linux字符设备驱动的基本概念与实现原理。文章从用户空间与内核空间的交互机制入手,阐述了系统调用的工作原理,重点讲解了file_operations结构体作为驱动功能接口的核心作用。通过对比老内核(4.1.15)和新内核(6.12.49/7.0.0-rc4)中file_operations的差异,展现了Linux驱动架构的演进。文章采用生动的比喻(如"翻译官"、"足球队名单")帮助理解驱动开发的核心思想,为后续深入讲解字符设备驱动开发奠定了基础。原创 2026-04-17 09:01:40 · 350 阅读 · 0 评论
分享