2013年(9)
分类: LINUX
2013-01-29 22:21:11
原文地址:linux内核驱动中参数传入 作者:HYYLINUX
led.h
#define LED_ON(a) ((a) > 0?1:0)
#define LED_OFF(a) ((a) > 0?0:1)
led.c
static int hw_vsion = 0;
……
gpio_direction_output(GpioId,LED_ON(hw_vsion));
……
module_param(hw_vsion, int, S_IRUGO);
//EXPORT_SYMBOL(hw_vsion); //如果不需要将此变量导出,让其它驱动也可以用,则可以将其屏蔽
加载时:insmod led.ko hw_vsion=0(or 1)
此程序作用为根据传入参数不同,对宏定义LED_ON LED_OFF 分别设置为不同的值。
相关知识:
module_param():
一、在用户态下编程可以通过main()来传递命令行参数,而编写一个内核模块则可通过module_param()来传递命令行参数.
二、 module_param使用了3个参数:变量名,它的类型,以及一个权限掩码用来做一个辅助的sysfs入口。
这个宏定义应当放在任何函数之外,典型地是出现在源文件的前面。
eg: static char *whom="world"
static int tige=1;
module_param(tiger,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);
三、模块参数支持许多类型:
byte
bool
invbool
一个布尔型( true 或者 false)值(相关的变量应当是 int 类型). invbool 类型颠倒了值, 所以真值变成 false, 反之亦然.
charp :一个字符指针值. 内存为用户提供的字串分配, 指针因此设置.
int
long
short
uint
ulong
ushort
基本的变长整型值. 以 u 开头的是无符号值.
四、数组参数, 用逗号间隔的列表提供的值, 模块加载者也支持。
声明一个数组参数, 使用:
module_param_array(name,type,num,perm);
这里 name 是你的数组的名子(也是参数名),
type 是数组元素的类型,
num 是一个整型变量,
perm 是通常的权限值.
如果数组参数在加载时设置, num 被设置成提供的数的个数. 模块加载者拒绝比数组能放下的多的值.
五、perm参数的作用是什么?
最后的 module_param
字段是一个权限值,表示此参数在sysfs文件系统中所对应的文件节点的属性。你应当使用
权限在include/linux/stat.h中有定义
比如:
#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
使
用 S_IRUGO 参数可以被所有人读取, 但是不能改变; S_IRUGO|S_IWUSR 允许 root 来改变参数. 注意, 如果一个参数被
sysfs 修改, 你的模块看到的参数值也改变了, 但是你的模块没有任何其他的通知. 你应当不要使模块参数可写,
除非你准备好检测这个改变并且因而作出反应.
EXPORT_SYMBOL();
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的。
2.6就必须用EXPORT_SYMBOL() 来导出来(因为2.6默认不到处所有的符号)。
三、使用范例
一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。
在模块mod1中,EXPORT_SYMBOL(func1);
在模块mod2中,extern int func1();
就可以在mod2中调用func1了。
在编译模块时如果#include “xxx.h” 使用到了本地的头文件,在makefile中
PRINT_INC = 头文件所在目录 //标示头文件所在目录
EXTRA_CFLAGS += -I $(PRINT_INC) // 表示在编译模块时需要添加目录
在编译mod2时需要用到mod1中产生的Module.symvers文件
使用:
KBUILD_EXTRA_SYMBOLS=/..../Module.symvers
KBUILD_EXTRA_SYMBOLS 包涵在编译mod1时,产生的符号表文件Module.symvers,这个文件列出mod1中函数的地址没在编译mod2时需要这个列表