驱动的参数传入:module_param,module_param_array,module_param_cb
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