Pregunta

I've inherited a mildly-complicated C program for one of the AVR32 32 bit microprocessors.

However, I have no information about how to compile it. I've been trying to put together a make-file for it for a bit now, and have been having no success. Hopefully someone can tell me where I am going wrong.


Basically, I have a project structure that looks like this:

/
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

Basically, ControllerR3.c includes adc.h, gpio.h, etc, and calls functions that are prototyped in those various header files. The actual functions in the various FRAMEWORK headers are actually defined in the .c files.

All the .h files are wrapped in include protections:

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

Now, as I understand it, I have to compile the various .c files into object (.o) files, and then call the linker to merge all the object files together in to the final executable (in this case, it's a .elf file).
As such, I have written a small 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/$@"

This successfully builds all the various object files, and then fails at the linking stage with:

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]

So obviously, I have a problem with multiple definitions.

At this point, I'm a bit over my head. I don't have much experience with C development, and just getting the makefile to the point where it is now took a lot of reading.

What is causing the multiple definition issues I have here? What changes do I need to make to the makefile to prevent this?

I know this project was built successfully in the past, as we have a hardware device that actually runs it. However, I need to make some changes, so just using the existing compiled version is no-longer acceptable.

The existing version was built by an external-contractor who is no-longer available, so I can't really ask them how they made it work.

¿Fue útil?

Solución 2

Well, it turned out I was using too recent an IDE.

I opened the project in the correct IDE (in this case, the older version of Atmel avr32 studio that's based on eclipse), and it somehow automagically deduced the structure, and put everything together correctly.

Anyways, while it's not so much that I solved the problem as avoided it, I'm marking this question as answered. I've already spent too much time trying to figure out what eclipse is doing.

Otros consejos

It looks like you have a function implemented in your header files. When you compile object1 and object2 (say main.o and gpio.o) you have your code duplicated in both object, and those cannot be linked together.

In this situation typically I leave the declaration of the function in the header file and move its implementation in one of the object code (no matter which).

Can you confirm that at "gpio.h:507" you have the implementation and not only the signature of the function?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top