0

私は、AVR32 32 ビット マイクロプロセッサの 1 つ用にやや複雑な C プログラムを継承しました。

ただし、コンパイル方法に関する情報はありません。少しの間、そのためのメイクファイルをまとめようとしてきましたが、成功していません。うまくいけば、誰かが私が間違っている場所を教えてくれます。


基本的に、次のようなプロジェクト構造があります。

/
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.cadc.hgpio.hなどをインクルードし、それらのさまざまなヘッダー ファイルでプロトタイプ化された関数を呼び出します。FRAMEWORKさまざまなヘッダーの実際の関数は、実際には.cファイルで定義されています。

すべての.hファイルはインクルード保護でラップされています。

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

さて、私が理解しているように、さまざまな.cファイルをオブジェクト ( .o) ファイルにコンパイルし、リンカーを呼び出して、すべてのオブジェクト ファイルを最終的な実行可能ファイル (この場合は.elfファイル) にマージする必要があります。
そのため、小さなメイクファイルを作成しました。

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)をコンパイルすると、両方のオブジェクトでコードが複製され、それらをリンクすることはできません。

この状況では、通常、関数の宣言をヘッダーファイルに残し、その実装をオブジェクトコードの1つに移動します(どちらでも)。

「gpio.h:507」で、関数のシグネチャだけでなく、実装があることを確認できますか?

于 2012-09-17T13:01:30.953 に答える
0

さて、私はあまりにも最近のIDEを使用していたことがわかりました。

プロジェクトを正しいIDE(この場合はEclipseに基づく古いバージョンのAtmel avr32 studio)で開いたところ、どういうわけか自動的に構造が推測され、すべてが正しくまとめられました。

とにかく、それを避けて問題を解決したほどではありませんが、私はこの質問を回答済みとしてマークしています。私はすでに日食が何をしているのかを理解しようと多くの時間を費やしてきました。

于 2012-12-28T08:55:15.787 に答える