20260103 - Linux平台总线LED驱动架构深度解析

Linux 平台总线 LED 驱动架构深度解析笔记

基于韦东山Linux驱动基础视频:LED模板驱动程序的改造

1. 总体架构概览

这套代码展示了一个标准的 Linux 平台总线 (Platform Bus) 设备驱动模型 。其核心设计思想是 分层 (Layering)分离 (Separation)

  • 分离:将"硬件有哪些(资源)"与"硬件怎么用(驱动)"分开。
  • 分层:将"通用的字符设备接口"与"底层的硬件操作逻辑"分层。

系统分层图解

我们可以将系统划分为三层,由上至下分别为:

  1. 上层(核心层 Core):leddrv.c
    • 职责 :负责向内核注册字符设备,向应用层提供标准文件接口 (open/write),管理 /dev 设备节点。它不关心底层具体怎么操作硬件。
  2. 中层(驱动层 Driver):chip_demo_gpio.c
    • 职责 :作为 platform_driver,负责从 Device 获取资源,并实现具体的 GPIO 操作逻辑。它是连接核心层与硬件资源的桥梁。
  3. 下层(设备层 Device):board_A_led.c
    • 职责 :作为 platform_device,负责"描述"当前板子上有哪些 LED,引脚编号是多少。

2. 详细文件功能分析

A. 头文件 (协议与接口)

  • led_resource.h
    • 定义数据格式。利用位操作宏 GROUP(x), PIN(x) 将 GPIO 的组号和引脚号打包成一个整数,方便在 resource 中传递。
  • led_opr.h
    • 定义 硬件抽象层 (HAL) 接口 struct led_operations。包含 init (初始化) 和 ctl (控制) 两个函数指针。这使得上层不需要知道底层的具体实现。
  • leddrv.h
    • 核心层导出的 API 声明,供驱动层调用,如 led_class_create_deviceregister_led_operations

B. leddrv.c (核心层 - 字符设备框架)

这是通用的 LED 驱动框架,不包含任何具体的硬件寄存器操作

  • 关键数据
    • p_led_opr: 指向底层注册进来的操作结构体。
    • led_drv: file_operations 结构体,定义 open, write 等系统调用对应的处理函数。
  • 关键机制
    • 注册接口register_led_operations(struct led_operations *opr),供底层驱动将自己的 init/ctl 函数注册进来。
    • 用户调用响应
      • led_drv_open: 根据次设备号 (minor) 调用 p_led_opr->init(minor)
      • led_drv_write: 获取用户数据,调用 p_led_opr->ctl(minor, status)
    • 设备节点创建led_class_create_device 封装了 device_create,供底层在探测到硬件资源时动态创建 /dev/100ask_ledX

C. board_A_led.c (设备层 - 资源描述)

模拟硬件板级信息,纯数据描述。

  • 资源传递 Hack :利用 IORESOURCE_IRQ 类型的资源字段来存储自定义的 GPIO 编码(由 GROUP_PIN 生成)。
  • 平台设备 :定义 struct platform_device,名字为 "100ask_led"
  • 作用:加载时,在平台总线上挂载一个名为 "100ask_led" 的设备,携带了具体的引脚数据。

D. chip_demo_gpio.c (驱动层 - 逻辑实现)

这是最繁忙的一层,负责承上启下。

  • 平台驱动 :定义 struct platform_driver,名字也为 "100ask_led"注意:名字必须与 Device 层完全一致才能触发匹配。
  • chip_demo_gpio_probe (核心入口)
    1. 当 Driver 和 Device 匹配成功时被内核调用。
    2. 调用 platform_get_resource 从 Device 获取 GPIO 引脚号。
    3. 记录引脚信息到 g_ledpins
    4. 调用 leddrv.cled_class_create_device 创建设备节点。
  • chip_demo_gpio_drv_init (模块入口)
    1. 调用 register_led_operations 向核心层注册操作函数。
    2. 注册平台驱动。

3. 完整运行流程 (Workflow)

为了看清各部分如何协作,我们模拟从 模块加载用户控制 的全过程:

