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

Linux驱动开发probe字符设备的完整创建流程

一、        设备号分配

        1.静态分配

                通过register_chrdev_region预先指定设备号(需要确保未被占用)

        2.动态分配

                通过alloc_chrdev_region由内核自动分配主设备号,一般都是动态分配以避免冲突。

3316     xxxx_dev.major = 0;
3317 
3318     if (xxxx_dev.major)
3319     {
3320         xxxx_dev.devid = MKDEV(xxxx_dev.major,0);
3321         ret = register_chrdev_region(xxxx_dev.devid, xxxx_CNT, XX_DRV_NAME);
3322     }
3323     else
3324     {
3325         ret = alloc_chrdev_region(&xxxx_dev.devid, 0, xxxx_CNT, XX_DRV_NAME);
3326         xxxx_dev.major = MAJOR(xxxx_dev.devid);
3327         xxxx_dev.minor = MINOR(xxxx_dev.devid);
3328     }

二、        初始化cdev结构体

                通过cdev_init绑定file_operations操作集(需实现open、read、write等函数)

                示例:

static struct file_operations xx_fops = {.owner = THIS_MODULE,.open = my_open,.read = my_read,.write = my_write,
};
cdev_init(&xxxx_dev.cdev, &xx_fops);

三、        注册字符设备

                通过cdev_add将cdev添加到系统,关联设备号与操作集。

cdev_add(&xxx_dev.cdev, xxx_dev.devid, xxx_CNT);

四、        创建设备节点

                1、手动创建:mknod命令在/dev 下生成设备文件

                2、自动创建:

                        1)通过class_create创建设备类

                        2)调用device_create在/dev和/sys下自动生成设备节点

xxx_dev.class = class_create(THIS_MODULE, XXX_DRV_NAME);
xxx_dev.device = device_create(xxx_dev.class, NULL, xxx_dev.devid, NULL, xxx_DRV_NAME)

五、        资源释放(remove函数)   

        卸载驱动时需逆序释放资源:

device_destroy(my_class, dev_num);
class_destroy(my_class);
cdev_del(&my_cdev);
unregister_chrdev_region(dev_num, 1);

六、        总结 

ret = alloc_chrdev_region(&xx_dev.devid, 0, xx_CNT, XX_DRV_NAME);
cdev_init(&xxx_dev.cdev, &xx_fops);
ret = cdev_add(&xx_dev.cdev, xx_dev.devid, xx_CNT);
xx_dev.class = class_create(THIS_MODULE, XX_DRV_NAME);
xx_dev.device = device_create(xx_dev.class, NULL, xx_dev.devid, NULL, XX_DRV_NAME);

http://www.lryc.cn/news/618970.html

相关文章:

  • 【前端八股文面试题】【JavaScript篇7】什么是JavaScript的原型、原型链? 有什么特点
  • JavaScript Array.prototype.flatMap ():数组 “扁平化 + 映射” 的高效组合拳
  • 无人机三维路径规划
  • 2020/12 JLPT听力原文 问题一 4番
  • MyBatis-Plus——SQL注入器
  • LintCode第1526-N叉树的前序遍历
  • RabbitMQ面试精讲 Day 20:RabbitMQ压测与性能评估
  • 【游戏优化笔记】开发中如何减少建筑和树木等环境元素的资源消耗?
  • 行业热点丨智能仿真时代:电子工程多物理场解决方案创新实践
  • 【盘古100Pro+开发板实验例程】FPGA学习 | 中值滤波 | 图像实验指导手册
  • Redis知识点+项目+面试八股
  • redis认识缓存击穿
  • Flutter UI Kits by Olayemi Garuba:免费开源的高质量UI组件库
  • Element用法---Loading 加载
  • React 腾讯面试手写题
  • Photoshop软件打开WebP文件格的操作教程
  • 第六十四章:AI的“觅食”之路:数据采集器设计与多源数据获取
  • Android性能优化:架构层面的性能考量
  • Android 引导式访问(屏幕固定 Screen Pinning)完整指南
  • CPPIO流
  • 北京JAVA基础面试30天打卡08
  • 信号反射规律
  • [激光原理与应用-254]:理论 - 几何光学 - 自动对焦的原理
  • W5500之“socket.c”中的相关函数
  • Vue接口平台小功能——发送报告到飞书
  • AWT与Swing深度对比:架构差异、迁移实战与性能优化
  • Unity数据可视化图表插件XCharts
  • Elasticsearch JS 自定义 ConnectionPool / Connection / Serializer、敏感信息脱敏与 v8 平滑迁移
  • python调研本地 DeepSeek API的例子
  • NLP—词向量转换评论学习项目分析真实案例