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 = &notify_param, // Use our setter ...
        .get = &param_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 = &notify_param, // Use our setter ...
        .get = &param_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

版权声明:本文为bigcatio原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/bigcatio/p/14059010.html