在Linux内核学习-字符设备驱动学习(一)中编写字符设备驱动的一种方法,但是需要手动创建设备节点。

有没有能够自动的创建设备节点的呢?

有!使用class_create()和device_create()函数可以自动创建节点。

class_create : 创建class
class_destroy : 销毁class
class_device_create : 创建device
class_device_destroy : 销毁device

class_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
class_create - create a struct class structure
@owner: pointer to the module that is to "own" this struct class
@name: pointer to a string for the name of this class.
在/sys/class/下创建类目录

class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_create(struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)

class_device_create - creates a class device and registers it with sysfs
@cls: pointer to the struct class that this device should be registered to.
@parent: pointer to the parent struct class_device of this new device, if any.
@devt: the dev_t for the char device to be added.
@device: a pointer to a struct device that is assiociated with this class device.
@fmt: string for the class device's name
在驱动模块初始化函数中实现设备节点的自动创建

设备驱动文件char01.c

[cpp] view plaincopyprint?
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/cdev.h>
  4. #include <linux/device.h>
  5. #include <linux/kdev_t.h>
  6. #include <linux/fs.h>
  7. /
  8. int char01_open(struct inode *inode, struct file *filp)
  9. {
  10. printk("char01 open!/n");
  11. return 0;
  12. }
  13. int char01_release(struct inode *inode, struct file *filp)
  14. {
  15. printk("char01 release!/n");
  16. return 0;
  17. }
  18. ssize_t char01_read(struct file *filp, char *buf,
  19. size_t count, loff_t *fpos)
  20. {
  21. printk("char01 read!/n");
  22. return 0;
  23. }
  24. ssize_t char01_write(struct file *filp, const char *buf,
  25. size_t count, loff_t *fpos)
  26. {
  27. printk("char01 write!/n");
  28. return 0;
  29. }
  30. int char01_ioctl(struct inode *inode, struct file *filp,
  31. unsigned int cmd, unsigned long param)
  32. {
  33. printk("char01 ioctl!/n");
  34. printk("cmd:%d param:%ld/n", cmd, param);
  35. return 0;
  36. }
  37. /
  38. struct file_operations fops =
  39. {
  40. .owner = THIS_MODULE,
  41. .open = char01_open,
  42. .release = char01_release,
  43. .read = char01_read,
  44. .write = char01_write,
  45. .ioctl = char01_ioctl
  46. };
  47. dev_t devno;
  48. struct class *pclass;
  49. struct cdev dev;
  50. int char01_dev_init(void)
  51. {
  52. int result;
  53. result = alloc_chrdev_region(&devno, 0, 1, "char01");
  54. if (result != 0)
  55. {
  56. printk("alloc_chrdev_region failed!/n");
  57. goto ERR1;
  58. }
  59. cdev_init(&dev, &fops);
  60. dev.owner = THIS_MODULE;
  61. dev.ops = &fops;
  62. result = cdev_add(&dev, devno, 1);
  63. if (result != 0)
  64. {
  65. printk("cdev_add failed!/n");
  66. goto ERR2;
  67. }
  68. pclass = class_create(THIS_MODULE, "char01");
  69. if (IS_ERR(pclass))
  70. {
  71. printk("class_create failed!/n");
  72. goto ERR3;
  73. }
  74. device_create(pclass, NULL, devno, NULL, "char01");
  75. return 0;
  76. ERR3:
  77. cdev_del(&dev);
  78. ERR2:
  79. unregister_chrdev_region(devno, 1);
  80. ERR1:
  81. return -1;
  82. }
  83. /
  84. /
  85. /
  86. static int __init char01_init(void)
  87. {
  88. printk("module char01 init!/n");
  89. return char01_dev_init();
  90. }
  91. static void __exit char01_exit(void)
  92. {
  93. printk("module char01 exit!/n");
  94. class_destroy(pclass);
  95. device_destroy(pclass,devno);
  96. cdev_del(&dev);
  97. unregister_chrdev_region(devno, 1);
  98. }
  99. /
  100. MODULE_LICENSE("Dual BSD/GPL");
  101. MODULE_AUTHOR("Yao.GUET");
  102. module_init(char01_init);
  103. module_exit(char01_exit);
  104. /

