设备号

设备编号的类型: dev_t
设备号相关宏:
#include <linux/kdev_t.h>
int MAJOR(dev_t dev);    //得到主设备号
int MINOR(dev_t dev);    //得到次设备号

MKDEV(int major,int minor); //将主设备号和次设备号转换为dev_t类型   

相关函数:
#include <linux/fs.h>
int register_chrdev_region(dev_t first, unsigned int count, char *char); //first,要分配的设备编号范围的起始值,其中的次设备号经常被设置位0,count是所请求的连续设备编号的个数,name,设备名称。

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);  //dev,完成调用之后保存设备编号,firstminor,要请求的第一个次设备号,其它两个参数相同。区别是不需要提前指定主设备号。

void unregister_chrdev_region(dev_t first, unsigned int count);  //释放设备编号

//一段经常使用的分配设备编号的代码
scull_major=0;  //全局变量,用来保存选择的主设备号
scull_minor=0;  //保存次设备号

if(scull_major)  //若默认的不是0,则
{
    dev=MKDEV(scull_major,scull_minor);  //通过主设备号和次设备号得到设备编号
    result=register_chrdev_region(dev,scull_nr_devs, "scull");  //申请该设备编号
}
else    //若默认的主设备号是0,则
{
    result=alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");  //动态申请设备编号
    scull_major=MAJOR(dev);    //通过设备编号得到主设备号
}   

if(result<0) //申请设备编号失败
{
    printk(KERN_WARNING "scull: can't get major %d/n",scull_major);
    return result;
}

//附带自己的调试代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
static char *whom="world";
static int howmany=1;
module_param(howmany,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);

dev_t dev;
unsigned int scull_nr_devs=4;
unsigned int scull_major=0;  //全局变量,用来保存选择的主设备号
unsigned int scull_minor=0;  //保存次设备号
int result;

MODULE_LICENSE("Dual BSD/GPL");//告诉内核,该模块才用了自由许可证,否则转载时会遭到内核抱怨

static int hello_init(void)//装载时运行
{
    int i;
    for(i=0;i<howmany;i++)
        printk(KERN_ALERT "hello %s./n",whom);//printk()内核态的输出函数;KERN_ALERT,显示的优先级

    if(scull_major)  //若默认的不是0,则
    {
        dev=MKDEV(scull_major,scull_minor);  //通过主设备号和次设备号得到设备编号
        result=register_chrdev_region(dev,scull_nr_devs, "scull");  //申请该设备编号
    }
    else    //若默认的主设备号是0,则
    {
        result=alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");  //动态申请设备编号
        scull_major=MAJOR(dev);    //通过设备编号得到主设备号
        scull_minor=MINOR(dev);
    }  

    if(result<0) //申请设备编号失败
    {
        printk(KERN_WARNING "scull: can't get major %d/n",scull_major);
        return result;
    }
    return 0;
}

static void hello_exit(void)//卸载时运行
{
    printk(KERN_ALERT "Goodbye,cruel world. My first drivers is over!/n");
    unregister_chrdev_region(dev,scull_nr_devs);
}

module_init(hello_init);    //指定装载时调用的函数
module_exit(hello_exit);    //指定卸载时调用的函数

你可能感兴趣的:(设备号)