完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
# 1.当前教程所需工具和掌握程度
(1.vscode使用了几周,只是作为程序代码编辑器使用,只装了C/C++代码编辑插件,和一个ReUI主题插件,感觉完成vscode+arm-gcc组合编译工作,得了解vscode的外部工具调用方式,即.vscode/launch.json、tasks.json命令配置,(c_cpp_properties.json只是C/C++编辑插件相关)。它俩就是完成自动化的脚本执行重点了。 (2.gcc-arm-none-eabi是被调用的外部工具,是ARM官方提供的ARM架构编译工具链,暂时只用到了其中一个工具arm-none-eabi-gcc.exe,用以编译链接程序源码。实际编译有复杂层次的工程程序代码时,是通过Makefile进行组织的,make工具通过Makefile文件来识别和调用arm-none-eabi-gcc.exe对整个工程进行精细编译链接和管理。 (3.make工具是另一个被调用的外部工具,由GNU提供,有两种方式使用,一是通过mgwin32跨平台的linux工具集软件(好像仍然需要单独下载make工具,只提供操作环境),另一种是直接使用make for windows的make工具(我是用的这的,因为我只需要make不需要其他一堆工具)。由于make基本是直接调用Makefile文件执行的,所以本身不难,难点在于Makefile理解和使用。 # 2.三个工具下载网址 (1.[vscode](Visual Studio Code - Code Editing. Redefined) (2.[gcc-arm-none-eabi](GNU Toolchain | GNU Arm Embedded Toolchain – Arm Developer) (3.[make](GNU make for Windows (equation.com)) (4.vscode直接解压就可以使用,我把启动程序添加到开始磁贴栏里用的。gcc-arm-none-eabi和make也是直接解压到软件盘目录下(我都下载的压缩包文件),不过这两个需要添加启动程序文件所在路径的环境变量(用户环境变量即可),这样才可以全局启动。 可以在win终端窗口里用命令启动测试下是否全局可以启动使用,用 arm-none-eabi-gcc -v 和 make -v测试下,能正常找到和输出软件版本信息说明可以使用。 # 3.编译工程需要的文件 (1.tasks.json { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "dependsOn": "clean", // 依赖项,表示在执行 build 前会首先自动执行 clean ,然后才执行build。 "label": "build", // build任务标签,将出现在vscode的task栏里 "type": "shell", "command": "make", "args": [ //"--file=STM32F4xx_StdPeriph_Templates/GNU-ARM/Makefile", "-j4" // make 工具参数,作用暂时未知,另外还有 -j -j8等。 ], "group": "build", // 作用暂时未知。 "problemMatcher": "$gcc" }, { "label": "clean", // clean任务标签,将出现在vscode的task栏里 "type": "shell", // 默认类型 "command": "make", // 使用工程编译工具是make,它通过Makefile调用arm-gcc进行底层代码编译链接。 "args": [ //"--file=STM32F4xx_StdPeriph_Templates/GNU-ARM/Makefile", // 这是一开始想作为一个独立工程文件夹来使用的,后续会尝试使用 "clean" // 自定义的clean标签,make工具会在Makefile内查找这个自定义标签并执行其代表的实际make指令或者powershell指令。 ], "problemMatcher": "$gcc" // 无影响参数 }, ] } a.这里表示有坑。vscode貌似提供两种任务文件,task.json 和 tasks.json 文件,我理解的是两者分别可以创建单任务和多任务,我按照一篇教程写了单任务的,但是实际是创建了多个任务,貌似因为这个原因导致不能正常打开执行,后续我改为tasks.json使用的。 b.这里表示也有坑。vscode新建*.json文件有两种,一种普通json文件,另一种是json with comments命令脚本文件,这里需要设为json with comments文件作为命令脚本使用,否则不会被识别和执行(我不保证确实有这个区别,记得有一篇博文也提到了这个问题,我按照那个要求修改的) c.还有个坑。整个工程编译过程需要先清理掉旧的编译中间文件,才能进行新的编译,否则一直卡在开头的几个源文件处报错,提示无法找到XXXXX.c文件,依赖于XXXX.elf文件。由于是在Makefile中,后面Makefile详谈。 (2.launch.json { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "ARM Debug", "type": "cppdbg", "request": "launch", // 这个名称需要和前面tasks.json文件的参数保持一致,其他参数在本教程暂时未使用,或者编译过程不受影响。 "miDebuggerPath": "d:/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gdb.exe", "targetArchitecture": "arm", //"program": "./build/${workspaceRootFolderName}.elf", "args": [], "stopAtEntry": false, "MIMode": "gdb", "setupCommands": [ { "text": "file './build/${workspaceRootFolderName}.elf'" }, { "text": "target remote localhost:3333" }, { "text": "monitor reset" }, { "text": "monitor halt" }, { "text": "load" } ], "preLaunchTask": "build", "cwd": "${workspaceRoot}" }, { "name": "Debug (OpenOCD)", "cwd": "${workspaceRoot}", //"executable": "./build/0119test.elf", "request": "launch", "type": "cortex-debug", "servertype": "openocd", "device": "STM32F4", "runToMain": true, "configFiles": [ "cmsis-dap.cfg", "stm32f4x.cfg" ] } ] } a.这里需要提示有坑。原因同上。 (3.Makefile ########################################################################################################################## # File automatically-generated by tool: [projectgenerator] version: [3.0.0] date: [Fri Jul 10 15:04:01 CST 2020] ########################################################################################################################## # ------------------------------------------------ # Generic Makefile (based on gcc) # # ChangeLog : # 2017-02-10 - Several enhancements + project update mode # 2015-07-22 - first version # ------------------------------------------------ ###################################### # target ###################################### ## 生成的目标文件名 *.elf, *.hex 等 TARGET = GCC_F407 ###################################### # building variables ###################################### # debug build? DEBUG = 1 # optimization OPT = -Og ####################################### # paths ####################################### # Build path ## 编译中间文件和目标文件存放文件夹名称 BUILD_DIR = build ###################################### # source ###################################### # C sources ## 程序工程的C源文件,同样需要逐个添加,可以精确指定需要编译的C源文件 C_SOURCES = Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c user/system_stm32f4xx.c user/stm32f4xx_it.c user/main.c # ASM sources ## 程序工程的ASM汇编源文件,注意ST标准外设库的启动文件是gcc_ride7/文件夹下的 ASM_SOURCES = Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f40_41xxx.s ####################################### # binaries ####################################### PREFIX = arm-none-eabi- 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 ####################################### # CFLAGS ####################################### # cpu ## 程序工程的芯片架构指定,本工程使用STM32F407是cortex-m4 CPU = -mcpu=cortex-m4 # fpu # NONE for Cortex-M0/M0+/M3 # float-abi # mcu MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) # macros for gcc # AS defines ## 程序工程的ASM汇编源文件全局宏定义,未使用不管 AS_DEFS = # AS includes ## 程序工程的ASM汇编源文件全局包含文件,未使用不管 AS_INCLUDES = # C defines ## 程序工程的C源文件全局宏定义,注意前缀 -D (define) C_DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F40_41xxx # C includes ## 程序工程的C源文件全局包含文件,注意前缀 -I (include) C_INCLUDES = -ILibrariesCMSISInclude -ILibrariesCMSISDeviceSTSTM32F4xxInclude -ILibrariesSTM32F4xx_StdPeriph_Driverinc -Iuser # 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)" ####################################### # LDFLAGS ####################################### # link script ## 程序工程的链接文件 LDSCRIPT = Libraries/CMSIS/linker/stm32_flash.ld # libraries #LIBS = -lc -lm -lnosys LIBS = -lc LIBDIR = #LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections # default action: build all all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_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) $@ $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) $(HEX) $< $@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) $(BIN) $< $@ $(BUILD_DIR): mkdir $@ ####################################### # clean up ####################################### clean: ## 程序工程的旧文件清理指令,通过make在windows终端powershell上执行,不能使用rm等unix shell指令,rd指令说可以自行查找 # -rm -fR $(BUILD_DIR) # -rd /s /q STM32F4xx_StdPeriph_TemplatesMAKE-ARM$(BUILD_DIR) -rd /s /q $(BUILD_DIR) ####################################### # dependencies ####################################### -include $(wildcard $(BUILD_DIR)/*.d) # *** EOF *** a.好了,应该是最后一个坑了。这个文件在ST标准外设库里没找到,作用是划分指定芯片flash存储地址和程序、数据等界限的,arm-gcc链接编译生成的*.o目标文件生成最终程序文件需要这个文件。我是在网上另一篇博文找的这段代码,里面的中文注释应该是博主在写博文时好心添加的,但是我没注意注释是否合法,在其他问题都解决后,最后链接一直出问题,找来找去发现是*.ld文件不支持双斜杠 // 注释,所以把全部的 // 注释 改为 /**/ 块注释就可以了。 感觉是C的标准注释,好像新的 // 注释是C++引进的。 网友大佬说 # 注释也可以在*.ld文件使用,我试了下果然可以,虽然内容显示不是注释,而且会编译提示告警,但是确实能正常编译链接了! # 4.程序示例工程目录结构 这个感觉还是挺重要的,可以直观的让大家了解前面一堆东西怎么组合起来的。 a.说明。我用的是STM32F4xx标准外设库,库目录结构就不多展示了,main程序也是标准库官方示例未作改动。 b.说明。linker这个文件夹是我自己添加进Libraries库的,可以放工程的任意位置,只要在Makefile中指明路径就可以。 c.更新说明。新的测试结果表明不适用mgwin32这个unix工具集,在win的cmd窗口下操作DOS指令,不想bashshell那样灵活,当前主要遇到问题就是tasks.json调用了不在当前目录下的Makefile后不能正常执行make指令,所以Makefile文件和build文件夹还是暂时老实放在工程根目录下吧。 # 5.这是编译结果截图 真是太难了……激动地写这个博文留个念吧。 # 其他注意 1. c_cpp_properties.json 软件工程的C语言智能识别配置 这个是编辑代码时vscode进行自动识别C/C++代码的工具配置文件 { "configurations": [ { "name": "ARM", // 1. 工程的头文件路径 "includePath": [ // JSON的工作空间文件路径 "${workspaceFolder}/**", "libraries/CMSIS/CM3/CoreSupport/", "libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/", "libraries/STM32F10x_StdPeriph_Driver_V3.5.0/inc/", "libraries/TCPIP_ENC28J60_lib/", "user/" ], // 2. ST库工程配置全局宏 "defines": [ "USE_STDPERIPH_DRIVER", "STM32F10X_LD" //"VECT_TAB_FLASH" ], // 为编译工具arm-gcc提供依赖环境文件的路径 // 例如 "compilerPath": "d:/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc.exe", "cStandard": "c11", "cppStandard": "c++17", // 编译器为windows下的arm-gcc "intelliSenseMode": "windows-gcc-arm" } ], "version": 4 } 需要按照工程配置的一般只有头文件路径和全局宏定义两项。 但是"compilerPath"这个标签必须指定,否则会出现程序中的基础依赖文件找不到或者宏控制异常,导致全部文件的基础数据类型(例如int8_t/uint8_t等)找不到定义,如果只是简单地将编译器的依赖文件夹“include/”路径添加到普通的工程头文件路径"includePath"下,仍然会出现问题(应该是编译器的自身控制宏导致的)。……这个忘了添加导致我搞了半天路径包含还是解决不掉类型未定义的问题,尴尬。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1621 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1546 浏览 1 评论
980 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
686 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1599 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
648浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
534浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 17:13 , Processed in 0.900799 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号