(arm-none-eabi-gcc + GNU make + Makefile +嵌入式单片机)环境搭建篇(linux+windows)

一. Linux篇

linux下自带GNU make,所以只需要安装arm-none-eabi-gcc和Jlink驱动就可以了

1,arm-none-eabi-gcc下载及安装

在我这篇博文有记录:
在Linux Ubnutu下安装arm-none-eabi-gcc及所必须的各种依赖包

2,Jlink驱动下载及安装

官网下载链接:
https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack
在这里插入图片描述
官网下载太慢,附网盘链接如下:
JLink_Linux_V688a_x86_64.deb
链接:https://pan.baidu.com/s/11YnBjWtl9L9V7YCQABC60Q
提取码:ysgp

下载好之后执行指令:sudo dpkg -i JLink_Linux_V688a_x86_64.deb
即可安装完成,但目前只能用通用的ST系列等芯片,如果使用国产芯片的话还需要以下几个操作以便让JLink能识别你的芯片型号
(1) 从芯片供应商或者官网获取.FLM文件,例如
在这里插入图片描述

(2) 在JLink的Device建立以你的芯片厂商命名的文件夹,然后将你所有的.FLM文件移动进去,最后给予这些.FLM文件777权限(必须的),例如:
sudo mkdir /opt/SEGGER/JLink/Device/FM
sudo chmod 777 /opt/SEGGER/JLink/Device/FM/*
最终结果如下图:
在这里插入图片描述
(3) 修改/opt/SEGGER/JLink/下的JLinkDevices.xml文件,以FM的芯片为例,加入以下内容:

  <!--                -->
  <!-- FMSH Devices -->
  <!--                -->
  <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33A02xx"   WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x20000" Loader="Devices/FM/FM33A0XX_FLASH128.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
  <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33A03xx"   WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x30000" Loader="Devices/FM/FM33A0XX_FLASH192.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
  <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33A04xx"   WorkRAMAddr="0x20000000" WorkRAMSize="0x8000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x40000" Loader="Devices/FM/FM33A0XX_FLASH256.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
  <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33A05xx"   WorkRAMAddr="0x20000000" WorkRAMSize="0xC000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x60000" Loader="Devices/FM/FM33A0XX_FLASH384.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
    <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33A06xx"   WorkRAMAddr="0x20000000" WorkRAMSize="0x10000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x80000" Loader="Devices/FM/FM33A0XX_FLASH512.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
   <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33G02x"   WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x20000" Loader="Devices/FM/FM33G02X_FLASH128.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
   <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33G04x"   WorkRAMAddr="0x20000000" WorkRAMSize="0x6000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x40000" Loader="Devices/FM/FM33G04X_FLASH256.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
   <Device>
    <ChipInfo Vendor="FMSH Devices" Name="FM33LC02X"   WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash Block " BaseAddr="0x00000000" MaxSize="0x20000" Loader="Devices/FM/FM33LC02X_FLASH128.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>

注意不要在”DataBase“之前加
在这里插入图片描述
到这里环境就搭完了,写好Makefile后就可以正常的烧写和仿真了

3,仿真调试教程

仿真需要用到vscode及厂商提供的.svd文件

(1) vscode下载插件cortex debug插件

在这里插入图片描述

(2) 创建launch.json文件

如下图所示:
在这里插入图片描述
然后选择Cotrex Debug即可创建好launch.json文件
在这里插入图片描述

(3) 配置launch.json文件

稍微按照自己的芯片修改下就好,以FM33LC026为例:
在这里插入图片描述
然后将厂商提供的.svd文件放到你的工程根目录即可开始仿真,可以看变量、看外设寄存器、内核寄存器等等,还可以保存你的断点等。

至此linux下的环境就搭建完成,以下附录一个通用Makefile写法,换芯片的时候只需要将里面需要用户修改的地方按照自己的芯片稍微一修改即可投入使用。

4,通用Makefile示例

此Makefile可自动识别你的工程里的所有.c文件,自动包含你的所有头文件,不用在指定头文件路径。

使用方法:
1,根目录下执行make指令,即可编译出.hex .bin .elf文件
2,执行make clean,可清除.o .d文件
3,执行make cleanAll,可清除.o .d .hex .bin .elf文件
4,执行make download,可一键下载hex到目标板子并让板子复位运行,相当于keil的一键下载按钮
5,执行make commit,可一键推送到你的github或者giteee远程服务器上去,但前提是你自己创建了这个工程的git

#*************************************************************************
#  **
#  ** File         : Makefile
#  ** Abstract     : This is the introduction to the document
#  ** Author       : wr
#  ** mail         : [email protected]
#  ** Created Time : 2020年11月22日 星期日 11时58分06秒
#  ** copyright    : COPYRIGHT(c) 2020
#  **
#  ************************************************************************/

