Embedded-GCC-Template third-party resource collection
STM32F407-GCC-Template
Arm-none-eabi-gcc + Makefile + OpenOCD + CMSIS-DAP + Vscode project template
1. Software and hardware used to build this environment
1) Windows or Linux (this article focuses on Windows)
2) JLink, Daplink, Wch-Link programmer
3) GNU Arm Embedded Toolchain cross-compiler
4) Mingw-w64 GCC for Windows 64
5) Debug debugging tool openocd
6) Visual Studio Code
2. Software installation and configuration
-
GNU Arm Embedded Toolchain cross-compiler
Go to the official arm developer website, scroll down and select the available ZIP package file to download and decompress.
Download link: Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer
Unzip the downloaded compressed package file in the “gcc-arm-none-eabi” folder, and remember the path of the “bin” file in the file, which needs to be added to the system environment variable Path later.
After adding the environment variables, test to see if it is installed properly.
-
InstallMingw-w64 GCC
Click the link to enter the SourceForge official website. Scroll down to find download links for many versions. Just select the model in the red box. For the specific differences between different suffixes, please refer to:
MinGW gcc download link and similarities and differences of sjlj, dwarf, seh and gcc installation_AMDDMA’s blog-CSDN blog_seh and sjlj
Download link:
MinGW-w64 – for 32 and 64 bit Windows – Browse Files at SourceForge.net
Similarly, unzip the downloaded file to the “gcc-arm-none-eabi” folder and remember the “bin” file path in the directory.
Go to the “bin” file to find the “mingw32-make” application file, make a copy and rename it to “make”. This facilitates executing the make command on the command line instead of typing mingw32-make.
? After adding the environment variables, test to see if it is installed properly.
3. Install the debugging software Download pre-built OpenOCD for Windows
Vscode is installed by default. The installation process is relatively simple. Please refer to other articles. With the support of the above three software, it is possible to compile and generate bin files and hex files in VScode. However, as we all know, the biggest job of programmers is debugging, so a debugging software is inevitably needed.
Commonly used hardware for debugging include STLink, JLink, WCH-Link, and DapLink.
Download pre-built OpenOCD for WindowsDownload link:OpenOCD for Windows
?
Also decompress the downloaded compressed package to “OpenOCD-20231002-0.12.0” and remember the path of the “bin” file in the file.
After adding the environment variables, test to see if it is installed properly.
In summary, the basic software environment has been configured.
3. STM32-GCC-Template project configuration
-
engineering structure
STM32-GCC-Template uses the standard firmware library for development. Of course, you can use HAL for development (this is not important, as long as you have the library)
-Application Application/inc Application/src -BspLibraries BspLibraries/inc BspLibraries/src -FwlibLibraries FwlibLibraries/CMSIS/Include FwlibLibraries/inc FwlibLibraries/src - Kernel Kernel/inc Kernel/src - SystemLibraries SystemLibraries/inc SystemLibraries/src -Build //Compilation process output file - tools tools/startup_stm32f407xx.s tools/STM32F407ZGTx_FLASH.ld -Makefile Makefile script file, focus, build full process script //OpenOCD debugging download configuration file cmsis-dap.cfg stm32f4x.cfg
- Makefile writing (key points)
Author = dele ##################################### # target build target ##################################### TARGET = stm32f407-gcc-template ##################################### # building variables ##################################### # debug build? DEBUG = 1 # optimization OPT=-Og ###################################### # paths ###################################### # source path # firmware library path PERIFLIB_PATH = #Build path BUILD_DIR = Build ##################################### # source # ##################################### # Modify 1 C source file addition. Participate in the file project and add all c files according to the following format. # C sources C_SOURCES = \ Kernel/src/stm32f4xx_it.c \ Kernel/src/system_stm32f4xx.c \ FwlibLibraries/src/misc.c \ FwlibLibraries/src/stm32f4xx_adc.c \ FwlibLibraries/src/stm32f4xx_can.c \ FwlibLibraries/src/stm32f4xx_crc.c \ FwlibLibraries/src/stm32f4xx_cryp_aes.c \ FwlibLibraries/src/stm32f4xx_cryp.c \ FwlibLibraries/src/stm32f4xx_cryp_des.c \ FwlibLibraries/src/stm32f4xx_cryp_tdes.c \ FwlibLibraries/src/stm32f4xx_dac.c \ FwlibLibraries/src/stm32f4xx_dbgmcu.c \ FwlibLibraries/src/stm32f4xx_dcmi.c \ FwlibLibraries/src/stm32f4xx_dma2d.c \ FwlibLibraries/src/stm32f4xx_dma.c \ FwlibLibraries/src/stm32f4xx_exti.c \ FwlibLibraries/src/stm32f4xx_flash.c \ FwlibLibraries/src/stm32f4xx_flash_ramfunc.c \ FwlibLibraries/src/stm32f4xx_gpio.c \ FwlibLibraries/src/stm32f4xx_hash.c\ FwlibLibraries/src/stm32f4xx_hash_md5.c \ FwlibLibraries/src/stm32f4xx_hash_sha1.c \ FwlibLibraries/src/stm32f4xx_i2c.c \ FwlibLibraries/src/stm32f4xx_iwdg.c \ FwlibLibraries/src/stm32f4xx_ltdc.c \ FwlibLibraries/src/stm32f4xx_pwr.c \ FwlibLibraries/src/stm32f4xx_rcc.c \ FwlibLibraries/src/stm32f4xx_rng.c \ FwlibLibraries/src/stm32f4xx_rtc.c \ FwlibLibraries/src/stm32f4xx_sai.c \ FwlibLibraries/src/stm32f4xx_sdio.c \ FwlibLibraries/src/stm32f4xx_spi.c \ FwlibLibraries/src/stm32f4xx_syscfg.c \ FwlibLibraries/src/stm32f4xx_tim.c \ FwlibLibraries/src/stm32f4xx_usart.c \ FwlibLibraries/src/stm32f4xx_wwdg.c \ BspLibraries/src/key.c \ BspLibraries/src/led.c \ SystemLibraries/src/delay.c \ SystemLibraries/src/usart.c \ SystemLibraries/src/sys.c \ SystemLibraries/src/timer.c \ Application/src/main.c \ \t\t #ASM sources # Modification 2: Add assembly startup source file ASM_SOURCES = \ tools/startup_stm32f407xx.s ###################################### # binaries ###################################### # Modify 3 gcc-arm-none-eabi tool chain address PREFIX = arm-none-eabi- GCC_PATH = /SoftwareApplication/gcc-arm-none-eabi/bin 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 architecture 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 # Modify 4 global macro definition -DXXX C_DEFS = \ -DSTM32F40_41xxx \ -DUSE_STDPERIPH_DRIVER\ # AS includes AS_INCLUDES = # C includes # Modify 5 H source file addition. Participate in the file project and add all folders according to the following format. C_INCLUDES =\ -I Kernel/inc \ -I FwlibLibraries/inc \ -I FwlibLibraries/CMSIS/Include \ -I BspLibraries/inc \ -I SystemLibraries/inc \ -I Application/inc \ # 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)" -MT "$(@:%.o=%.d)" ###################################### #LDFLAGS ###################################### # link script # Modify 6 link script link script file addition. How to obtain the link script, please refer to the stm32cubemx official project. LDSCRIPT = \ tools/STM32F407ZGTx_FLASH.ld # 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 $(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) @echo "[CC] $<" @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) @echo "[AS] $<" @$(AS) -c $(CFLAGS) $< -o $@ $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile @echo "[HEX] $< -> $@" @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ @$(SZ) $@ $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) @echo "[HEX] $< -> $@" @$(HEX) $< $@ \t $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) @echo "[BIN] $< -> $@" @$(BIN) $< $@ \t $(BUILD_DIR): @mkdir $@ ###################################### # clean up ###################################### # make clean clear compilation intermediate files # The Windows environment does not support rm, so it is written as -del # Linux environment clean: -del /q $(BUILD_DIR) # Openocd debugging download tool # Modify 7 cmsis-dap.cfg -f stm32f4x.cfg # Modify the configuration file to the tools and chip files you use, such as stlink.cfg jlink.cfg stm32f1xx.cfg flash: openocd -f cmsis-dap.cfg -f stm32f4x.cfg -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).bin 0x8000000" -c reset -c shutdown ###################################### # dependencies ###################################### -include $(wildcard $(BUILD_DIR)/*.d) #***EOF***
4. STM32-Engineering Test
-
make build project
-
make flash
Connect the serial port cable, open the serial port software, and check the terminal output (if it is transplanted from the MDK-Keil project, printf should not be supported, so there is no output from the terminal. You need to modify the relevant code and write the modification file later) (in the picture The situation is the effect after modification)
![Insert picture description here](https://img-blog.csdnimg.cn/1cf3ac67fade4aa49f3648b98d0759ab.png#pic_center)
-
make clean
Clear the project, modify the main.c code, and rebuild the code
-
Pay attention to the modified parts (only my project, not all)
(1) usart.c printf redirection problem
//Redirect the c library function printf to the serial port. The printf function can be used after redirection. // int fputc(int ch, FILE *f) // {<!-- --> // /* Send one byte of data to the serial port */ // USART_SendData(DEBUG_USART, (uint8_t) ch); // /* Wait for sending to complete */ // while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET); // return (ch); // } int _write (int fd, char *pBuffer, int size) {<!-- --> for (int i = 0; i < size; i + + ) {<!-- --> while((USART1->SR & amp;0X40)==0);//Wait for the last serial port data transmission to be completed USART1->DR = (uint8_t) pBuffer[i]; //Write DR, serial port 1 will send data } return size; }
(2) sys.c assembly code (note that since the project comes from project modifications of Zhengdian Atom, it may be different from other project templates, so it is not necessary)
//THUMB instruction does not support assembly inlining //Use the following method to implement the assembly instruction WFI __asm void WFI_SET(void) {<!-- --> WFI; } //Close all interrupts (but not including fault and NMI interrupts) __asm void INTX_DISABLE(void) {<!-- --> CPSID I BXLR } //Enable all interrupts __asm void INTX_ENABLE(void) {<!-- --> CPSI I BXLR } //Set the top address of the stack //addr: top address of stack __asm void MSR_MSP(u32 addr) {<!-- --> MSR MSP, r0 //set Main Stack value BX r14 }
After modification
//THUMB instruction does not support assembly inlining //Use the following method to implement the assembly instruction WFI void WFI_SET(void) {<!-- --> __ASM volatile("WFI"); } //Close all interrupts (but not including fault and NMI interrupts) void INTX_DISABLE(void) {<!-- --> __ASM volatile("CPSID I"); __ASM volatile("BX LR"); \t \t\t } //Enable all interrupts void INTX_ENABLE(void) {<!-- --> __ASM volatile("CPSIE I"); __ASM volatile("BX LR"); } //Set the top address of the stack //addr: top address of stack void MSR_MSP(u32 addr) {<!-- --> __ASM volatile("MSR MSP, r0"); __ASM volatile("BX r14"); }
5. Test results
? Use Vscode to modify, edit, compile, and download code (you can use Cortex-Debug for debugging)