1、模块传参意义
一个简单的C语言程序,在执行的时候通过命令行输入运行参数传递参数(main函数的参数),而模块化驱动也可以像普通程序一样,在加载时,通过命令行获取参数,只不过方法不一样而已,这个就是模块传递参数的意义。
模块参数存在的意义就是向用户提供一种随时向内核模块传递、修改参数的方法。比如串口驱动的波特率、数据位数、校验位、停止位这些参数,我们可以在驱动中定义相关变量,然后通过模块传参的方法去读写他们。
2、如何传参
在Linux内核中,提供了专门的宏用来在驱动中获取进行模块加载时传输的变量值:module_param和module_param_array、module_param_string,这三个内核宏定义的功能就是从命令行中获取参数。
(1)module_param(name, type, perm)
功能描述:用来从用户层获取参数值
@name:既表示变量名称(驱动中存放值的变量),又表示参数名称(传参数时指定的参数名称)
@type:传递的参数类型,这里只支持常见的byte(没有char), short, ushort, int, uint, long, ulong,charp(指针)
@perm:参数在sysfs中作为文件的读写权限
这里注意,模块参数加载之后都会在/sys/module/模块名称/下对应一个文件,而perm指的就是我们对这个参数文件的访问权限,例如0644
(2)module_param_array(name, type, nump, perm)
功能描述:从用户层获取数组
@name:既是数组名称,又是变量名称
@type:数组成员类型,和module_param支持的type一致
@perm:权限,和module_param的perm一样
(3)module_param_string(name, string, len, perm)
功能描述:从用户层获取字符串
@name:参数名称(用户看见的)
@string:变量名称(模块变量)
@len:模块中存放变量的最大空间
@prem:权限
(4)MODULE_PARM_DESC(_parm, desc)
功能描述:当用户使用modinfo查看模块详细信息的时候,用来对参数功能进行描述,方便用户使用参数
@_parm:参数名称
@desc:描述字符串
3、应用实例
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
//这些参数必须要先定义,否则是没有空间存放这些参数的
static char *who = "wor ld";
static int aa = 0x11;
MODULE_PARM_DESC(aa,"this is short var");
static short bb = 0x22;
static int cc_len = 0;
static char cc[6] = {1,2,3,4,5,6};
static char str[12] = "wellcome !\n";
module_param(who, charp, 0644); //声明字符串,但是这里的字符串不能有空格
module_param(aa, int, 0644); //声明int变量
module_param(bb, short, 0644); //声明short变量
//module_param_array(cc, char, 0644); //声明字节,这种写法是错误的,编译报错,因为没有char类型
module_param_array(cc, byte, &cc_len, 0644);//声明数组,不能出现char类型
module_param_string(test, str, 6, 0644);
static int __init demo_init(void)
{
char i = 0;
printk(KERN_DEBUG"demo_init !\n");
printk("who = %s\n",who);
printk("aa = %d\n", aa);
printk("bb = %d\n",bb);
for(i=0; i<6; i++)
{
printk("cc[%d] = %d\n", i, cc[i]);
}
printk("str = %s\n", str);
return 0;
}
static void __exit demo_exit(void)
{
printk(KERN_DEBUG"demo_exit!\n");
}
module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
4、查看和修改参数
(1)加载时传递
(2)通过sysfs读写
在/sys/modules/模块名称/parameters/下有以参数名称为名的文件,可以直接进行读写