当前位置:首页 > 公众号精选 > 嵌入式云IOT技术圈
[导读]关于如何来写一个misc设备,在前面有篇文章已经介绍了大致的流程,现在就让我们来实现一个最简单的misc设备驱动。 http://blog.csdn.net/morixinguan/article/details/52700146 关于前面的字符设备有以下四篇文章,可以做参考: http://blog.csdn.net/morixing

关于如何来写一个misc设备,在前面有篇文章已经介绍了大致的流程,现在就让我们来实现一个最简单的misc设备驱动。

http://blog.csdn.net/morixinguan/article/details/52700146

关于前面的字符设备有以下四篇文章,可以做参考:

http://blog.csdn.net/morixinguan/article/details/55002774

http://blog.csdn.net/morixinguan/article/details/55003176

http://blog.csdn.net/morixinguan/article/details/55004646

http://blog.csdn.net/morixinguan/article/details/55006654


为什么要学习misc设备的编程?

因为,如果我们 每个驱动设备都要像最初那样子去写一个字符设备驱动一样,要分配主设备号,次设备号,实现对应的文件操作函数等等的步骤,未免就有点多了,而且也不好记住它,为此,Linux内核提供了一系列偷懒的技巧,那就是实现了misc设备,其实misc设备,也算是字符设备,只不过对字符设备进行了封装,看看下面的介绍就知道了。

我们先来看看misc设备的结构体:

//miscdevice结构体

struct miscdevice  {

//次设备号一般赋值为MISC_DYNAMIC_MINOR---->由内核自动去分配次设备号

int minor;

//misc设备的名称

const char *name;

//文件操作结构体

const struct file_operations *fops;

struct list_head list;

struct device *parent;

struct device *this_device;

const char *nodename;

umode_t mode;

};


这里,我们写最简单的misc设备,我们只需要关注minor(次设备号),name(设备名称),fops(文件操作函数).

看到这里我们可以想象到,misc设备是对字符设备做了一个再次的封装,而且,在misc设备中,主设备号都是一样的,都是10,只有次设备号不同,当我们不知道内核中应该去分配那个此设备号时,可以直接给minor赋值为MISC_DYNAMIC_MINOR这个宏,意思就是由内核来帮我们分配次设备号。

name就不用说了,如果设备注册成功,在根文件系统/dev/下就会有注册设备后的name。

fops就是一系列的文件操作函数啦,什么open , read ,write , ioctl等等,很多,跟写字符设备是一样的。

那么,接下来,我们来看一个例子,这里我就省略我的Makefile还有Kcofig了,可以参考前面的文章,轻松实现。

实现一个简单的Misc设备驱动程序(在TINY4412开发板上编写)

cdev_test.c

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

#include <linux/types.h>

#include <linux/moduleparam.h>

#include <linux/slab.h>

#include <linux/ioctl.h>

#include <linux/cdev.h>

#include <linux/delay.h>

 

#include <linux/gpio.h>

#include <mach/gpio.h>

#include <plat/gpio-cfg.h>


//misc设备名称--->就是字符设备

#define DEVICE_NAME "misc_dev"

//实现open函数

int tiny4412_misc_dev_open(struct inode *inode, struct file *filp)

{

printk("tiny4412 misc dev open!\n");

return 0 ;

}

//实现close函数

int tiny4412_misc_dev_close(struct inode *inode, struct file *filp)

{

printk("tiny4412 misc dev close!\n");

return 0 ;

}

//初始化文件操作结构体

struct file_operations tiny4412_file_ops = {

.owner = THIS_MODULE ,

.open = tiny4412_misc_dev_open,

.release = tiny4412_misc_dev_close,

};

//初始化misc设备结构体

struct miscdevice tiny4412_misc_dev = {

//由内核自动分配次设备号

.minor = MISC_DYNAMIC_MINOR ,

//初始化设备名称

.name = DEVICE_NAME ,

//初始化文件操作结构体

.fops = &tiny4412_file_ops,

};



static int __init tiny4412_misc_dev_init(void) 

{

int ret_error ;

//注册misc设备

int ret = misc_register(&tiny4412_misc_dev);

if(ret != 0){

  ret_error = ret ;

  printk("misc register fair!\n");

  goto fair ;

}

printk("misc init success!\n");

return ret ;

fair:

return ret_error ;

}


static void __exit tiny4412_misc_dev_exit(void) 

{

//注销misc设备

misc_deregister(&tiny4412_misc_dev);

}


module_init(tiny4412_misc_dev_init);

module_exit(tiny4412_misc_dev_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("YYX add misc driver");

然后,将驱动程序编译后,讲zImage下载到板子上。

我们可以看到,在开机的时候,misc init成功打印,证明,misc设备注册成功。

接下来,到安卓的根文件系统里,我们打开/dev/下,可以看到设备名称为misc_dev的设备:

我们可以看到,misc_dev的主设备号是10,次设备号是39

接下来,cat /proc/misc:


说明,misc已经被注册到proc文件系统中去了。

下节,我们将实现一个真正的misc设备驱动。


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