Kernel中Module调用编译问题

来源:互联网 发布:数据产品经理面试题目 编辑:程序博客网 时间:2024/06/15 16:34

   最近在kernel driver中写一个功能,遇到module之间调用的问题,以此记录一下。

在kernel中两个不同的模块之间是不能通过简单的#include “XX.h”来相互调用函数的。如果这样在调用的地方不会出现语法错误,但是在最后生成模块文件XXX.ko时就会出现error:“xxxx” 【xxx.ko】undefined! 在生成 .ko文件(kernel object)这个时候就报资源没有定义的错误了。

出现这样的情况是因为kernel的模块都是相互独立的,如果要共享就必须做一些处理了。


以/driver中的gpio和ir这两个module为例,如下:

ir.c中调用gpio中对gpio口操作的函数:

void MDrv_GPIO_Set_High(U8 u8IndexGPIO);


一.被调用模块gpio


1.gpio.c中被调用函数必须添加EXPORT_SYMBOL声明,如下:

void MDrv_GPIO_Set_High(U8 u8IndexGPIO){    MHal_GPIO_Set_High(u8IndexGPIO);}EXPORT_SYMBOL(MDrv_GPIO_Set_High);

EXPORT_SYMBOL声明一下函数是为了奖此函数导出,可供外部使用!


2.gpio模块中的Kconfig以及Makefile设置

Kconfig中必须定义Kernel中相对应的模块名:

config MDRV_GPIO

Makefile中编译目标:

obj-$(CONFIG_MDRV_GPIO)+= gpio.o

3.被调用模块上层的Makefile配置

gpio.c的上一目录driver中的Makefile中:

obj-$(CONFIG_MDRV_GPIO)                            += gpio/

其中gpio也就是gpio.c所在的目录。


这样MDrv_GPIO_Set_High才能被正确的导出到kernel的根目录下的Module.symvers文件,这个文件里面就是kernel里所有的EXPORT_SYMBOL和EXPORT_SYMBOL_GPL导出来的符号以及函数,EXPORT_SYMBOL_GPL和EXPORT_SYMBOL的区别就是:如果module的协议不是GPL的, 那么EXPORT_SYMBOL_GPL导出的那些符号以及函数,就用不了!

这个Module.symvers每次编译kernel的时候重新生成!

如果碰到上面的编译错误,第一步就是到这个Module.symvers中查看是否有你要调用的函数或者变量!


二.调用模块ir

在ir.c中需要调用MDrv_GPIO_Set_High(U8 u8IndexGPIO):

extern void MDrv_GPIO_Set_High(U8 u8IndexGPIO);




这样ir.c中的函数就可以调用MDrv_GPIO_Set_High(U8 u8IndexGPIO)这个函数啦!


撰写不易,转载请注明出处http://blog.csdn.net/jscese/article/details/16991679




原创粉丝点击