十四、linux 静态/动态申请字符设备号
一、靜態申請
??????????所在目錄:include/linux/fs.h
– int register_chrdev_region(dev_t from, unsigned count, const char *name)
????????? register_chrdev_region()是我們人為確定好設備號,再去申請設備號,屬于靜態申請。
二、動態申請
????????? 所在目錄:include/linux/fs.h
??– int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
???????? alloc_chrdev_region()?系統動態分配主次設備號。
注意:
????????? register_chrdev()。這個是2.6以前使用的,目前不用了。
三、相關定義
???????“include/linux/kdev_t.h”
? ? ? ? ? ? ? ? – MKDEV宏定義是用來合成主設備號和次設備號。
????????????????– 在kdev_t.h頭文件中有一系列設備號處理的宏命令,用于處理各種設備號相關的數據。
????????include/linux/cdev.h
????????????????– cdev類型是是字符設備描述的結構
????????– 其中的設備號必須用“dev_t”類型來描述,高12位為主設備號,低20位為次設備號。
? ? ? ??– 宏定義MAJOR提取dev_t數據中的主設備號
四、相關代碼
驅動代碼:
#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>/*三個字符設備函數*/ #include <linux/fs.h> /*MKDEV轉換設備號數據類型的宏定義*/ #include <linux/kdev_t.h> /*定義字符設備的結構體*/ #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"); /*聲明是開源的,沒有內核版本限制*/ MODULE_AUTHOR("iTOPEET_dz"); /*聲明作者*/int numdev_major = DEV_MAJOR; int numdev_minor = DEV_MINOR;/*輸入主設備號*/ module_param(numdev_major,int,S_IRUSR); /*輸入次設備號*/ 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{/*動態注冊設備號*/ret = alloc_chrdev_region(&num_dev,numdev_minor,DEVICE_MINOR_NUM,DEVICE_NAME);/*獲得主設備號*/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); /*初始化函數*/ module_exit(scdev_exit); /*卸載函數*/makefile
#!/bin/bash #通知編譯器我們要編譯模塊的哪些源碼 #這里是編譯itop4412_hello.c這個文件編譯成中間文件mini_linux_module.o obj-m += request_ascdev_num.o #源碼目錄變量,這里用戶需要根據實際情況選擇路徑 #作者是將Linux的源碼拷貝到目錄/home/topeet/android4.0下并解壓的 KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0#當前目錄變量 PWD ?= $(shell pwd)#make命名默認尋找第一個目標 #make -C就是指調用執行的路徑 #$(KDIR)Linux源碼目錄,作者這里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0 #$(PWD)當前目錄變量 #modules要執行的操作 all:make -C $(KDIR) M=$(PWD) modules#make clean執行的操作是刪除后綴為o的文件 clean:rm -rf *.mod.c *.o *.order *.ko *.mod.o *.symvers五、運行效果
總結
以上是生活随笔為你收集整理的十四、linux 静态/动态申请字符设备号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十三、linux 内核驱动模块传参数
- 下一篇: 十五、linux 注册字符类设备和生成节