嵌入式LINUX驱动学习之3.字符设备(设备号申请)
一、设备号申请函数:alloc_chrdrv_region()
1.1 函数头文件
//头文件位置:include/linux/fs.h
//函数实现:fs/char_dev.c
#include <linux/fs.h>
int alloc_chrdev_region(dev_t *dev, unsigned baseminor,\
unsigned count,const char *name);
1.2 函数功能:
获取向内核申请一个设备号,保存到dev中;
1.3 函数参数:
dev : 用于保存内核分配的设备号(需要使用全局静态变量,即:当前原文件中可用);
baseminor : 次设备号,一般填0,即:内核从0开始分配次设备号
count : 次设备号的个数;
name : 指定一个名称,相当于标签,将来可以通过执行 cat /proc/devices查看
1.4 关键宏函数使用
//获取 主、次设备号使用的宏
//定义位置:include/linux/kdev_t.h
#include <linux/kdev_t.h> //头文件在<linux/fs.h>中已包含
#define MINORBITS 20 //20位
#define MINORMASK ((1U << MINORBITS) - 1) //0~19,20个1,
//Linux系统中,通过一个32bit位的无符号整数表示驱动程序的设备号,
//其中高12位表示主设备号,低20位表示次设备号;
//unsigned int 一共4个字节32位,
//MAJOR(dev)根据设备号获取主设备号,即:将设备号右移20位
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
//MINOR(dev)根据设备号获取次设备号,即:用设备号和20bit位的1逻辑与运算。
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
//MKDEV(ma,mi) //根据主、次设备号,获取 设备号
//ma为主设备号,mi为次设备号。
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
二、释放设备号函数
2.1 函数头文件
//头文件位置:include/linux/fs.h
//函数实现:fs/char_dev.c
#include <linux/fs.h>
void unregister_chrdev_region(dev_t from, unsigned count)
1.2 函数功能:
释放一个设备号
1.3 函数参数:
from : 需要释放的设备号;
count : 次设备号个数(申请多少个,就释放多少个);
三、举例:
// vim dev_num.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
static dev_t dev_num;
static int dev_init(void){
alloc_chrdev_region(&dev_num,0,1,"dev_test");
printk("%s , 申请的设备号:%d,主设备号:%d,次设备号:%d\n",\
__func__,dev_num,MAJOR(dev_num),MINOR(dev_num));
/*
__func__ : 打印当前函数名
*/
return 0;
}
static void dev_exit(void){
unregister_chrdev_region(dev_num,1);
printk("%s , 释放设备号:%d\n",__func__,dev_num);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
//:wq
//make
// 将生成的驱动模块文件dev_num.ko 拷贝到下位机
//以下所有操作均在下位机执行
//echo 10 >/proc/sys/kernel/printk
//insmod dev_num.ko //加载模块,打印如下信息:
// dev_init , 申请的设备号:255852544,主设备号:244,次设备号:0
//在下位机执行:cat /proc/devices 可以看到主设备号和对应的name
/*
....省略更多.......
189 usb_device
204 ttySAC
216 rfcomm
244 dev_test //这个是内核为dev_num模块分配的主设备号和我们定义的name.
245 roccat
246 BaseRemoteCtl
247 ttyGS
....省略更多.......
*/