驱动模块传参

驱动模块传参


文章目录

  • 驱动模块传参
  • 什么是驱动传参
  • 驱动传参的意义
  • 可传递的参数
  • 怎么给驱动传参数
  • 具体实现
    • module_param.c
    • Makefile


什么是驱动传参

在系统编程中绝大多数情况需要main函数作为程序的入口函数来进行参数的传递。如:

int main(int argc,char **argv){
}

参数说明:
argc英文全称为argument count,代表形参表示传入参数的个数。
argv全称为argument value,代表参数传入的值。
在装载内核模块时,用户可以向模块传递参数,形式为“insmode(或 modprobe)模块名参数名=参数值”,如果不传递,参数将使用模块内定义的缺省值。如果模块被内置,就无法 insmod 了,但是 bootloader可以通过在 bootargs 里设置“模块名.参数名=值”的形式给该内置的模块传递参数。

驱动传参的意义

优势:
1,通过驱动传参,可以让驱动程序史加灵活。兼容性史强。
2.可以通过驱动传参,设置安个校验,防止驱动被盗用。
不足:
1.使驱动代码变得复杂化。
2.增加了驱动的资源占用。

可传递的参数

c语言中常用的数据类型内核大部分都支持驱动传参。这里将内核支持的驱动传递参数
的类型分成三类:
基本类型:char,bool,int,long,short’byte,ushort’uinto
数组:array
字符串:string

怎么给驱动传参数

驱动支持的参数类型有基本类型,数组,字符串。这三个类型分别对应函
module_param:传递基本类型函数
module_param_array:传递数组类型函数
module_param_string:传递字符串类型函数
这三个函数在Linux内核源码include/linux/moduleparam.h中有定义,如下:

#define module_param(name, type, perm)                \
    module_param_named(name, name, type, perm)
#define module_param_array(name, type, nump, perm)        \
    module_param_array_named(name, name, type, nump, perm)
#define module_param_string(name, string, len, perm)            \
    static const struct kparam_string __param_string_##name        \
        = { len, string };                    \
    __module_param_call(MODULE_PARAM_PREFIX, name,            \
                &param_ops_string,                \
                .str = &__param_string_##name, perm, -1, 0);\
    __MODULE_PARM_TYPE(name, "string")

传递普通的参数,比如 char int 类型,使用如下函数
驱动模块传参_第1张图片

传递数组使用以下函数:
驱动模块传参_第2张图片

部分常用参数权限解释如下:
驱动模块传参_第3张图片

其它的可以使用下面的方法来判断:
可以将数字最后三位转化为二进制:xxx xxx xxx,高位往低位依次看,第一位为 1 表示文件所有者可读,第二位为 1 表示文件所有者可写,第三位为 1 表示文件所有者可执行;接下来三位表示文件所有者同组成员的权限;再下来三位为不同组用户权限。
include/uapi/linux/stat.h

//user,owner,group

// 文件权限
#define S_IRWXU 00700 // 读写执行权限,用户
#define S_IRUSR 00400 // 读权限,用户
#define S_IWUSR 00200 // 写权限,用户
#define S_IXUSR 00100 // 执行权限,用户

#define S_IRWXG 00070 // 读写执行权限,组
#define S_IRGRP 00040 // 读权限,组
#define S_IWGRP 00020 // 写权限,组
#define S_IXGRP 00010 // 执行权限,组

#define S_IRWXO 00007 // 读写执行权限,其他
#define S_IROTH 00004 // 读权限,其他
#define S_IWOTH 00002 // 写权限,其他
#define S_IXOTH 00001 // 执行权限,其他
efine S_IXOTH 00001

include/linux/stat.h

// 定义文件权限掩码
#define S_IRWXUGO    (S_IRWXU|S_IRWXG|S_IRWXO)
// 定义文件所有者、组、其他用户的权限掩码
#define S_IALLUGO    (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
// 定义文件所有者、组、其他用户的读权限掩码
#define S_IRUGO        (S_IRUSR|S_IRGRP|S_IROTH)
// 定义文件所有者、组、其他用户的写权限掩码
#define S_IWUGO        (S_IWUSR|S_IWGRP|S_IWOTH)
// 定义文件所有者、组、其他用户的执行权限掩码
#define S_IXUGO        (S_IXUSR|S_IXGRP|S_IXOTH)

这部分代码定义了一些用于文件权限控制的宏,如S_IRWXUGO、S_IALLUGO、S_IRUGO、S_IWUGO、S_IXUGO等。这些宏可以用于设置文件的权限,以及判断文件的权限。其中,S_IRWXUGO表示所有用户都有读、写、执行权限;S_IALLUGO表示所有用户都有读、写、执行权限,并且设置了set-user-ID、set-group-ID和sticky位;S_IRUGO表示所有用户都有读权限;S_IWUGO表示所有用户都有写权限;S_IXUGO表示所有用户都有执行权限。
MODULE_PARM_DESC函数
函数功能:描述模块参数的信息。在include/linux/moduleparam.h定义
函数原型:MODULE_PARM_DESC(_parm,desc)
函数参数:
_parm:要描述的参数的参数名称。
desc:描述信息。

#include <linux/moduleparam.h>
#define MODULE_PARM_DESC(name, desc) __MODULE_PARM_DESC(name, desc)

具体实现

module_param.c

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

static int a = 0;

static int array[5] = {0};
static int array_size;

//static char str[10] = {0};
static char str1[10] = {0};

module_param(a, int, S_IRUGO);
MODULE_PARM_DESC(a,"int module param");

module_param_array(array, int, &array_size, S_IRUGO);//自动获取长度
MODULE_PARM_DESC(array,"array module param");

module_param_string(str, str1, sizeof(str1), S_IRUGO);
MODULE_PARM_DESC(str,"str module param");



static int module_param_init(void){

    int i = 0;
    printk("a is %d\n",a);

    for(i = 0;i < array_size;i++){
        printk("array[%d] is %d\n",i,array[i]);
    }
    printk("array_size is %d\n",array_size);

    printk("str1 is %s\n",str1);
    return 0;

}


static void module_param_exit(void){

    printk("module_param exit!!!\n");
    

}
module_init(module_param_init);
module_exit(module_param_exit);
MODULE_AUTHOR("Paranoid");
MODULE_VERSION("V1.0");
MODULE_LICENSE("GPL");

注意权限设置S_IRUGO,若设置为另外的S_IALLUGO会报错
驱动模块传参_第4张图片

Makefile

#make 编译项目
#make file 在存放.ko文件目录中创建对应项目的目录
#make install 将*.ko及其应用测试文件移动到根文件中

KERN_DIR = /home/alientek/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek

ROOTFS_DIR = /home/alientek/linux/nfs/rootfs/experiment

#项目名字
PROJECT_NAME = module_param

#各驱动名字,ko
DRIVER_NAME1 = module_param


all:
    make -C $(KERN_DIR) M=`pwd` modules
    
clear:

    
    rm -rf modules.order $(DRIVER_NAME1).mod.c *.o Module.symvers .*.cmd .tmp_versions 

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

file:
    mkdir $(ROOTFS_DIR)/$(PROJECT_NAME)
install:
    cp *.ko $(ROOTFS_DIR)/$(PROJECT_NAME)

# 参考内核源码drivers/char/ipmi/Makefile
# 要想把a.c, b.c编译成ab.ko, 可以这样指定:
 obj-m += $(DRIVER_NAME1).o

驱动模块传参_第5张图片

驱动模块传参_第6张图片

你可能感兴趣的:(Linux驱动V2.0,#,内核模块,linux,arm开发,驱动开发,arm,嵌入式)