ARM Linux 驱动开发篇---新版led驱动实验原理(2)--基于 mdev 机制实现设备节点自动创建及--利用私有数据结构体管理设备属性-- Ubuntu20.04

ARM Linux 驱动开发篇---新版led驱动实验原理(2)--基于 mdev 机制实现设备节点自动创建及--利用私有数据结构体管理设备属性-- Ubuntu20.04
🎬 渡水无言个人主页渡水无言

专栏传送门linux专栏
⭐️流水不争先,争的是滔滔不绝

 📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生

| 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生

在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连

目录

前言

一、自动创建设备节点

1.1、mdev 机制

1.2、创建和删除类

1.3、创建设备

1.4、示例

1.5、总结流程图

二、设置文件私有数据

2.1具体原理代码

2.2总体流程框图

总结


前言

上一期介绍了一些新的分配和释放设备号,字符设备注册方法,接下来本期博客将介绍一下自动创建设备节点,设置文件私有数据的方法。


一、自动创建设备节点

在上一期的 Linux LED驱动实验中,当我们使用 modprobe 加载驱动程序以后还需要使用命令

“mknod”手动创建设备节点。接下来就来介绍一下如何实现自动创建设备节点,在驱动中实现自动创建设备节点的功能以后,使用 modprobe 加载驱动模块成功的话就会自动在/dev 目录下创建对应的设备文件。

1.1、mdev 机制

在 Linux 系统中,udev 是一个用户态守护进程,负责动态管理 /dev 目录下的设备节点文件。它通过监听内核事件,实时检测硬件设备的插拔与状态变化,并自动完成设备文件的创建与删除。

例如:当使用 modprobe 命令成功加载驱动模块时,udev 会自动在 /dev 目录下生成对应的设备节点;反之,使用 rmmod 卸载驱动后,相关设备节点也会被自动清理。

在嵌入式 Linux 场景中,为了适应资源受限的环境,通常使用 BusyBox 提供的轻量级工具 mdev。mdev 是 udev 的简化实现,同样承担着设备节点自动管理与热插拔事件处理的核心职责。在基于 BusyBox 构建的根文件系统中,mdev 的初始化配置通常位于 /etc/init.d/rcS 脚本中。

相关语句如下:

echo /sbin/mdev > /proc/sys/kernel/hotplug

上述命令设置热插拔事件由 mdev 来管理。接下来我们详细介绍一下如何通过 mdev 来实现设备文件节点的自动创建与删除。

1.2、创建和删除类

在 Linux 驱动开发中,设备节点的自动创建工作,通常是在驱动程序的入口函数中完成的,具体来说,我们一般会在 cdev_add 函数调用之后,补充自动创建设备节点的相关代码。

要实现这一功能,首先需要创建一个 class 类 ——class 是 Linux 内核中用于管理设备的核心结构体,其定义位于内核头文件 include/linux/device.h 中。

而创建这个类的核心接口是 class_create,需要注意的是,class_create 并非一个普通函数,而是内核封装的宏定义,其具体的宏展开内容如下:

#define class_create(owner, name) \ ({ \ static struct lock_class_key __key; \ __class_create(owner, name, &__key); \ }) struct class *__class_create(struct module *owner, const char *name, struct lock_class_key *key)

class_create 一共有两个参数,参数 owner 一般为 THIS_MODULE,参数 name 是类名字。 返回值是个指向结构体 class 的指针,也就是创建的类。

卸载驱动程序的时候需要删除掉类,类删除函数为 class_destroy,函数原型如下:

void class_destroy(struct class *cls);

参数 cls 就是要删除的类。

1.3、创建设备

创建好类以后还不能实现自动创建设备节点,我们还需要在这个类下创建一个设备。使用device_create 函数在类下面创建设备,device_create 函数原型如下:

struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)

class:指定该设备要归属的设备类(即创建在哪个类目录下),需传入之前通过 class_create 创建的 struct class 指针,决定了设备节点在 /sys/class 下的归属。
parent:指向父设备的指针,用于标识设备的层级关系,绝大多数场景下无需指定父设备,直接传 NULL 即可。
devt:设备号(包含主设备号和次设备号),是设备在系统中的唯一标识,需与 cdev_add 中注册的设备号保持一致。
drvdata:指向设备私有数据的指针,可用于传递驱动需要的自定义数据,若无特殊需求,通常传 NULL。
fmt:设备名称的格式化字符串(可变参数的核心),比如设置 fmt = "xxx",系统会自动在 /dev 目录下生成 /dev/xxx 这个设备节点文件。

同样的,卸载驱动的时候需要删除掉创建的设备,设备删除函数为 device_destroy,函数原型如下:

void device_destroy(struct class *class, dev_t devt)

参数 class 是要删除的设备所处的类,参数 devt 是要删除的设备号。

1.4、示例

在驱动入口函数里面创建类和设备,在驱动出口函数里面删除类和设备,示例如下:

struct class *class; /* 类 */ struct device *device; /* 设备 */ dev_t devid; /* 设备号 */ /* 驱动入口函数 */ static int __init led_init(void) { /* 创建类 */ class = class_create(THIS_MODULE, "xxx"); /* 创建设备 */ device = device_create(class, NULL, devid, NULL, "xxx"); return 0; } /* 驱动出口函数 */ static void __exit led_exit(void) { /* 删除设备 */ device_destroy(newchrled.class, newchrled.devid); /* 删除类 */ class_destroy(newchrled.class); } module_init(led_init); module_exit(led_exit);

1.5、总结流程图

左侧是驱动加载 + 自动创建设备节点正向流程,右侧是驱动卸载 + 自动删除设备节点反向流程

注意:

