Build Makefile+OpenOCD+CMSIS-DAP+Vscode arm-none-eabi-gcc project template

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

  1. 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.


  1. 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

  1. 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
  1. 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

  1. make build project

  2. 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)
  1. make clean

    Clear the project, modify the main.c code, and rebuild the code


  2. 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)