使用GCC新建工程的好处是windows 与 linux 系统无需更改项目,都能进行编译
进入GNU Arm Embedded Toolchain Downloads ,下载gcc-arm-none-eabi-10-2020-q4-major-win32.exe
下载完毕安装后,将安装路径 D:\GNU Arm Embedded Toolchain\10 2020-q4-major\bin (根据你的安装安装路径) 添加到系统变量,打开命令行工具,输入命令 arm-none-eabi-g++.exe -v 出现如图版本号信息,表示arm-gcc安装成功
Target: arm-none-eabi
Configured with: /mnt/workspace/workspace/GCC-9-pipeline/jenkins-GCC-9-pipeline-100_20191030_1572397542/src/gcc/configure --…
…
Thread model: single
gcc version 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] (GNU Tools for Arm Embedded Processors 9-2019-q4-major)
PS C:\Users>
make: *** No targets specified and no makefile found. Stop.
# 项目名称,编译生成的 hex和bin名称
TARGET = Demo
# 是否会进行调试
DEBUG = 1
# optimization ## 选择优化等级,优化等级低->高,可参考Keil的设置,如果程序运行不理想,优化程序或降低优化等级
#OPT = -O0 ## 没有优化。
#OPT = -O1 ## 编译器试图减少代码大小和执行时间,而不执行任何花费大量编译时间的优化。
OPT = -Og ## 参数 -Og 是在 -O1 的基础上,去掉了那些影响调试的优化告诉编译器,编译后的代码不要影响调试,但调试信息的生成还是靠 -g 参数的。
#OPT = -O2 ## 更加优化。GCC执行几乎所有支持的优化,不涉及空间速度权衡。此选项既增加编译时间,提高了生成代码的性能。
#OPT = -O3 ## 优化更多。
#OPT = -Os ## 优化大小。启用所有优化,除了那些经常增加代码大小
#OPT = -Ofast ## 不遵守严格的标准。使所有优化。它还支持并非对所有符合标准的程序都有效的优化。
# Build path ## Build编译产生的文件存放目录 , Output生成hex与bin的存放位置
BUILD_DIR = Build
OUT_DIR = Output
# source ## 检索项目目录下的c文件的,注意C大小写
C_SOURCES := $(wildcard */*/*/*/*/*/*/*.c) \
$(wildcard */*/*/*/*/*/*.c) \
$(wildcard */*/*/*/*/*.c) \
$(wildcard */*/*/*/*.c) \
$(wildcard */*/*/*.c) \
$(wildcard */*/*.c) \
$(wildcard */*.c)
# ASM sources ## 检索项目目录下的s汇编文件的,注意s是小写
ASM_SOURCES := $(wildcard */*/*/*/*/*/*/*.s) \
$(wildcard */*/*/*/*/*/*.s) \
$(wildcard */*/*/*/*/*.s) \
$(wildcard */*/*/*/*.s) \
$(wildcard */*/*/*.s) \
$(wildcard */*/*.s) \
$(wildcard */*.s)
# C includes ## 添加 h头文件的 Include路径,格式 -I + 路径,添加文件夹注意在此添加include
C_INCLUDES = \
-Isrc\User \
-Isrc\Libraries\CMSIS\CoreSupport \
-Isrc\Libraries\CMSIS\DeviceSupport \
-Isrc\Libraries\STM32F10x_StdPeriph_Driver\inc \
# AS includes ## 添加 汇编的 Include路径,格式 -I + 路径,添加文件夹注意在此添加include
AS_INCLUDES =
# C defines ## 添加全局 Define ,std库参照stm32f10x.h,换芯片需更换 宏定义,格式 -D + dd
C_DEFS = \
-DSTM32F10X_HD \
-DUSE_STDPERIPH_DRIVER \
# link script ## 添加 ld链接 文件,注意路径
LDSCRIPT = STM32F103ZETx_FLASH.ld
# cpu ## 参照 stm32cube
CPU = -mcpu=cortex-m3
# fpu
# NONE for Cortex-M0/M0+/M3
# float-abi
# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
# macros for gcc
# AS defines
AS_DEFS =
#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(OUT_DIR)/$(TARGET).hex $(OUT_DIR)/$(TARGET).bin
#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(OUT_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(OUT_DIR)
$(HEX) $< $@
$(OUT_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(OUT_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir $@
$(OUT_DIR):
mkdir $@
#######################################
# clean up
#######################################
clean:
-rm -fR $(BUILD_DIR)
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20010000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
打开命令行,进入项目目录Demo,输入命令make,出现下列错误
C:\416: Error: registers may not be the same -- `strexb r0,r0,[r1]'
C:\436: Error: registers may not be the same -- `strexh r0,r0,[r1]'
打开src\Libraries\CMSIS\CoreSupport\core_cm3.c文件,将 736行,753行 中的 “=r"修改为”=&r",如下
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
arm-none-eabi-size Build/Demo.elf
text data bss dec hex filename
948 8 1568 2524 9dc Build/Demo.elf
arm-none-eabi-objcopy -O ihex Build/Demo.elf Output/Demo.hex
arm-none-eabi-objcopy -O binary -S Build/Demo.elf Output/Demo.bin
JTAG
JTAGConf -1 -1
speed 4000
device STM32F103ZE
r
h
loadfile "./Output/Demo.hex"
r
g
qc
"C:\Program Files (x86)\SEGGER\JLink_V620a\JLink.exe" ".\jlink_config"