linux驅動模塊參數傳遞方式

2023-08-09 09:15:40 來源:嵌入式小生

一、簡介

嵌入式linux應用開發中,可以給main()函數傳遞參數,這樣應用程序就能知道最初的控制參數是什么,當然也可以選擇不向應用程序傳遞參數。在驅動開發中,會使用到insmod命令來加載一個驅動模塊,這時候我們也可以使用insmod命令向驅動模塊傳遞參數。

使用模塊的參數傳遞機制,對調試系統非常方便!


【資料圖】

二、參數傳遞方式

參數傳遞分為兩種:

內置模塊參數傳遞:即將模塊編譯構建進內核鏡像。

外置模塊參數傳遞:使用insmod等命令裝在的內核模塊。

對于內置模塊參數傳遞,一般在bootloader中可向內置的模塊傳遞參數,例如可以在bootargs中設置模塊名.參數名=值的形式給該內置的模塊傳遞參數;對于外置模塊,在裝載內核模塊時,我們可以向模塊傳遞參數,形式為:

insmode(或modprobe)模塊名參數名=參數值

如果不傳遞參數,參數將使用模塊內定義的缺省值。

三、技術點

1、變量權限

向驅動模塊傳遞參數,必須事先在驅動源碼中聲明某一個變量可作為模塊參數傳遞,并且指定變量的權限,常見的權限參數如下:

宏定義權限解釋
#defineS_IRUSR 00400文件所有者可讀
#defineS_IWUSR 00200文件所有者可寫
#defineS_IXUSR 00100文件所有者可執行
#defineS_IRGRP 00040與文件所有者同組的用戶可讀
#defineS_IWGRP 00020
#defineS_IXGRP 00010
#defineS_IROTH 00004與文件所有者不同組的用戶可讀
#defineS_IWOTH 00002
#defineS_IXOTH 00001

上述宏定義中,S_I是公共的寫法,R = read,W = write,X = execute , USR = user,GPR = group。

當然,也可以這樣看:可以將數字最后三位轉化為二進制:xxx xxx xxx,高位往低位依次看,第一位為 1 表示文件所有者可讀,第二位為 1 表示文件所有者可寫,第三位為 1 表示文件所有者可執行;接下來三位表示文件所有者同組成員的權限;再下來三位為不同組用戶權限。

使用"|"(或操作),可以一次設置多個權限。

了解了一個變量有哪些常見的權限可供設置,接下來看看如何將一個變量聲明為可傳遞參數的變量。

2、傳遞普通的參數

傳遞普通的參數(例如 bool、char、int),使用下列宏定義:

module_param(name,type,perm);

name:要傳遞進去參數的名稱。

type:要傳遞進去參數的類型。

perm:要傳遞進去參數的讀寫權限。

module_param()宏在/sys/module下創建子目錄。上述代碼,將在/sys/module/中可查看對應的參數:

3、傳遞數組

傳遞數組參數使用下列的宏定義:

module_param_array(name,type,nump,perm)

name:要傳遞進去參數的名稱。

type:要傳遞進去參數的類型。

nump:實際傳入進去參數的個數。

perm:要傳遞進去參數的讀寫權限。

4、參數改變時回調

我們已經知道,可以向/sys/module/下的參數名稱寫入參數,這意味將改變參數的值,如果使用module_param()和module_param_array(),則無法獲知參數的值是否改變,如果我們想要讓系統獲知參數的改變,并根據參數改變進一步執行處理,則需要使用module_param_cb()注冊參數值改變時的處理函數。在內核中,module_param_cb()宏用于注冊回調,每當參數(形參)發生變化時,將調用此回調函數:

module_param_cb(name,ops,arg,perm)

name:要傳遞進去參數的名稱。

ops:該參數的set和get操作。

arg:傳遞給ops中回到函數的參數。

perm:要傳遞進去參數的讀寫權限。

四、代碼實驗

例如下列代碼:

/************************************************************************************@Copyright:IriczhaoCo.,Ltd.2021-2029.Allrightsreserved.*@File:dt_param_trans_demo.c*@Descripttion:linuxkernelmoduleparameterpassingexperiment*@version:1.0*@Author:iriczhao*@Date:2023-08-71506*@LastEditors:iriczhao************************************************************************************/#include#include#include#includeintvalue,arr_value[4];char*name;intcb_value=0;//聲明模塊參數module_param(value,int,S_IRUSR|S_IWUSR);//integer類型module_param(name,charp,S_IRUSR|S_IWUSR);//String類型module_param_array(arr_value,int,NULL,S_IRUSR|S_IWUSR);//整型數組/*----------------------Module_param_cb()--------------------------------*/intnotify_param(constchar*val,conststructkernel_param*kp){intres=param_set_int(val,kp);//Usehelperforwritevariableif(res==0){printk(KERN_INFO"Callbackfunctioncalled...");printk(KERN_INFO"Newvalueofcb_value=%d",cb_value);return0;}return-1;}conststructkernel_param_opsmy_param_ops={.set=notify_param,.get=param_get_int,};module_param_cb(cb_value,&my_param_ops,&cb_value,S_IRUGO|S_IWUSR);staticint__initdt_param_trans_demo_init(void){inti;//打印出模塊參數printk(KERN_INFO"Value=%d",value);printk(KERN_INFO"cb_value=%d",cb_value);printk(KERN_INFO"Name=%s",name);for(i=0;i<(sizeofarr_value/sizeof(int));i++){printk(KERN_INFO"Arr_value[%d]=%d",i,arr_value[i]);}printk(KERN_INFO"KernelModuleInsertedSuccessfully...");return0;}staticvoid__exitdt_param_trans_demo_exit(void){printk(KERN_INFO"KernelModuleRemovedSuccessfully...");}module_init(dt_param_trans_demo_init);module_exit(dt_param_trans_demo_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("iriczhao");MODULE_DESCRIPTION("linuxkernelmoduleparameterpassingexperiment");MODULE_VERSION("1.0");

將上述代碼以模塊方式構建,然后將生成的dt_param_trans_demo.ko模塊載入內核,在加載該模塊時,傳入value、name、arr_value的參數值,在程序中將會打印出輸出的參數值:

從上述輸出的結果中,cb_value的參數值為0(默認參數值),然后我們通過向/sys/module/dt_param_trans_demo/parameters/cb_value文件寫入參數值,這時候將會觸發該參數改變時綁定的回調函數,并打印出修改過后的參數值:

在載入一個模塊后,我們可以在/sys/module/模塊名/parameters/目錄下查看該模塊包含導出了哪些動態參數(參數以文件名稱表示),以及對應參數的權限(文件的權限對應參數的權限),例如本例中,將在/sys/module/dt_param_trans_demo/parameters/目錄下查看:

五、總結

1、模塊在載入的時候可以傳遞參數給模塊,前提是在模塊中提前聲明需要傳遞的參數。

2、當在系統啟動后,在/sys/module/模塊名/parameters/目錄中可以查看對應模塊下導出了哪些參數。也可以通過該目錄下的文件向對應的參數傳遞信新的參數值。

審核編輯:湯梓紅

標簽:

上一篇:STM32單片機的延時原理和延時函數方法
下一篇:最后一頁