LINUX.ORG.RU

не могу слинковать libopencm3

 ,


0

1

Захотел попробовать libopencm3. Написал моргание светодиодом с копипастой makefile, получилось так:

MCU := cortex-m3

CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
OBJCOPY := arm-none-eabi-objcopy
LD :=arm-none-eabi-ld
SIZE := arm-none-eabi-size
SF := st-flash

TARGET := blink

ARCH_FLAGS = -mcpu=$(MCU) -mthumb
CSTD ?= -std=c99

CFLAGS = $(ARCH_FLAGS) $(CSTD) -Wall -Wextra
CFLAGS += -Wshadow 
CFLAGS += -MD -O0 
CFLAGS += -DSTM32F1
CFLAGS += -I./libopencm3/include

LD_SCRIPT = stm32f1.ld
LIB_PATH = ./libopencm3/lib
LIB_NAME = opencm3_stm32f1

LDFLAGS = -T$(LD_SCRIPT) -L$(LIB_PATH) -l$(LIB_NAME)
LDFLAGS += -nostartfiles $(ARCH_FLAGS) --specs=nosys.specs

all:
	$(CC) $(CFLAGS) $(LDFLAGS) main.c -o bin.elf

Вот так падает:

/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /tmp/cc8qsoBW.o: in function `main':
main.c:(.text+0x2a): undefined reference to `rcc_periph_clock_enable'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x38): undefined reference to `gpio_set_mode'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x42): undefined reference to `gpio_clear'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x4c): undefined reference to `gpio_toggle'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x5e): undefined reference to `gpio_toggle'

Сам libopencm3 для f1 скомпилирован

find libopencm3/lib/ -name "*.a"
libopencm3/lib/libopencm3_stm32f1.a

Также у меня падает проект на линковке, который я хочу перевести на libopencm3 с примерно таким Makefile-ом (CFLAFG примерно такое же как и в прошлом Makefile):

...
INCLUDE := ./libopencm3/include
LIBPATH := ./libopencm3/lib
LIBNAME := opencm3_stm32f3

LINKER_SCRIPT := linker.ld
...
LDFLAGS = --static -L$(LIBPATH) -l$(LIBNAME) -T$(LINKER_SCRIPT) 
...
$(TARGET).elf: $(OBJS) | $(BIN_DIR)
	$(LD) $(LDFLAGS) $^ -o $(BIN_DIR)/$@

Он также не может найти символы:

undefined reference to `rcc_periph_clock_enable'
undefined reference to `gpio_mode_setup'
и т.д.

libopencm3 компилировал make TARGETS=stm32/f1 для f1 и CFLAGS='-mfloat-abi=hard -mfpu=fpv4-sp-d16' make TARGETS=stm32/f3 для f3 (без CFLAGS потом ругается на application.elf uses VFP register arguments blah.o does not не знаю хорошее ли это решение, нашел его методом проб и ошибок).

Что я делаю не так? Я не очень понимаю, почему оно не работает: библиотека скомпилирована, я указываю линкеру -L и -l. Что могло пойти не так?

Решение

Я поставил -lopencm3_stm32f* в конец и все заработало.

Добавь к объектникам собственно библиотеку:

$(ELF):	$(OBJS) $(LIBS) makefile
	$(LD) $(OBJS) $(LIBS) $(LD_FLAGS) -o "$(ELF)"

В LIBS должна быть нужная *.a

Beewek ()
Ответ на: комментарий от Beewek

Это же нужно больше для автоматизации сборки, я пока руками собраю библиотеку, потом добавлю правило для проверки сборки libopencm3. А так, на момент компиляции библиотека лежит на месте.

$ find libopencm3/lib/ -name "*.a"
libopencm3/lib/libopencm3_stm32f1.a
$ make
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -std=c99 -Wall -Wextra -Wshadow  -MD -O0  -DSTM32F1 -nostartfiles -nostdlib -I./libopencm3/include -Tstm32f1.ld -L./libopencm3/lib -lopencm3_stm32f1 -mcpu=cortex-m3 -mthumb --specs=nosys.specs main.c -o bin.elf
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /tmp/ccqB2Ya6.o: in function `main':
main.c:(.text+0x2a): undefined reference to `rcc_periph_clock_enable'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x38): undefined reference to `gpio_set_mode'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x42): undefined reference to `gpio_clear'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x4c): undefined reference to `gpio_toggle'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x5e): undefined reference to `gpio_toggle'
collect2: error: ld returned 1 exit status
make: *** [Makefile:30: all] Error 1

Ну и даже если добавить, то ничего не меняется:

