Linux 驱动开发实战:从手写 LED 字符设备驱动到设备树

前言

学习Linux驱动,LED是经典入门案例。本文从最基础的硬编码寄存器字符设备驱动,过渡到设备树+platform平台驱动,完整梳理IMX6ULL上的实现思路,理解软硬件解耦思想。

一、传统字符设备驱动(无设备树)

原理

直接在驱动代码写死寄存器物理地址,使用ioremap完成地址映射,手动注册字符设备,提供open/release/write接口,应用层通过/dev/led操作LED。

核心代码片段

c 复制代码
static struct file_operations led_fops = {
    .owner = THIS_MODULE,
    .open = led_open,
    .release = led_release,
    .write = led_write,
};

static int __init led_init(void)
{
    register_chrdev(LED_MAJOR, "led", &led_fops);
    gpio_base = ioremap(GPIO_PHYS_ADDR, REG_SIZE);
    writel(OUT_MODE, gpio_base + GPIO_DIR);
    return 0;
}

缺点:硬件信息硬编码,更换硬件就要修改驱动源码、重新编译模块,可移植性差,仅适合入门理解字符设备底层原理。

二、设备树版本 platform 驱动(工程标准写法)

设备树将硬件信息剥离到dts文件,驱动只保留业务逻辑,依靠compatible属性完成设备与驱动匹配,实现软硬件分离。

dts节点片段

dts 复制代码
led_test {
    compatible = "myimx6ull,led";
    gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
    status = "okay";
};

平台驱动核心片段

c 复制代码
static const struct of_device_id led_of_match[] = {
    { .compatible = "myimx6ull,led" },
    {}
};

static struct platform_driver led_platform_driver = {
    .probe = led_probe,
    .remove = led_remove,
    .driver = {
        .name = "led-drv",
        .of_match_table = led_of_match,
    },
};
module_platform_driver(led_platform_driver);

匹配成功后自动执行probe函数,解析设备树GPIO属性、申请引脚资源并完成初始化。

三、应用层测试代码

c 复制代码
fd = open("/dev/led", O_RDWR);
write(fd, &val, 1);
close(fd);

写入1点亮LED,写入0熄灭LED。

四、完整实操流程

  1. 修改dts添加led节点,编译生成dtb并更新到开发板
  2. 编写platform驱动,Makefile编译生成ko模块
  3. 开发板insmod加载驱动,内核匹配设备树,自动创建设备节点
  4. 运行应用程序控制LED;测试完毕rmmod卸载驱动

五、两种方案对比

传统字符设备:代码简单,适合初学;硬件写死,移植性差。

设备树+platform驱动:工业主流方案,硬件描述和驱动逻辑分离,换硬件只需修改设备树,不用改动驱动代码。

六、常见问题

  1. compatible字符串驱动和设备树必须完全一致,大小写敏感,字符串不匹配会导致probe不执行
  2. GPIO电平极性容易颠倒,GPIO_ACTIVE_LOW代表低电平点亮
  3. 修改设备树后需要重新编译dtb,只编译ko不会更新硬件配置
  4. 内核模块版本要和开发板内核版本保持一致,否则加载模块报错
相关推荐
灯澜忆梦1 小时前
【Linux】#7 | vi/vim 编辑器
linux·编辑器·vim
Escalating_xu1 小时前
【Linux 网络编程】UDP Socket 编程(上):从地址与字节序到完整回显服务器
linux·服务器·网络
重生之小比特1 小时前
【Linux系统】08 进程切换
linux·运维·服务器
kyle~1 小时前
Linux --- 内存管理内核子系统
linux·运维·服务器
昌原的儿子LEO1 小时前
嵌入式 Linux I2C 驱动开发核心知识总结:设备树与 platform 架构全解析
linux·驱动开发·架构
程序员-Benothing1 小时前
Linux内存管理详解:free、vmstat、buff/cache、swap
linux·运维·服务器
gwf2162 小时前
常见驱动问题定位与解决:设备识别、性能不达预期、CQ错误码 —— 资深RDMA驱动调试排错指南
驱动开发·linux内核·性能调优·rdma·故障排查·mlx5·irdma
_不会dp不改名_2 小时前
leetcode_3727 最大平方交替和
linux·算法·leetcode
Lsetea2 小时前
OpenSSL报certificate revoked:error 23与CRL吊销层级排查
linux·https·ssl证书·openssl·crl