linux 混杂设备模型

    在Linux系统中,存在一类字符设备,他们共享一个主设备号(10),但此设备号不同,我们称这类设备为混杂设备(miscdeivce),查看/proc/device中可以看到一个名为misc的主设备号为10.所有的混杂设备形成一个链表,对设备访问时内核根据次设备号找到对应的miscdevice设备。

Linux内核使用struct miscdeivce来描述一个混杂设备

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文件操作函数集即可。

Linux内核使用misc_register函数注册一个混杂设备,使用misc_deregister移除一个混杂设备。注册成功后,linux内核为自动为该设备创建设备节点,在/dev/下会产生相应的节点。

 注册函数:

int misc_register(struct miscdevice * misc)

输入参数:struct miscdevice

返回值:

   表示注册成功。

负数 表示未成功。

卸载函数:

int  misc_deregister(struct miscdevice *misc)

0 表示成功。

负数 表示失败。

下面是基于linux 混杂设备模型的一个简单示例: 

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#define DEVICE_NAME "BELL-Control"
volatile unsigned long *gpbcon = NULL ;
volatile unsigned long *gpbdat = NULL ;  
volatile unsigned long *gpbup = NULL ;
static int bell_drv_open(struct inode *inode, struct file *file)
{
     *gpbcon &= ~(0x3<<(0*2));
     *gpbcon |= (0x1<<(0*2)) ; 
     *gpbup = 0x0;
      printk("first_drv_open\n");
      return 0;
}

static ssize_t bell_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
      int val;   
      copy_from_user(&val, buf, count) ;    
      if (val == 1)
      {
       *gpbdat &= ~(1<<0);
         printk("first_drv_write 1111111\n");
      }
      else
      {

         *gpbdat |= (1<<0);
          printk("first_drv_write 00000\n");
      }  
     return 0;
}

static struct file_operations bell_drv_fops = {
     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
     .open   =   bell_drv_open,     
    .write = bell_drv_write,    
};
 //注册混杂设备,每一个misc驱动会自动出现在/sys/class/misc/下
static struct miscdevice misc = {
      .minor =MISC_DYNAMIC_MINOR,
      .name = DEVICE_NAME,
      .fops = &bell_drv_fops,
};

static int bell_drv_init(void)
{
     int result;
     result = misc_register(&misc);   
     printk (""DEVICE_NAME" initialized\n"); 
     gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
     gpbdat = gpbcon + 1;
     gpbup = gpbcon + 2;
     return 0; 
}

static void bell_drv_exit(void)
{
      misc_deregister(&misc);
      iounmap(gpbcon);
}

module_init(bell_drv_init);
module_exit(bell_drv_exit);
MODULE_LICENSE("GPL");
 

 

你可能感兴趣的:(linux 混杂设备模型)