+ LIB = $(LIB_PATH)/libopencm3_stm32f1.a
- all:
+ all: $(LIB)
$ make
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -std=c99 -Wall -Wextra -Wshadow  -MD -O0  -DSTM32F1 -nostartfiles -nostdlib -I./libopencm3/include -Tstm32f1.ld -L./libopencm3/lib -lopencm3_stm32f1 -mcpu=cortex-m3 -mthumb --specs=nosys.specs main.c -o bin.elf
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /tmp/ccggLm2s.o: in function `main':
main.c:(.text+0x2a): undefined reference to `rcc_periph_clock_enable'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x38): undefined reference to `gpio_set_mode'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x42): undefined reference to `gpio_clear'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x4c): undefined reference to `gpio_toggle'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x5e): undefined reference to `gpio_toggle'
collect2: error: ld returned 1 exit status
make: *** [Makefile:30: all] Error 1
snake266 ★★ ()
Последнее исправление: snake266 (всего исправлений: 1)
Ответ на: комментарий от snake266

Я имел в виду, что линкеру нужно указать, какие объекты линковать. У тебя это объектные файлы (*.o), и библиотека: *.a.

Там у меня $(LIBS) не только в правиле, но и в команде фигурирует.

Beewek ()
Ответ на: комментарий от snake266

А, я понял. Ты указываешь библиотеку при помощи ключей -L и -l. И это почему-то не срабатывает. А я предлагаю указать её напрямую, в перечне объектов для линковки, типа:

arm-none-eabi-g++ foo.o bar.a -o my.elf

Я так делаю, и это точно работает.

Beewek ()
Ответ на: комментарий от Beewek

Все равно не работает

$ arm-none-eabi-gcc --specs=nosys.specs -Ilibopencm3/include -mcpu=cortex-m3 libopencm3/lib/libopencm3_stm32f1.a main.c 
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /tmp/ccafjdc0.o: in function `main':
main.c:(.text+0x2a): undefined reference to `rcc_periph_clock_enable'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x38): undefined reference to `gpio_set_mode'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x42): undefined reference to `gpio_clear'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x4c): undefined reference to `gpio_toggle'
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: main.c:(.text+0x5e): undefined reference to `gpio_toggle'
collect2: error: ld returned 1 exit status
snake266 ★★ ()

Бери, выбирай любой, там Makefile и т.п.

Только я бы на твоем месте эту дрянь не использовал, пиши на гольных регистрах…

anonymous ()
Ответ на: комментарий от anonymous

Спасибо, посмотрю.

Ну у меня есть проект над CMSIS, но я понял что хочу быстрее перейти к предметной области (не используя HAL и куб), а не регистры настраивать. Может потом, если меня не будет устраивать libopencm3, сделаю свою небольшую библиотеку которую можно будет слинковать вместо libopencm3

snake266 ★★ ()
Ответ на: комментарий от snake266

Она тебя очень быстро перестанет устраивать, т.к. сделана в корне неправильно. Даже при хорошей оптимизации, некоторые вещи все равно будут в виде функций, т.к. тратятся лишние такты на копирование стека, переход туда-обратно и т.п.

Если тебе нужна именно библиотека, пиши ее на С++ с шаблонами. Либо делай макросы и static inline функции. Но не так, как в opencm3 или тем более калокубе.

anonymous ()
Ответ на: комментарий от Beewek

Я если честно не знаю в чем проблема. Все флаги линковки вроде одинаковые. Решил работать не с makefile, дошел до вот такой минимальной команды, где ну просто невозможно ошибиться: arm-none-eabi-gcc --specs=nosys.specs -Ilibopencm3/include -Llibopencm3/lib -lopencm3_stm32f1 main.c, также пробовал arm-none-eabi-gcc --specs=nosys.specs -Ilibopencm3/include libopencm3/lib/libopencm3_stm32f1.a main.c – оба варианта не работают. Пойду схожу в чат opencm3, ну либо подниму куб с HAL.

snake266 ★★ ()
Ответ на: комментарий от snake266

Попробуй всё-таки не main.c, a main.o. И укажи скрипт линкера.

Мой makefile даёт для линковки вот такую команду (я убрал остальные *.o):

arm-none-eabi-g++  ./obj/main.o ../lib/libopencm3/lib/libopencm3_stm32f1.a   -mcpu=cortex-m3 -mthumb  -nostartfiles  --specs=nano.specs -L./prj -TSTM32F10X_MD.ld -o "./exe/mini-stm32-usb-terminal-0-1.elf"
Beewek ()
Ответ на: комментарий от snake266

Все равно, лучше набирай своих сниппетов, пиши без всяких библиотек.

Вот тебе пример для F103, там есть еще под F0x2 и F303. А с F401 я было начал, но на какое-то время забил.

anonymous ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.