阶段 1: 模块加载与匹配

  1. 加载 leddrv.ko
    • 内核有了 register_led_operations 等符号。
  2. 加载 chip_demo_gpio.ko
    • 初始化时调用 register_led_operationsleddrv.c 中的 p_led_opr 指针被赋值,指向具体的 GPIO 操作函数。
    • 注册平台驱动,开始在总线上守候。
  3. 加载 board_A_led.ko
    • 注册平台设备 "100ask_led"。
    • Match:平台总线发现 Device 和 Driver 名字相同。
    • Probe :触发 chip_demo_gpio_probe。读取引脚资源,创建 /dev/100ask_led0

阶段 2: 用户空间调用

假设用户执行命令:./ledtest /dev/100ask_led0 on

  1. App : main() 调用 write(fd, &val, 1)
  2. Kernel VFS : 找到字符设备,调用 leddrv.c -> led_drv_write
  3. Core Layer : led_drv_write 解析出次设备号 0,调用 p_led_opr->ctl(0, 1)
  4. Driver Layer : 跳转到 chip_demo_gpio.c -> board_demo_led_ctl
  5. Implementation : 查表 g_ledpins[0] 找到引脚,打印 "set led on..." (模拟硬件操作)。

4. 模块依赖与加载顺序指南

由于代码之间存在 符号依赖 (Symbol Dependency),加载和卸载模块必须严格遵守顺序。

依赖关系

  1. chip_demo_gpio.ko 依赖 leddrv.ko
    • 原因:chip_demo_gpio.c 调用了 leddrv.c 导出的 EXPORT_SYMBOL (如 register_led_operations)。
  2. board_A_led.ko 不依赖 具体符号,但依赖平台总线机制。

正确的加载顺序 (insmod)

必须先让"被依赖者"进入内核。

  1. insmod leddrv.ko
    • (建立地基:提供注册函数和设备创建函数)
  2. insmod chip_demo_gpio.ko
    • (建立驱动逻辑:依赖 leddrv 的符号,注册操作函数,等待设备)
  3. insmod board_A_led.ko
    • (提供硬件资源:触发 Probe,生成 /dev 节点)
    • 注:board_A_led.ko 其实可以在第1步之后任意时间加载,但通常最后加载它来触发实际工作。

正确的卸载顺序 (rmmod)

必须先卸载"依赖者",防止指针悬空或内核崩溃。

  1. rmmod board_A_led (移除设备资源)
  2. rmmod chip_demo_gpio (移除驱动逻辑,它依赖 leddrv)
  3. rmmod leddrv (最后拆除地基)

5. 总结:这套代码好在哪里?

  • 可扩展性
    • 换板子?只需重写 board_A_led.c,无需动驱动逻辑。
    • 换芯片?只需重写 chip_demo_gpio.c,无需动上层逻辑。
  • 维护性 :核心层 leddrv.c 极其稳定,作为通用框架,一旦写好几乎不需要修改。

这份笔记涵盖了从代码细节到架构设计的全部核心内容。

相关推荐
polarislove02149 小时前
10.1 [ADC] 逐次逼近型ADC-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
qq_672592759 小时前
STM32超声测距离的测量精度评估
stm32·硬件架构·硬件工程
单片机系统设计9 小时前
基于STM32的智能垃圾桶/语音分类/自动开盖/矩阵按键
stm32·矩阵·毕业设计·语音识别·智能垃圾桶
三品吉他手会点灯11 小时前
STM32F103 学习笔记-21-串口通信(第3节)-STM32串口初始化结构体和固件库讲解
笔记·stm32·单片机·嵌入式硬件·学习
TEC_INO12 小时前
STM32_5:I2C
stm32·单片机·嵌入式硬件
TEC_INO12 小时前
STM32_6:OLED屏幕开发
stm32·嵌入式硬件·mongodb
单片机系统设计13 小时前
基于stm32的智能健康监测/老人摔倒/智能防摔
stm32·单片机·嵌入式硬件·毕业设计·健康系统
czhaii13 小时前
STM32 F1 高级定时器TIM8 脉冲计数 计数器1模式 CH1通道
stm32·单片机·嵌入式硬件
polarislove021414 小时前
9.7 [ 定时器 ] 从模式控制器-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
沐欣工作室_lvyiyi14 小时前
基于物联网的智慧花园的设计与实现(论文+源码)
stm32·单片机·毕业设计·智慧花园