#当由用户传入的参数V等于1时,条件为真,输出编译信息,当V不等于1时禁止信息
ifneq ($(V),1)
Q := @
else
Q :=
endif

################################以下项目需用户根据需要更改##########################
# 输出文件的名称,默认为main(main.elf main.bin main.hex)
TARGET := main

#链接文件名称和所在路径
LDSCRIPT := \
./libraries/FM/Drivers/CMSIS/Device/FM/FM33xx/Source/Templates/gcc/fm33lc02x_flash.ld

#启动文件名称和所在路径
START_FILE_SOURCES := \
./libraries/FM/Drivers/CMSIS/Device/FM/FM33xx/Source/Templates/gcc/startup_fm33lc0xx.s

#内核选择,FPU, FLOAT-ABI可为空
CPU       := -mcpu=cortex-m0
FPU       :=
FLOAT-ABI :=

#系统宏定义
C_DEFS    := \
-DFM33LC0XX \
-DUSE_FULL_ASSERT \
-D_DLIB_FILE_DESCRIPTOR

# 芯片型号,用于Jlink仿真调试、下载
CHIP      := FM33LC02X

# 选择优化等级:
# 1. gcc中指定优化级别的参数有:-O0、-O1、-O2、-O3、-Og、-Os、-Ofast。
# 2. 在编译时,如果没有指定上面的任何优化参数,则默认为 -O0,即没有优化。
# 3. 参数 -O1、-O2、-O3 中,随着数字变大,代码的优化程度也越高,不过这在某种意义上来说,也是以牺牲程序的可调试性为代价的。
# 4. 参数 -Og 是在 -O1 的基础上,去掉了那些影响调试的优化,所以如果最终是为了调试程序,可以使用这个参数。不过光有这个参数也是不行的,这个参数只是告诉编译器,编译后的代码不要影响调试,但调试信息的生成还是靠 -g 参数的。
# 5. 参数 -Os 是在 -O2 的基础上,去掉了那些会导致最终可执行程序增大的优化,如果想要更小的可执行程序,可选择这个参数。
# 6. 参数 -Ofast 是在 -O3 的基础上,添加了一些非常规优化,这些优化是通过打破一些国际标准(比如一些数学函数的实现标准)来实现的,所以一般不推荐使用该参数。
# 7. 如果想知道上面的优化参数具体做了哪些优化,可以使用 gcc -Q --help=optimizers 命令来查询,比如下面是查询 -O3 参数开启了哪些优化:
OPT       := -Og

# 是否将debug信息编译进.elf文件,默认打开
DEBUG     := 1

# 输出文件夹,.hex .bin .elf放在此文件夹下,.o .d文件放在此文件的子目录Obj下(自动创建)
BUILD     := ./build
###################################用户修改结束###################################


# 以下与系统相关,用于支持JLink下载和仿真
# linux 执行make download的时候不用带参数,windows下需要带SYS=1,用以支持Jlink
ifneq ($(SYS), 1)
JLINKEXE       := JLinkExe
JLINKGDBSERVER := JLinkGDBServer
else
JLINKEXE       := JLink.exe
JLINKGDBSERVER := JLinkGDBServer.exe
endif

# 编译器定义
CC      := arm-none-eabi-gcc
SZ      := arm-none-eabi-size
OBJCOPY := arm-none-eabi-objcopy
GDB     := arm-none-eabi-gdb
BIN     := $(OBJCOPY) -O binary -S
HEX     := $(OBJCOPY) -O ihex

#################### CFLAGS Config Start ##########################
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

#搜索所有的h文件,并输出携带-I的.h文件路径
C_INCLUDES := $(addprefix -I,$(sort $(dir $(shell find ./ -type f -iname "*.h"))))

