zoukankan      html  css  js  c++  java
  • 手把手教你从零实现Linux misc设备驱动一(基于友善之臂4412开发板)

    关于怎样来写一个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!
    ");
    	return 0 ;
    }
    //实现close函数
    int tiny4412_misc_dev_close(struct inode *inode, struct file *filp)
    {
    	printk("tiny4412 misc dev close!
    ");
    	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!
    ");
    	   goto fair ;
    	}
    	printk("misc init success!
    ");	
    	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设备驱动。





  • 相关阅读:
    宏定义define和const的区别
    C++11新特性(1)
    TCP协议
    sql查询 不等于的坑null
    To B市场品牌实战课 用产品故事引爆市场
    Tomcat在windows服务器下,将tomcat控制台日志记录到日志文件中
    极客时间返现小程序,全网最优惠返现最多
    分布式数据库,从功能特性到运行机制,讲透本质
    生财有术知识星球整理
    ff
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7366198.html
Copyright © 2011-2022 走看看