← Back to app
See also: Help · Firmware update

Build the Firmware

Clone the repository

Next: Use STM32CubeIDE · Build on Windows (MSYS2 MinGW64) · Build on Linux

Build from scratch (STM32CubeMX)

  1. Download and install STM32CubeMX version 6.15 or newer from STMicroelectronics.
    Tip: Make sure the version is 6.15+.
  2. Get the project configuration files from this repo and place them in a fresh working folder on your PC:
    You may rename the .ioc file, but the folder name must match the .ioc filename (without the extension). For example, if you rename it to MyProj.ioc, the folder must be MyProj/.
  3. Open the .ioc file in STM32CubeMX.
  4. In Project Manager → Project Settings, set Toolchain / IDE to CMake and GCC.
  5. Click Generate Code to produce the CMake-based project.
  6. Create the folder Application/src inside the generated project and copy the file melexis_io_fw/Application/src/heap_useNewlib_ST.c there (so it becomes Application/src/heap_useNewlib_ST.c in your project tree).
  7. Open Core/Src/sysmem.c in the generated project and change the _sbrk signature to be weak by adding the attribute:
    __attribute__((weak)) void *_sbrk(ptrdiff_t incr)
    This allows overriding/compatibility with the newlib heap implementation added above.
  8. Edit your project's top-level CMakeLists.txt and add heap_useNewlib_ST.c to the executable sources:
    # Add sources to executable
    target_sources(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user sources here
        Application/src/heap_useNewlib_ST.c
    )
  9. Add USB VID/PID definitions to the same CMakeLists.txt so they are available as compile-time macros:
    # Add project symbols (macros)
    target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user defined symbols
        USB_FS_VID=0x1111
        USB_FS_PID=0x2222
    )
    Adjust the values to match your device identifiers.
  10. Generate a .hex file from the built ELF by adding this to CMakeLists.txt:
    # Generate HEX file from ELF
    add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.hex
        COMMENT "Generating HEX file"
    )
    If ${CMAKE_OBJCOPY} isn’t defined by your toolchain file, replace it with arm-none-eabi-objcopy.
  11. Edit the linker script (e.g., STM32F446xx_FLASH.ld) to preserve Flash sectors 1–3 for EEPROM emulation. Keep the vector table in sector 0 and start the application at 0x08010000:
    /* Memories definition */
    MEMORY
    {
      RAM     (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
      ISR      (rx) : ORIGIN = 0x08000000, LENGTH = 16K   /* Vector table (Sector 0) */
      /* EEPROM  (rwx): ORIGIN = 0x08004000, LENGTH = 3 * 16K */ /* Sectors 1, 2 and 3 for EEPROM emulation */
      FLASH    (rx) : ORIGIN = 0x08010000, LENGTH = 512K-16K-48K /* Use remaining for code */
    }
    
    /* Place vector table in dedicated ISR region */
    .isr_vector :
    {
      . = ALIGN(4);
      KEEP(*(.isr_vector)) /* Startup code */
      . = ALIGN(4);
    } >ISR
    Addresses and sizes are for STM32F446 with 512 KB Flash. Adjust for your MCU if it differs.

After code generation (optional)

If you prefer STM32CubeIDE instead, you can import the generated project there and build/flash from the IDE.

Use STM32CubeIDE

Build on Windows (MSYS2 MinGW64)

  1. Install MSYS2 and update the package database and core system.
    Follow MSYS2's first-run update steps (run update, restart the shell if prompted, and update again).
  2. Open the MSYS2 MinGW64 terminal (Start Menu → MSYS2 MinGW 64-bit).
  3. Install required packages (ARM GCC ≥ 12.1):
    pacman -S --needed mingw-w64-x86_64-arm-none-eabi-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja
    Verify version with arm-none-eabi-gcc --version. If you prefer Makefiles instead of Ninja, install mingw-w64-x86_64-make and adjust the generator accordingly.
  4. Change to your generated project folder and build:
    cd /c/Projects/<your-path-to-generated-project>
    mkdir build
    cd build
    cmake -G Ninja .. -DCMAKE_TOOLCHAIN_FILE=../cmake/gcc-arm-none-eabi.cmake
    cmake --build .
    Ninja is recommended on Windows for speed and compatibility. If needed, specify it explicitly: cmake -G Ninja .. -DCMAKE_TOOLCHAIN_FILE=../cmake/gcc-arm-none-eabi.cmake.

Build on Linux

  1. Install the required packages (ARM GCC ≥ 12.1): arm-none-eabi-gcc, cmake, ninja-build.
    On Debian/Ubuntu, for example: sudo apt install gcc-arm-none-eabi cmake ninja-build. Package names may vary by distro.
  2. Change to your generated project folder and build:
    cd ~/Documents/projects/<your-path-to-generated-project>
    mkdir build
    cd build
    cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/gcc-arm-none-eabi.cmake
    cmake --build .
    Use your Linux path instead of /c/Projects/..., e.g., /home/<user>/Projects/.... If needed, specify a generator explicitly: cmake -G Ninja ...
← Back to app