2016-06-18 2 views
0

J'utilise le toolchain bras-aucun-eabi-gcc onlinux et j'ai du mal à créer des archives liées à d'autres archives. A titre d'exemple spécifique, l'archive de base (libstm32f4_hal.a) doit avoir une fonction HAL_SPI_GetState et en utilisant nm, il semble qu'il neComment éviter les symboles indéfinis lorsque je lie des bibliothèques les unes contre les autres avec arm-none-eabi-ar

$ nm libstm32f4_hal.a 
stm32f4xx_hal_spi.o: 
... 
0000158d T HAL_SPI_GetState 
00001495 T HAL_SPI_IRQHandler 
00000271 T HAL_SPI_Init 
... 

Je veux donc faire une autre archive (libstm32f4_bsp.a) qui utilise libstm32f4_hal.a. La deuxième archive semble se construire correctement, mais lorsque j'essaie de lier ces bibliothèques, l'éditeur de liens renvoie l'erreur suivante.

cube/Drivers/BSP/STM32F4-Discovery/libstm32f4_bsp.a(stm32f4_discovery.o): In function `SPIx_Init': 
cube/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.c:313: undefined reference to `HAL_SPI_GetState' 

Quand je vérifie libstm32f4_bsp.a en utilisant nm, en effet la fonction HAL_SPI_GetState n'est pas définie.

$ nm libstm32f4_bsp.a 
stm32f4_discovery.o: 
... 
     U HAL_SPI_GetState 
     U HAL_SPI_Init 
... 

Voici le fichier Make que j'utilise pour créer la deuxième archive.

CC=arm-none-eabi-gcc 
AR=arm-none-eabi-ar 

HAL_DIR = ../../STM32F4xx_HAL_Driver 

########################################### 

vpath %.c 

CFLAGS = -g -O2 -Wall 
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork 
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 
CFLAGS += -ffreestanding -nostdlib 

CFLAGS += -I$(HAL_DIR)/Inc 
CFLAGS += -I../../CMSIS/Device/ST/STM32F4xx/Include 
CFLAGS += -I../../CMSIS/Include 

SRCS = stm32f4_discovery.c stm32f4_discovery_accelerometer.c stm32f4_discovery_audio.c 


OBJS = $(SRCS:.c=.o) 

.PHONY: all clean 

all: libstm32f4_bsp.a 

%.o : %.c 
    $(CC) $(CFLAGS) -c -o [email protected] $^ -L$(HAL_DIR) -lstm32f4_hal 

libstm32f4_bsp.a: $(OBJS) 
    $(AR) -rvs [email protected] $(OBJS) 

clean: 
    rm -f $(OBJS) libstm32f4_bsp.a 

Quelqu'un pourrait-il expliquer pourquoi cela pourrait se produire? Je serais heureux de fournir plus de détails, mais je suis relativement inexpérimenté avec ce que j'essaie de faire ici et je ne suis pas complètement sûr de ce qui serait utile. Le contexte est, j'essaye de construire le code de démonstration pour la carte de découverte de STM32F4. Il configure essentiellement la carte pour agir comme une souris USB. Comme la pile USB est énorme, mon plan est de construire la couche d'abstraction matérielle (HAL) en archive, puis de construire le middleware spécifique au tableau en tant qu'archive liée à l'archive HAL, puis dans mon build final, le code de démonstration ces deux archives.

Merci pour l'aide.

EDIT:

Voici le Makefile J'utilise pour construire le projet.

# STM32 Makefile for GNU toolchain and openocd 
# 
# This Makefile fetches the Cube firmware package from ST's' website. 
# This includes: CMSIS, STM32 HAL, BSPs, USB drivers and examples. 
# 
# Usage: 
# make cube  Download and unzip Cube firmware 
# make program  Flash the board with OpenOCD 
# make openocd  Start OpenOCD 
# make debug  Start GDB and attach to OpenOCD 
# make dirs  Create subdirs like obj, dep, .. 
# make template  Prepare a simple example project in this dir 
# 
# Copyright 2015 Steffen Vogel 
# License http://www.gnu.org/licenses/gpl.txt GNU Public License 
# Author Steffen Vogel <[email protected]> 
# Link  http://www.steffenvogel.de 
# 
# edited for the STM32F4-Discovery 

# A name common to all output files (elf, map, hex, bin, lst) 
TARGET  = demo 

# Take a look into $(CUBE_DIR)/Drivers/BSP for available BSPs 
BOARD  = STM32F4-Discovery 
BSP_BASE = stm32f4_discovery 

OCDFLAGS = -f board/stm32f4discovery.cfg 
GDBFLAGS = 

#EXAMPLE = Templates 
EXAMPLE = Demonstrations 

# MCU family and type in various capitalizations o_O 
MCU_FAMILY = stm32f4xx 
MCU_LC  = stm32f401xc 
MCU_MC  = STM32F407xx 
MCU_UC  = STM32F407VG 




# Your C files from the /src directory 
SRCS  = main.c 
SRCS  += system_$(MCU_FAMILY).c 
SRCS  += stm32f4xx_it.c 

# Basic HAL libraries 
#SRCS  += stm32f4xx_hal_rcc.c stm32f4xx_hal_rcc_ex.c stm32f4xx_hal.c stm32f4xx_hal_cortex.c stm32f4xx_hal_gpio.c $(BSP_BASE).c 

# USB .c 
SRCS  += usbd_conf_template.c usbd_core.c usbd_ctlreq.c usbd_ioreq.c 
SRCS  += usbd_hid.c 
SRCS  += usbd_desc.c 
SRCS  += stm32f4xx_hal_pcd.c 

SRCS  += stm32f4_discovery_accelerometer.c stm32f4xx_hal_tim.c 

# Directories 
OCD_DIR = /usr/share/openocd/scripts 

CUBE_DIR = cube 

BSP_DIR = $(CUBE_DIR)/Drivers/BSP/$(BOARD) 
HAL_DIR = $(CUBE_DIR)/Drivers/STM32F4xx_HAL_Driver 
CMSIS_DIR = $(CUBE_DIR)/Drivers/CMSIS 

DEV_DIR = $(CMSIS_DIR)/Device/ST/STM32F4xx 

CUBE_URL = http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stm32cubef4.zip 

# that's it, no need to change anything below this line! 

############################################################################### 
# Toolchain 

PREFIX  = arm-none-eabi 
CC   = $(PREFIX)-gcc 
AR   = $(PREFIX)-ar 
OBJCOPY = $(PREFIX)-objcopy 
OBJDUMP = $(PREFIX)-objdump 
SIZE  = $(PREFIX)-size 
GDB  = $(PREFIX)-gdb 

OCD  = openocd 

############################################################################### 
# Options 

# Defines 
DEFS  = -D$(MCU_MC) -DUSE_HAL_DRIVER 

# Debug specific definitions for semihosting 
DEFS  += -DUSE_DBPRINTF 

# Include search paths (-I) 
INCS  = -Itemplate/inc 
INCS  += -I$(BSP_DIR) 
INCS  += -I$(CMSIS_DIR)/Include 
INCS  += -I$(DEV_DIR)/Include 
INCS  += -I$(HAL_DIR)/Inc 

# USB .h 
INCS  += -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Inc 
INCS  += -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc 

# Library search paths 
LIBS  = -L$(CMSIS_DIR)/Lib 

# Compiler flags 
CFLAGS  = -Wall -g -std=c99 -Os 
CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb 
CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard 
CFLAGS += -ffunction-sections -fdata-sections 
CFLAGS += $(INCS) $(DEFS) 

CFLAGS += -mthumb-interwork 

# Linker flags 
LDFLAGS = -Wl,--gc-sections -Wl,-Map=$(TARGET).map $(LIBS) -Ttemplate/$(MCU_LC).ld 

# Enable Semihosting 
LDFLAGS += --specs=rdimon.specs -lc -lrdimon 

# Source search paths 
VPATH  = ./template/src 
VPATH  += $(BSP_DIR) 
VPATH  += $(HAL_DIR)/Src 
VPATH  += $(DEV_DIR)/Source/ 

VPATH  += $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src 
VPATH  += $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src 

OBJS  = $(addprefix template/obj/,$(SRCS:.c=.o)) 
DEPS  = $(addprefix template/dep/,$(SRCS:.c=.d)) 

# Prettify output 
V = 0 
    Q = @ 
    P = > /dev/null 
endif 

################################################### 

.PHONY: all dirs program debug template clean 

all: $(TARGET).elf 

-include $(DEPS) 

dirs: template/dep template/obj cube 
template/dep template/obj template/src template/inc: 
    @echo "[MKDIR] [email protected]" 
    $Qmkdir -p [email protected] 

