2016-12-03 92 views
1

我想包括我自己的头文件及其相应的源代码到我的内核模块。但是出于某种奇怪的原因,我在制作模块时总会遇到同样的错误。有人能解释我为什么以及如何解决这个问题吗?C Makefile - 如何在构建时添加头文件(linux内核)?

我有以下使文件:

TARGET = procdriver 

obj-m := procdriver.o 
procdriver-obj+= gpioLib.o 

KDIR:= /home/pi/myRpi/linux 
PWD := $(shell pwd) 

all: gpioLib.o procdriver.c 
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules 
    rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers 

gpioLib.o: gpioLib.c gpioLib.h 
    gcc -c gpioLib.c -o gpioLib.o 

clean: 
    make -C $(KDIR) SUBDIRS=$(PWD) clean 

与下面的一段这应该成为一个procfs的驱动程序.ko文件“主代码”:

#include <linux/module.h> 
    #include <linux/proc_fs.h> 
    #include <linux/seq_file.h> 

    #include "gpioLib.h" 




    static int __init hello_proc_init(void) { 
     int i; 

     //initialize GPIO 
     procFileStr = proc_create("procdriver", 0, NULL, &hello_proc_fops); 
     printk(KERN_DEBUG MODULE_NAME "init procdriver!\n"); 
     for (i=0; i<43; i++) 
     { 
      gpioSetMode(i, PI_OUTPUT); ////THIS IS THE PROBLEM 
     } 

     return 0; 
    } 

而我的头我试图包含的文件,以保持其结构。

gpioLib.c

#include "gpioLib.h" 

void gpioSetMode(unsigned gpio, unsigned mode) 
{ 
    int reg, shift; 

    reg = gpio/10; 
    shift = (gpio%10) * 3; 

    gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift); 
} 

和相应的gpioLib.h

#define PI_ALT3 7 

#define PI_ALT4 3 

#define PI_ALT5 2 

void gpioSetMode(unsigned gpio, unsigned mode); 

这是我得到每次错误:

[email protected]:~/myRpi $ make 
gcc -c gpioLib.c -o gpioLib.o 

make -C /home/pi/myRpi/linux SUBDIRS=/home/pi/myRpi modules 
make[1]: Entering directory '/home/pi/myRpi/linux' 
    CC [M] /home/pi/myRpi/procdriver.o 
    Building modules, stage 2. 
    MODPOST 1 modules 
WARNING: "gpioSetMode" [/home/pi/myRpi/procdriver.ko] undefined! 
    CC  /home/pi/myRpi/procdriver.mod.o 
    LD [M] /home/pi/myRpi/procdriver.ko 
make[1]: Leaving directory '/home/pi/myRpi/linux' 
rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers 

回答

1

看来你的头文件和makefile是正确的,但链接程序找不到gpioSetMode函数,因为它的名称不可用ou忘记gpioLib模块。

在C语言中,它是extern关键字,它使得在该模块外可用的模块内声明一个函数。 (在C++ hovewer extern中关键字的含义有点不同)。

添加extern关键字gpioSetMode函数声明,如下所示:

extern void gpioSetMode(unsigned gpio, unsigned mode);

+0

令人惊讶的是没有解决不了的问题! – LandonZeKepitelOfGreytBritn

+0

您是否在'gpioLib.h'文件中将'extern'关键字添加到*函数声明*,而不是'gpioLib.c'文件中的*函数定义*中? – SergeyLebedev

+0

是的(几个字符) – LandonZeKepitelOfGreytBritn

0

该解决方案由两个部分组成:

1)由@SergeyLebedev指出:我必须声明我的函数使用extern关键字。

2)正确的语法是procdriver-OBJ文件+ = gpioLib.o不procdriver-OBJ + = gpioLib.o