Linux下每个设备都需要有一个专属设备号:主设备号 + 次设备号
【申请字符设备】
主设备号:一类驱动:如:USB驱动
次设备号:这类驱动下的某个设备 如:键盘鼠标
设备号是32位的dev_t类型的,高12位主设备号,低20位次设备号。
随便打开一个例程:
1.1怎么分配设备号?
1.静态申请 :
register_chrdev_region(dev_t ,unsigned ,const char *)
dev_t :设备号起始值,比如MKDEV(100,0)
unsigned :次设备号的数量
const char * :设备名称 ,随意取
2.动态申请:
alloc_chrdev_region(dev_t ,unsigned ,unsigned ,const char *)
dev_t : 保存自动申请的设备号
unsigned : 次设备号的起始,一般为0
unsigned : 次设备号的数量
const char * :设备名称 ,随意取
1.2设备号释放
unregister_chrdev_region(dev_t, unsigned))
dev_t :设备号
unsigned :设备号的数量
【实验1】申请字符设备号
通过驱动传参,将设备号传进驱动
static int major = 0;
static int minor = 0;
module_param(major ,int ,S_IRUGO);
module_param(minor ,int ,S_IRUGO);
dev_t dev_num;
static int moduleparam_init()
{
int ret;
if(major) /* 判断设备号有没有传进来成功 */
{
printk("major is %d\n",major);
printk("minor is %d\n",minor);
dev_num = MKDEV(major, minor);
/* 静态申请设备号 */
ret = register_chrdev_region(dev_num, DEVICE_NUMBER,DEVICE_SNAME);
if(ret<0)
{
printk("register_chrdev_region error\n");
}
/* 静态注册设备号成功,则打印 */
printk("register_chrdev_region ok\n");
}else{
/* 没有传递进来,就动态申请 */
ret = alloc_chrdev_region(&dev_num,0,1);
if(ret<0)
{
printk("alloc_chrdev_region error\n");
}
//动态注册设备号成功,则打印
printk("alloc_chrdev_region ok\n");
major_num = MAJOR(dev_num); //将主设备号取出来
minor_num = MINOR(dev_num);//将次设备号取出来
printk("major_num = %d\n",major_num);//打印传入进来的主设备号
printk("minor_num = %d\n",minor_num);//打印传入进来的次设备号
}
return 0;
}
static void hello_exit(void)
{
unregister_chrdev_region(MKDEV(major_num,minor_num),DEVICE_NUMBER);//注销设备号
printk("gooodbye! \n");
}
module_init(moduleparam_init);
module_init(moduleparam_exit);
【实验结果】
修改Makefile:
编译生成.ko文件
1.动态方法:
加载模块:insmod dev_t.ko
******************
会打印主设备号和次设备号
2.静态方法:
查看设备号:cat proc/devices
手动给设备号:insmod dev_t.ko major = 222 minor =0
再查看设备号。
PS:perm指定了在sysfs中相应文件的访问权限。访问权限与linux文件爱你访问权限相同的方式管理,如0644,或使用stat.h中的宏如S_IRUGO表示。