#include <linux/init.h> #include <linux/module.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/fs.h> / int char01_open(struct inode *inode, struct file *filp) { printk("char01 open!/n"); return 0; } int char01_release(struct inode *inode, struct file *filp) { printk("char01 release!/n"); return 0; } ssize_t char01_read(struct file *filp, char *buf, size_t count, loff_t *fpos) { printk("char01 read!/n"); return 0; } ssize_t char01_write(struct file *filp, const char *buf, size_t count, loff_t *fpos) { printk("char01 write!/n"); return 0; } int char01_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { printk("char01 ioctl!/n"); printk("cmd:%d param:%ld/n", cmd, param); return 0; } / struct file_operations fops = { .owner = THIS_MODULE, .open = char01_open, .release = char01_release, .read = char01_read, .write = char01_write, .ioctl = char01_ioctl }; dev_t devno; struct class *pclass; struct cdev dev; int char01_dev_init(void) { int result; result = alloc_chrdev_region(&devno, 0, 1, "char01"); if (result != 0) { printk("alloc_chrdev_region failed!/n"); goto ERR1; } cdev_init(&dev, &fops); dev.owner = THIS_MODULE; dev.ops = &fops; result = cdev_add(&dev, devno, 1); if (result != 0) { printk("cdev_add failed!/n"); goto ERR2; } pclass = class_create(THIS_MODULE, "char01"); if (IS_ERR(pclass)) { printk("class_create failed!/n"); goto ERR3; } device_create(pclass, NULL, devno, NULL, "char01"); return 0; ERR3: cdev_del(&dev); ERR2: unregister_chrdev_region(devno, 1); ERR1: return -1; } / / / static int __init char01_init(void) { printk("module char01 init!/n"); return char01_dev_init(); } static void __exit char01_exit(void) { printk("module char01 exit!/n"); class_destroy(pclass); device_destroy(pclass,devno); cdev_del(&dev); unregister_chrdev_region(devno, 1); } / MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Yao.GUET"); module_init(char01_init); module_exit(char01_exit); /

测试文件char01_test.c

[cpp] view plaincopyprint?
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <errno.h>
  4. #include <sys/stat.h>
  5. /
  6. int main(int argc, char *argv)
  7. {
  8. int fd;
  9. fd = open("/dev/char01", O_RDWR);
  10. if (fd<0)
  11. {
  12. printf("open /dev/char01 failed!/n");
  13. printf("%s/n", strerror(errno));
  14. return -1;
  15. }
  16. printf("open /dev/char01 ok!/n");
  17. ioctl(fd, 0);
  18. close(fd);
  19. }

#include <stdio.h> #include <fcntl.h> #include <errno.h> #include <sys/stat.h> / int main(int argc, char *argv) { int fd; fd = open("/dev/char01", O_RDWR); if (fd<0) { printf("open /dev/char01 failed!/n"); printf("%s/n", strerror(errno)); return -1; } printf("open /dev/char01 ok!/n"); ioctl(fd, 0); close(fd); }

Makefile文件:

[xhtml] view plaincopyprint?
  1. obj-m := char01.o
  2. PWD := $(shell pwd)
  3. K_DIR := /lib/modules/$(shell uname -r)/build
  4. all:
  5. $(MAKE) -C $(K_DIR) M=$(PWD) modules
  6. clean:
  7. $(MAKE) -C $(K_DIR) M=$(PWD) clean
  8. test:char01_test.o
  9. gcc -o $@ $^

