VC++ CTreeCtrl 中 checkbox 的使用:TaoToken 统一 Key 接入与 settings.json 配置骨架
2026/9/26 10:16:48
基于韦东山Linux驱动基础视频:LED模板驱动程序的改造
这套代码展示了一个标准的Linux 平台总线 (Platform Bus) 设备驱动模型。其核心设计思想是分层 (Layering)与分离 (Separation)。
我们可以将系统划分为三层,由上至下分别为:
leddrv.copen/write),管理/dev设备节点。它不关心底层具体怎么操作硬件。chip_demo_gpio.cplatform_driver,负责从 Device 获取资源,并实现具体的 GPIO 操作逻辑。它是连接核心层与硬件资源的桥梁。board_A_led.cplatform_device,负责“描述”当前板子上有哪些 LED,引脚编号是多少。led_resource.hGROUP(x),PIN(x)将 GPIO 的组号和引脚号打包成一个整数,方便在resource中传递。led_opr.hstruct led_operations。包含init(初始化) 和ctl(控制) 两个函数指针。这使得上层不需要知道底层的具体实现。leddrv.hled_class_create_device和register_led_operations。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。board_A_led.c(设备层 - 资源描述)模拟硬件板级信息,纯数据描述。
IORESOURCE_IRQ类型的资源字段来存储自定义的 GPIO 编码(由GROUP_PIN生成)。struct platform_device,名字为"100ask_led"。chip_demo_gpio.c(驱动层 - 逻辑实现)这是最繁忙的一层,负责承上启下。
struct platform_driver,名字也为"100ask_led"。注意:名字必须与 Device 层完全一致才能触发匹配。chip_demo_gpio_probe(核心入口):platform_get_resource从 Device 获取 GPIO 引脚号。g_ledpins。leddrv.c的led_class_create_device创建设备节点。chip_demo_gpio_drv_init(模块入口):register_led_operations向核心层注册操作函数。为了看清各部分如何协作,我们模拟从模块加载到用户控制的全过程:
leddrv.ko:register_led_operations等符号。chip_demo_gpio.ko:register_led_operations,leddrv.c中的p_led_opr指针被赋值,指向具体的 GPIO 操作函数。board_A_led.ko:chip_demo_gpio_probe。读取引脚资源,创建/dev/100ask_led0。假设用户执行命令:./ledtest /dev/100ask_led0 on
main()调用write(fd, &val, 1)。leddrv.c->led_drv_write。led_drv_write解析出次设备号 0,调用p_led_opr->ctl(0, 1)。chip_demo_gpio.c->board_demo_led_ctl。g_ledpins[0]找到引脚,打印 “set led on…” (模拟硬件操作)。由于代码之间存在符号依赖 (Symbol Dependency),加载和卸载模块必须严格遵守顺序。
chip_demo_gpio.ko依赖leddrv.kochip_demo_gpio.c调用了leddrv.c导出的EXPORT_SYMBOL(如register_led_operations)。board_A_led.ko不依赖具体符号,但依赖平台总线机制。必须先让“被依赖者”进入内核。
insmod leddrv.koinsmod chip_demo_gpio.koinsmod board_A_led.koboard_A_led.ko其实可以在第1步之后任意时间加载,但通常最后加载它来触发实际工作。必须先卸载“依赖者”,防止指针悬空或内核崩溃。
rmmod board_A_led(移除设备资源)rmmod chip_demo_gpio(移除驱动逻辑,它依赖 leddrv)rmmod leddrv(最后拆除地基)board_A_led.c,无需动驱动逻辑。chip_demo_gpio.c,无需动上层逻辑。leddrv.c极其稳定,作为通用框架,一旦写好几乎不需要修改。这份笔记涵盖了从代码细节到架构设计的全部核心内容。