首页 > 其他分享 >3 - 传参

3 - 传参

时间:2024-02-19 21:01:21浏览次数:17  
标签:传参 int cb param module valueETX hello

Passing Arguments to Linux Device Driver

原文链接

我的博客

模块参数宏

  • module_param()
  • module_param_array()
  • module_param_cd()

在此之前,我们需要确定变量的权限,下面是几种权限:

  • S_IWUSR
  • S_IRUSR
  • S_IXUSR
  • S_IRGRP
  • S_IWGRP
  • S_IXGRP

module_param()

这个宏用来初始化参数,这个函数需要三个参数,变量名,变量类型,权限。宏需要放在函数外部。使用时需要 linux/moduleparam.h 头文件:

module_param(name, type, perm);

module_param 会在 /sys/module/下面创建子目录,比如:

module_param(valueETX, int, SIWUSR | SIRUSR);

将会创建:

/sys/module/hello_world_module/parameters/valueETX

模块参数支持很多类型:

  • bool,布尔型,True/False
  • invbool,反布尔型,False 表示 True,True 表示 False
  • charp,字符指针型,会为用户提供的字串分配空间
  • int
  • long
  • short
  • uint
  • ulong
  • ushort

module_param_array()

将数组做为参数给到设备驱动,声明这个参数:

module_param_array(name, type, num, perm);

其中:

  • name,是数组名
  • type,是数组元素类型
  • num,整型数,或不指定
  • perm,权限值

module_param_cb()

这个宏用来注册回调。一旦参数改变,会调用这个回调函数。比如,我们首先创建下面的参数:

module_param(valueETX, int, S_IWUSR | S_IRUSR);

可以通过下面的命令修改这个参数:

sudo su
echo 1 > /sys/module/hello_world_module/parameters/valueETX

这个行为将会更新 valueETX 的值,通过使用 module_param_cb 宏,可以创建一个通知,首先,我们需要首先注册句柄函数到文件操作结构体:

struct kernel_param_ops {
    int (*set) (const char *var, const struct kernel_param *kp);
    int (*get) (char *buffer, const struct kernel_param *kp);
    void (*free) (void *arg);
}

在下面的例子中,介绍了如何使用这个宏来注册参数修改回调函数。

编程示例

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>

int valueETX, arr_valueETX[4];
char *nameETX;
int cb_valueETX=0;

module_param(valueETX, int, S_IRUSR | S_IWUSR);
module_param(nameETX, charp, S_IRUSR | S_IWUSR);
module_param_array(arr_valueETX, int, NULL, S_IRUSR | S_IWUSR);

int notify_param(const char *val, const struct kernel_param *kp)
{
        int res = param_set_int(val, kp);
        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,
        .get = &param_get_int,
};

module_param_cb(cb_valueETX, &my_param_ops, &cb_valueETX, S_IRUGO | S_IWUSR);

static int __init hello_init(void)
{
        int i;
        printk(KERN_INFO "valueETX = %d\n", valueETX);
        printk(KERN_INFO "cb_valueETX = %d\n", cb_valueETX);
        printk(KERN_INFO "nameETX = %s\n", nameETX);

        printk(KERN_CONT "arr_valueETX: ");
        for (i = 0; i < sizeof(arr_valueETX)/sizeof(int); i++)
                printk(KERN_CONT "%d ", arr_valueETX[i]);

        printk(KERN_CONT "\n");
        printk(KERN_INFO "%s success\n", __FUNCTION__);

        return 0;
}

