驱动14.字符设备的另一种写法

原本的字符设备只能有255个驱动程序,原因是一个主设备号占用了0~255的次设备号

把register_chrdev展开可得到一下几个部分:register_chrdev_region/alloc_chrdev_region,cdev_init,cdev_add

参照register_chrdev的写法完成hello.c的代码

 1 #include <linux/module.h>
 2 #include <linux/kernel.h>
 3 #include <linux/fs.h>
 4 #include <linux/init.h>
 5 #include <linux/delay.h>
 6 #include <linux/irq.h>
 7 #include <asm/uaccess.h>
 8 #include <asm/irq.h>
 9 #include <asm/io.h>
10 #include <asm/arch/regs-gpio.h>
11 #include <asm/hardware.h>
12 #include <linux/poll.h>
13 #include <linux/cdev.h>
14
15 static int major;
16
17 static int hello_open(struct inode *inode, struct file *file)
18 {
19     printk("hello_open\n");
20     return 0;
21 }
22
23 static int hello2_open(struct inode *inode, struct file *file)
24 {
25     printk("hello2_open\n");
26     return 0;
27 }
28
29
30
31 static struct file_operations hello_fops = {
32     .owner = THIS_MODULE,
33     .open  = hello_open,
34 };
35
36 static struct file_operations hello2_fops = {
37     .owner = THIS_MODULE,
38     .open  = hello2_open,
39 };
40
41 #define HELLO_CNT   2
42
43 static struct cdev hello_cdev;
44 static struct cdev hello2_cdev;
45 static struct class *cls;
46
47
48 static int hello_init(void)
49 {
50     dev_t devid;
51
52     if (major) {
53         devid = MKDEV(major, 0);
54         register_chrdev_region(devid, HELLO_CNT, "hello");
55     } else {
56         alloc_chrdev_region(&devid, 0, HELLO_CNT, "hello");
57         major = MAJOR(devid);
58     }
59     cdev_init(&hello_cdev, &hello_fops);
60     cdev_add(&hello_cdev, devid, HELLO_CNT);
61
62     devid = MKDEV(major, 2);
63     register_chrdev_region(devid, 1, "hello2");
64     cdev_init(&hello2_cdev, &hello2_fops);
65     cdev_add(&hello2_cdev, devid, 1);
66
67     cls = class_create(THIS_MODULE, "hello");
68     class_device_create(cls, NULL, MKDEV(major, 0), NULL, "hello0"); /* /dev/hello0 */
69     class_device_create(cls, NULL, MKDEV(major, 1), NULL, "hello1"); /* /dev/hello1 */
70     class_device_create(cls, NULL, MKDEV(major, 2), NULL, "hello2"); /* /dev/hello2 */
71     class_device_create(cls, NULL, MKDEV(major, 3), NULL, "hello3"); /* /dev/hello3 */
72
73
74     return 0;
75
76 }
77
78 static void hello_exit(void)
79 {
80     class_device_destroy(cls, MKDEV(major, 0));
81     class_device_destroy(cls, MKDEV(major, 1));
82     class_device_destroy(cls, MKDEV(major, 2));
83     class_device_destroy(cls, MKDEV(major, 3));
84     class_destroy(cls);
85
86     cdev_del(&hello_cdev);
87     unregister_chrdev_region(MKDEV(major, 0), HELLO_CNT);
88
89     cdev_del(&hello2_cdev);
90     unregister_chrdev_region(MKDEV(major, 2), 1);
91 }
92
93 module_init(hello_init);
94 module_exit(hello_exit);
95
96
97 MODULE_LICENSE("GPL");

hello.c

(major,0~1)对应于hello,即/dev/hello0,/dev/hello1

(major,2)对应于hello2,即/dev/hello2

/dev/hello3打不开

时间: 2024-10-25 02:15:54

驱动14.字符设备的另一种写法的相关文章

【转】深入浅出:Linux设备驱动之字符设备驱动

