05 字符设备驱动

一、字符设备驱动函数接口

1.初始化cdev结构体
void cdev_init(struct cdev * cdev, const struct file_operations * fops)
功能:初始化cdev结构体
参数:
@cdev cdev结构体
@fops 操作函数的结构体

2.申请设备号
int register_chrdev_region(dev_t from, unsigned count, const char * name);
参数:
@from 包含主设备号的数字
@count 设备号的个数
@name 设备的名字 (在cat /proc/devices看到它)
返回值:
成功返回0,失败返回负的错误码

3.添加字符设备
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
参数:
@p cdev结构体
@dev 设备号(第一个设备号)
@count 次设备的个数
返回值:
成功返回0,失败返回负的错误码

二、例子

1. 字符设备驱动

 1 #include <linux/module.h>
 2 #include <linux/init.h>
 3 #include <linux/cdev.h>
 4 #include <linux/fs.h>
 5
 6 MODULE_LICENSE("GPL");
 7
 8 #define MAJOR  250
 9
10 struct mycdev
11 {
12     int major;
13     int minor;
14     struct cdev cdev;
15 };
16
17 //int (*open) (struct inode *, struct file *);
18 int mycdev_open(struct inode *inode,struct file *file)
19 {
20     printk("Call mycdev_open()\n");
21
22     return 0;
23 }
24
25 //ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
26 //ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
27 //int (*release) (struct inode *, struct file *);
28
29 struct mycdev cdev_device;
30
31 struct file_operations fops = {
32     .owner =  THIS_MODULE,
33     .open  =  mycdev_open,
34 };
35
36
37 int mycdev_init(void)
38 {
39     int ret;
40     dev_t dev_num;
41
42     //cdev_init(struct cdev * cdev, const struct file_operations * fops)
43     cdev_init(&cdev_device.cdev,&fops);
44
45
46     dev_num = MKDEV(MAJOR, 0);
47
48     //register_chrdev_region(dev_t from, unsigned count, const char * name)
49     ret = register_chrdev_region(dev_num,1,"mycdev");
50     if(ret != 0){
51         printk("Fail to register chrdev region\n");
52         goto err_register_chrdev_region;
53     }
54
55     cdev_device.major = MAJOR;
56     cdev_device.minor = 0;
57
58     //cdev_add(struct cdev * p, dev_t dev, unsigned count)
59     ret = cdev_add(&cdev_device.cdev,dev_num,1);
60     if(ret != 0){
61         printk("Fail to cdev_add\n");
62         goto err_cdev_add;
63
64     }
65
66     return 0;
67
68 err_cdev_add:
69     //unregister_chrdev_region(dev_t from, unsigned count)
70     unregister_chrdev_region(dev_num,1);
71
72 err_register_chrdev_region:
73     return ret;
74 }
75
76
77 void mycdev_exit(void)
78 {
79     dev_t dev_num = MKDEV(MAJOR,0);
80
81     //cdev_del(struct cdev * p)
82     cdev_del(&cdev_device.cdev);
83     unregister_chrdev_region(dev_num,1);
84
85     return ;
86 }
87
88
89 module_init(mycdev_init);
90 module_exit(mycdev_exit);

2. 应用层open驱动

 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6
 7 int main(int argc, const char *argv[])
 8 {
 9     int fd;
10
11     fd = open("/dev/mycdev",O_RDONLY);
12     printf("fd = %d\n",fd);
13     while(1);
14
15     return 0;
16 }

3. Makefile

时间: 2024-10-01 07:08:42

05 字符设备驱动的相关文章

register_chrdev_region/alloc_chrdev_region和cdev注册字符设备驱动

内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region().alloc_chrdev_region() 和 register_chrdev(). (1)register_chrdev  比较老的内核注册的形式   早期的驱动(2)register_chrdev_region/alloc_chrdev_region + cdev  新的驱动形式 (3)register_chrdev()函数是老版本里面的设备号注册函数,可以实现静态和动态注册两种方法

linux字符设备驱动

一.字符设备.字符设备驱动与用户空间访问该设备的程序三者之间的关系. 如图,在Linux内核中使用cdev结构体来描述字符设备,通过其成员dev_t来定义设备号(分为主.次设备号)以确定字符设备的唯一性.通过其成员file_operations来定义字符设备驱动提供给VFS的接口函数,如常见的open().read().write()等. 在Linux字符设备驱动中,模块加载函数通过register_chrdev_region( ) 或alloc_chrdev_region( )来静态或者动态获

linux 字符设备驱动开发详解

一.设备的分类及特点 1.字符设备 字符设备是面向数据流的设备,没有请求缓冲区,对设备的存取只能按顺序按字节的存取而不能随机访问.    Linux下的大多设备都是字符设备.应用程序是通过字符设备节点来访问字符设备的.通常至少需要实现 open, close, read, 和 write 等系统调用.    设备节点一般都由mknod命令都创建在/dev目录下,包含了设备的类型.主/次设备号以及设备的访问权限控制等,如:crw-rw----  1 root  root 4, 64 Feb 18

linux设备驱动第三篇:写一个简单的字符设备驱动

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [plain] vie

13、字符设备驱动的使用

编译和安装驱动 下面是通过一个例子来学会使用驱动程序: 1---驱动程序: Memdev.c #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/cdev.h> #include <asm/uaccess.h> int dev1_registers[5]; int dev2_registers[5]; struct cdev

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

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

字符设备驱动模型

1.设备描述结构cdev驱动模型种类繁多,这就需要我从众多的模型中提取出他们的一些共性:a.驱动初始化a.1 分配设备描述结构a.2 初始化设备描述结构a.3 注册设备描述结构a.4 硬件初始化b.实现设备操作c.驱动注销 ------------------------------------------------------------------ 设备描述结构:在任何一种驱动模型中,设备都会用的内核中的一种结构来描述,我们的字符设备在内核中使用struct cdev 来来描述.struc

Linux字符设备驱动剖析

一.先看看设备应用程序 1.很简单,open设备文件,read.write.ioctl,最后close退出.如下: intmain(int argc ,char *argv[]){ unsigned char val[1] = 1; int fd =open("/dev/LED",O_RDWR);//打开设备 write(fd,val,1);//写入设备,这里代表LED全亮 close(fd);//关闭设备 return 0; } 二./dev目录与文件系统 2./dev是根文件系统下

字符设备驱动框架

scull from <Linux设备驱动程序> memdev.c /* * memdev.c * create at 2015/01/07 * 字符设备驱动程序框架 */ #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <