主页 > 创业  > 

【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFsgcc环境搭建

【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFsgcc环境搭建

为摒弃在接受keil邮件,研究了下gun编译,以STM32F407为例,简单记录

1. 软件包准备 Git 选择对应版本直接安装即可 git-scm /download/winmakegcc ​ 1)将上述软件包放置于C盘根目录 2)添加环境变量

3)cmd命令行测试环境 分别输入

make -v gcc -v

2. 编写makefile # ------------------------------------------------ # # @file Makefile (based on gcc) # @author urien # @version v1.0.0 # # ChangeLog : # 2023-10-20 # ------------------------------------------------ ###################################### # target ###################################### TARGET = update ###################################### # building variables ###################################### # debug build? DEBUG = 1 # optimization OPT = -Og ####################################### # paths ####################################### # Build path BUILD_DIR = build ###################################### # source ###################################### # C sources C_DIRS += ../Libraries/FreeRTOS C_DIRS += ../Libraries/FreeRTOS/portable/GCC/ARM_CM4F C_DIRS += ../Libraries/CMSIS/Device/ST/STM32F4xx/Source C_DIRS += ../Libraries/STM32F4xx_StdPeriph_Driver/src C_DIRS += ../User/app C_DIRS += ../User/bsp C_DIRS += ../User/mid C_DIRS += ../User/misc C_DIRS += ../User/gui/app C_DIRS += ../User/gui/lib C_DIRS += ../User/usb C_DIRS += ../Libraries/FATFS/source C_DIRS += ../Libraries/STM32_USB_HOST_Library/Core/src C_DIRS += ../Libraries/STM32_USB_HOST_Library/Class/MSC/src C_DIRS += ../Libraries/PDF SRC_OBJS_DIRS += $(foreach DIR, $(C_DIRS), $(wildcard $(DIR)/*.c)) C_SOURCES = $(SRC_OBJS_DIRS) \ ../Libraries/FreeRTOS/portable/MemMang/heap_4.c \ ../Libraries/STM32_USB_OTG_Driver/src/usb_core.c \ ../Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c \ ../Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c \ # Core/Src/main.c \ # Core/Src/fr # ASM sources ASM_SOURCES = \ startup_stm32f407xx.s ####################################### # 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 ####################################### # CFLAGS ####################################### # cpu CPU = -mcpu=cortex-m4 # fpu FPU = -mfpu=fpv4-sp-d16 # float-abi FLOAT-ABI = -mfloat-abi=hard # mcu MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) # macros for gcc # AS defines AS_DEFS = # C defines C_DEFS = \ -DSTM32F407xx \ -DSTM32F40_41xxx \ -DUSE_STDPERIPH_DRIVER \ -DUSE_USB_OTG_FS \ -DUSER_VECT_TAB_ADDRESS \ # -D__FPU_PRESENT \ # -D__FPU_USED \ # AS includes AS_INCLUDES = # C includes C_INCS += ../Libraries/CMSIS/Include C_INCS += ../Libraries/CMSIS/Core/Include C_INCS += ../Libraries/CMSIS/Device/ST/STM32F4xx/Include C_INCS += ../Libraries/STM32F4xx_StdPeriph_Driver/inc C_INCS += ../Libraries/FreeRTOS/include C_INCS += ../Libraries/FreeRTOS/GCC/ARM_CM4F C_INCS += ../Libraries/FreeRTOS/portable/GCC/ARM_CM4F C_INCS += ../Libraries/PDF C_INCS += ../User/app C_INCS += ../User/bsp C_INCS += ../User/mid C_INCS += ../User/misc C_INCS += ../User/gui/app C_INCS += ../User/gui/lib C_INCS += ../User/usb C_INCS += ../Libraries/STM32_USB_OTG_Driver/inc C_INCS += ../Libraries/STM32_USB_HOST_Library/Class/MSC/inc C_INCS += ../Libraries/STM32_USB_HOST_Library/Core/inc C_INCS += ../Libraries/FATFS/source INCS_OBJS_DIR = $(foreach DIR2, $(C_INCS), $(wildcard $(DIR2)/*.h)) INCS_OBJS_PATH = $(sort $(dir $(INCS_OBJS_DIR))) C_INCLUDES = $(addprefix -I,$(INCS_OBJS_PATH)) \ # 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 = STM32F407VGTx_FLASH.ld # libraries LIBS = -lc -lm -lnosys LIBDIR = # LDFLAGS += -lc -lrdimon -u _printf_float # LDFLAGS += -specs=nano.specs 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: -rm -fR $(BUILD_DIR) ####################################### # dependencies ####################################### -include $(wildcard $(BUILD_DIR)/*.d) ####################################### # download .hex/.bin by jlink ####################################### #Your JLink installation directory PATH_WINPC = 'C:/Program Files (x86)/SEGGER/JLink/' #PATH_LINUX = /opt/SEGGER/JLink_V640b/JLinkExe JK_DPATH = $(PATH_WINPC) #Jlink script store directory JKS_DIR = . #Chip type CHIP_TYPE = STM32F407VG flash: @$(JK_DPATH)JLink.exe -device $(CHIP_TYPE) -if SWD -speed 4000 -autoconnect 1 -CommanderScript $(JKS_DIR)/flash.jlink @echo "Download Completed!" debug: @$(JK_DPATH)JLinkGDBServer.exe -select USB -device $(CHIP_TYPE) -if SWD -speed auto -noir -LocalhostOnly # *** EOF *** 3. __CC_ARM转__GUNC__注意 启动文件及LD文件 通过CubeMx工具生成即可 目录路径表示问题 // __CC_ARM环境 #define DBG_PATH_DIR '\\' // 目录结构 // __GUNC__环境 #define DBG_PATH_DIR '/' // 目录结构 字节对齐及指定位置存储问题 // __CC_ARM环境 __align(32) unsigned char ucaMemPool[MEM_MAX_SIZE]; // 内存池(32字节对齐) // __GUNC__环境 #pragma pack(32) // 内存池(32字节对齐) unsigned char ucaMemPool[MEM_MAX_SIZE]; #pragma pack() // __CC_ARM环境 static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((at(0X10000000))); // __GUNC__环境 static uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__ ((section(".ccmram"))); /** 其中.ccmram在LD中定义,如果没有则需要自定义 */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH FreeRTOS兼容问题