Linux内核学习-字符设备驱动学习(二)相关推荐

  1. [转载]Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)

    [转载]Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1) 2011年09月13日 可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会轻松很多,驱动模型是整个linux设备 ...

  2. Linux内核部件分析 设备驱动模型之driver ---mark 详细

    Linux内核部件分析 设备驱动模型之driver 转载:https://www.linuxidc.com/Linux/2011-10/44627p7.htm 上节我们分析设备驱动模型中的device ...

  3. linux内核创建字符节点,Tiny6410学习ing—(四)、嵌入式Linux内核驱动进阶—(7)、高级字符设备驱动(自动创建节点)—#931...

    按照国嵌的视频教程上来说的,最后就是-自动创建设备文件! 其实我感觉以前完全可以直接是手动创建了设备文件,然后就可以直接讲述自动创建设备文件,为啥非要拖到最后来讲述,我也就不清楚了!! 不管了,写完收 ...

  4. 驱动学习----字符设备驱动框架

    字符设备驱动框架 1.字符设备驱动简介 2.file_operations 3.驱动模块的加载和卸载 4.字符设备的注册与注销 5.实现设备具体操作函数 6.添加LICENSE和作者信息 7.linu ...

  5. linux内核的块设备驱动框架详解

    1.块设备和字符设备的差异 (1)块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位.大多数设备是字符设备,因为它们不需要缓冲而且不以固定块大小进行操作; (2)块设备对于 I/O 请求 ...

  6. linux下的字符设备驱动

    Linux字符设备驱动程序的一个简单示例 一.开发环境: 主  机:VMWare--Fedora 9 开发板:友善之臂mini2440--256MB Nandflash 编译器:arm-linux-g ...

  7. Linux内核大讲堂之设备驱动的基石驱动模型(1)

    转自 http://blog.csdn.net/gqb_driver/article/details/8449588 转自:无为和尚的Linux内核大讲堂系列,并对个别地方进行了补充更正(见标红处). ...

  8. Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)

    可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会轻松很多,驱动模型是整个linux设备驱动的基石.大部分人把驱动模型叫做设备模型,但是我查了linux的帮助文档,就是在下载源码路 ...

  9. 【转】Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)

    原文传送门http://blog.csdn.net/z2007b/archive/2011/05/03/6388753.aspx 可能把驱动模型放在第一章讲会会有点难度,但是只要能跨过这道坎,后面就会 ...

最新文章

  1. 用sqlplus为oracle创建用户和表空间
  2. 发那科机器人注油_如何给发那科机器人做三年保养?干货!
  3. oracle TNS: 协议适配器错误 解决办法
  4. java环境变量中classpath是必须配置吗
  5. C语言其实不难,只是你没有找对方法!
  6. dnf上海2服务器维护,DNF上海2出现大面积盗号并迅速蔓延请注意
  7. PostgreSQL视图使用特殊名称作字段时的处理
  8. python中的进程(二)
  9. ubuntu mysql双主热备配置_mysql学习:mysql双主热备+lvs+keepalived配置
  10. 【集合论】容斥原理 ( 包含排斥原理 | 示例 )
  11. 单阶段人体姿态估计解决方案
  12. GStreamer 简化 Linux 多媒体开发
  13. 第十七章 - 垃圾回收器
  14. 宝华计算机维修,唐山市路北区宝华计算机维修服务
  15. Flashback 技术
  16. linux忘记root密码怎么办——重置root密码的四种方法
  17. android中留言板功能,Android -- 留言板的简单实现
  18. 广告VS电商 抖音快手的变现之争
  19. [2018-5-4]BNUZ你们还差得远呢
  20. 分布式计算,大型网站技术架构:核心原理与案例分析

热门文章

  1. pytorch 保存、读取 tensor 数据
  2. python打印进程号与线程号
  3. 博弈树α-β剪枝搜索学习参考资料
  4. Mac os更新系统后安装scrapy报错error: command ‘xcrun‘ failed with exit status 1
  5. python发送文件_python:socket传输大文件
  6. LeetCode开心刷题二十七天——51. N-Queens
  7. ios7之后的一些更改
  8. 手写分页 个人感觉还能优化,甚至抽象出来,需要高手讲解
  9. org.hibernate.HibernateException: 'hibernate.dialect' must be set when no Connection avalable
  10. Android中URI的格式