链接脚本文件,用于控制链接过程。以stm32在Linux环境下编译作为示例,项目链接git库地址:
tangquan/test.ld_file.proghttps://gitee.com/tq797/test.ld_file.prog
各种原因,视频参考教程的地址在文件startup_stm32f401xc.c里面。Makefile语法参考文章:
【Linux开发】一个小规模工程的Makefile模板_欢迎光临-CSDN博客本Makefile适用于小规模软件工程。修改SOURCE_PATH变量设置源码路径,修改BINARY_PATH变量设置输出文件的路径,OBJECT_PATH变量为中间.o文件的存放目录,INCLUDE_PATH变量为头文件包含路径,TARGET变量为输出文件名。Makefile会输出依赖关系文件“xxx.o.d”,以便根据依赖关系只进行必要的编译工作。# GNU的make工作时的执行步骤如下...https://blog.csdn.net/tq384998430/article/details/100087283?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163489021416780274187536%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163489021416780274187536&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-3-100087283.pc_v2_rank_blog_default&utm_term=makefile&spm=1018.2226.3001.4450ARM处理器的裸机代码编译可以使用armcc编译器(MDK,收费)或者gcc编译器(免费)。我使用的是arm-none-eabi-gcc,百度一下就能下载。交叉编译器的命名规则比较迷,这里arm表示处理器架构,none表示未指定制造商,eabi表示遵循嵌入式应用二进制接口标准,未指定操作系统。链接脚本的语法参考视频教程。
Makefile:
PROJECT = bare_metal_arm
TARGET = $(PROJECT)
TARGET_ELF = $(PROJECT).elf
TARGET_BIN = $(PROJECT).bin
TARGET_HEX = $(PROJECT).hex
TARGET_MAP = $(PROJECT).map
MACH = cortex-m4
ROOT_DIR = .
OBJ_DIR = $(ROOT_DIR)/obj
OUT_DIR = $(ROOT_DIR)/out
SOURCE_PATH ?= $(ROOT_DIR)
OBJECT_PATH ?= $(OBJ_DIR)
INCLUDE_PATH :=
LINKER_SCRIPT = $(ROOT_DIR)/link.ld
LINKER_SPECS = nano.specs
SOURCES := $(foreach tmp,$(SOURCE_PATH),$(wildcard $(tmp)/*.c $(tmp)/*.cpp))
OBJECTS := $(addsuffix .o,$(addprefix $(OBJECT_PATH)/,$(basename $(notdir $(SOURCES)))))
DEPENDS := $(addsuffix .d,$(OBJECTS))
# $(info SOURCES: $(SOURCES))
# $(info OBJECTS: $(OBJECTS))
# $(info DEPENDS: $(DEPENDS))
CC := arm-none-eabi-gcc
# LD := arm-none-eabi-ld
LD := arm-none-eabi-gcc # use gcc as the linker which can automatically find the dependent libraries
OBJCOPY := arm-none-eabi-objcopy
CFLAGS := -c -mcpu=$(MACH) -mthumb -std=gnu11 -Wall -O0
# CFLAGS += -ffunction-sections
LDFLAG := -mcpu=$(MACH) -mthumb -T link.ld -Wl,-Map=$(OUT_DIR)/$(TARGET_MAP) --specs=$(LINKER_SPECS) -mfloat-abi=soft
# LDFLAG += -Wl,--gc-sections
# LDFLAG += -L/c/gcc-arm-none-eabi-10.3/arm-none-eabi/lib
# LDFLAG += -L/c/gcc-arm-none-eabi-10.3/lib/gcc/arm-none-eabi/10.3.1
all : $(TARGET_ELF)
$(info Build "$(PROJECT)" finished)
$(TARGET_ELF): $(OBJECTS)
# $(info LD $@)
$(LD) $(LDFLAG) -o $(OUT_DIR)/$@ $^
$(OBJCOPY) -O binary -R .note -R .comment -S $(OUT_DIR)/$@ $(OUT_DIR)/$(TARGET_BIN)
-include $(DEPENDS)
$(foreach tmp,$(SOURCES),\
$(eval $(addprefix $(OBJECT_PATH)/,$(addsuffix .o,$(basename $(notdir $(tmp))))):; \
${CC} ${CFLAGS} $(INCLUDE_PATH) \
-MMD -MF $(OBJECT_PATH)/$(basename $(notdir $(tmp))).o.d \
-c -o $(OBJECT_PATH)/$(basename $(notdir $(tmp))).o $(tmp)))
.PHONY : clean setenv
clean:
rm *.o ${TARGET}.* obj/* out/* -rf
linker script file:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20005000; /* end of 20K RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x100; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH(rx):ORIGIN =0x08000000,LENGTH =64K
SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
_exit = _etext;
}> FLASH
_la_data = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .;
}> SRAM AT> FLASH
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
}> SRAM
PROVIDE ( end = _ebss ); /* head starts after the .bss section */
PROVIDE ( _end = _ebss );
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >SRAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}
编译出来的文件:
?bin文件就可以下载到MCU中去,segger j-flash有linux版本:
SEGGER - The Embedded Experts - Downloads - J-Link / J-Tracehttps://www.segger.com/downloads/jlink/使用JFlash命令可以打开UI界面,和windows上的j-flash是一样的:
?下载运行,使用的是STM32F401CCU,没有找到openocd的合适的脚本,没有进行调试验证。
|