• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

03.杂项设备驱动

开发技术 开发技术 5小时前 1次浏览

Linux三大设备驱动

字符设备:IO的传输过程是以字符为单位的,没有缓冲。比如I2C,SPI都是字符设备。

块设备:IO的传输过程是以块为单位的。跟存储相关的,都属于块设备,比如TF卡。

网络设备:与前俩个不一样,是以socket套接字来访问的。

 

杂项设备(misc device)

1、 本小节讲述的杂项设备是属于字符设备的一种。可以自动生成设备节点。

  我们的系统中有许多杂项设备,可以输入cat /proc/misc来查看。

2、杂项设备除了比字符设备代码简单,还有什么区别?

  杂项设备的主设备号是相同的,均为10,次设备号是不同的。主设备号相同就可以节省内核的资源

3、主设备号和次设备号是什么?

  设备号包括主设备号和次设备号,主设备号在Linux系统里是唯一的,次设备号不一定唯一。

  设备号是计算机识别设备的一种方式,主设备号相同的就被视作为同一类设备。

  主设备号可以比作成电话号码的区号,比如北京的区号是010.

  次设备号可以比作电话号码。

  主设备号可以通过命令cat /proc/devices来查看。

4、杂项设备的描述

  定义在内核源码路径:include/linux/miscdevice.h

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;
};

  include/linux/fs.h讲述了文件操作集的结构体定义

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 *, loff_t, loff_t, 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 *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **);
    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);
};

  里面的一个结构体成员都要对应一个调用。

extern int misc_register(struct miscdevice * misc);//注册杂项设备
extern int misc_deregister(struct miscdevice *misc);//注销杂项设备

5、注册杂项设备的流程

  (1)填充miscdevice这个结构体。

  (2)填充file_operations这个结构体。

  (3)注册杂项设备并生成设备节点。

 

杂项设备注册实践

 按照5中讲述的注册杂项设备的流程实现代码misc.c

 1 #include <linux/init.h>   
 2 #include <linux/module.h>
 3 #include <linux/miscdevice.h>
 4 #include <linux/fs.h>
 5 
 6 stuct file_operations misc_fops = {
 7     .owner = THIS_MODULE
 8 };
 9 
10 struct miscdevice misc_dev = {
11     ./minor = MISC_DYNAMIC_MINOR,//此宏定义表示自动分配次设备号
12     .name = "hello_misc",//设备名
13     .fops = &misc_fops//文件操作集
14     
15 };
16 static int misc_init(void)
17 {
18     int ret;
19     ret = misc_register(&misc_dev);
20     if(ret < 0)
21     {
22         printk("misc register is errorn");
23     }
24     
25     printk("misc register is succeedn");
26     return 0;
27 }
28 
29 
30 static int misc_exit(void)
31 {
32     misc_deregister(&misc_dev);
33     printk("misc bye byen"); 
34     return 0;
35 }  
36 
37 module_init(hello_init);//模块入口
38 module_exit(hello_exit);//模块出口
39 
40 MODULE_LICENSE("GPL");

 

 使用如下的Makefile,编译成模块

obj-m +=helloworld.o #obj-m表示把驱动编译成模块,生成的中间文件名字为helloworld.o

KDIR:=/home/topeet/topeet/imx6ull/linux-imx-rel_imx_4.1.15_2.1.0_ga #指定内核路径

PWD?=$(shell pwd) #获取当前目录变量

all:
    make -C $(KDIR) M=$(PWD) modules #make进入到内核源码路径因为编译需要这个环境,把当前路径代码编译成模块

当然不要忘记指定内核的环境变量和交叉编译配置

export CROSS_COMPILE=XXX
export ARCH=arm

 

 

编译成功后,加载模块到板子上

insmod misc.ko

 

查看现象,/dev/路径下有hello_misc

03.杂项设备驱动

 

这样,一个最简单的杂项设备就完成了。 

 


程序员灯塔
转载请注明原文链接:03.杂项设备驱动
喜欢 (0)