Je souhaite créer un projet pour le microcontrôleur STM32F217IG.
Ensuite, j'ai installé Eclipse et le GNU pour ARM compilateur croisé GCC intégré . Je ne pense pas que ce soit le code Sourcery. Je l'ai utilisé, car il prend en charge la virgule flottante et Code Sourcery non.
Une fois que j’ai fait cela, j’ai essayé de créer un très petit projet avec seulement deux fichiers sources: test.c et main.c avec seulement écrit dans les deux:
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
printf("Hello, World!");
return 0;
}
J'ai modifié la commande line de la propriété project pour remplacer GCC par arm-none-eabi-gcc, puis j'ai essayé de compiler le projet.
Je n'ai pas créé de fichier make moi-même; J'ai utilisé la création automatique dans Eclipse.
Le bâtiment semble bien fonctionner, mais en ce qui concerne l'éditeur de liens, j'ai eu les erreurs suivantes dans la console:
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
J'ai regardé sur Internet et j'ai découvert que c'était peut-être un problème systémique. Mais je ne sais pas comment ajouter cette bibliothèque à mon projet sous Linux.
Est-ce vraiment ça? Si oui, comment puis-je le réparer? Et si non, d'où ça vient?
Comme quelqu'un l'a suggéré, j'ai essayé de "lier" la bibliothèque d'exécution C. Sur Eclipse, il semble que j'ai deux solutions pour le faire:
Tout d’abord sur les propriétés du projet → C/C++ → Construire → Paramètres → Éditeur de liens → bibliothèques. J'ajoute simplement la lettre c
et ensuite l'erreur ne change pas, mais il y a -lc
à la fin de la ligne de commande:
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
Mais je ne sais pas s’il s’agit vraiment d’ajouter la bibliothèque d’exécution C.
Deuxièmement, j'ai ajouté la bibliothèque libc.a dans les propriétés du projet → C/C++ général → Chemin et symboles → Bibliothèques, et voici ce que j'ai (complètement différent):
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
Alors cela ne fonctionne toujours pas, mais est-ce le bon moyen de chercher?
Oh et un fait très intéressant:
J'ai eu les erreurs uniquement en mode débogage. Si je suis en mode de publication, tout va bien et je n'ai pas d'erreur (sauf si j'ajoute la libc.a, alors je pense que ce n'est pas la bonne chose à faire). Est-ce que cela signifie que le problème est la création du fichier .elf?
J'ai consulté la boîte à outils que vous avez liée, juste pour lire ce qui suit dans le readme.txt
:
Cette chaîne d’outils est construite et optimisée pour le développement nu-métal Cortex-R/M.
En d’autres termes, cet ensemble d’outils est spécifiquement configuré pour les systèmes intégrés, peut-être même sans aucun système d’exploitation. Dans ce cas, il n’existe aucun système à fournir, par exemple. sortie standard où printf()
est censé écrire, il n'y a pas de système de fichiers, etc. - vous devez établir une liaison avec une bibliothèque fournissant ces services de base, si vous souhaitez les utiliser.
Cela dit, votre boîte à outils fournit la bibliothèque librdimon.a
qui fournit tous ces services de base. Cette bibliothèque fait en réalité partie de libgloss compilation. Si vous souhaitez créer un lien, essayez la commande suivante:
arm-none-eabi-gcc --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c
Cela relie bien mon ordinateur, mais si vous voulez vraiment, c’est une autre histoire (où vous attendez-vous à voir printf()
, en tout cas?).
Pour votre puce, vous devriez probablement chercher une bibliothèque qui redirige la sortie standard vers le port série ou fournit une sortie de débogage via JTAG. Vous pouvez également utiliser votre fonction personnalisée, par exemple envoi de la sortie de débogage à la console série au lieu de printf()
- à vous de choisir .. Si vous décidez d'utiliser printf()
, je suggère de lire la documentation libgloss
.
En outre, je suggère de rechercher une chaîne d’outils spécialement fournie pour la famille STM32. Configurer correctement tous ces éléments de base (bibliothèque C, script de l'éditeur de liens, etc.) nécessite un peu d'expérience.
Edit: De nombreux systèmes embarqués n'utilisent pas vraiment la bibliothèque C standard, en partant de zéro. Si vous voulez utiliser cette méthode, vous devez passer -nostdlib
à votre invocation gcc
. Bien entendu, vous ne disposerez plus d'éléments tels que printf()
.
Edit 2: Une autre méthode consiste à utiliser la bibliothèque standard (newlib
, je veux dire) sans libgloss
et à fournir des stubs appropriés aux éléments dont vous n’avez pas besoin. Vous voudrez peut-être suivre ce tutoriel , où _read
et _write
sont implémentés sur le port série, et tout le reste est tronqué. C'est très probablement ce que vous voulez vraiment.
Je sais que c’est une vieille question, mais j’en ai rencontré une aujourd’hui lorsque j’essayais de construire un tableau STM32. Le projet que j'ai a quelques scripts de lieur (plus précisément libs.ld). L'ajout d'une entrée pour libnosys.a dans ce fichier satisfait l'éditeur de liens et j'ai pu continuer.
libs.ld:
GROUP(
libgcc.a
libg.a
libc.a
libm.a
libnosys.a
)
Enregistrer votre programme C en tant que "myprint.c", je le compile comme suit:
arm-none-eabi-gcc myprint.c -lc -specs = nosys.specs
Aucune erreur et la sortie est bonne.
Il y avait aussi un problème avec les appels de fonction malloc()
et free()
dans le projet Eclipse. J'ai écrit un micrologiciel pour un microcontrôleur STM32 en utilisant Eclipse + GNU pour ARM compilateur transversal GCC intégré + STM32CubeMX pour l'initialisation de la périphérie du microcontrôleur et la création d'un script pour l'éditeur de liens.
Lorsque j'ai ajouté les chaînes manquantes libg.a
(*) et libnosys.a
(*) dans la sectionDISCARDdu script .ld
, mon projet a été construit avec succès.
J'avais créé un projet RTOS à l'aide de CubeMX et ajouté un printf. J'avais le même problème de liaison lorsque je déboguais avec OpenOCD.
J'ai remplacé printf ("Hello ARM World!") Par trace_puts ("Hello ARM World!"); et les messages sont apparus dans la console de débogage.