底层接口RVDS替换为GCC

const功能接口注册问题 // __CC_ARM环境 #define REGISTER_CMD(cmd, handler, desc) \ const char _register_##cmd##_cmd[] = #cmd; \ const char _register_##cmd##_desc[] = #desc; \ CMD_USED cmd_t _register_##cmd SECTION("CMDS") = \ { \ _register_##cmd##_cmd, \ _register_##cmd##_desc, \ (unsigned int)CMD_HASH, \ (cmd_handler)&handler}; void cmd_get_time(void *param) { CALENDAR_T struCal; if_rtc_get(&struCal); __printf("%d-%d-%d %d:%d:%d %d\r\n", struCal.year, struCal.month, struCal.day, struCal.hour, struCal.minute, struCal.second, struCal.week); } REGISTER_CMD(get_time, cmd_get_time, get_time); // __GUNC__环境需要实现功能注册必须建表。 // 屏蔽原先接口 #define REGISTER_CMD(...) // 新建关联表 cmd_t cmd_table[] = { {"set_time", "set_time[ymdhmsw]", 0, cmd_set_time}, {"get_time", "get_time", 0, cmd_get_time}, {"get_sensor", "get_sensor", 0, cmd_get_sensor}, {"set_tp", "set_tp[tp1 tp2]", 0, cmd_set_target}, ... {0, 0, 0, 0}, }; USB_OTG问题

移植是需要删除一下文件:

usbh_msc_fatfs.c usb_conf_template.h 特殊函数替换

__CC_ARM环境

// THUMB指令不支持汇编内联 // 采用如下方法实现执行汇编指令WFI __asm void WFI_SET(void) { WFI; } // 关闭所有中断(但是不包括fault和NMI中断) __asm void INTX_DISABLE(void) { CPSID I BX LR } // 开启所有中断 __asm void INTX_ENABLE(void) { CPSIE I BX LR } // 设置栈顶地址 // addr:栈顶地址 __asm void MSR_MSP(u32 addr) { MSR MSP, r0 // set Main Stack value BX r14 }

__GUNC__环境

