device driver也可以像用戶態程序一樣在運行開始時傳入參數,例如argc和argv。
- module_param(name, type, perm)
- module_param_array(name, type, nump, perm)
- module_param_cb(name, ops, arg, perm)
此外,module_param還會在/sys/module/下面創建對應的節點,可以查看有哪些數值是可供查詢或修改的。
其定義在include/linux/moduleparam.h中。
權限參數perm的定義如下:
-
- S_IWUSR
- S_IRUSR
- S_IXUSR
- S_IRGRP
- S_IWGRP
- S_IXGRP
In this S_I is a common header.
R = read ,W =write ,X= Execute.
USR =user ,GRP =Group
Using OR ‘|’ (or operation) we can set multiple permissions at a time.
參數type支持的類型如下:
- bool
- invbool: A boolean (true or false) value (the associated variable should be of type int). The
invbool
type inverts the value, so that true values become false and vice versa.
- charp:A char pointer value. Memory is allocated for user-provided strings, and the pointer is set accordingly.
- int
- long
- short
- uint
- ulong
- ushort
module_param
static char *sysfs_string= "my_sysfs_test_string"; static int sysfs_int= 111; static long sysfs_long= 222; static short sysfs_short= 333; static unsigned int sysfs_uint= 444; static unsigned long sysfs_ulong= 555; static unsigned short sysfs_ushort= 666; static bool sysfs_bool= 777; static bool sysfs_invbool= 888; module_param(sysfs_string, charp, 00644); module_param(sysfs_int, int, 00644); module_param(sysfs_long, long, 00644); module_param(sysfs_short, short, 00644); module_param(sysfs_uint, uint, 00644); module_param(sysfs_ulong,ulong, 00644); module_param(sysfs_ushort,ushort, 00644); module_param(sysfs_bool,bool, 00644); module_param(sysfs_invbool,invbool, 00644);
module_param_array
static int sysfs_int_array[]= {1,2,3,4,5,6,7,8}; module_param_array(sysfs_int_array, int, NULL, S_IRUSR|S_IWUSR);
參數nump表示array的大小,可選項。默認設置為NULL即可。
module_param_cb
如果在設定或讀取參數時,需要進行類似通知等操作,可以使用module_param_cb,在get或set時調用對應的回調函數。module_param_array和module_param調用的是默認的回調函數, module_param_cb支持自定義回調函數。
static int cb_valueETX = 999; 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...\n"); printk(KERN_INFO "New value of cb_valueETX = %d\n", cb_valueETX); return 0; } return -1; } const struct kernel_param_ops my_param_ops = { .set = ¬ify_param, // Use our setter ... .get = ¶m_get_int, // .. and standard getter }; module_param_cb(cb_valueETX, &my_param_ops, &cb_valueETX, S_IRUGO|S_IWUSR );
全部代碼如下:
#include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/delay.h> static char *sysfs_string= "my_sysfs_test_string"; static int sysfs_int= 111; static long sysfs_long= 222; static short sysfs_short= 333; static unsigned int sysfs_uint= 444; static unsigned long sysfs_ulong= 555; static unsigned short sysfs_ushort= 666; static bool sysfs_bool= 777; static bool sysfs_invbool= 888; module_param(sysfs_string, charp, 00644); module_param(sysfs_int, int, 00644); module_param(sysfs_long, long, 00644); module_param(sysfs_short, short, 00644); module_param(sysfs_uint, uint, 00644); module_param(sysfs_ulong,ulong, 00644); module_param(sysfs_ushort,ushort, 00644); module_param(sysfs_bool,bool, 00644); module_param(sysfs_invbool,invbool, 00644); static int sysfs_int_array[]= {1,2,3,4,5,6,7,8}; module_param_array(sysfs_int_array, int, NULL, S_IRUSR|S_IWUSR); /*----------------------Module_param_cb()--------------------------------*/ static int cb_valueETX = 999; 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...\n"); printk(KERN_INFO "New value of cb_valueETX = %d\n", cb_valueETX); return 0; } return -1; } const struct kernel_param_ops my_param_ops = { .set = ¬ify_param, // Use our setter ... .get = ¶m_get_int, // .. and standard getter }; module_param_cb(cb_valueETX, &my_param_ops, &cb_valueETX, S_IRUGO|S_IWUSR ); /*-------------------------------------------------------------------------*/ static int mytest_init(void) { printk("sysfs_buff=%s\n", sysfs_string); return 0; } static void mytest_exit(void) { } module_init(mytest_init); module_exit(mytest_exit); MODULE_LICENSE("GPL");
參考資料:
https://embetronicx.com/tutorials/linux/device-drivers/linux-device-driver-tutorial-part-3-passing-arguments-to-device-driver