Linux 编写一个 字符设备驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/rockchip/common.h> #include <linux/kdev_t.h> #include <linux/device.h> /** struct hello_test_data { struct device *classdev; int blue=456; } static struct hello_test_data *hello_data; **/ static struct class *hello_test_class; //定义设备类 static struct device *classdev; static char mybuf[100]= "123" ; //执行cat会调用到此函数 show对应的是read static ssize_t hello_test_show( struct device *dev, struct device_attribute *attr, char *buf) { return sprintf (buf, "%s\n" , mybuf); } //执行echo 1 > hello_test会执行到此函数 store 对应的是write static ssize_t hello_test_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { sprintf (mybuf, "%s" , buf); return count; } // _name _mode(权限) (显示函数) (写入) static DEVICE_ATTR(hello_test, 0777, hello_test_show, hello_test_store); //设备属性文件 名 // probe初始化函数 //cdev 分配设备对象空间 static int hello_test_probe( struct platform_device *pdev) { printk( "Gatsby probe hello_test\n" ); // 创建对应的节点file //device_create_file(&pdev->dev, &dev_attr_hello_test); classdev=device_create(hello_test_class, &pdev->dev, MKDEV(0, 0), NULL, "hello_test_device" ,0); sysfs_create_file(&pdev->dev.kobj, &dev_attr_hello_test.attr); return 0; } static const struct of_device_id hello_of_match[] = { { .compatible = "rockchip,hello_test" }, { }, }; // platform_driver 的结构 static struct platform_driver hello_test_driver = { .probe = hello_test_probe, .driver = { .name = "hello_test_class" , .owner = THIS_MODULE, .of_match_table = hello_of_match, //需要再dts中做匹配 } }; static int __init hello_init( void ) { printk( "Gatsby hello_init\n" ); /** struct device *classdev; classdev = device_create(hello_test, 0, MKDEV(0,0),NULL,"mytest_device"); //创建mytest_device设备 **/ hello_test_class = class_create(THIS_MODULE, "hello_test_class" ); // 在/sys/class目录下生成 hello_test目录 platform_driver_register(&hello_test_driver); return 0; } static void __exit hello_exit( void ) { printk( "Gatsby hello_exit\n" ); platform_driver_unregister(&hello_test_driver); } module_init(hello_init); module_exit(hello_exit); MODULE_AUTHOR( "hello_test" ); MODULE_DESCRIPTION( "Gatsby" ); MODULE_LICENSE( "GPL" ); |
makefile
1 | obj-$(CONFIG_HELLO_TEST) += hello_test.o |
kconfig
1 2 3 4 | config HELLO_TEST tristate "Hello world for Gatsby" help Hello for Gatsby |
上一级目录 makefile
1 | obj-y += gatsby/ |
kconfig
1 | source "drivers/gatsby/Kconfig" |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】