#编译参数
CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -fdata-sections -ffunction-sections
#开关警告
CFLAGS += -Wall #-W 
#标准
CFLAGS += -std=c99

#当开启DEBUG功能时携带DEBUG参数
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif

#自动生成依赖文件
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
#################### CFLAGS Config End ##########################

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
#链接指令集-specs=nosys.specs
LDFLAGS = $(MCU) -T$(LDSCRIPT) -specs=nano.specs $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD)/Obj/$(TARGET).map,--cref
#是否开启优化掉未使用的函数和符号
LDFLAGS += -Wl,--gc-sections

#制作启动文件依赖Obj,输出去掉路径的.o文件,可兼容.s和.S
START_FILE_OBJ     = $(addsuffix .o, $(basename $(notdir $(START_FILE_SOURCES))))
OBJECTS            = $(addprefix $(BUILD)/Obj/, $(START_FILE_OBJ))

#搜索所有的c文件,制作所有的.c文件依赖Obj
C_SOURCES          = $(shell find ./ -type f -iname "*.c")
OBJECTS           += $(addprefix $(BUILD)/Obj/,$(notdir $(C_SOURCES:%.c=%.o)))
#PS:去掉终极目标的原始路径前缀并添加输出文件夹路径前缀(改变了依赖文件的路径前缀,需要重新指定搜索路径)

#指定makefile搜索文件的路径(假如终极目标的依赖文件不携带.c文件所在的路径,
#且不指定搜索路径,makefile会报错没有规则制定目标)
vpath %.c $(sort $(dir $(C_SOURCES)))  #取出路径并去重和排序(以首字母为单位)
vpath %.s $(dir $(START_FILE_SOURCES))
vpath %.S $(dir $(START_FILE_SOURCES))


#指定为伪目标跳过隐含规则搜索,提升makefile的性能,并防止make时携带的参数与实际文件重名的问题
.PHONY:all cleanAll clean printf JLinkGDBServer debug download commit

all : $(BUILD)/Obj $(BUILD)/$(TARGET).elf $(BUILD)/$(TARGET).bin $(BUILD)/$(TARGET).hex


#链接所有的.o生成.elf文件
$(BUILD)/$(TARGET).elf : $(OBJECTS) | $(LDSCRIPT)
	$(Q)$(CC) $(LDFLAGS) -o $@ $(OBJECTS)
	$(Q)echo "make $@:"
	$(Q)$(SZ) $@

#编译启动文件  备用参数:#-x assembler-with-cpp
$(BUILD)/Obj/$(START_FILE_OBJ) : $(START_FILE_SOURCES) Makefile
	$(Q) $(CC) -c $(CFLAGS) -x assembler-with-cpp -o $@ $<
	$(Q)echo "buid $(notdir $<)"

#编译工程 备用参数:#-Wa,-a,-ad,-alms=$(BUILD_DIR)/Obj/$(notdir $(<:.c=.lst))
$(BUILD)/Obj/%.o : %.c Makefile
	$(Q) $(CC) -c $(CFLAGS) -o $@ $< 
	$(Q)echo "buid $(notdir $<)"

$(BUILD)/Obj :
	$(Q)mkdir -p $(BUILD)/Obj
	$(Q)echo "mkdir $(BUILD)/Obj"

%.bin : $(BUILD)/$(TARGET).elf
	$(Q) $(BIN) $< $@

%.hex : $(BUILD)/$(TARGET).elf
	$(Q) $(HEX) $< $@

#用于检查链接脚本和启动文件是否存在,不存在则报错误
$(START_FILE_SOURCES):
	$(Q)echo ERROR: The startup file does not exist or has the wrong path !;\
	exit 1
$(LDSCRIPT):
	$(Q)echo ERROR: The link file does not exist or has the wrong path !;\
	exit 2

cleanAll: clean
	$(Q)$(RM) -r build
	$(Q)echo "clean all *.elf *.hex *.bin";

clean:
	$(Q)$(RM) $(shell find ./ -type f -iname "*.o")
	$(Q)$(RM) $(shell find ./ -type f -iname "*.d")
	$(Q)$(RM) $(shell find ./ -type f -iname "*.d.*")
	$(Q)$(RM) $(shell find ./ -type f -iname "*.map")
	$(Q)$(RM) $(shell find ./ -type f -iname "*.gdb")
	$(Q)echo "clean all *.o *.d *.map";

