- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在 Linux 上使用 arm-none-eabi-gcc 工具链,但在创建链接到其他文件的文件时遇到了问题。作为一个具体的例子,基础文件(libstm32f4_hal.a)应该有一个函数HAL_SPI_GetState
并且使用nm
,它似乎有
$ nm libstm32f4_hal.a
stm32f4xx_hal_spi.o:
...
0000158d T HAL_SPI_GetState
00001495 T HAL_SPI_IRQHandler
00000271 T HAL_SPI_Init
...
然后我想制作另一个使用 libstm32f4_hal.a 的存档 (libstm32f4_bsp.a)。第二个存档似乎构建正确,但当我尝试链接这些库时,链接器抛出以下错误。
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'
当我使用 nm
检查 libstm32f4_bsp.a 时,确实未定义函数 HAL_SPI_GetState
。
$ nm libstm32f4_bsp.a
stm32f4_discovery.o:
...
U HAL_SPI_GetState
U HAL_SPI_Init
...
这是我用来构建第二个存档的 makefile。
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 $@ $^ -L$(HAL_DIR) -lstm32f4_hal
libstm32f4_bsp.a: $(OBJS)
$(AR) -rvs $@ $(OBJS)
clean:
rm -f $(OBJS) libstm32f4_bsp.a
有人可以解释为什么会这样吗?我很乐意提供更多详细信息,但我对我在这里尝试做的事情相对缺乏经验,并且我不完全确定还有什么可以提供帮助。
上下文是,我正在尝试为 STM32F4-Discovery 开发板构建演示代码。它基本上将电路板设置为充当 USB 鼠标。由于 USB 堆栈很大,我的计划是将硬件抽象层 (HAL) 构建为存档,然后将特定于板的中间件构建为链接到 HAL 存档的存档,然后在我的最终构建中将演示代码链接到这两个文件。
感谢您的帮助。
编辑:
这是我用来构建项目的 makefile。
# 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 <post@steffenvogel.de>
# 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] $@"
$Qmkdir -p $@
template/obj/%.o : %.c | dirs
@echo "[CC] $(notdir $<)"
$Q$(CC) $(CFLAGS) -c -o $@ $< -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 $@ -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)
这是失败的链接命令。
`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'
我把项目加载到github here以防万一有人有足够的动力尝试自己构建项目。作为旁注,我正在运行 Arch Linux。
最佳答案
你失败的命令是这样的
arm-none-eabi-gcc ...-mcpu=cortex-m4 .. template/obj/main.o \
-lstm32f4_hal ... -lstm32f4_bsp
并且您的 libstm32f4_hal.a
存档定义了函数 HAL_SPI_GetState
,并且此函数由 libstm32f4_bsp.a
存档使用。
因此,您的链接命令中的存档顺序错误。您应该知道链接器(ld
,通常由 gcc 调用以执行实际的链接步骤)从左到右处理输入存档(.a
文件),检查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.
您可以尝试更改 hal 和 bsp 存档的顺序 (-lstm32f4_bsp ... -lstm32f4_hal
),但如果它也失败了,那么您就有了循环依赖。您可能会在链接命令 (-lstm32f4_bsp ... -lstm32f4_hal -lstm32f4_bsp
) 中多次提及库,或者只是指示链接器使用 -(
和-)
或 --start-group
和 --end-group
链接器选项,如 man 和在 https://stackoverflow.com/a/5651895/196561 .这些选项应放置在具有循环依赖性的库周围:--start-group -lstm32f4_bsp ... -lstm32f4_hal --end-group
来自 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.
当您使用 gcc 调用链接器时,如果您的 gcc 无法识别它们,请使用 -Wl,
前缀将选项传递给链接器:-Wl,--start-group - lstm32f4_bsp ... -lstm32f4_hal -Wl,--结束组
当您使用 shell/make 时,您可能需要在选项的简短变体中引用 (
和 )
,例如使用单引号:'-Wl ,-(' -lstm32f4_bsp ... -lstm32f4_hal '-Wl,-)'
关于c - 使用 arm-none-eabi-ar 将库相互链接时如何避免 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37900872/
这里有两个问题: 将共享库移植到许多 Linux-or-Android-on-ARM 系统时,需要知道 GCC 交叉编译器支持的确切 EABI 版本以及默认的 EABI 版本。怎么做? 如何调查哪个
我正在使用 Launchpad Arm 编译器工具。具体来说, arm-none-eabi-g++ 和 arm-none-eabi-gcc 来自: (ARM 嵌入式处理器的 GNU 工具)5.2.1
我正在使用下面的 gcc 工具链。gcc 版本 5.4.1 20160919(发布)[ARM/embedded-5-branch 修订版 240496](用于 ARM 嵌入式处理器的 GNU 工具)
我正在尝试使用arm-none-eabi-gcc为STM32编译一个USB环回示例,但遇到了bool变量的编译器错误。错误为错误:“_Bool”之前应有“;”、标识符或“(”,违规行为 typedef
如果一个 Android 应用程序最初只支持 armeabi-v7a 和 x86,并且在未来它增加了对 arm64-v8a 的支持,设备(主要和次要 ABI 分别是 arm64-v8a 和 armea
我有一个复杂的开源库需要移植到安卓NDK。首先,我需要配置 (./Configure)。我明白:我必须使用/home/user/android-ndk/build/prebuilt/进行交叉编译lin
我们在Android开发中需要ARM EABI v7a系统镜像做什么?该特定图像的目的是什么? 最佳答案 如果您使用 NativeDK,没有该图像,模拟器将无法模拟 ARMv7 代码的执行(如多核指令
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我在 Linux 机器上用 C 语言编写了一个 hello world 程序。编译是使用工具链 arm-none-eabi-gcc 完成的(稍后我将使用它进行交叉编译)。但我想在进一步推进之前在同一台
我有一个视频模块,我正在使用 arm-eabi-gcc 交叉编译器进行编译。我使用以下命令进行编译$ arm-eabi-gcc -O2 -DMODULE -D__KERNEL__ -W -Wall -
我正在为我的 Android 项目运行 arm-eabi-addr2line,我的命令是 /Applications/android-sdk-mac_86/android-ndk-r5b/toolch
我正在尝试在树莓派上安装用于汇编代码的工具链。我使用以下过程来安装包文件: $ wget http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/
我正在通过 arm-unknown-linux-gnueabi 交叉编译我的代码,在编译期间可以看到很多以下警告 Unknown EABI object attribute 44 上面的警告是可以忽略
我正在 64 位 Linux 机器上用 C 编译一个 hello world 程序。我正在使用 GCC ARM 嵌入式工具链在配备 ATMEL AT91SAM9G20 处理器的 FOX G20 V 板
arm-eabi-gcc和arm-elf-gcc有什么区别? 他们可以为cortex-m3 arch编译相同的源代码吗? 最佳答案 arm-elf-gcc是支持旧版浮点加速器(FPA)和混合字节序浮点
我越看这个 PDF ( Application Binary Interface forthe ARM Architecture: The Base Standard ),我就越不明白它的意思。我还想
我正在尝试将“眨眼”示例上载到我的MKR1000。但是,我一直收到相同的错误: fork/exec /Users/username/Library/Arduino15/packages/arduino
我正在尝试在minGW中使用arm-none-eabi-gcc编译HELLOWORLD.c,命令如下: D:\code>arm-none-eabi-gcc hello.c -o hello -shar
我正在尝试为 STM32L030x6 MCU 制作固件。 我编写了一个简单的代码,似乎可以在具有 STM32L030x8 MCU 的评估板上运行。我所说的“似乎有效”是指我能够访问主 fct 并切换
我在库中有一个头文件,其中包括 inttypes.h (使用 PRIu8 等所需)。我将库头文件包含到我自己的应用程序文件中。 当我尝试在lpcxpresso(基于eclipse)中使用arm-non
我是一名优秀的程序员,十分优秀!