十四、linux 静态/动态申请字符设备号
一、靜態(tài)申請(qǐng)
??????????所在目錄:include/linux/fs.h
– int register_chrdev_region(dev_t from, unsigned count, const char *name)
????????? register_chrdev_region()是我們?nèi)藶榇_定好設(shè)備號(hào),再去申請(qǐng)?jiān)O(shè)備號(hào),屬于靜態(tài)申請(qǐng)。
二、動(dòng)態(tài)申請(qǐng)
????????? 所在目錄:include/linux/fs.h
??– int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
???????? alloc_chrdev_region()?系統(tǒng)動(dòng)態(tài)分配主次設(shè)備號(hào)。
注意:
????????? register_chrdev()。這個(gè)是2.6以前使用的,目前不用了。
三、相關(guān)定義
???????“include/linux/kdev_t.h”
? ? ? ? ? ? ? ? – MKDEV宏定義是用來(lái)合成主設(shè)備號(hào)和次設(shè)備號(hào)。
????????????????– 在kdev_t.h頭文件中有一系列設(shè)備號(hào)處理的宏命令,用于處理各種設(shè)備號(hào)相關(guān)的數(shù)據(jù)。
????????include/linux/cdev.h
????????????????– cdev類型是是字符設(shè)備描述的結(jié)構(gòu)
????????– 其中的設(shè)備號(hào)必須用“dev_t”類型來(lái)描述,高12位為主設(shè)備號(hào),低20位為次設(shè)備號(hào)。
? ? ? ??– 宏定義MAJOR提取dev_t數(shù)據(jù)中的主設(shè)備號(hào)
四、相關(guān)代碼
驅(qū)動(dòng)代碼:
#include <linux/init.h> /*包含初始化宏定義的頭文件,代碼中的module_init和module_exit在此文件中*/ #include <linux/module.h> /*包含初始化加載模塊的頭文件,代碼中的MODULE_LICENSE在此頭文件中*//*定義module_param module_param_array的頭文件*/ #include <linux/moduleparam.h> /*定義module_param module_param_array中perm的頭文件*/ #include <linux/stat.h>/*三個(gè)字符設(shè)備函數(shù)*/ #include <linux/fs.h> /*MKDEV轉(zhuǎn)換設(shè)備號(hào)數(shù)據(jù)類型的宏定義*/ #include <linux/kdev_t.h> /*定義字符設(shè)備的結(jié)構(gòu)體*/ #include <linux/cdev.h>#define DEVICE_NAME "ascdev" #define DEVICE_MINOR_NUM 2 #define DEV_MAJOR 0 #define DEV_MINOR 0MODULE_LICENSE("Dual BSD/GPL"); /*聲明是開源的,沒有內(nèi)核版本限制*/ MODULE_AUTHOR("iTOPEET_dz"); /*聲明作者*/int numdev_major = DEV_MAJOR; int numdev_minor = DEV_MINOR;/*輸入主設(shè)備號(hào)*/ module_param(numdev_major,int,S_IRUSR); /*輸入次設(shè)備號(hào)*/ module_param(numdev_minor,int,S_IRUSR);static int scdev_init(void) {int ret = 0;dev_t num_dev;printk(KERN_EMERG "numdev_major is %d!\n",numdev_major);printk(KERN_EMERG "numdev_minor is %d!\n",numdev_minor);if(numdev_major){num_dev = MKDEV(numdev_major,numdev_minor);ret = register_chrdev_region(num_dev,DEVICE_MINOR_NUM,DEVICE_NAME);}else{/*動(dòng)態(tài)注冊(cè)設(shè)備號(hào)*/ret = alloc_chrdev_region(&num_dev,numdev_minor,DEVICE_MINOR_NUM,DEVICE_NAME);/*獲得主設(shè)備號(hào)*/numdev_major = MAJOR(num_dev);printk(KERN_EMERG "adev_region req %d !\n",numdev_major);}if(ret<0){printk(KERN_EMERG "register_chrdev_region req %d is failed!\n",numdev_major); }printk(KERN_EMERG "scdev_init!\n");/*打印信息,KERN_EMERG表示緊急信息*/return 0; }static void scdev_exit(void) {printk(KERN_EMERG "scdev_exit!\n");unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM); }module_init(scdev_init); /*初始化函數(shù)*/ module_exit(scdev_exit); /*卸載函數(shù)*/makefile
#!/bin/bash #通知編譯器我們要編譯模塊的哪些源碼 #這里是編譯itop4412_hello.c這個(gè)文件編譯成中間文件mini_linux_module.o obj-m += request_ascdev_num.o #源碼目錄變量,這里用戶需要根據(jù)實(shí)際情況選擇路徑 #作者是將Linux的源碼拷貝到目錄/home/topeet/android4.0下并解壓的 KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0#當(dāng)前目錄變量 PWD ?= $(shell pwd)#make命名默認(rèn)尋找第一個(gè)目標(biāo) #make -C就是指調(diào)用執(zhí)行的路徑 #$(KDIR)Linux源碼目錄,作者這里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0 #$(PWD)當(dāng)前目錄變量 #modules要執(zhí)行的操作 all:make -C $(KDIR) M=$(PWD) modules#make clean執(zhí)行的操作是刪除后綴為o的文件 clean:rm -rf *.mod.c *.o *.order *.ko *.mod.o *.symvers五、運(yùn)行效果
總結(jié)
以上是生活随笔為你收集整理的十四、linux 静态/动态申请字符设备号的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十三、linux 内核驱动模块传参数
- 下一篇: 十五、linux 注册字符类设备和生成节