当前位置: 首页 > news >正文

Linux 字符设备驱动框架学习记录(三)

Linux字符设备驱动开发新框架详解

一、新旧驱动框架对比

传统字符设备驱动流程

  1. 手动分配设备号 (register_chrdev_region)
  2. 实现file_operations结构体
  3. 使用mknod手动创建设备节点

新式驱动框架优势

  • 自动设备号分配:动态申请避免冲突
  • 自动节点创建:通过class_create/device_create实现
  • 更好的设备管理:通过struct cdev规范设备操作 cdev_add 向 Linux 系统添加字符设备…

二、自动设备号申请机制

核心函数实现

/* 动态分配设备号 */
alloc_chrdev_region(&newchrled.devid, 0, 1, LED_NAME);
newchrled.major = MAJOR(newchrled.devid); // 提取主设备号
newchrled.minor = MINOR(newchrled.devid); // 提取次设备号/* 传统静态分配示例(对比) */
// register_chrdev_region(devid, 1, "led");

设备号管理流程

  1. 调用alloc_chrdev_region申请未使用设备号
  2. 通过MAJOR/MINOR宏分解主次设备号
  3. 驱动卸载时使用unregister_chrdev_region释放

三、自动创建设备节点

现代驱动节点创建

/* 创建设备类 */
newchrled.class = class_create(THIS_MODULE, LED_NAME);/* 创建设备节点 */
newchrled.dev = device_create(newchrled.class, NULL, newchrled.devid, NULL, LED_NAME);

工作机制说明

  1. class_create:在/sys/class下创建设备类
  2. device_create:基于udev机制自动创建/dev节点
  3. 无需手动执行mknod命令

四、完整驱动加载流程

初始化函数实现

static int __init newchrled_init(void)
{/* 硬件初始化 */ioremap(CCM_CCGR1_BASE, 4); // 寄存器地址映射/* 字符设备注册四部曲 */1. alloc_chrdev_region() // 设备号申请2. cdev_init()           // 初始化cdev结构体3. cdev_add()            // 添加设备到系统4. device_create()       // 自动创建设备节点
}

驱动卸载流程

static void __exit newchrled_exit(void)
{/* 逆向释放资源 */1. device_destroy()      // 删除设备节点2. class_destroy()       // 销毁设备类3. cdev_del()           // 移除字符设备4. unregister_chrdev_region() // 释放设备号
}

五、应用层交互示例

int main(int argc, char *argv[])
{// 打开自动创建的设备节点int fd = open("/dev/newchrled", O_RDWR);// 控制指令下发unsigned char cmd = 1; // 1:开灯 0:关灯write(fd, &cmd, sizeof(cmd));// 关闭设备close(fd);return 0;
}

六、测试命令集

# 加载驱动模块
insmod newchrled.ko
# 方法二
modporbe nwechrled.ko# 查看自动生成的设备节点
ls -l /dev/newchrled# 查看内核分配的设备号
dmesg | grep newchrled# 测试LED控制
./ledAPP /dev/newchrled 1  # 开灯
./ledAPP /dev/newchrled 0  # 关灯

七、常见问题排查

  1. 设备节点未生成

    • 检查class_create返回值
    • 确认udev服务正常运行
    • 查看/sys/class下是否生成对应类目录
  2. 权限问题

    sudo chmod 666 /dev/newchrled
    
  3. 设备号冲突

    cat /proc/devices | grep newchrled
    
http://www.dtcms.com/a/366036.html

相关文章:

  • 数学建模-非线性规划(NLP)
  • STM32HAL 快速入门(十七):UART 硬件结构 —— 从寄存器到数据收发流程
  • DOM常见的操作有哪些?
  • Day34 UDP套接字编程 可靠文件传输与实时双向聊天系统
  • 信号调制与解调 matlab仿真
  • 异常处理机制与debug
  • 复写零(双指针)
  • 单片机day2
  • 配置时钟分频与倍频
  • 解构复杂财务逆向业务:如何优雅地生成与管理负数单?
  • Python基础(⑥属性装饰器)
  • 你只需输入一句话,MoneyPrinterTurbo直接给你输出一个视频
  • 普通人如何用 AI 提效?5 个低门槛工具 + 3 类场景案例,让 AI 成为日常助手
  • phpstorm 操作git 另外的操作在 我的收藏
  • c#编写的应用程序调用不在同一文件夹下的DLL
  • Java继承
  • c++ zint二维码、条形码开发库
  • c++多线程(1)------创建和管理线程td::thread
  • Python数据分析与处理(二):将数据写回.mat文件的不同方法【超详细】
  • AI+法律:用ERNIE-Bot解析合同条款,识别风险点
  • 进程管理和IPC
  • 常用假设检验方法及 Python 实现
  • 多层环境室内定位系统综述总结
  • 【JavaEE】(22) Spring 事务
  • 苏哒智能会议一体机:让会议管理进入智能时代
  • Java与Vue构建的企业设备资产管理系统,集成后台管理与移动端操作,覆盖设备全生命周期,支持采购、维护、报废等流程,提供完整源码,助力企业高效管控资产
  • 刻意练习实践说明使用手册
  • nginx配置讲解
  • GitLens:VS Code下高效解决代码追溯的Git管理实用插件
  • Spring Boot + Nacos 配置中心示例工程