0

我为其中一个 AVR32 32 位微处理器继承了一个稍微复杂的 C 程序。

但是,我没有关于如何编译它的信息。我一直在尝试为它整理一个make-file,但一直没有成功。希望有人能告诉我哪里出错了。


基本上,我的项目结构如下所示:

/
ControllerR3.c     # This is the main program file
    /FRAMEWORK
        /DRIVERS
            /ADC
                adc.c
                adc.h
            /GPIO
                gpio.c
                gpio.h
            {another 6 hardware drivers}
        /SERVICES
            /DELAY
                delay.c
                delay.h

基本上,ControllerR3.c包括adc.hgpio.h等,并调用在各种头文件中原型化的函数。各种FRAMEWORK头文件中的实际功能实际上是在.c文件中定义的。

所有.h文件都包含在包含保护中:

#ifndef _USART_H_
#define _USART_H_
{snip header file contents}
#endif  // _USART_H_

现在,据我了解,我必须将各种.c文件编译成 object ( .o) 文件,然后调用链接器将所有 object 文件合并到最终的可执行文件中(在这种情况下,它是一个.elf文件)。
因此,我写了一个小makefile:

CC      = avr32-gcc

CFLAGS  = -mpart=uc3a0512 -O1 -ffunction-sections -masm-addr-pseudos -g3 -Wall -c -std=gnu99 
COMP_INC =  -I"./FRAMEWORK/UTILS" \
            -I"./FRAMEWORK/UTILS/PREPROCESSOR"

LIB_INC =   -I"./FRAMEWORK/UTILS/LIBS/NEWLIB_ADDONS/INCLUDE" \
            -I"./FRAMEWORK/SERVICES/DELAY" \
            -I"./FRAMEWORK/DRIVERS/USART" \
            -I"./FRAMEWORK/DRIVERS/TC" \
            -I"./FRAMEWORK/DRIVERS/SPI" \
            -I"./FRAMEWORK/DRIVERS/PWM" \
            -I"./FRAMEWORK/DRIVERS/PM" \
            -I"./FRAMEWORK/DRIVERS/INTC" \
            -I"./FRAMEWORK/DRIVERS/GPIO" \
            -I"./FRAMEWORK/DRIVERS/FLASHC" \
            -I"./FRAMEWORK/DRIVERS/CPU/CYCLE_COUNTER" \
            -I"./FRAMEWORK/BOARDS" \
            -I"./FRAMEWORK/DRIVERS/ADC" 

DRIVER_PATH = ./FRAMEWORK/DRIVERS



all: libraries main

main:
    $(CC) $(CFLAGS) $(COMP_INC) $(LIB_INC) -o"Debug/$@.o" "ControllerR3.c"
    $(CC) "Debug/adc.o" "Debug/flashc.o" "Debug/gpio.o" "Debug/intc.o" "Debug/pm.o" "Debug/pwm.o" "Debug/tc.o" "Debug/usart.o" "Debug/spi.o" "Debug/main.o" "Debug/delay.o" \
        -o Debug/CookerControlR3.elf

libraries: adc.c flashc.c gpio.c intc.c pm.c pwm.c spi.c tc.c usart.c delay.c


adc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/ADC/$@"

flashc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/FLASHC/$@"

gpio.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/GPIO/$@"

intc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/INTC/$@"

pm.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/PM/$@"

pwm.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/PWM/$@"

spi.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/SPI/$@"

tc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/TC/$@"

usart.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/USART/$@"


delay.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" -I"FRAMEWORK/DRIVERS/CPU/CYCLE_COUNTER" "FRAMEWORK/SERVICES/DELAY/$@"

这成功构建了所有各种目标文件,然后在链接阶段失败:

C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:507: multiple definition of `gpio_local_clr_gpio_open_drain_pin'
Debug/gpio.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:507: first defined here
Debug/main.o: In function `gpio_local_tgl_gpio_open_drain_pin':
C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:525: multiple definition of `gpio_local_tgl_gpio_open_drain_pin'
Debug/gpio.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:525: first defined here
Debug/main.o: In function `usart_reset_status':
C:\[snip - private]/./FRAMEWORK/DRIVERS/USART/usart.h:409: multiple definition of `usart_reset_status'
Debug/usart.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/USART/usart.h:409: first defined here
Debug/main.o: In function `usart_parity_error':
[snip a hundred or so lines]

很明显,我有多个定义的问题。

在这一点上,我有点过头了。我在 C 开发方面没有太多经验,只是将 makefile 写到现在需要大量阅读的地步。

是什么导致了我在这里遇到的多个定义问题?我需要对生成文件进行哪些更改以防止这种情况发生?

我知道这个项目在过去是成功构建的,因为我们有一个实际运行它的硬件设备。但是,我需要进行一些更改,因此不再接受仅使用现有的编译版本。

现有版本是由一个不再可用的外部承包商构建的,所以我真的不能问他们是如何让它工作的。

4

2 回答 2

1

看起来您在头文件中实现了一个功能。当您编译 object1 和 object2(比如 main.o 和 gpio.o)时,您的代码在两个对象中都重复了,并且它们不能链接在一起。

在这种情况下,我通常将函数的声明留在头文件中,并将其实现移动到一个目标代码中(不管是哪个)。

你能确认在“gpio.h:507”你有实现,而不仅仅是函数的签名吗?

于 2012-09-17T13:01:30.953 回答
0

好吧,事实证明我使用的 IDE 太新了。

我在正确的 IDE 中打开了项目(在本例中,是基于 eclipse 的旧版 Atmel avr32 studio),它以某种方式自动推断出结构,并将所有内容正确组合在一起。

无论如何,虽然我解决问题并没有解决问题,但我将这个问题标记为已回答。我已经花了太多时间试图弄清楚日食在做什么。

于 2012-12-28T08:55:15.787 回答