本次直播从蜂鸣器misc驱动入手,讲解混杂设备简化字符设备驱动的实现方式,引出Linux驱动最核心的设备与驱动分离思想,最后系统学习设备树语法、文件结构、OF接口与完整开发流程。
一、基于Misc混杂设备编写蜂鸣器驱动
蜂鸣器依靠三极管驱动,基极输出低电平,三极管导通,蜂鸣器发声;高电平则关闭。开发板上蜂鸣器连接引脚为GPIO5_01,需要配置引脚复用寄存器、PAD电气属性寄存器、GPIO方向寄存器、GPIO数据寄存器。引脚更换后,控制电平的移位操作从左移3位改为左移1位。
传统字符设备驱动需要手动申请设备号、分配cdev结构体、绑定操作集、创建设备节点,样板代码量大。而misc混杂设备内核预置主设备号10,适合LED、蜂鸣器这类不属于I2C、SPI、USB标准总线的简易外设。
开发时填充miscdevice结构体,使用misc_register注册、misc_deregister注销设备,搭配ioremap完成寄存器虚拟地址映射,只需要实现模块入口出口、寄存器映射、读写操作,省去大量重复代码。
二、驱动核心思想:设备与驱动分离
设备驱动分离是Linux驱动架构最重要的设计思路,把硬件资源描述和硬件操作逻辑拆分开:
- 设备信息:寄存器地址、引脚编号、中断号等硬件固有资源;
- 驱动逻辑:硬件打开、读写、开关等通用操作方法。
优势明显:同一套驱动代码可以适配多个同类硬件,比如多个LED,仅硬件资源不同,无需重复编写驱动。基于该思想可以做驱动分层,代码更容易维护、扩展。设备树就是这套思想的落地载体,用来集中管理板载硬件信息,避免硬件资源硬编码在驱动代码中。
三、设备树核心概念与开发流程
1. 设备树文件分类
.dts:板级设备树源码,存放开发板独有的硬件配置。.dtsi:设备树头文件,芯片厂商提供通用外设定义,通过#include引入。.dtb:编译后的二进制文件,内核启动时加载识别硬件。dtc:设备树编译器,负责将dts源码编译成dtb。
2. 节点与常用属性
基础结构:节点名 { 属性 = 值; };
compatible:匹配字符串,用于驱动和设备节点匹配。reg:描述寄存器物理基地址和地址长度。status:okay代表设备可用,disabled代表禁用。#address-cells、#size-cells:规定reg中地址、长度占用单元数量,一般取值1。
3. OF系列操作API
of_find_node_by_path():通过节点路径查找设备树节点。of_property_read_u32_array():读取属性中的32位整型数组,多用于读取reg信息。of_iomap():根据设备树节点直接完成寄存器地址映射,替代手动ioremap。
4. 完整开发步骤
- 修改
.dts,在根节点添加自定义硬件节点,补充compatible、reg等属性。 - 执行
make dtbs编译,生成新.dtb。 - 将dtb放到TFTP目录,重启开发板加载新设备树。
- 在开发板使用
ls /sys/firmware/devicetree/base/验证节点是否加载成功。 - 编写驱动,调用OF接口读取设备树硬件资源,完成驱动注册。