Configuring VSCode and CMake for MindMotion MM32F5330 Development

Toolchain Installation and Setup

To establish a robust development environment for the MM32F5330 microcontroller using Visual Studio Code, several core components must be installed sequentially. Begin by installing the VSCode editor itself. Following this, install the MinGW environment to provide necessary Unix-like tools on Windows. CMake is required for build system generation, and the Ninja build system is recommended for speed.

Within the VSCode extension marketplace, install the following plugins:

  • C/C++ Extension Pack
  • CMake Tools
  • CMake

For cross-compilation, download and install the ARM GNU Toolchain (specifically the mingw-w64 version targeting arm-none-eabi). Ensure all binaries are added to the system PATH environment variable.

Project Build Configuraton

The core of the build system lies in the CMakeLists.txt file. This script defines the compiler toolchain, target architecture, and source file inclusion. Below is a configured example tailored for the Cortex-M33 core found in the MM32 series.

cmake_minimum_required(VERSION 3.20)

# Define the system and compiler tools
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)

# Project Definition
project(mm32_firmware_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# Architecture Flags
add_compile_options(-mcpu=cortex-m33 -mthumb -mthumb-interwork)
add_compile_options(-ffunction-sections -fdata-sections -fno-common)

# Build Type Optimization
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
    add_compile_options(-Og -g)
endif ()

# Preprocessor Definitions
add_compile_definitions(USE_STDPERIPH_DRIVER)
add_compile_definitions(CUSTOM_HSE_VAL)

# Include Paths
include_directories(
    .
    ./board
    ./device
    ./device/CMSIS/Include
    ./device/drivers
)

# Source Collection
file(GLOB SOURCE_FILES 
    ./application/*.c 
    ./board/*.c 
    ./device/armgcc/*.S 
    ./device/drivers/*.c 
    ./device/*.c 
    ./*.c
)

# Linker Configuration
set(LD_SCRIPT_PATH D:/mini-f5330_blinky_led_armgcc/device/armgcc/linker/mm32f5333d_flash.ld)

add_link_options(-T ${LD_SCRIPT_PATH})
add_link_options(-Wl,-gc-sections,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-specs=nano.specs -specs=nosys.specs -u _printf_float)

# Executable Target
add_executable(firmware.elf ${SOURCE_FILES})

# Post-Build Artifacts
set(OUTPUT_HEX ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(OUTPUT_BIN ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)

add_custom_command(TARGET firmware.elf POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:firmware.elf> ${OUTPUT_HEX}
    COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:firmware.elf> ${OUTPUT_BIN}
    COMMENT "Generating HEX and BIN files"
)

Memory Layout Definition

The linker script defines the physical memory map for the device, specifying flash and RAM regions along with stack and heap sizes. The following script configures the memory for the MM32F5333 variant.

/* Memory Origins */
FLASH_ORG = 0x08000000;
FLASH_LEN = 0x00020000;

RAM_ORG = 0x20000000;
RAM_LEN = 0x00008000;

/* System Resources */
STACK_SZ = 0x00000800;
HEAP_SZ = 0x00000C00;

MEMORY {
    FLASH (rx) : ORIGIN = FLASH_ORG, LENGTH = FLASH_LEN
    RAM (xrw)  : ORIGIN = RAM_ORG, LENGTH = RAM_LEN
}

ENTRY(Reset_Handler)

SECTIONS {
    .text : {
        KEEP(*(.vectors))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))
        *(.rodata*)
        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH
    __exidx_start = .;
    .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH
    __exidx_end = .;

    .copy.table : {
        . = ALIGN(4);
        __copy_table_start__ = .;
        LONG (__etext)
        LONG (__data_start__)
        LONG ((__data_end__ - __data_start__) / 4)
        __copy_table_end__ = .;
    } > FLASH

    .zero.table : {
        . = ALIGN(4);
        __zero_table_start__ = .;
        __zero_table_end__ = .;
    } > FLASH

    __etext = ALIGN(4);

    .data : AT (__etext) {
        __data_start__ = .;
        *(vtable)
        *(.data*)
        . = ALIGN(4);
        __data_end__ = .;
    } > RAM

    .bss : {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    } > RAM

    .heap (COPY) : {
        . = ALIGN(8);
        __end__ = .;
        PROVIDE(end = .);
        . = . + HEAP_SZ;
        . = ALIGN(8);
        __HeapLimit = .;
    } > RAM

    .stack (ORIGIN(RAM) + LENGTH(RAM) - STACK_SZ) (COPY) : {
        . = ALIGN(8);
        __StackLimit = .;
        . = . + STACK_SZ;
        . = ALIGN(8);
        __StackTop = .;
    } > RAM
    
    PROVIDE(__stack = __StackTop);
    ASSERT(__StackLimit >= __HeapLimit, "Stack overflow detected")
}

Application Logic Implementation

The main application initializes the hardware abstraction layer and enters a continuous loop to toggle GPIO pins connected to LEDs. This serves as a verification that the toolchain and hardware configuration are functioning correctly.

int main(void)
{
    Board_Initialize();
    Start_LED_Sequence();

    while (1)
    {
        /* Main idle loop */
    }
}

The LED control logic is encapsulated in a separate function to manage the toggling of specific ports and pins with a defined delay interval.

void Start_LED_Sequence(void)
{
    printf("\r\nExecuting %s\r\n", __FUNCTION__);

    Configure_GPIO_Pins();

    while (1)
    {
        GPIO_IO_Toggle(GPIOB, GPIO_Pin_10);
        GPIO_IO_Toggle(GPIOB, GPIO_Pin_11);
        GPIO_IO_Toggle(GPIOC, GPIO_Pin_6);
        GPIO_IO_Toggle(GPIOC, GPIO_Pin_7);

        PLATFORM_DelayMS(100);
    }
}

Compilasion and Flashing

Configure the CMake Tools extension in VSCode to select the appropriate kit (ARM GCC) and variant. Trigger the build process to generate the ELF, HEX, and BIN files. Once compilation succeeds, use the POWERWRITE utility to flash the generated binary onto the evaluation board. Upon reset, the LEDs should begin toggling, indicating successful deployment.

Tags: mm32f5330 VSCode CMake arm-gcc linker-script

Posted on Tue, 16 Jun 2026 17:20:41 +0000 by misteryoji