红色背景(keyStep):驱动开发中需要手动编写代码的核心步骤(创建 / 删除类、设备);

蓝色背景(sysStep):系统层面自动执行的步骤(mdev 监听、热插拔事件处理)。

二、设置文件私有数据

2.1具体原理代码

在嵌入式 Linux 驱动开发中,我们经常需要管理设备的各种属性,如主设备号、cdev 结构体、设备类、设备指针等。如果将这些属性零散地定义为全局变量,不仅代码不专业,还会导致维护困难和线程安全问题。就像下面这种写法:

// 零散的全局变量,弊端显著 dev_t devid; /* 设备号 */ struct cdev test_cdev; /* 字符设备结构体 */ struct class *class; /* 设备类 */ struct device *device; /* 设备实例 */ int major; /* 主设备号 */ int minor; /* 次设备号 */

所以有必要使用私有数据结构体来封装设备属性,并在open函数中将其作为私有数据挂载到文件结构体中,实现高效、安全的设备管理。如下所示:

​ /* 设备结构体 */ struct test_dev{ dev_t devid; /* 设备号 */ struct cdev cdev; /* cdev */ struct class *class; /* 类 */ struct device *device; /* 设备 */ int major; /* 主设备号 */ int minor; /* 次设备号 */ }; struct test_dev testdev; /* open函数 */ static int test_open(struct inode *inode, struct file *filp) { filp->private_data = &testdev; /* 设置私有数据 */ return 0; } ​

重点在于open 函数挂载私有数据

filp->private_data = &testdev;

这是整个设计的 “枢纽”,将文件实例与设备结构体绑定;
后续所有文件操作函数(read/write/ioctl)都能通过filp->private_data访问设备属性。

2.2总体流程框图


总结

本期博客主要介绍了自动创建设备节点,设置文件私有数据的方法。

Read more

Clawdbot部署Qwen3:32B实操:解决‘gateway token missing’的三种Token注入方式对比

Clawdbot部署Qwen3:32B实操:解决‘gateway token missing’的三种Token注入方式对比 Clawdbot 是一个统一的 AI 代理网关与管理平台,旨在为开发者提供一个直观的界面来构建、部署和监控自主 AI 代理。通过集成的聊天界面、多模型支持和强大的扩展系统,Clawdbot 让 AI 代理的管理变得简单高效。 当你在 ZEEKLOG 星图镜像广场一键部署 Clawdbot 并集成本地运行的 qwen3:32b 模型后,大概率会遇到这样一个提示: disconnected (1008): unauthorized: gateway token missing (open a tokenized dashboard URL or paste token in Control UI settings) 这不是报错,也不是服务没起来—

By Ne0inhk
PostgreSQL 模式(SCHEMA)详解:数据库对象的命名空间管理

PostgreSQL 模式(SCHEMA)详解:数据库对象的命名空间管理

@[TOC](PostgreSQL 模式(SCHEMA)详解:数据库对象的命名空间管理) 🌺The Begin🌺点点关注,收藏不迷路🌺 一、模式(SCHEMA)概念解析 PostgreSQL中的模式(Schema)是数据库内部的一个命名空间,它包含表、视图、索引、序列、数据类型、函数、操作符等数据库对象。模式可以看作是数据库中的"文件夹",为数据库对象提供逻辑分组。 模式的核心特性: * 逻辑隔离:不同模式中的对象可以同名而不会冲突 * 权限控制:可以针对模式设置独立的访问权限 * 组织管理:将相关对象分组管理,提高可维护性 DatabaseSchema1Schema2Table1View1Function1 二、模式的应用场景 1. 多用户环境隔离 当多个用户共享一个数据库时,为每个用户创建独立的模式,避免命名冲突。 2. 应用程序隔离 第三方应用可以使用独立模式,避免与现有对象名称冲突。 3.

By Ne0inhk
Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案

Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案 前言 在前文中,我们探讨了 okay 在鸿蒙(OpenHarmony)端实现基础 Result 模式包装的实战。但在真正的“分布式微服务聚合”、“高并发资产对账”以及“具备自愈能力的 IoT 指令链”场景中。简单的 ok() 与 err() 判定往往不足以支撑起复杂的业务全景。面对需要同时并行发起 3 个 API 请求,并要求在“所有请求均成功时执行合并、任一请求失败时执行局部逻辑路由”的高阶需求。如果缺乏一套完善的异步结果映射与多级逻辑聚合机制。不仅会导致异步回调地狱(Callback Hell)在

By Ne0inhk
国产替代不掉链子:KingbaseES如何做到MySQL零感迁移

国产替代不掉链子:KingbaseES如何做到MySQL零感迁移

前言 在信创国产化的大趋势下,数据库作为数字基础设施的核心,其替代迁移工作成为企业数字化转型的关键环节。MySQL 作为国内企业应用最广泛的开源关系型数据库之一,凭借轻量、易用、生态完善的特点,在互联网、金融、政务、制造等多个行业落地生根。但不少企业在将 MySQL 向国产数据库迁移的过程中,却陷入了 “看似简单,实则踩坑” 的困境 —— 表面上的语法兼容背后,是 JSON 数据类型行为差异、事务隔离级别在高并发下的隐性适配问题、Group By 严格模式等细节带来的兼容性故障,甚至出现 “改一行代码,崩整个系统” 的极端情况。 业务方对迁移的核心顾虑,从来都不是 “能不能迁”,而是 “能不能稳迁、低成本迁、不影响业务迁”。本文将从 MySQL 迁移的核心痛点出发,深度解析电科金仓 KingbaseES 的 MySQL 兼容性技术实现,以及全流程迁移工程的落地能力,为企业 MySQL

By Ne0inhk