snifer

【原创】嵌入式系统中设备号的意义

0
阅读(2503)

设备号:设备号主要是用查找设备对象用的。

格式:设备号由主设备号和次设备号组成。一般的,主设备用来表征一类设备,次设备号用来表示该设备是第几个。

内核函数:

声明头文件:linux/kdev_t.h

/*

*功能:组装设备号

*参数:

*   int major主设备号

*   int minor次设备号

*返回值:

*   设备号

*/

dev_t MKDEV(int major, int minor);

/*

*功能:分离主设备号

*参数:

*   dev_t dev设备号

*返回值:

*   主设备号

*/

int MAJOR(dev_t dev);

/*

*功能:分离次设备号

*参数:

*   dev_t dev设备号

*返回值:

*   次设备号

*/

int MINOR(dev_t dev);

 

声明头文件:linux/fs.h

/*

*功能:静态申请设备号

*参数:

*   dev_t被指定的设备号

*   unsigned设备号的数量,从指定的次设备号开始分配,到这个值的指定数量结束

*   const char *设备名称,如果申请成功cat /proc/devices中可以看到主设备号及该字符串指定的名称

*返回值:

*   成功:0;失败:错误码

*/

int register_chrdev_region(dev_t, unsigned, const char *);

/*

*功能:动态分配设备号

*参数:

*   dev_t指向分配的设备号,用来保存内核分配的第一个设备号(次设备号是第二个参数指定的)

*   unsigned第一个次设备号

*   unsigned设备号的数量,从指定的次设备号开始分配,到这个值的指定数量结束

*   const char *设备名称,如果申请成功cat /proc/devices中可以看到主设备号及该字符串指定的名称

*返回值:

*   成功:0;失败:错误码

*/

int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);




基本框架及测试应用程序范例

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/errno.h>

#include <linux/types.h>

#include <linux/cdev.h>

 

static int demo_major = 0;

static int demo_minor = 0;

static int demo_nrdevs = 1;

static const char demodevname[] = "demodev";

static struct cdev cdev;

 

static int demo_open(struct inode *inode, struct file *filep)

{

       printk(KERN_INFO "demo_open\n");

       return 0;

}

static int demo_release(struct inode *inode, struct file *filp)

{

       printk(KERN_INFO "demo_release\n");

       return 0;

}

static ssize_t demo_read(struct file *filep, char __user *buf, size_t count, loff_t *fpos)

{

       printk(KERN_INFO "demo_read\n");

       return 0;

}

static ssize_t demo_write(struct file *filep, const char __user *buf, size_t count, loff_t *fpos)

{

       printk(KERN_INFO "demo_write\n");

       return 0;

}

static struct file_operations fops = {

       .owner =    THIS_MODULE,

       .read =     demo_read,

       .write =    demo_write,

       .open =     demo_open,

       .release =  demo_release,

};

static void __exit demo_exit(void)

{

       dev_t dev;

       dev = MKDEV(demo_major, demo_minor);

       cdev_del(&cdev);

       unregister_chrdev_region(dev, demo_nrdevs);

}

 

static int __init demo_init(void)

{

       int err;

       dev_t dev;

       if (demo_major) {

              dev = MKDEV(demo_major, demo_minor);

              err = register_chrdev_region(dev, demo_nrdevs, demodevname);

       } else {

              err = alloc_chrdev_region(&dev, demo_minor, demo_nrdevs, demodevname);

              demo_major = MAJOR(dev);

       }

       if (err < 0) {

              printk(KERN_ERR "Can't get major %d\n", demo_major);

              return err;

       }

       cdev_init(&cdev, &fops);

       cdev.owner = THIS_MODULE;

      err = cdev_add (&cdev, dev, 1);

       if (err){

              printk(KERN_ERR "Error %d adding %s", err, demodevname);

              goto ERR_STEP_0;

       }

       return 0;

 

ERR_STEP_1:

       cdev_del(&cdev);

ERR_STEP_0:

       unregister_chrdev_region(dev, demo_nrdevs);

       return err;

}

MODULE_LICENSE("Dual BSD/GPL");

module_init(demo_init);

module_exit(demo_exit);