Подтвердить что ты не робот

Ошибка компоновщика в проекте C с использованием eclipse

Я хочу создать проект для микроконтроллера STM32F217IG.

Затем я установил eclipse и GNU для встроенного gcc-перекрестного компилятора ARM. Я не думаю, что это код sourcery один, я использовал его, потому что он поддерживает плавающие точки, а код sourcery не работает.

Как только я это сделал, я попытался создать действительно небольшой проект с двумя исходными файлами: test.c и main.c, только написанными в обоих из них:

#include <stdlib.h>
#include <stdio.h>
int main (void)
{
    printf("hellowolrd");
    return 0;

}

Я изменил команду line в свойстве проекта, чтобы заменить gcc на arm-none-eabi-gcc, а затем попытался скомпилировать проект.

Я не создавал файл make самостоятельно, я использовал автоматическое создание в eclipse.

Здание кажется прекрасным, но когда дело доходит до компоновщика, я получил следующие ошибки в консоли:

make all 
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status

make: *** [test3] Erreur 1

Я посмотрел в Интернете, и я обнаружил, что это может быть проблема с syscall. Но я не знаю, как добавить эту библиотеку в свой проект в Linux.

Неужели это так? Если да, то как мне это исправить? А если нет, то откуда?

изменить

Как кто-то предложил, я попробовал "привязать" библиотеку времени выполнения c. На затмении кажется, что у меня есть два решения: сначала в свойствах проекта → C/С++ build- > Settings- > Crosslinker- > library Я просто добавляю букву c, а затем ошибка не изменяется, но в конце командной строки есть -lc:

 make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -lc

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

Но я не знаю, действительно ли это означает добавить библиотеку времени выполнения C

Вторым я добавил библиотеку libc.a в свойствах проекта → C/С++ general- > Путь и символы → Библиотеки, и вот что я получаю (совершенно другое):

make all 
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -l"C:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a"

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

Тогда он все еще не работает, но это хороший способ поиска?

Ох и очень интересный факт: Я получил ошибки только в режиме отладки. Если я в режиме выпуска, все в порядке, и у меня нет ошибок (execpt, если я добавлю libc.a, тогда я думаю, что это не очень хорошо). Означает ли это, что проблема заключается в создании файла .elf?

4b9b3361

Ответ 1

Я просмотрел набор инструментов, который вы связали, чтобы прочитать следующее в readme.txt:

Эта инструментальная цепочка построена и оптимизирована для разработки голого металла Cortex-R/M.

Другими словами, эта инструментальная привязка специально сконфигурирована для встроенных систем, возможно, без какой-либо операционной системы. В этом случае нет системы для обеспечения, например, стандартный вывод, где printf() должен писать, нет файловой системы и т.д. - вам нужно связать с какой-либо библиотекой, предоставляющей эти основные службы, если вы хотите их использовать.

Тем не менее, ваш инструментарий предоставляет библиотеку librdimon.a, которая предоставляет все эти основные службы. Эта библиотека фактически является частью компиляции libgloss. Если вы хотите связать его, попробуйте выполнить следующую команду:

arm-none-eabi-gcc --specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c

Это хорошо работает на моем ПК, но нужно ли это то, что вам действительно нужно, - это другая история (где вы ожидаете увидеть вывод printf()?).

Для чипа вы, вероятно, должны искать библиотеку, которая перенаправляет стандартный вывод на последовательный порт или обеспечивает вывод отладки через JTAG. Кроме того, вы можете использовать свою собственную функцию, например. отправка отладочного вывода на последовательную консоль вместо printf() - это вам. Если вы решите использовать printf(), я предлагаю прочитать документацию libgloss.

Кроме того, я предлагаю оглянуться на инструментальную цепочку, специально предназначенную для семейства STM32. Правильная настройка всего этого базового материала (библиотека C, компоновщик script и т.д.) Требует немного опыта.

Изменить: Многие встроенные системы на самом деле не используют стандартную библиотеку C, начиная с нуля. Если вы хотите пройти этот путь, вы должны передать -nostdlib вашему вызову gcc. Конечно, у вас больше не будет таких вещей, как printf().

Изменить 2: Другой способ - использовать стандартную библиотеку (newlib, я имею в виду) без libgloss и предоставить соответствующие заглушки для вещей, которые вам не нужны. Возможно, вам захочется следовать этот учебник, где _read и _write реализованы через последовательный порт, а все остальное - нарезано. Это, скорее всего, то, что вы действительно хотите.

Ответ 2

Я знаю, что это старый вопрос, но я столкнулся с этим сегодня, пытаясь построить плату STM32. Проект, который у меня есть, имеет некоторые скрипты компоновщика (в частности, libs.ld). Добавление записи для libnosys.a в этом удовлетворило компоновщик, и я смог продолжить.

libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )

Ответ 3

Сохраняя вашу программу на языке C как "myprint.c", я скомпилирую ее следующим образом:

arm-none-eabi-gcc myprint.c -lc -specs = nosys.specs

Ошибок и вывода не получается.

Ответ 4

Также была проблема с вызовами функций malloc() и free() в проекте eclipse. Я написал прошивку для STM32 mcu, используя eclipse + GNU для встроенного gcc-компилятора gcc crossС++ + STM32CubeMX для создания и компоновки периферийных устройств mcu и компоновщика script. Когда я добавил отсутствующие строки libg.a (*) и libnosys.a (*) в разделе DISCARD .ld script, мой проект был успешно создан.

Ответ 5

Я создал проект RTOS с использованием CubeMX и добавил printf и имел ту же проблему при связывании при отладке с помощью openocd.

заменил printf ( "Hello ARM World!" ) на trace_puts ( "Hello ARM World!" ); появились сообщения на консоли отладки