1. 程式人生 > >【迅為iTop4412學習筆記】18.動態方式申請主次裝置號

【迅為iTop4412學習筆記】18.動態方式申請主次裝置號

宣告

以下都是我剛開始看驅動視訊的個人強行解讀,如果有誤請指出,共同進步。

本節目標

靜態方式申請主次裝置號


動態申請主次裝置號的函式

上節我們靜態申請,這一節我們用動態申請

// 動態申請主次裝置號(linux分配)
int alloc_chrdev_region(dev_t *dev,unsigned int -firstminor,unsigned int -count,char *name);

引數和靜態的差不多

引數1: dev_t* 型別的指標
引數2:第一個次裝置號的編號
引數3:申請的次裝置號的數量
引數4:裝置的名字

這一節幾乎與上節相同,所以直接上程式碼,看程式碼就很清楚了

#include <linux/init.h>
#include <linux/module.h>

// 字元裝置申請函式
#include <linux/fs.h>
// 裝置號資料型別 dev_t
#include <linux/cdev.h>
// 處理巨集定義 MKDEV
#include <linux/kdev_t.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("MrYang");

// 初始化主次裝置號
int device_major =
0; int device_minor = 0; static int mryang_init(void) { int ret; dev_t mryang_dev; // 輸出 printk(KERN_EMERG "HELLO MrYang\n"); // 申請主裝置號 ret = alloc_chrdev_region(&mryang_dev, device_minor, 2, "mryang_acdev"); if(ret < 0) printk(KERN_EMERG "failed!\n"); else printk(KERN_EMERG "success!\n"
); // 提取主、次裝置號 device_major = MAJOR(mryang_dev); device_minor = MINOR(mryang_dev); printk(KERN_EMERG "major: %d, minor: %d\n", device_major, device_minor); return 0; } static void mryang_exit(void) { dev_t mryang_dev; // 輸出 printk(KERN_EMERG "Bye MrYang\n"); // 登出 mryang_dev = MKDEV(device_major, device_minor); unregister_chrdev_region(mryang_dev, 2); printk(KERN_EMERG "over!\n"); } module_init(mryang_init); module_exit(mryang_exit);

編譯完成後,

輸入:

insmod probe_linux_module.ko

返回:
[ 40.115715] HELLO MrYang
[ 40.116806] success!
[ 40.118974] major: 248, minor: 0

結果正確,linux自動分配的主裝置號是248,次裝置號是0

輸入:

cat /proc/devices

返回:
248 mryang_acdev

我們檢視linux已註冊的裝置,反向我們的裝置已經“登記在冊”。

至於解除安裝是一樣的,就不說了。

我理解的與上節的區別是:

  1. 靜態方式需要自己指定主次裝置號,然後MKDEV巨集合成為一個dev_t型別的引數,再把這個值傳給linux去註冊。當然,你如果指定的0,那麼linux會自動給你分配一個主次裝置的號碼,但本質還是你把號碼傳給linux去註冊。
  2. 動態方式則是通過函式去申請,linux把申請好的主次裝置號返回給你。你通過MAJOR和MINOR去解析主裝置號和次裝置號是多少。

雖然兩者看上去好像差別不大,但是我們還是要注意本質區別,你傳給他申請叫靜態,linux傳給你是動態。(說的是這個方向,雖然靜態裡的號是由linux分配的,但他仍然是 靜態)

收尾

這兩節主要講的就是靜態指定編號or動態分配編號,去註冊裝置。