настроить компоновщик для обнаружения stm32f4 и g++

Я пытаюсь скомпилировать некоторый код, который использует функции USART и std, такие как printf() для обнаружения stm32f4. Сначала я компилирую все файлы кода в объектный файл с помощью g++, но когда я использую компоновщик для создания исполняемого файла, компоновщик выдает ошибки, описывающие, что он не может найти какие-либо функции, реализованные в файле сборки startup_stm32f4xx.s.

Могу ли я иметь форму шаблона Makefile, которая компилирует весь исходный код в объектные файлы, а затем связывает его с исполняемым файлом *.elf?

Кроме того, как мне настроить компоновщик для просмотра newlib_stubs.c, чтобы я мог использовать printf() в своем исходном коде?


person NicholasB    schedule 27.12.2013    source источник
comment
вот ссылка на пример проекта makefile, который я не могу скомпилировать: ссылка   -  person NicholasB    schedule 27.12.2013


Ответы (1)


Это общий Makefile для вашего проекта (компиляция проверена, но не проверена, будет ли она работать на MCU)

Этот сценарий может работать с файлами C/C++ и S (gas asm). Так что нет необходимости использовать C-файл запуска от coocox

# ELF target name
TARGET=testmode09.elf

# C source files
SRC=src/system_stm32f4xx.c

# C++ source files
CXXSRC=src/main.cpp

# ASM source files
ASRC=lib/startup_stm32f4xx.s

# include directories
INCDIRS=inc lib/inc lib/inc/core lib/inc/peripherals

# search path for .so and .a
LIBDIRS=lib

# libraries to link
LIBS=libstm32f4.a

# Linker script
LDSCRIPT=stm32_flash.ld

# Tool configuration
CROSS=arm-none-eabi-
CC=$(CROSS)gcc
CXX=$(CROSS)g++
AS=$(CROSS)gcc
LD=$(CROSS)gcc
OBJCOPY=$(CROSS)objcopy

# Architecture configuration
ARCH_FLAGS=-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 

# Flags for gcc
CFLAGS+=-O0 -ggdb3
CFLAGS+=$(ARCH_FLAGS)
CFLAGS+=-flto
CFLAGS+=-ffunction-sections
CFLAGS+=-fdata-sections
CFLAGS+=$(foreach i, $(INCDIRS), -I$(i))

# Flags for g++
CXXFLAGS=$(CFLAGS)
CXXFLAGS+=-fno-rtti -fno-exceptions
CXXFLAGS+=-std=c++11

# Flags for gcc as linker
LDFLAGS=$(ARCH_FLAGS)
LDFLAGS+=-Wl,--gc-sections
LDFLAGS+=$(foreach i, $(LIBDIRS), -L$(i))
LDFLAGS+=-T $(LDSCRIPT)

# No man land! Enter at your risk

OBJS=$(SRC:.c=.o) $(ASRC:.s=.o) $(CXXSRC:.cpp=.o)
DEPS=$(OBJS:.o=.d)

# Default make target (first target)
all: $(TARGET) bins

# include dependency files (*.d)
-include $(DEPS)

# Rules to build c/cpp/s files
%.o: %.c
    @echo " CC $<"
    @$(CC) -MMD $(CFLAGS) -o $@ -c $<

%.o: %.cpp
    @echo " CXX $<"
    @$(CXX) -MMD $(CXXFLAGS) -o $@ -c $<

%.o: %.s
    @echo " AS $<"
    @$(AS) $(CFLAGS) -o $@ -c $<

# Linker rule
$(TARGET): libs $(OBJS)
    @echo " LINK $@"
    @$(LD) -o $@ $(LDFLAGS) $(OBJS)

# Phony rules (not file-asociated)
.PHONY: clean all libs clean_lib bins

libs:
    @$(MAKE) -C lib

clean_lib:
    @$(MAKE) -C lib clean

clean:
    @echo " CLEAN"
    @rm -fR $(OBJS) $(DEPS) $(TARGET) $(TARGET:.elf=hex) $(TARGET:.elf=.bin)

bins: $(TARGET)
    @echo " BUILD HEX & BIN"
    @$(OBJCOPY) -O ihex $(TARGET) $(TARGET:.elf=.hex)
    @$(OBJCOPY) -O binary $(TARGET) $(TARGET:.elf=.bin)

Основная ссылка на make находится в официальном руководстве: http://www.gnu.org/software/make/manual/make.html, но вам нужно время, чтобы понять это ;-)

Предложение, поместите код системных вызовов в отдельный файл C/C++ с именем syscall.c/cpp или что-то в этом роде.

person martinribelotta    schedule 27.12.2013
comment
Я изменил несколько вещей, чтобы они соответствовали вашему файлу make. Обновленный тестовый проект можно загрузить по адресу: dl.dropboxusercontent.com/u/32204435. /testmodel09.2.zip Я все еще получаю такие ошибки, как /usr/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libc.a(lib_a-sbrkr.o): In function '_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to '_sbrk' для _sbrk, _write, _read, _close, _fstats, _isatty и _lseek. Но этот make-файл близок к достижению цели. Это создание и компиляция объектных файлов. Вы успешно скомпилировали проект локально? - person NicholasB; 28.12.2013
comment
Привет, вижу проблему ;-) Вы поместили заглушку системных вызовов в файл .cpp без объявления extern "C" . В функции C++ компоновщик видит такие имена, как pv_sbrkEui (искаженное имя void _sbrk(unsigned int)) вместо _sbrk. Добавьте extern C к любому объявлению функции или extern "C" { <...file body...> } для его разрешения - person martinribelotta; 28.12.2013
comment
Или переименуйте файл src/newlib_stubs.cpp в src/newlib_stubs.c. - person martinribelotta; 28.12.2013
comment
@martinribelotta, это полезная информация об искажении. Как вы узнали об этом? - person ; 24.11.2016