设备编号的类型: 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); //指定卸载时调用的函数