news 2026/1/25 11:58:36

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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极其稳定,作为通用框架,一旦写好几乎不需要修改。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/25 3:55:31

WaveTools鸣潮工具箱终极使用指南:120帧解锁与画质优化全流程

WaveTools鸣潮工具箱终极使用指南:120帧解锁与画质优化全流程 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 还在为《鸣潮》游戏帧率卡顿而烦恼吗?WaveTools作为一款专业的鸣潮游戏…

作者头像 李华
网站建设 2026/1/7 0:06:17

【毕业设计】基于机器学习ATT-LSTM的语音情感分类

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/1/16 6:24:42

PlayCover完整实践指南:在Mac上原生运行iOS应用与游戏

PlayCover完整实践指南:在Mac上原生运行iOS应用与游戏 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 想在Apple Silicon Mac上无缝运行iOS应用和游戏?PlayCover为你提供了完美…

作者头像 李华
网站建设 2026/1/22 16:12:09

OpenCore Legacy Patcher完全指南:老旧Mac系统升级的终极方案

OpenCore Legacy Patcher完全指南:老旧Mac系统升级的终极方案 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher OpenCore Legacy Patcher是一款革命性的工具&…

作者头像 李华
网站建设 2026/1/19 16:45:46

网易云音乐插件管理器:一键解锁音乐播放器隐藏功能

网易云音乐插件管理器:一键解锁音乐播放器隐藏功能 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在用原版网易云音乐听歌吗?是不是总觉得界面单调、功能有限…

作者头像 李华
网站建设 2026/1/24 19:16:54

WaveTools鸣潮工具箱:从性能优化到数据管理的全方位指南

是否在为鸣潮游戏的卡顿问题而烦恼?想要获得更流畅的游戏体验却不知从何入手?WaveTools作为专为鸣潮玩家设计的全能工具箱,能够帮助你解决从帧率限制到抽卡统计的各种需求。本文将为你详细解析这款工具的核心功能与使用技巧。 【免费下载链接…

作者头像 李华