/** * @brief 执行: WFI指令(执行完该指令进入低功耗状态, 等待中断唤醒) * @param 无 * @retval 无 */ void sys_wfi_set(void) { __ASM volatile("wfi"); } /** * @brief 关闭所有中断(但是不包括fault和NMI中断) * @param 无 * @retval 无 */ void sys_intx_disable(void) { __ASM volatile("cpsid i"); } /** * @brief 开启所有中断 * @param 无 * @retval 无 */ void sys_intx_enable(void) { __ASM volatile("cpsie i"); } /** * @brief 设置栈顶地址 * @note 左侧的红X, 属于MDK误报, 实际是没问题的 * @param addr: 栈顶地址 * @retval 无 */ void sys_msr_msp(uint32_t addr) { __set_MSP(addr); /* 设置栈顶地址 */ } IAP相关问题

bootloader工程flash最好也修改限制自身的大小限制

MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K }

bootloader跳转问题

// __GUNC__环境编译后得到的hex及bin文件无法满足以下条件 if ((tmp & 0x2FFE0000) == 0x20000000) // 检查栈顶地址是否合法. 目前没有找到更好的办法,做注释处理。 u32 tmp = 0; s8 iap_load_app(u32 appxaddr) { // if ((tmp & 0x2FFE0000) == 0x20000000) // 检查栈顶地址是否合法. { jump2app = (iapfun) * (vu32 *)(appxaddr + 4); // 用户代码区第二个字为程序开始地址(复位地址) __set_MSP(appxaddr); /* 设置栈顶地址 */ // MSR_MSP(*(vu32 *)appxaddr); // 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); // 跳转到APP. } return 1; }

application需要修改三处

// 第一处 LD文件 MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x08010000, LENGTH = 960K } // 第二处 makefile文件 // 增加USER_VECT_TAB_ADDRESS宏定义 C_DEFS = \ -DUSER_VECT_TAB_ADDRESS \ // 第三处 system_stm32f4xx.c文件 #if defined(VECT_TAB_SRAM) #define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #else #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00010000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #endif /* VECT_TAB_SRAM */ #endif /* USER_VECT_TAB_ADDRESS */ 关于下载

下载可以借用sergger - jlink驱动,在makefile文件添加如下:

####################################### # download .hex/.bin by jlink ####################################### #Your JLink installation directory PATH_WINPC = 'C:/Program Files (x86)/SEGGER/JLink/' #PATH_LINUX = /opt/SEGGER/JLink_V640b/JLinkExe JK_DPATH = $(PATH_WINPC) #Jlink script store directory JKS_DIR = . #Chip type CHIP_TYPE = STM32F407VG flash: @$(JK_DPATH)JLink.exe -device $(CHIP_TYPE) -if SWD -speed 4000 -autoconnect 1 -CommanderScript $(JKS_DIR)/flash.jlink @echo "Download Completed!" debug: @$(JK_DPATH)JLinkGDBServer.exe -select USB -device $(CHIP_TYPE) -if SWD -speed auto -noir -LocalhostOnly

主要注意两个地方:

1)驱动的安装位置

2)JKS_DIR定义的位置,这个直接索引编译后的hex文件

浮点数打印及格式化问题 makefile文件中去除-specs=nano.specs # LDFLAGS += -specs=nano.specs

注意:去除后编译大小将增加40K代码空间

关于VSCODE编写代码高亮、索引、宏定义关联问题

在.vscode文件夹下根据需要添加目录索引及相关宏定义即可

4. 关于二次开发

二次开发新建的文件,存放于user对应的目录下即可,无需修改makefile文件。

4. 编译、下载、清除 urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc) $ make -j20 .... -mfloat-abi=hard -TSTM32F407VGTx_FLASH.ld -lc -lm -lnosys -Wl,-Map=build/update.map,--cref -Wl,--gc-sections -o build/update.elf arm-none-eabi-size build/update.elf text data bss dec hex filename 243772 60912 113784 418468 662a4 build/update.elf arm-none-eabi-objcopy -O ihex build/update.elf build/update.hex arm-none-eabi-objcopy -O binary -S build/update.elf build/update.bin urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc) $ urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc) $ make flash ... Script processing completed. Download Completed! urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc) $ urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc) $ make clean rm -fR build
标签:

【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFsgcc环境搭建由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFsgcc环境搭建