組み込みLINUXドライバーの学習3.キャラクターデバイス(デバイス番号アプリケーション)
1.デバイス番号アプリケーション関数: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
カウントからマイナーデバイス番号を割り当てます:マイナーデバイス番号の数、
名前:ラベルと同等の名前を指定します。これは、将来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.デバイス番号機能の解放
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:マイナーデバイス番号の数(申請した数のリリース)。
3.例:
// 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
....省略更多.......
*/