当前位置: 首页 > 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.dtcms.com/a/328099.html

相关文章:

  • 【游戏优化笔记】开发中如何减少建筑和树木等环境元素的资源消耗?
  • 【RHCE】自动化备份全网服务器数据平台
  • 36-综合案例开发-2
  • Chrome插件开发【manifest.json】
  • 【传奇开心果系列】Flet框架桌面程序组件Custom Ribbon自定义组件模板
  • Class34锚框
  • 分享单位开通固定公网IP,不需要找运营商申请
  • sqli-libs通关教程(41-50)
  • lesson36:MySQL从入门到精通:全面掌握数据库操作与核心原理
  • Elasticsearch JS 客户端子客户端(Child Client)实践指南
  • DAY38作业(补)
  • CTO如何通过录音转写和音频降噪,提升企业远程协作效率?
  • Secure 第四天作业
  • Linux环境部署RocketMQ
  • C++算法·排序
  • 第六十四章:AI的“觅食”之路:数据采集器设计与多源数据获取
  • DL-FWI 的三项主要任务: 网络构建, 数据生成, 训练控制
  • 跑腿APP开发未来趋势:同城O2O系统源码在智能调度与个性化中的进化
  • Spring Boot项目中调用第三方接口
  • HCIP项目之OSPF综合实验
  • Flux.1系列模型解析--Kontext
  • 8月12号打卡
  • 【Leetcode hot 100】560.和为K的子数组
  • 无人机航拍数据集|第13期 无人机城市斑马线目标检测YOLO数据集963张yolov11/yolov8/yolov5可训练
  • 为什么304不锈钢仍会生锈?
  • Ubuntu20.06环境下安装VS Code及中文设置方法
  • CSRF 攻击
  • 【机器学习】什么是DNN / MLP(全连接深度神经网络, Deep Neural Network / Multilayer Perceptron)?
  • 【Python】支持向量机SVM
  • Web攻防-业务逻辑篇Fuzz技术数据并发条件竞争JS挖掘参数盲猜Turbo插件SRC