static void __exit hello_exit(void)
{
        printk(KERN_INFO "%s success\n", __FUNCTION__);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me");
MODULE_DESCRIPTION("A parameter driver");
MODULE_VERSION("1.0");

编译

ubuntu 环境中使用编写下面的 Makefile 文件:

obj-m += hello_world.o

KER_DIR =/lib/modules/$(shell uname -r)/build


all:
        make -C $(KER_DIR) M=$(shell pwd) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean

执行如下命令编译生成模块:

make

载入模块

sudo insmod hello_world.ko valueETX=14 nameETX="testString" arr_valueETX=100,102,104,106

通过 dmesg 检验参数

$ dmesg | tail -n 5
[5015630.457650] valueETX = 14
[5015630.457652] cb_valueETX = 0
[5015630.457653] nameETX = testString
[5015630.457653] arr_valueETX: 100 102 104 106
[5015630.457656] hello_init success

使用下面命令中的一条修改模块变量值:

sudo sh -c "echo 13 > /sys/module/hello_world_module/parameters/cb_valueETX"
sudo su
echo 13 > /sys/module/hello_world_module/parameters/cb_valueETX
$ dmesg | tail -n 2
[5015706.580696] Call back function called...
[5015706.580697] New value of cb_valueETX = 13

卸载驱动

执行如下命令来卸载驱动:

sudo rmmod hello_world
$ dmesg | tail -n 1
[5015828.286013] hello_exit success

标签:传参,int,cb,param,module,valueETX,hello
From: https://www.cnblogs.com/arvin-blog/p/18021945

相关文章

  • python函数传参
    python函数传参参考:python函数参数传递(params,*params,**params)位置参数常见的函数参数:defadd_both(x,y):returnx+y默认参数defenroll(name,gender,age=6,city='Beijing'):print('name:',name)print('gender:',gender)print(&......
  • 方法的重载和命令行传参
    方法的重载重载就是在一个类中,有相同的函数名称,但形参不同的函数。方法的重载的规则:方法名称必须相同。参数列表必须不同。(个数不同、或类型不同,参数排列顺序不同等)方法的返回类型可以相同也可以不相同。仅仅返回类型不同不足以成为方法的重载。实现理论:方法名称相......
  • Vue 3开发者必看:路由传参的终极分析与实践建议!
    前言在Vue应用中,路由传参是一项常见的需求,它允许我们在不同的页面之间传递数据,实现更加灵活和动态的页面交互。下面我将介绍如何在Vue应用中实现路由传参,包括基本的路由参数传递和更复杂的场景下的传参技巧。router与route区别router是通过VueRouter构造函数new出来得到了的一......
  • Azure Data Factory(十二)传参调用 Azure Function
    一,引言 在实际的项目中,AzureDataFactroy中的DataFlow并不能彻底帮我们完成一系列复制逻辑计算,比如我们需要针对数据集的每一行数据进行判断计算,DataFlow就显的有些吃力。别怕,AzureDataFactory提供了调用AzureFunction的组件,有了代码的加持,那么解决更复杂的都能迎......
  • 页面跳转传参,携带的数值型数据会转成是字符串
    onLoad(options){let{limit,index}=optionsindex=Number(index);limit=Number(limit)console.log(options); //获取视频页面数据wx.cloud.callFunction({name:'getMedia',data:{sort:'video',......
  • 微信小程序页面跳转传参
    A页面跳转分包B页面 //A页面携带 wx.navigateTo({        url: '/findPackage/video-detail-page/video-detail-page?skip='+skip+'&limit='+limit+'&index='+index,      })路径与参数以?相连,参数与参数之间以&相连,键值对形式传参//B页面获取onLoa......
  • axios实现,在一个极短时间内,请求同一个接口,若传参完全一样,则使用浏览器中的缓存中的上
    axios实现,在一个极短时间内,请求同一个接口,若传参完全一样,则使用浏览器中的缓存中的上次的值。同时,上次的值应该在指定时间内可以自动清除。请写一个axios适配器。实现上述功能。在axios中,我们可以利用浏览器的缓存机制(HTTP缓存)来实现这个需求。不过,浏览器的HTTP缓存主要依赖于服......
  • python中get请求传参方式的写法
    get请求分为两大类:无参数和有参数1.无参数2.有参数2.1参数较少2.2参数较多-字典形式2.3参数较多-列表+元祖形式......
  • 通过LINUX驱动控制FPGA端PWM外设(LED) 通过应用程序命令传参随意修改寄存器的值(PWM波频
    用法:先下发下面的命令让kernel信息打印到串口:echo7417>/proc/sys/kernel/printk然后增加程序可执行性:chmod777pwmdriver_app  先执行./pwmdriver_app/dev/pwm400000200然后执行./pwm_driver_app/dev/pwm400000200,可以发现LED[1]......
  • c语言main传参
    c语言中怎么理解main函数为什么传参main函数传参是为了接收命令行参数。在C语言中,main函数可以接收两个参数,分别是argc和argv。argc表示命令行参数的个数,而argv是一个指向字符串数组的指针,其中存储了命令行参数的值。通过传参给main函数,可以在程序运行时从命令行中接收参数,从而实......