printf:
	$(Q)echo $(info $(LDFLAGS))


JLinkGDBServer:
	$(Q)JLinkGDBServer -select USB -device $(CHIP) \
	-endian little -if SWD -speed 4000 -noir -LocalhostOnly

debug:
	$(Q)make
	$(Q)echo target remote localhost\:2331 > gdb.gdb
	$(Q)echo monitor reset >> gdb.gdb
	$(Q)echo monitor halt >> gdb.gdb
	$(Q)echo load >> gdb.gdb
	$(Q)echo b main >> gdb.gdb
	$(Q)echo - >> gdb.gdb
	$(Q)echo c >> gdb.gdb
	$(Q)-$(GDB) $(BUILD)/$(TARGET).elf --command=gdb.gdb 
	$(Q)$(RM) gdb.gdb

download:
	$(Q)make
	$(Q)echo "h" > jlink.jlink
	$(Q)echo "loadfile" $(BUILD)/$(TARGET).bin >> jlink.jlink
	$(Q)echo "r" >> jlink.jlink
	$(Q)echo "qc" >> jlink.jlink
	$(Q)$(JLINKEXE) -device $(CHIP) -Speed 4000 -IF SWD -CommanderScript jlink.jlink
	$(Q)$(RM) jlink.jlink

commit:
	$(Q)git add .
	$(Q)echo read -p \"Please input git commit explain:\" explain > git.so
	$(Q)echo if test -z \"\$$explain\"\; then explain=\"Daily development submission\"\; fi >> git.so
	$(Q)echo echo \$$explain >> git.so
	$(Q)echo git commit -m \"'$$'explain\" >> git.so
	$(Q)bash ./git.so
	$(Q)$(RM) git.so
	$(Q)git push

include $(wildcard $(BUILD)/Obj/*.d)


一. Windows篇

Windows下安装arm-none-eabi-gcc、MinGW(GNU make)、Jlink驱动这3个即可。

1,arm-none-eabi-gcc下载及安装

官网下载链接:
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

打开网址后找到如下图所示最新版本
gcc-arm-none-eabi-9-2019-q4-major-win32.exe
然后点击就可下载
在这里插入图片描述
下载完成后点击.exe直接一直点下一步就好,千万要记得在最后一布的时候将add path打上勾,默认是不打勾的。
网盘链接如下:
gcc-arm-none-eabi-9-2019-q4-major-win32-sha2.exe
链接:https://pan.baidu.com/s/1GrQLaU9D-vnv_Zpfuj2Ryw
提取码:9w7r

2,Gnu make工具下载及安装

在这里插入图片描述
链接:https://pan.baidu.com/s/1XzjM-H8hhP1t7BIq2zxkeg
提取码:awem

下载好之后解压到D盘根目录,然后将bin文件路径加到环境变量
如下图所示:
在这里插入图片描述

重启后即可生效。
然后结束教程,windwos环境搭好之后其他的基本和linux下一样,写好Makefile后之后正常使用Make指令即可,推荐在git bash里使用make命令,也可以在vs code里将默认终端改成git bash,以后直接打开vs code终端就可以make程序啦。添加方法如下:
打开设置,搜索shell然后点击在settings.json中编辑
在这里插入图片描述
然后换成你的git bash路径就可以啦!
在这里插入图片描述

3,Jlink驱动下载及安装

Jlink驱动的下载及安装同linux版一样,唯一不同的是在官网要选windws版的,如下图:
在这里插入图片描述
同样附上网盘永久链接:
链接:https://pan.baidu.com/s/1BrBuNbxqC-KkcrYdMu7tgA
提取码:7j5w

Jlink驱动下载完成后同样需要做2部分工作

(1) 与Llinux类似,新建FM文件夹,将.FLM文件移动进去,并修改JLinkDevices.xml,修改方法同Linux方法

在这里插入图片描述
在这里插入图片描述

(2) 将Jlink按照自己的文件夹路径加到系统环境变量

在这里插入图片描述
至此下载和仿真环境就搭建好了,windows下要执行一键下载的时候要带上SYS=1才能正常下载噢,如下图:
在这里插入图片描述

仿真的话同样推荐vs code的插件Cortex debug,使用方法同linux一样,最终windows下debug界面如下图所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35333978/article/details/110398968