template/obj/%.o : %.c | dirs 
    @echo "[CC]  $(notdir $<)" 
    $Q$(CC) $(CFLAGS) -c -o [email protected] $< -MMD -MF template/dep/$(*F).d -L$(HAL_DIR) -lstm32f4_hal -L$(BSP_DIR) -lstm32f4_bsp 

$(TARGET).elf: $(OBJS) 
    @echo "[LD]  $(TARGET).elf" 
    $Q$(CC) $(CFLAGS) $(LDFLAGS) template/src/startup_$(MCU_LC).s $^ -o [email protected] -L$(HAL_DIR) -lstm32f4_hal -L$(BSP_DIR) -lstm32f4_bsp 
    @echo "[OBJDUMP] $(TARGET).lst" 
    $Q$(OBJDUMP) -St $(TARGET).elf >$(TARGET).lst 
    @echo "[SIZE] $(TARGET).elf" 
    $(SIZE) $(TARGET).elf 

openocd: 
    $(OCD) -s $(OCD_DIR) $(OCDFLAGS) 

program: all 
    $(OCD) -s $(OCD_DIR) $(OCDFLAGS) -c "program $(TARGET).elf verify reset" 

debug: 
    @if ! nc -z localhost 3333; then \ 
     echo "\n\t[Error] OpenOCD is not running! Start it with: 'make openocd'\n"; exit 1; \ 
    else \ 
     $(GDB) -ex "target extended localhost:3333" \ 
      -ex "monitor arm semihosting enable" \ 
      -ex "monitor reset halt" \ 
      -ex "load" \ 
      -ex "monitor reset init" \ 
      $(GDBFLAGS) $(TARGET).elf; \ 
    fi 

cube: 
    rm -fr $(CUBE_DIR) 
    wget -O /tmp/cube.zip $(CUBE_URL) 
    unzip /tmp/cube.zip 
    mv STM32Cube* $(CUBE_DIR) 
    chmod -R u+w $(CUBE_DIR) 
    rm -f /tmp/cube.zip 

