linux杂项设备驱动模型模板 下载本文

Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述)。miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同。 所有的miscdevice设备形成了一个链表,对设备访问时内核根据次设备号查找对应的miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。 在内核中用struct miscdevice表示miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。miscdevice的API实现在drivers/char/misc.c中。

混杂项设备驱动的程序组织架构:

新建一个first_led.c,先可能用到的头文件都引用上吧!

#include

#include //驱动模块必需要加的个头文件 #include #include #include

#include #include #include #include #include .

//对应着相应机器平台的头文件 #include

#include #include

//给自己设备驱动定义一个名字

#define DEVICE_NAME \

名字有了,但样子是怎样的呢?现在就开始定义一个“样子”!

如果一个字符设备驱动要驱动多个设备,那么它就不应该用misc设备来实现。

通常情况下,一个字符设备都不得不在初始化的过程中进行下面的步骤:

通过alloc_chrdev_region()分配主次设备号。

使用cdev_init()和cdev_add()来以一个字符设备注册自己。

而一个misc驱动,则可以只用一个调用misc_register()

来完成这所有的步骤。(所以miscdevice是一种特殊的chrdev字符设备驱动) 所有的miscdevice设备形成一个链表,对设备访问时,内核根据次设备号查找 对应的miscdevice设备,然后调用其file_operations中注册的文件操作方法进行操作。

在Linux内核中,使用struct miscdevice来表示miscdevice。这个结构体的定义为:

struct miscdevice {

int minor;

const char *name;

const struct file_operations *fops; struct list_head list; struct device *parent; struct device *this_device; const char *nodename; mode_t mode; };

minor是这个混杂设备的次设备号,若由系统自动配置,则可以设置为 MISC_DYNANIC_MINOR,name是设备名

为了容易理解,我们先打大概的“样子”做好。只做minor、name、fops; 定义一个myfirst_led_dev设备:

static struct miscdevice myfirst_led_dev = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &myfirst_led_dev_fops, };

Minor name 都已经定义好了。那么接下来实现一下myfirst_led_dev_fops方法。

内核中关于file_operations的结构体如下: struct file_operations { struct module *owner;

loff_t (*llseek) (struct file *, loff_t, int);

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

int (*readdir) (struct file *, void *, filldir_t);

unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, int datasync);

int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int);

int (*lock) (struct file *, int, struct file_lock *);

ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int);

int (*flock) (struct file *, int, struct file_lock *);