J'essaie de compiler du code pour un micro ATMEGA328, et je veux utiliser les bibliothèques et le noyau d'Arduino. J'utilise CMAKE . Je me suis acheté pour compiler la bibliothèque principale et tous les objets de mon code et des bibliothèques d'Arduino. Mais quand il s'agit de lier, ils me montrent l'erreur suivante.
... "Relocalisation tronquée à l'ajustement: r_avr_13_pcrel contre Symbole "..." AVR5 / LIBGCC.A "... P> blockQuote>
J'ai
trouvé via Google que c'est une erreur courante, mais aucune solution n'a fonctionné pour moi. La seule chose que je ne peux pas faire est de mettre des drapeaux "-LM" et "-LC" drapeaux à la fin de la phrase de liaison, car je ne sais pas comment je peux le faire avec cmake. P> Modifier Strard>: J'ai essayé de le compiler avec un maquillage aussi, mais j'ai eu le même résultat, même mettre des drapeaux "-LM" et "-LC" à la fin de la phrase de liaison. P>
Je mets mes fichiers makefile et cmake ici: p>
cmakelist.txt strong> Le fichier de cumake principal p>
xxx pré> arduino.cmake strong>. Cela est importé par CMAKELIST.TXT: P>
TARGET = IMU PORT = /dev/ttyACM0 BAUD = 57600 PROGRAMMER = arduino MCU = atmega328p F_CPU = 8000000L CXX_SRCS = ADXL345.cpp \ ApplicationRoutines.cpp \ DCM.cpp \ HMC5883L.cpp \ ITG3200.cpp \ matrix.cpp \ output.cpp \ timing.cpp \ vector.cpp CXX_OBJ = $(CXX_SRCS:.cpp=.o) CXX_HDRS = ADXL345.h \ ApplicationRoutines.h \ DCM.h \ declarations.h \ HMC5883L.h \ ITG3200.h \ matrix.h \ output.h \ timing.h \ vector.h CORE_DIR = libarduinocore CORE_CXX_SRCS = $(CORE_DIR)/HardwareSerial.cpp \ $(CORE_DIR)/Print.cpp \ $(CORE_DIR)/Tone.cpp \ $(CORE_DIR)/WMath.cpp \ $(CORE_DIR)/WString.cpp CORE_CXX_OBJ = $(CORE_CXX_SRCS:.cpp=.o) CORE_CC_SRCS = $(CORE_DIR)/pins_arduino.c \ $(CORE_DIR)/WInterrupts.c \ $(CORE_DIR)/wiring_analog.c \ $(CORE_DIR)/wiring.c \ $(CORE_DIR)/wiring_digital.c \ $(CORE_DIR)/wiring_pulse.c \ $(CORE_DIR)/wiring_shift.c CORE_CC_OBJ = $(CORE_CC_SRCS:.c=.o) CORE_HDRS = $(CORE_DIR)/binary.h \ $(CORE_DIR)/HardwareSerial.h \ $(CORE_DIR)/pins_arduino.h \ $(CORE_DIR)/Print.h \ $(CORE_DIR)/Stream.h \ $(CORE_DIR)/WCharacter.h \ $(CORE_DIR)/WConstants.h \ $(CORE_DIR)/wiring.h \ $(CORE_DIR)/wiring_private.h \ $(CORE_DIR)/WProgram.h \ $(CORE_DIR)/WString.h ARD_LIB_DIR = libraries ARD_LIB_CXX_SRCS = $(ARD_LIB_DIR)/EEPROM/EEPROM.cpp \ $(ARD_LIB_DIR)/Wire/Wire.cpp \ $(ARD_LIB_DIR)/HMC58X3/HMC58X3.cpp ARD_LIB_CC_SRCS = $(ARD_LIB_DIR)/Wire/utility/twi.c ARD_LIB_CXX_OBJ = $(ARD_LIB_CXX_SRCS:.cpp=.o) ARD_LIB_CC_OBJ = $(ARD_LIB_CC_SRCS:.c=.o) CC = avr-gcc CXX = avr-g++ OBJCOPY = avr-objcopy OBJDUMP = avr-objdump AR = avr-ar SIZE = avr-size NM = avr-nm AVRDUDE = avrdude ARD_LIB_INC = -I$(ARD_LIB_DIR) -I$(ARD_LIB_DIR)/EEPROM -I$(ARD_LIB_DIR)/Wire -I$(ARD_LIB_DIR)/HMC58X3 -I$(ARD_LIB_DIR)/Wire/utility FLAGS_WARN = -Wall -Wstrict-prototypes FLAGS_TUNING = -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums FLAGS_OPT = -Os ALL_INC = -I. $(ARD_LIB_INC) -I$(CORE_DIR) OBJS = $(CXX_OBJ) $(CORE_CXX_OBJ) $(CORE_CC_OBJ) $(ARD_LIB_CC_OBJ) $(ARD_LIB_CXX_OBJ) ALL_OBJS := $(addprefix build/, $(notdir $(OBJS))) ALL_CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(ALL_INC) $(FLAGS_WARN) $(FLAGS_TUNNIG) $(FLAGS_OPT) ALL_CXXFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(ALL_INC) -Wall $(FLAGS_TUNNIG) $(FLAGS_OPT) #ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) all : $(TARGET).hex avr-objcopy -O ihex -R .eeprom $(TARGET).out $(TARGET).hex $(TARGET).out : $(OBJS) $(CXX) $(ALL_CXXFLAGS) main.cpp $(ALL_OBJS) -o $(TARGET).out -lc -lm upload : $(TARGET).hex avrdude -c$(PROGRAMMER) -p$(MCU) -P$(PORT) -U flash:w:$(TARGET).hex serialmon : picocom -b$(BAUD) $(PORT) .SUFFIXES: .hex .cpp .o .c # Compile: create object files from C++ source files. .cpp.o: $(CXX) -c $(ALL_CXXFLAGS) $< -o $(addprefix build/, $(notdir $@)) -lc -lm # Compile: create object files from C source files. .c.o: $(CC) -c $(ALL_CFLAGS) $< -o $(addprefix build/, $(notdir $@)) -lc -lm # Compile: create assembler files from C source files. .c.s: $(CC) -S $(ALL_CFLAGS) $< -o build/$@ -lc -lm
8 Réponses :
J'ai résolu le problème, j'ai restructuré le code (j'ai supprimé presque toutes les variables de globals) et j'ai ajouté des drapeaux '-LC -LC -LC' -LC 'pour faireFILE. Je suppose que le problème était la structure de code, trop de variables globales dus à une mauvaise adaptation d'un style de code Arduino (tous les fichiers sources sont collés dans le même dossier)
J'ai mis le maquillage ici, j'espère que cela est utile à quelqu'un:
Je travaille sur ce problème depuis quelques heures et j'ai finalement résolu. Pour moi, il fallait faire avec le fait que l'AVR libm.A doit être incluse dans la commande Linker, et j'utilisais la bibliothèque Math.H, qui est séparée de la bibliothèque libc.a et n'était pas liée correctement .
Essayez de modifier la commande Linker pour ressembler à ceci en ajoutant -lc -lm au début de la commande et à la fin de la commande: p> Ma référence:
http://www.arduino.cc.c/cgi-bin/yabb2 /Yabb.pl?num=1290294587 P> P>
Comme le suggère le message d'erreur, le problème concerne la relocalisation (EM> (du code) qui provoque une troncature em>. Le message provient de la liaison qui tente de cartographier des morceaux de code sur des emplacements appropriés dans la mémoire du programme. P>
Lorsque le code est placé ou déplacé vers un emplacement ("relocalisation") et em> ce code est mentionné à partir d'une autre pièce de code, via Les périphériques AVR prennent en charge deux types de types de saut / d'appel: sur des périphériques avec plus de 8 kb de mémoire de programme, cependant, ce n'est pas vrai pour tous les emplacements possibles em>. Par conséquent, si em> le em> linker em> décide qu'il peut placer le code à appeler dans em> la plage de +/- 4kb du Notez que ce peut em> ou peut ne pas em> se produire pour un projet donné dépassant 4 Ko de la mémoire de programme (sur les périphériques avec> 8kb de mémoire de programme) à un moment donné, car elle dépend de la relocalisation du code nécessaire, qui peut changer essentiellement de chaque nouvelle ligne de code C ajouté ou supprimé, avec chaque bibliothèque ajoutée à être liée, ou même l'ordre em> dans lequel les bibliothèques ou autres pièces de code sont liés (par exemple, l'appelant "A" à "B" peut fonctionner lorsque le lien de liaison localise le code comme "abc" mais échoue lorsque le lien décide de déménager comme "ACB"). P>
Vous devez laisser le compilateur savoir qu'il doit générer Pour éviter la confusion inutile, cette erreur peut causer Les utilisateurs doivent maintenant utiliser JMP code> ou
appel code> (c'est-à-dire un appel de fonction), l'adresse reloquée doit être ajoutée au
JMP code> ou
appel code> instructions en référence. p>
JMP code> vs.
RJMP code> et
appel code> vs. code> rcall code>. Les variantes
r code> appellent les appels relative em> à l'emplacement actuel et sont plus efficaces à la fois dans l'utilisation de la mémoire de programme et du temps d'exécution. Cela vient à un coût que:
rjmp code> et
rcall code> ne peut être utilisé que pour les adresses de la plage de +/- 4kb à partir de leur emplacement dans la mémoire de programme. Ce n'est jamais un problème sur des périphériques sans plus de 8 kb de mémoire de programme car toute la gamme de 8 kb peut être adressée à partir de n'importe quel emplacement via
RCall code> ou
rjmp code>. P>.
RJMP Code> /
RCALL code> Il n'y aura pas de problème, mais em> si le lien de liaison échoue à () localiser le code dans cette plage,
rjmp code > /
rcall code> ne peut pas em> être utilisé pour atteindre la nouvelle adresse du code, l'adresse est ainsi tronquée em> (comme lors de la réalisation de
uint16_t valeur = 12345; uint8_t tronquéevalue = valeur; code> in c) et le code généré casse. P>
Solution: h2>
jmp code> /
appel code> à la place du (plus efficace)
rjmp code> / < Code> RCALL code> instructions. Dans AVR Studio / Atmel Studio, cela peut être effectué dans les propriétés du projet, Toolchain, le compilateur AVR / GNU C, l'optimisation. L'option correspondante est
-Mshort-appels code> qui doit être supprimé em> à partir de la liste de paramètres de ligne de commande GCC pour obtenir la même chose lors de l'invocation de la GCC de l'extérieur de l'IDE. P>
Mise à jour: h2>
-Mshort-appels code> était obsolète dans AVR-GCC 4.7 strong> et sera supprimé de 4.8. Source: Changements de GCC 4.8 . p>
-mrelax code> à la place pour générer des fichiers binaires qui ont les optimisations d'appel où possibles em> mais ne produiront jamais l'erreur. P>
Je couru dans le message d'erreur de troncature de relocalisation et gcc-AVR a passé deux des jours de tri dehors. En bref, il semble y avoir un bogue dans l'éditeur de liens.
Pour une solution rapide, mettre dans votre code dans la zone variable globale. Tu peut-être essayer quelques tailles de tableaux différents. p>
// // rjmp vector table relocation truncation bug // // works when the -mrelax option is not used // // avr-gcc -g -Wall -mrelax pad.c -mmcu=atmega2560 -Wl,-Map -o pad.elf // avr-objdump -h -S pad.elf > pad.list // // avr-gcc --version -> avr-gcc (GCC) 4.7.2 // #include <avr/pgmspace.h> // note, there are other bands of works/fails // // 3884 works // 3886 fails // 3894 fails // 3896 works const char pad[3886] PROGMEM = { 0 }; int main() { int i, j; for (i = 0; 1; i++) j += pad[i]; }
L'utilisation de deux jmp et rjmp est un artefact de l'indicateur de compilateur -mrelax. Entre autres choses, il dit au compilateur d'utiliser des instructions de rjmp lorsque la destination est assez proche (qui est de +/- 4K). Autrement, le compilateur doit utiliser JMP. Ce n'est pas une mauvaise chose, les instructions rjmp exécuter 1 horloge plus rapide et utiliser 2 octets moins de données. p>
Sans -mrelax, le compilateur utilise uniquement des instructions JMP dans le vecteur table et le problème disparaît. BTW, pour nos besoins, est --relax le même que -mrelax. p>
Le problème est que l'éditeur de liens est coinçages en quelque sorte. Au dessus par exemple, lorsque la routine bad_interrupt se trouve à l'adresse 0x1028, le vecteur doit à l'adresse 0x24 devrait se transformer en un jmp, mais l'éditeur de liens ne peut le faire pour une raison quelconque. Elle laisse l'instruction en tant que rjmp avec un décalage de 4098 relative. Comme la plage autorisée est 4096, le décalage serait tronqués à +2, ce qui est une grave erreur p>
La raison pour laquelle "pad [500] PROGMEM = {0};". Si le travail est-il allouera un bloc de mémoire flash entre la table vectorielle et se déplace bad_interrupt () assez loin de la table de vecteur que l'éditeur de liens est même pas tenté d'utiliser une instruction de rjmp. p>
Dans la recherche sur le web, cela semble être un problème chronique avec tous sortes de solutions qui fonctionnent parfois. Populaire utilisent plus / moins constructions et différentes options -lc -lm PStr ( "Bonjour tout le monde"). Je soupçonne ces choses sont trémousse adresses de sous-programme et par aveugle chance, ils tombent dans des endroits que le travail. p>
Voici le code que j'utilisé pour isoler ce bogue. p>
#include <avr/pgmspace.h> const char pad[500] PROGMEM = { 0 };
Bonne réponse. On dirait Le bogue a été corrigé en 2012 .
Je me suis débarrassé des erreurs de réinstallation après une longue lutte
En ajoutant -lm -lc à définir (CUKE_SHARDED_LIBRARY_LINK_CXX_FLAGS "-LM -LC")
Donc, ils seront annexés à la fin par CMKE dans link.txt
mon cmakelists.txt strong> link.txt ressemblerait à. p>
Je l'ai réglé par des règles de dépassement au bas de mon maquillage:
J'ai eu le même problème lors de l'utilisation de MPLAB X IDE et d'AVR-Toolchain pour compiler un programme C court-C pour un ATTINY861. J'ai également utilisé les paramètres -LC -LM dans le menu Linker des propriétés du projet et j'ai trouvé qu'il a fonctionné avec -O0 pour aucune optimisation du compilateur. Un peu plus tard, je pensais qu'aucune optimisation n'est sûre pas idéale et j'ai fait un autre essai avec -O3 - et cela a fonctionné bien! Aucune erreur de relocalisation! P>
Peut-être que cela aide à d'autres examens. Ma connaissance de ce que tout n'est pas profondément, alors j'espère que je ne reviendrai plus cette erreur. P>
-LM code> n'est plus nécessaire dans le récent AVR-GCC Ajout -LM code> tel que proposé dans les autres réponses est pas strong> La solution appropriée pour la version récente d'AVR-GCC ( V4.7.2 Publié 2012 et plus récent). P> Les distributions Toolchain AVR jusqu'à versions V4.6 avaient le problème que Libgcc et AVR-Libc fournissaient des implémentations de flotteurs. Tandis que la mise en œuvre de l'AVR-LIBC est beaucoup plus efficace, elle supposait que les fonctions d'émulation de flotteur sont situées à proximité, de sorte que rcall code> / rcall code> pourrait atteindre les autres fonctions de flotteur même sur des appareils avec des appareils avec tailles flash plus grandes em> 8 kib. Cependant, il n'ya aucune garantie que de telles fonctions de flotteur sont situées à proximité. qui pourrait conduire à des situations où rjmp code> / rcall code> n'a pas pu atteindre leurs objectifs (codés comme relocalisation r_avr_13_pcrel code>). P> Le problème a été aggravé en liant le code de flotteur inefficace de Libgcc (qui n'était pas réellement nécessaire car ces fonctions ont également été fournies par AVR-LIBC). Cela a été corrigé dans V4.7.2: Les fonctions respectives sont exclues de libgcc. //gcc.gnu.org/pr54461 "rel =" nOfollow NOREFERRER "> PR54461 . Vous pouvez voir cela lors de la compilation et de la liaison avec, par exemple AVR-GCC Simple.c -wl, -V -MMCU = ATMEGA8 CODE>. Les options que AVR-GCC transmet à la liaison en lecture: p> xxx pré> ce qui signifie -lm code> est déjà dans le bon endroit et vous pouvez faire référence libgccc Fonctions de la libm et de libc et vice versa. P> Si votre libgcc est livré avec des fonctions de flotteur censées être fournies par AVR-Libc peut être détectée par la commande suivante: p>
avr-objdump -d <INSTALL>/lib/gcc/avr/<VERSION>/libgcc.a | grep __addsf3
Pouvez-vous montrer quelle sortie vous obtenez lorsque vous utilisez le makefile? Je viens d'avoir exactement le même problème et je l'ai résolu en ajoutant le -lm (mais non -LC) à. Je ne l'ai ajouté qu'à la fin de la ligne pour la cible .OFE dans le maquillage.
Êtes-vous sûr que vous n'êtes pas simplement à court de mémoire? Le 328P a un espace de 32 kb, et une partie de celle utilisée par le chargeur de démarrage.