报名方式:
一、前言
① Linux驱动开发工程师的要求:
招聘网站BOSS需求:(即使是Linux应用岗位,也开始要求Linux底层驱动技术栈)
Linux驱动开发工程师的要求:
② 为什么传统学习Linux驱动的路径总是充满挫折?
对于初入Linux底层驱动领域的新手来说,这条学习之路往往布满荆棘。你可能经历过这样的困境:
硬件与软件的迷局 - 你按照教程一步步操作,确认了软件环境配置无误,检查了硬件连线正确,但设备就是毫无反应。面对沉默的黑屏,你陷入自我怀疑:是教程过时了?是硬件兼容问题?还是自己遗漏了某个关键步骤?这种无从下手的挫败感消耗着你的学习热情。
术语的汪洋大海 - 刚接触Linux驱动开发,你被"中断下半部"、"自旋锁"、"设备树"、"Platform设备"、"输入子系统"等专业名词轰炸。每个概念都像一扇紧闭的门,不打开怕错过重要知识,强行打开又发现自己理解不透彻,最终陷入"学了很多却什么都不会"的尴尬境地。
孤独的求索之路 - 当你在某个问题上卡壳数日,翻遍Stack Overflow却找不到解决方案时,那种孤立无援的感觉尤为强烈。加入的学习群要么沦为闲聊群,要么你的技术提问石沉大海。最初的热情在这种孤独中逐渐冷却,最终可能放弃学习。
我们一起再训练营中学习吧,帮你破解上面问题~~~~
③ 完整课程大纲:
二、适合人群
三、实战项目介绍
项目:智能楼宇广告机终端
一、项目描述: 基于瑞芯微 RK3568 平台开发,使用LVGL UI框架进行显示,楼宇广告机终端界面UI 分为七个板块,支持显示网络实时时间、支持电梯温度的实时采集及显示,支持电梯的运转次数记录、支持广告图片的轮询播放,支持,电梯内wifi 二维码的实时显示等。
二、项目负责的内容:
应用部分:
LVGL 工程的移植
楼宇广告机界面的UI布局控制
NTP 实时获取网络时间
LVGL 图片、汉字库的加载
驱动部分:
DHT11温度传感器底层驱动的移植
RTL8822CE 无线WIFI的驱动移植
MPU6050 加速度传感器的驱动移植,以及加速度方向业务代码的实现
烟雾传感器的驱动移植,已经实时监控业务代码的实现。
Linux 系统定制裁剪。
舵机的控制,使用到了PWM驱动子系统。
RGMII接口以太网的驱动移植。
HDMI显示输出驱动内容的使能,及使用。
四、课程的各个阶段学习内容
4.1、基础核心能力(必学)
01 Linux模块化编程
详细描述:理解Linux内核如何用一种统一、层次化的模型来管理所有的设备。核心对象包括 kobject(提供基础功能如引用计数、sysfs接口)、kset(kobject的集合)、ktype(定义kobject的类型)。sysfs 虚拟文件系统是此模型在用户空间的直观体现(/sys/目录)。udev 守护进程则基于 sysfs 提供的信息,在用户空间动态地管理设备节点。
学习目标:理解设备模型的基本概念和组成关系;能够通过 sysfs 查看设备信息;理解 udev 规则的工作原理。
重要性:这是理解所有现代Linux驱动子系统(如platform, I2C等)如何组织和工作的理论基础。没有它,看驱动代码会感觉“只见树木,不见森林”。
02 中断及异常
详细描述:硬件与CPU通信的主要方式是中断。学习如何通过 request_irq 函数向内核注册一个中断处理程序。理解“顶半部”和“底半部”机制至关重要:顶半部负责快速响应硬件中断,执行最紧急的任务(如清除中断标志),而将耗时的处理工作推迟到底半部执行。常见的底半部机制包括软中断、tasklet(小任务,原子性执行)和 workqueue(工作队列,可以睡眠)。
学习目标:掌握中断的注册、处理和释放流程;深刻理解为何要区分顶半部/底半部,并能根据场景选择合适的底半部机制。
重要性:处理来自硬件的异步事件(如按键按下、数据到达、传感器触发)的唯一高效方式。不会中断处理,就无法编写响应迅速的驱动。
05 内核互斥技术
详细描述:在多核处理器或多线程环境中,驱动代码的多个执行路径可能同时访问共享数据(全局变量、硬件寄存器),从而导致竞态条件。内核提供多种同步机制来保护临界区:
自旋锁:在短期内等待时使用,请求锁的线程会忙等待,不可睡眠。适用于中断上下文和持有时间极短的场景。
信号量:允许线程在获取不到锁时进入睡眠,适用于持有锁时间较长的场景。
互斥体:是信号量的一个简化版本,用法更直观,使用场景与信号量类似,但限制更多(如只能由持有者解锁)。
RCU:读-拷贝-更新,一种无锁的同步机制,对于读多写少的场景性能极高,但实现和使用较为复杂。
学习目标:能够准确分析驱动中的并发风险,并根据场景选择最合适的同步机制。
重要性:是保证驱动在多核环境下稳定、可靠运行的生命线。也是嵌入式/Linux内核面试中必考的知识点。
03 字符设备驱动模型
详细描述:字符设备(如LED、按键、串口)是指那些以字节流形式被顺序访问的设备。此模型的核心是 file_operations 结构体,它填充了一系列函数指针(如 open, release, read, write),定义了用户空间应用程序通过文件操作(open, close, read, write)来访问设备时,内核应该调用的具体驱动函数。同时,需要学习设备号的申请与分配(alloc_chrdev_region)以及字符设备的注册(cdev_init, cdev_add)。
学习目标:能够构建一个完整的字符设备驱动,实现基本的文件操作,并在用户空间通过设备文件进行访问。
重要性:这是最基础、最经典的驱动模型,绝大多数简单的、非存储类的硬件外设都采用此模型。是理解Linux驱动与VFS(虚拟文件系统)接口的基石。
04 高级字符设备进阶
详细描述:在基础字符设备之上,为了提供更高效、更灵活的交互方式,需要掌握一系列高级特性。
ioctl:用于实现自定义的命令,进行设备的特定配置或操作(如设置波特率、读取寄存器值)。
poll / select / epoll:支持多路复用I/O,允许应用程序同时监视多个设备,并在某个设备就绪(可读、可写)时得到通知,实现非阻塞I/O。
异步通知:类似于信号,允许驱动在事件发生时(如数据到达)主动通知应用程序,使其无需轮询。
mmap:将设备的内存或驱动缓冲区直接映射到用户进程的地址空间。这实现了“零拷贝”数据传输,极大地提升了大数据量交换的效率。
学习目标:理解并能在驱动中实现这些高级特性,以优化驱动的性能和易用性。
重要性:这些是构建高性能、低延迟驱动的关键技术,尤其在数据采集、音视频处理等场景中不可或缺。
4.2、Linux驱动子系统(重点必学)
01 Linux设备模型
详细描述:理解Linux内核如何用一种统一、层次化的模型来管理所有的设备。核心对象包括 kobject(提供基础功能如引用计数、sysfs接口)、kset(kobject的集合)、ktype(定义kobject的类型)。sysfs 虚拟文件系统是此模型在用户空间的直观体现(/sys/目录)。udev 守护进程则基于 sysfs 提供的信息,在用户空间动态地管理设备节点。
学习目标:理解设备模型的基本概念和组成关系;能够通过 sysfs 查看设备信息;理解 udev 规则的工作原理。
重要性:这是理解所有现代Linux驱动子系统(如platform, I2C等)如何组织和工作的理论基础。没有它,看驱动代码会感觉“只见树木,不见森林”。
02 设备树
详细描述:一种描述硬件配置数据的树形结构语言,以 .dts 源文件和 .dtb 二进制文件存在。它完全将硬件信息(如内存映射、中断号、外设连接关系)从内核驱动代码中分离出来。学习内容包括设备树的基本语法(节点、属性、兼容性compatible)、编译方法(dtc)以及内核如何解析设备树并生成platform_device等。
学习目标:能够阅读、修改和编写简单的设备树文件;理解驱动代码如何通过OF API(Open Firmware API)从设备树中获取资源。
重要性:现代嵌入式开发(ARM, PowerPC等)的绝对标准,已全面替代板级文件(board-*.c)中的硬编码。不掌握设备树,几乎无法进行新的嵌入式Linux开发。
03 设备树overlay
详细描述:一种动态修改、叠加到基础设备树上的机制。它允许在系统运行时(或启动时)动态地添加、修改或覆盖设备节点的属性,而无需重新编译整个内核或基础设备树。
学习目标:理解overlay的概念,能够编写和加载overlay文件。
重要性:对于支持可插拔的扩展硬件(如树莓派的HAT扩展板)至关重要,提供了极大的硬件适配灵活性。
04 Platform虚拟总线驱动
必要性:platform_driver、platform_device分离设计。
详细描述:一种虚拟的“总线”,用于将那些不直接挂在物理总线(如I2C, SPI)上的片上外设纳入Linux设备模型。它严格遵循“驱动与设备分离”的思想:platform_device 描述设备本身(资源、名称等),通常由设备树解析生成;platform_driver 描述如何操作设备(驱动函数、兼容性匹配)。总线核心负责在匹配时将它们绑定。
学习目标:掌握如何编写一个 platform_driver,并理解其与 platform_device 的分离和匹配机制。
重要性:是理解Linux驱动框架设计思想的典范。绝大多数片上系统外设(如GPIO控制器、看门狗、ADC)都采用此模型,是面试高频考点。
原因:Li
05 GPIO子系统
详细描述:内核提供的用于通用输入/输出引脚控制的统一接口。通过 gpiod_get 系列函数获取GPIO描述符,然后可以设置其方向(输入/输出)、读取输入值、设置输出值、以及将GPIO配置为中断源。
学习目标:能够使用GPIO子系统的API来控制引脚,并实现GPIO中断。
重要性:控制最简单外设(LED、按键、继电器)的标准方式,避免了直接操作底层寄存器,保证了代码的可移植性。
06 Pinctrl子系统
详细描述:在现代复杂SoC中,一个物理引脚可能被复用于多种功能(如GPIO、UART的TX、I2C的SCL)。Pinctrl子系统负责管理引脚的复用和电气属性(如上拉/下拉、驱动强度)的配置。
学习目标:理解引脚控制的概念,知道如何在设备树中配置引脚的复用功能。
重要性:解决了多功能引脚间的冲突问题。在驱动开发中,如果串口无法正常工作,首先需要检查的就是Pinctrl配置是否正确。
07 LED子系统
详细描述:内核为LED设备提供的一个标准化驱动框架。驱动开发者只需创建一个 led_classdev 结构体并注册,内核就会在 /sys/class/leds/ 下创建相应的接口。该框架还内置了丰富的“触发器”,可以轻松实现LED在特定事件下的闪烁模式(如心跳、定时、磁盘活动)。
学习目标:能够遵循LED子系统框架编写LED驱动,并使用触发器。
重要性:是内核“不要重复造轮子”理念的完美体现,极大地简化了LED驱动的开发,并实现了统一控制。
08 DMA
详细描述:直接内存访问,允许外设直接在内存和设备缓冲区之间传输数据,而无需CPU的持续参与。学习如何使用内核提供的DMA API(如 dma_alloc_coherent 分配一致性DMA内存)来建立DMA传输通道。
学习目标:理解DMA的原理,掌握基本的DMA API使用方法。
重要性:在大数据量传输场景(如网络数据包、音频流、图像数据)中,使用DMA可以极大地解放CPU,降低系统负载,是高性能驱动的必备技术。
09 Input子系统
详细描述:为所有输入设备(按键、键盘、鼠标、触摸屏)建立的统一驱动框架。核心是 input_dev 结构体,驱动需要向其注册设备所能产生的事件类型(EV_KEY, EV_ABS等)和编码。当有输入事件发生时,驱动通过 input_event 等函数将事件上报给子系统,子系统再分发给用户空间的应用程序(如evdev)。
学习目标:能够编写一个基于Input子系统的输入设备驱动(如按键驱动)。
重要性:为用户空间提供了统一、抽象化的输入事件接口,简化了应用开发。
10 I2C/SPI/UART子系统
详细描述:学习嵌入式领域最常用的三种串行通信总线的驱动开发模型。
学习目标:能够为常见的I2C/SPI传感器(如MPU6050、BMP280)编写驱动;理解UART驱动的基本框架。
重要性:连接各种传感器、执行器、通信模块的生命线,是嵌入式驱动开发中最常接触的总线。
i2c:
spi:
uart:
11 PWM/IIO
Pwm:
Iio:
4.3、复杂外设驱动(按方向选学)
01 SDIO
02 以太网
03 MIPI DSI 屏幕驱动
04 HDMI 屏幕驱动
05 音频
06 WIFI
07 USB
详细描述:
重要性:最通用的外设扩展接口,应用极其广泛。
08 PCIE