【问题标题】:C Makefile - How to add header files when building (linux kernel)?C Makefile - 构建时如何添加头文件(Linux内核)?
【发布时间】:2016-12-03 21:30:41
【问题描述】:

我正在尝试将我自己的头文件及其相应的源代码包含到我的内核模块中。但是由于某些奇怪的原因,我在制作模块时总是遇到同样的错误。有人可以解释一下为什么以及如何解决这个问题吗?

我有以下make文件:

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);

这是我每次遇到的错误:

pi@raspberrypi:~/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

【问题讨论】:

    标签: c linux makefile compilation linux-kernel


    【解决方案1】:

    您的头文件和 makefile 似乎是正确的,但链接器找不到 gpioSetMode 函数,因为它的名称在您的 gpioLib 模块之外不可用。

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

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

    extern void gpioSetMode(unsigned gpio, unsigned mode);

    【讨论】:

    • 您是否在gpioLib.h 文件中的函数声明 中添加了extern 关键字,而不是在gpioLib.c 文件中的函数定义 中?跨度>
    • 是(几个 mor 字符)
    【解决方案2】:

    解决方案由两部分组成:

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

    2) 正确的语法是 procdriver-objs+= gpioLib.o 而不是 procdriver-obj+= gpioLib.o

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多