Linux 驱动开发流程(带最小可运行代码 + 通俗类比)
Linux 驱动开发流程带最小可运行代码 通俗类比很多人学 Linux 驱动都会卡在这里API 都看过但完全不知道它们是怎么串起来工作的这篇文章目标很明确✅ 用一条主线讲清流程✅ 用类比帮你记住✅ 给你一个最小可运行驱动模板一、先记住一条主线最重要用户操作 → 内核 → 设备号 → cdev → file_operations → 你的函数二、一个类比彻底记住 类比打电话现实Linux电话号码设备号通讯录cdev人file_operations打电话open/read/write 过程open(/dev/mydev) ↓ 设备号号码 ↓ cdev通讯录 ↓ file_operations人 ↓ 调用 read/write三、驱动开发完整流程工程版① 枚举设备DTS / 总线 ② 注册驱动 ③ 匹配compatible ④ probe() 执行 ⑤ 注册字符设备cdev ⑥ 创建 /dev 节点 ⑦ 用户操作 → 调用驱动四、最小字符设备驱动核心下面这个代码你可以直接用来练手 1. 驱动代码mydev.c#includelinux/module.h#includelinux/fs.h#includelinux/cdev.h#includelinux/device.h#defineDEVICE_NAMEmydevstaticdev_tdev_num;staticstructcdevmy_cdev;staticstructclass*my_class;/* ---------------- 核心操作函数 ---------------- */staticintmy_open(structinode*inode,structfile*file){printk(my_open called\n);return0;}staticssize_tmy_read(structfile*file,char__user*buf,size_tsize,loff_t*off){printk(my_read called\n);return0;}staticssize_tmy_write(structfile*file,constchar__user*buf,size_tsize,loff_t*off){printk(my_write called, size%ld\n,size);returnsize;}/* file_operations */staticstructfile_operationsmy_fops{.ownerTHIS_MODULE,.openmy_open,.readmy_read,.writemy_write,};/* ---------------- 初始化 ---------------- */staticint__initmy_init(void){printk(mydev init\n);/* 1️⃣ 分配设备号 */alloc_chrdev_region(dev_num,0,1,DEVICE_NAME);/* 2️⃣ 初始化 cdev */cdev_init(my_cdev,my_fops);/* 3️⃣ 添加 cdev */cdev_add(my_cdev,dev_num,1);/* 4️⃣ 创建设备节点 */my_classclass_create(THIS_MODULE,my_class);device_create(my_class,NULL,dev_num,NULL,DEVICE_NAME);return0;}/* ---------------- 退出 ---------------- */staticvoid__exitmy_exit(void){device_destroy(my_class,dev_num);class_destroy(my_class);cdev_del(my_cdev);unregister_chrdev_region(dev_num,1);printk(mydev exit\n);}module_init(my_init);module_exit(my_exit);MODULE_LICENSE(GPL);五、这个代码到底在干嘛一行一行串起来1️⃣ 分配设备号alloc_chrdev_region(dev_num,0,1,mydev); 作用给设备分配一个“身份证”major minor2️⃣ 定义行为file_operationsstaticstructfile_operationsmy_fops 定义这个设备能干什么open/read/write3️⃣ cdev_init核心cdev_init(my_cdev,my_fops); 本质把“设备号”和“操作函数”绑定4️⃣ cdev_add关键cdev_add(my_cdev,dev_num,1); 本质告诉内核这个设备可以用了5️⃣ 创建设备节点device_create(...) 最终生成/dev/mydev六、真正的数据流必须理解当你执行echo123/dev/mydev内核发生write(/dev/mydev) ↓ 找到设备号 ↓ 找到 cdev ↓ 找到 file_operations ↓ 调用 my_write()七、cdev 的本质终极总结cdev 内核里的“设备通讯录”它做了一件事设备号 → file_operations八、你必须能复述的三句话✅ 1️⃣file_operations 定义设备“能干什么”✅ 2️⃣设备号 标识“是谁”✅ 3️⃣最重要cdev 把“是谁”和“能干什么”绑定起来九、扩展和平台驱动的关系字符设备只是“用户接口层”完整驱动其实是DTS → platform_driver → probe → 注册 cdev → /dev十、为什么你之前学不会因为你之前是这样记的背 APIcdev_add、cdev_init但正确理解应该是用户调用 → 设备号 → cdev → file_operations → 函数十一、建议练习强烈推荐insmod mydev.koechohello/dev/mydevdmesg你会看到my_write called十二、一句话总结面试可用Linux 字符设备驱动的核心是通过 cdev将设备号映射到 file_operations从而让用户空间调用最终执行驱动代码。结尾如果你能讲清这三件事你已经超过 70% 初级驱动工程师① 设备怎么来的枚举 ② probe 为什么执行匹配 ③ read/write 为什么能调用cdev这才是驱动开发的“主线思维”。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2479382.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!