深入浅出:Linux设备驱动之字符设备驱动 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流的设备,常见的字符设备有鼠标.键盘.串口.控制台和LED设备等. 块设备:是指可以从设备的任意位置读取一定长度数据的设备.块设备包括硬盘.磁盘.U盘和SD卡等. 每一个字符设备或块设备都在/dev目录下对应一个设备文件.linux用户程序通过设备文件(或称

《驱动学习 - 字符设备驱动》

1.1字符设备驱动基础 字符设备驱动:设备对数据的处理是按照字节流的形式进行的. 在linux中,“一切皆文件”(除了网络设备),这表示设备最终都会体现为一个文件.设备文件通常位于/dev目录下. 内核通常用主设备号区别一类设备,次设备号用于区分同一类设备的不同个人或不同分区. 手动创建设备文件 mknod /dev/vser0 c 256 0 mknod是make node的缩写.用于创建一个节点(设备文件也叫设备节点).在linux系统中,一个节点代表一个文件. 原文地址:https://w

linux设备驱动之字符设备驱动模型(2)

在上一篇中我们已经了解了字符设备驱动的原理,也了解了应用层调用内核函数的机制,但是我们每次操作设备,都必须首先通过mknod命令创建一个设备文件名,比如说我们要打开u盘,硬盘等这些设备,难道我们还要自己创建,就如同刘老师常说的一句话,这也太山寨了吧,所以我们今天我们来点比较专业的,让函数帮我们自动创建: 在Linux 下,设备和驱动通常都需要挂接在一种总线上,总线有PCI.USB.I2C.SPI 等等,总线是处理器和设备之间的通道,在设备模型中,所有的设备都通过总线相连,一总线来管理设备和驱动函

深入浅出~Linux设备驱动之字符设备驱动

一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流的设备,常见的字符设备有鼠标.键盘.串口.控制台和LED设备等. 块设备:是指可以从设备的任意位置读取一定长度数据的设备.块设备包括硬盘.磁盘.U盘和SD卡等. 每一个字符设备或块设备都在/dev目录下对应一个设备文件.linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备和块设备

Linux设备驱动之字符设备驱动

一.linux系统将设备分为3类:字符设备.块设备.网络设备. 应用程序调用的流程框图: 三种设备的定义分别如下, 字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序进行.字符设备是面向流的设备,常见的字符设备如鼠标.键盘.串口.控制台.LED等. 块设备:是指可以从设备的任意位置读取一定长度的数据设备.块设备如硬盘.磁盘.U盘和SD卡等存储设备. 网络设备:网络设备比较特殊,不在是对文件进行操作,而是由专门的网络接口来实现.应用程序不能直接访

字符设备驱动体验,字符设备驱动学习

字符设备驱动学习 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块. 一.编译安装字符设备驱动程序 memdev文件中:在这个文件里和真实的硬件无关,只是虚构了一个数组 1 #include <linux/module.h> 2 #include <linux/fs.h> 3 #include <linux/init.h> 4 #include <linux/cdev.h> 5

【驱动】——字符设备驱动程序

字符设备不得不说的那些事: 一: 设备号:主设备号,次设备号: 数据类型 dev_t(unsigned int) 定义设备号  高12位主设备号 低20位次设备号: 二: 设备号的作用: 应用程序通过主设备号找到驱动程序: 三:如何分配设备号: ①:静态分配: 1: cat /proc/devices 查看linux系统哪个设备号没有被占用: 2: dev_t dev_id = MKDEV(主设备号,次设备号)  根据你的设备个数分配次设备号 如果设备个数只有一个,一般此设备号从0开始: 3: 

初入android驱动之字符设备(三)

回想当初在大学玩51单片机的时候,实验室的老师第一个任务,就是设计一个基于51单片机的LED流水灯设计,并实现几种样式.第二个任务,就是设计一个基于51单片机的按键控制LED流水灯样式的设计.需要自己设计硬件图.画protel电路图,并设计出PCB,实现keil和proteus的联调,然后焊接电路板,实现其功能.那时候什么都不懂,秉这一股冲劲,各种百度.看书,那时候郭天祥的51单片机视频超火,所以那时候基本以他的书和视频学得,牛人,膜拜. 所以,这主要讲关于按键最简单的字符驱动,通过设置连接该引

linux驱动之字符设备

第一部分:字符设备工作过程1.系统调用和驱动程序的关联关键结构体:struct file_operation:file_operation结构体的每一个成员的名字都对应着一个系统调用.用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数.这是linux的设备驱动程序工作的基本原理.编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域.