一般用户态传递参数是通过main函数,第一个参数表示args个数,即argc,第二个参数表示具体的参数
该宏的定义见/linux/moduleparam.h中
/**
* module_param - typesafe helper for a module/cmdline parameter
* @value: the variable to alter, and exposed parameter name.
* @type: the type of the parameter
* @perm: visibility in sysfs.
*
* @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a
* ".") the kernel commandline parameter. Note that - is changed to _, so
* the user can use "foo-bar=1" even for variable "foo_bar".
*
* @perm is 0 if the the variable is not to appear in sysfs, or 0444
* for world-readable, 0644 for root-writable, etc. Note that if it
* is writable, you may need to use kparam_block_sysfs_write() around
* accesses (esp. charp, which can be kfreed when it changes).
*
* The @type is simply pasted to refer to a param_ops_##type and a
* param_check_##type: for convenience many standard types are provided but
* you can create your own by defining those variables.
*
* Standard types are:
* byte, short, ushort, int, uint, long, ulong
* charp: a character pointer
* bool: a bool, values 0/1, y/n, Y/N.
* invbool: the above, only sense-reversed (N = true).
*/
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)
具体使用为:
适用于2.4与2.6内核的模块输入参数模板
#include
#ifdef LINUX26
#include
#endif
int debug = 0;
char *mode = "800x600";
int tuner[4] = {1, 1, 1, 1};
#ifdef LINUX26
int tuner_c = 1;
#endif
#ifdef LINUX26
MODULE_PARM(debug, "i");
MODULE_PARM(mode, "s");
MODULE_PARM(tuner,"1-4i");
#else
module_param(debug, int, 0644);
module_param(mode, charp, 0644);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
module_param_array(tuner, int, &tuner_c, 0644);
#else
module_param_array(tuner, int, tuner_c, 0644);
#endif
#endif
模块编译生成后,加载模块时可以输入:`modprobe my_module mode=1024x768 debug=1 tuner=22,33`。
还有一类,是函数回调 module_param_cb,类似于module_param_call
/**
* module_param_cb - general callback for a module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
* @ops: the set & get operations for this parameter.
* @perm: visibility in sysfs.
*
* The ops can have NULL set or get functions.
*/
#define module_param_cb(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1, 0)
具体实例如下:
在codec驱动代码中添加对寄存器访问的控制方式。调试codec的时候,可以直接查看或修改寄存器,免去了编译内核或模块的工作,节省宝贵时间。
static int nau8810_debug_reg_set(const char *buffer, struct kernel_param *kp)
{
u16 reg, val;
if(!buffer)
return -EINVAL;
if(sscanf(buffer, "%x,%x", (uint *)®, (uint *)&val) != 2) {
printk(KERN_ERR "invalid val = %s\n", buffer);
return -EINVAL;
}
if(debug)
printk(KERN_INFO"%s:R0x%x=0x%x\n", __func__, reg, val);
snd_soc_write(nau8810_codec, reg, val);
return 0;
}
static int nau8810_debug_reg_get(char *buffer, struct kernel_param *kp)
{
u16 reg, val;
int len = 0;
len = sprintf(buffer, "nau8810 DUMP registers:");
for(reg = 0; reg < NAU8810_CACHEREGNUM; reg++) {
val = snd_soc_read(nau8810_codec, reg);
if(!(reg%8))
len += sprintf(buffer+len,"\n");
len += sprintf(buffer+len, "R%02x:%03x ", reg, val);
}
return len;
}
static unsigned int dummy = 0;
module_param_call(regs, nau8810_debug_reg_set, nau8810_debug_reg_get, &dummy, 0644);
系统启动后,会在目录/sys/module/snd_soc_nau8810/parameters创建regs节点,此时即可对此节点进行相应的操作:
1. 读操作:cat regs
2. 写操作:如写0x5寄存器的值为1 echo 0x5,0x1 > regs