一、簡介
在嵌入式linux應(yīng)用開發(fā)中,可以給main()函數(shù)傳遞參數(shù),這樣應(yīng)用程序就能知道最初的控制參數(shù)是什么,當(dāng)然也可以選擇不向應(yīng)用程序傳遞參數(shù)。在驅(qū)動開發(fā)中,會使用到insmod命令來加載一個驅(qū)動模塊,這時候我們也可以使用insmod命令向驅(qū)動模塊傳遞參數(shù)。
使用模塊的參數(shù)傳遞機(jī)制,對調(diào)試系統(tǒng)非常方便!
二、參數(shù)傳遞方式
參數(shù)傳遞分為兩種:
內(nèi)置模塊參數(shù)傳遞:即將模塊編譯構(gòu)建進(jìn)內(nèi)核鏡像。
外置模塊參數(shù)傳遞:使用insmod等命令裝在的內(nèi)核模塊。
對于內(nèi)置模塊參數(shù)傳遞,一般在bootloader中可向內(nèi)置的模塊傳遞參數(shù),例如可以在bootargs中設(shè)置模塊名.參數(shù)名=值的形式給該內(nèi)置的模塊傳遞參數(shù);對于外置模塊,在裝載內(nèi)核模塊時,我們可以向模塊傳遞參數(shù),形式為:
?
insmode(或?modprobe)模塊名?參數(shù)名=參數(shù)值
?
如果不傳遞參數(shù),參數(shù)將使用模塊內(nèi)定義的缺省值。
三、技術(shù)點(diǎn)
1、變量權(quán)限
向驅(qū)動模塊傳遞參數(shù),必須事先在驅(qū)動源碼中聲明某一個變量可作為模塊參數(shù)傳遞,并且指定變量的權(quán)限,常見的權(quán)限參數(shù)如下:
宏定義 | 權(quán)限解釋 |
---|---|
#defineS_IRUSR 00400 | 文件所有者可讀 |
#defineS_IWUSR 00200 | 文件所有者可寫 |
#defineS_IXUSR 00100 | 文件所有者可執(zhí)行 |
#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。
當(dāng)然,也可以這樣看:可以將數(shù)字最后三位轉(zhuǎn)化為二進(jìn)制:xxx xxx xxx,高位往低位依次看,第一位為 1 表示文件所有者可讀,第二位為 1 表示文件所有者可寫,第三位為 1 表示文件所有者可執(zhí)行;接下來三位表示文件所有者同組成員的權(quán)限;再下來三位為不同組用戶權(quán)限。
使用'|'(或操作),可以一次設(shè)置多個權(quán)限。
了解了一個變量有哪些常見的權(quán)限可供設(shè)置,接下來看看如何將一個變量聲明為可傳遞參數(shù)的變量。
2、傳遞普通的參數(shù)
傳遞普通的參數(shù)(例如 bool、char、int),使用下列宏定義:
?
module_param(name,type,perm);
?
name:要傳遞進(jìn)去參數(shù)的名稱。
type:要傳遞進(jìn)去參數(shù)的類型。
perm:要傳遞進(jìn)去參數(shù)的讀寫權(quán)限。
module_param()宏在/sys/module下創(chuàng)建子目錄。上述代碼,將在/sys/module/中可查看對應(yīng)的參數(shù):
3、傳遞數(shù)組
傳遞數(shù)組參數(shù)使用下列的宏定義:
?
module_param_array(name,type,nump,perm)
?
name:要傳遞進(jìn)去參數(shù)的名稱。
type:要傳遞進(jìn)去參數(shù)的類型。
nump:實(shí)際傳入進(jìn)去參數(shù)的個數(shù)。
perm:要傳遞進(jìn)去參數(shù)的讀寫權(quán)限。
4、參數(shù)改變時回調(diào)
我們已經(jīng)知道,可以向/sys/module/下的參數(shù)名稱寫入?yún)?shù),這意味將改變參數(shù)的值,如果使用module_param()和module_param_array(),則無法獲知參數(shù)的值是否改變,如果我們想要讓系統(tǒng)獲知參數(shù)的改變,并根據(jù)參數(shù)改變進(jìn)一步執(zhí)行處理,則需要使用module_param_cb()注冊參數(shù)值改變時的處理函數(shù)。在內(nèi)核中,module_param_cb()宏用于注冊回調(diào),每當(dāng)參數(shù)(形參)發(fā)生變化時,將調(diào)用此回調(diào)函數(shù):
?
module_param_cb(name,?ops,?arg,?perm)?
?
name:要傳遞進(jìn)去參數(shù)的名稱。
ops:該參數(shù)的set和get操作。
arg:傳遞給ops中回到函數(shù)的參數(shù)。
perm:要傳遞進(jìn)去參數(shù)的讀寫權(quán)限。
四、代碼實(shí)驗(yàn)
例如下列代碼:
?
/*********************************************************************************** ?*?@Copyright:?Iriczhao?Co.,?Ltd.?2021-2029.?All?rights?reserved. ?*?@File:?dt_param_trans_demo.c ?*?@Descripttion:linux?kernel?module?parameter?passing?experiment??????? ?*?@version:1.0? ?*?@Author:?iriczhao ?*?@Date:?2023-08-7?1506 ?*?@LastEditors:?iriczhao ?*?***********************************************************************************/ #include#include #include #include ? int?value,?arr_value[4]; char?*name; int?cb_value?=?0; //聲明模塊參數(shù) 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);??????//整型數(shù)組 ? /*----------------------Module_param_cb()--------------------------------*/ int?notify_param(const?char?*val,?const?struct?kernel_param?*kp) { ????int?res?=?param_set_int(val,?kp);?//?Use?helper?for?write?variable ???? ????if(res?==?0)?{ ????????printk(KERN_INFO?"Call?back?function?called... "); ????????printk(KERN_INFO?"New?value?of?cb_value?=?%d ",?cb_value); ????????return?0; ????} ???? ????return?-1; } ? const?struct?kernel_param_ops?my_param_ops?=? { ????.set?=?notify_param,? ????.get?=?param_get_int,? }; ? module_param_cb(cb_value,?&my_param_ops,?&cb_value,?S_IRUGO|S_IWUSR?); static?int?__init?dt_param_trans_demo_init(void) { ????int?i; ????//打印出模塊參數(shù) ????printk(KERN_INFO?"Value?=?%d?? ",?value); ????printk(KERN_INFO?"cb_value?=?%d?? ",?cb_value); ????printk(KERN_INFO?"Name?=?%s? ",?name); ????for?(i?=?0;?i?(sizeof?arr_value?/?sizeof?(int));?i++)?{ ????????printk(KERN_INFO?"Arr_value[%d]?=?%d ",?i,?arr_value[i]); ????} ????printk(KERN_INFO?"Kernel?Module?Inserted?Successfully... "); ????return?0; } static?void?__exit?dt_param_trans_demo_exit(void) { ????printk(KERN_INFO?"Kernel?Module?Removed?Successfully... "); } ? module_init(dt_param_trans_demo_init); module_exit(dt_param_trans_demo_exit); ? MODULE_LICENSE("GPL"); MODULE_AUTHOR("iriczhao"); MODULE_DESCRIPTION("linux?kernel?module?parameter?passing?experiment"); MODULE_VERSION("1.0");
?
將上述代碼以模塊方式構(gòu)建,然后將生成的dt_param_trans_demo.ko模塊載入內(nèi)核,在加載該模塊時,傳入value、name、arr_value的參數(shù)值,在程序中將會打印出輸出的參數(shù)值:
從上述輸出的結(jié)果中,cb_value的參數(shù)值為0(默認(rèn)參數(shù)值),然后我們通過向/sys/module/dt_param_trans_demo/parameters/cb_value文件寫入?yún)?shù)值,這時候?qū)|發(fā)該參數(shù)改變時綁定的回調(diào)函數(shù),并打印出修改過后的參數(shù)值:
在載入一個模塊后,我們可以在/sys/module/模塊名/parameters/目錄下查看該模塊包含導(dǎo)出了哪些動態(tài)參數(shù)(參數(shù)以文件名稱表示),以及對應(yīng)參數(shù)的權(quán)限(文件的權(quán)限對應(yīng)參數(shù)的權(quán)限),例如本例中,將在/sys/module/dt_param_trans_demo/parameters/目錄下查看:
五、總結(jié)
1、模塊在載入的時候可以傳遞參數(shù)給模塊,前提是在模塊中提前聲明需要傳遞的參數(shù)。
2、當(dāng)在系統(tǒng)啟動后,在/sys/module/模塊名/parameters/目錄中可以查看對應(yīng)模塊下導(dǎo)出了哪些參數(shù)。也可以通過該目錄下的文件向?qū)?yīng)的參數(shù)傳遞信新的參數(shù)值。
審核編輯:湯梓紅
評論
查看更多