template: cube template/src template/inc 
    cp -ri $(CUBE_DIR)/Projects/$(BOARD)/$(EXAMPLE)/Src/* template/src 
    cp -ri $(CUBE_DIR)/Projects/$(BOARD)/$(EXAMPLE)/Inc/* template/inc 
    cp -i $(DEV_DIR)/Source/Templates/gcc/startup_$(MCU_LC).s template/src 
    cp -i $(CUBE_DIR)/Projects/$(BOARD)/$(EXAMPLE)/TrueSTUDIO/STM32F4-DISCO/$(MCU_UC)_FLASH.ld template/$(MCU_LC).ld 

clean: 
    @echo "[RM]  $(TARGET).elf"; rm -f $(TARGET).elf 
    @echo "[RM]  $(TARGET).map"; rm -f $(TARGET).map 
    @echo "[RM]  $(TARGET).lst"; rm -f $(TARGET).lst 
    @echo "[RMDIR] template/dep"   ; rm -fr template/dep 
    @echo "[RMDIR] template/obj"   ; rm -fr template/obj 

rm: 
    rm -rf template 
ifeq ($V, 0) 

Voici la commande de liaison défaillante.

`arm-none-eabi-gcc -Wall -g -std=c99 -Os -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Itemplate/inc -Icube/Drivers/BSP/STM32F4-Discovery -Icube/Drivers/CMSIS/Include -Icube/Drivers/CMSIS/Device/ST/STM32F4xx/Include -Icube/Drivers/STM32F4xx_HAL_Driver/Inc -Icube/Middlewares/ST/STM32_USB_Device_Library/Core/Inc -Icube/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc -DSTM32F407xx -DUSE_HAL_DRIVER -DUSE_DBPRINTF -mthumb-interwork -Wl,--gc-sections -Wl,-Map=demo.map -Lcube/Drivers/CMSIS/Lib -Ttemplate/stm32f401xc.ld --specs=rdimon.specs -lc -lrdimon template/src/startup_stm32f401xc.s template/obj/main.o template/obj/system_stm32f4xx.o template/obj/stm32f4xx_it.o template/obj/usbd_conf_template.o template/obj/usbd_core.o template/obj/usbd_ctlreq.o template/obj/usbd_ioreq.o template/obj/usbd_hid.o template/obj/usbd_desc.o template/obj/stm32f4xx_hal_pcd.o template/obj/stm32f4_discovery_accelerometer.o template/obj/stm32f4xx_hal_tim.o -o demo.elf -Lcube/Drivers/STM32F4xx_HAL_Driver -lstm32f4_hal -Lcube/Drivers/BSP/STM32F4-Discovery -lstm32f4_bsp' 

J'ai chargé le projet GitHub here au cas où quelqu'un est assez motivé pour essayer de construire le projet eux-mêmes. En remarque, je cours Arch Linux.

+1

Si c'est le fichier makefile de la bibliothèque qui a été compilé avec succès, quelle est la commande makefile/build pour la chose qui ne fonctionne pas? – Notlikethat

+0

La compilation de 'libstm32f4_hal.a' et de' libstm32f4_bsp.a' a réussi. Le problème est 'libstm32f4_bsp.a' utilise des fonctions de' libstm32f4_hal.a', mais ces fonctions ne sont pas définies dans 'libstm32f4_bsp.a' (même si la construction s'exécute sans erreur). – user2027202827

+1

Eh bien, oui, vous avez construit deux bibliothèques distinctes, dont l'une dépend de l'autre. D'où l'intérêt de savoir si le _third_ chose est réellement en train de se lier avec les deux, et [dans le bon ordre] (http://stackoverflow.com/a/24675715/1356926) pour démarrer. – Notlikethat

Répondre

2

Votre commande a échoué était quelque chose comme

arm-none-eabi-gcc ...-mcpu=cortex-m4 .. template/obj/main.o \ 
-lstm32f4_hal ... -lstm32f4_bsp 

Et votre archive a libstm32f4_hal.a fonction HAL_SPI_GetState définie, et cette fonction est utilisée par libstm32f4_bsp.a archive. Donc, vous avez un mauvais ordre des archives dans votre commande de liaison. Vous devez savoir que linker (ld, qui est habituellement appelé par gcc à faire l'étape de liaison réelle) fonctionne sur les archives d'entrée (.a fichiers) de gauche à droite, consulter la page man de ld(1) à http://linux.die.net/man/1/ld

Normally, an archive is searched only once in the order that it is specified on the command line.

Vous pouvez essayez de changer l'ordre des archives hal et bsp (-lstm32f4_bsp ... -lstm32f4_hal), mais si cela échoue aussi, alors vous avez une dépendance circulaire.Vous pouvez mentionner les bibliothèques à plusieurs reprises dans la commande de liaison (-lstm32f4_bsp ... -lstm32f4_hal -lstm32f4_bsp), ou tout simplement demander à linker itérer sur sublist des archives avec -( et -) ou --start-group et --end-groupoptions de l'éditeur de liens, comme décrit dans l'homme et dans https://stackoverflow.com/a/5651895/196561. Les options doivent être placées autour de vos bibliothèques avec des dépendances circulaires: --start-group -lstm32f4_bsp ... -lstm32f4_hal --end-group

Description complète d'options de la man page of ld

-(archives -) --start-group archives --end-group

The archives should be a list of archive files. They may be either explicit file names, or -l options.

The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.

Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.

Lorsque vous utilisez gcc pour appeler éditeur de liens, utilisez le préfixe -Wl, pour passer des options de liaison, si votre gcc ne les reconnaît pas: -Wl,--start-group -lstm32f4_bsp ... -lstm32f4_hal -Wl,--end-group

Lorsque vous utilisez shell/faire, vous devrez peut-être citer ( et ) en variante courte d'options, par exemple avec des guillemets simples: '-Wl,-(' -lstm32f4_bsp ... -lstm32f4_hal '-Wl,-)'

+0

Vous avez peut-être raison concernant l'ordre de liaison. J'ai essayé toutes les modifications que vous avez suggérées mais j'ai toujours des erreurs. Je dois aller me coucher tout de suite, mais j'espère y jeter un autre coup d'oeil demain. Merci d'essayer d'aider. J'ai posté le projet sur github au cas où vous voudriez essayer de le construire vous-même: https://github.com/hobenkr88/ArmUsb – user2027202827

+0

Ok, j'ai réussi à passer '-Wl, - start-group -lstm32f4_bsp .... ... -Wl, - groupe de fin ». J'ai aussi fait comme suggéré dans un autre commentaire et passé les archives sous la forme 'ABAB' qui vérifiait que vous aviez raison de me faire inverser l'ordre dans lequel je passais mes archives. Malheureusement, j'ai toujours un problème de liaison mais il a pris la question Dans une direction différente de ce que j'ai demandé, je finirai probablement par poser une nouvelle question pour répondre à cette question car ajouter à cette question serait une source de confusion pour quiconque ayant des problèmes similaires. Merci de votre aide. – user2027202827