⚠️ 产品声明 / Product Disclaimer
非量产产品,仅供工程验证,不承诺符合 RoHS。 Non-mass-production product; for engineering verification only. RoHS compliance is not guaranteed.
Overview
This chapter builds on the environment prepared in Software Setup: use VSCode connected to WSL, confirm the toolchain works, pull the official base project and complete your first build.
Inside the base project directory DOCS_TEST1, do one configuration step first, then build (either method works).
💡 Tip (required, one time only): by default the official base project only produces
9Mod_MCPBorad.elf, but flashing needs a.bin. Append the following to the top-level file~/DOCS_TEST1/CMakeLists.txtin the project root directory (the same directory as9Mod_MCPBorad.ioc) — CubeMX will not regenerate this file, so it is safe to edit:
# Generate .bin and .hex files after build
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.bin
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.hex
COMMENT "Generating .bin and .hex files"
)

Save the file and every build from then on will automatically generate 9Mod_MCPBorad.bin.
Inside the base project directory DOCS_TEST1 there are two ways to build:
Method 1: build from the VSCode CMake extension GUI (recommended)
-
Click the CMake icon in the VSCode Activity Bar on the left (the CMake Tools extension).

-
In the CMake panel in the sidebar, set the build preset to Debug (you can also switch it by clicking the CMake area on the bottom status bar).

-
Click the Build button and wait for the build to finish; the output panel reports success.

Method 2: build from the command line
# 1. Configure: read CMakePresets.json and generate the Ninja build scripts
cmake --preset Debug
# 2. Build: compile and link several hundred source files into the final firmware
cmake --build build/Debug
Example of a successful build output (the number of lines varies by environment):
[xx/xx] Linking C executable 9Mod_MCPBorad.elf
Memory region Used Size Region Size %age Used
RAM: 16xxx B 20 KB xx%
FLASH: 98xxx B 128 KB xx%
Check the artifacts:
ls -la build/Debug/

Check the artifacts:
build/Debug/should contain three files —9Mod_MCPBorad.elf,9Mod_MCPBorad.binand9Mod_MCPBorad.hex(.bin/.hex are generated automatically by POST_BUILD).
The artifact names come from
set(CMAKE_PROJECT_NAME 9Mod_MCPBorad)inCMakeLists.txt; every command in this tutorial is written for that artifact name.
Wiring: the ST-Link connects to the development board over SWD, as follows:
| ST-Link | Development Board | Description |
|---|---|---|
| SWDIO | PA13 | Data line |
| SWCLK | PA14 | Clock line |
| GND | GND | Common ground |
| 3.3V | 3.3V (optional) | Can be left unconnected when the board is self-powered |

Open Seahi-Serial and set up the WSL mapping (required before flashing)
By default WSL2 cannot see USB devices on Windows, so the ST-Link has to be mapped into WSL first:
- Open the Seahi-Serial app (installed in step ⑤ of Software Setup).
- Find the USB device (or COM port) for the ST-Link in the device list.
- Click Map to WSL (mounts it into WSL); once the status shows it is mapped, you are done.
The ST-Link is only visible inside WSL after mapping; if flashing reports that it cannot connect, check this step first.

Flash (VSCode Cortex-Debug GUI — the extension is already installed)
-
Create
.vscode/launch.jsonin the project root directory (contents below):{ "version": "0.2.0", "configurations": [ { "name": "烧录并调试 STM32F103 (OpenOCD)", "cwd": "${workspaceFolder}", "executable": "${workspaceFolder}/build/Debug/9Mod_MCPBorad.elf", "request": "launch", "type": "cortex-debug", "servertype": "openocd", "configFiles": ["interface/stlink.cfg", "target/stm32f1x.cfg"], "device": "STM32F103CB", "gdbPath": "arm-none-eabi-gdb", "toolchainPrefix": "arm-none-eabi", "runToEntryPoint": "main" } ] }
-
In the VSCode bottom bar (status bar), click the “烧录并调试 STM32F103 (OpenOCD)” button (“Flash & Debug STM32F103 (OpenOCD)”) → OpenOCD starts automatically, connects to the ST-Link and writes the firmware into the chip.

-
When flashing finishes the program stops at
main(); click Continue in the debug toolbar to run it. You can also set breakpoints in the code before starting, to debug live.
After flashing, the board runs the firmware: the OLED shows the welcome page and the LED strip plays a gradient animation (features are added step by step in later chapters).

-
Check the screen: the OLED should display two lines, “欢迎使用” (“Welcome”) and “九章开发板” (“Jiuzhang Development Board”) — the welcome page of the official base project.

-
Check the serial log: connect the Seahi-Serial serial assistant to USART1 (PA9) at 1500000 baud; you should see temperature and humidity logs refreshed once per second:
[INFO] sht3x_read_task:234: sht30: 29 C,52 %The temperature and humidity values change with the environment. Seeing this log means the firmware is running normally and the SHT30 sensor is communicating correctly.

-
You will also see initialization logs on the serial port:
[INFO] emMCP init done,[INFO] sht3x init OK!,[INFO] ch224 init OK!and so on.
If all of the above looks right, the download succeeded and the development board is running the base firmware.
Build Error Troubleshooting
| Error | Cause | Solution |
|---|---|---|
arm-none-eabi-gcc: not found | Cross-compiler not installed | sudo apt install -y gcc-arm-none-eabi |
CMake Error: Could not find ninja | Ninja not installed | sudo apt install -y ninja-build |
No CMAKE_C_COMPILER could be found | Toolchain file not taking effect | Make sure you run cmake in the project root directory and that CMakePresets.json exists |
cannot find -lc and similar link errors | newlib linking problem | Make sure newlib_lock_glue.c is in the project root directory |
| Stubborn build cache issues | Corrupted cache | rm -rf build && cmake --preset Debug && cmake --build build/Debug |
FAQ & Troubleshooting
🔧 sudo apt update is slow or fails
Cause: the default software sources are overseas
Fix: switch to a mirror closer to you (Tsinghua / Aliyun) and every command in this tutorial becomes fast
🔧 arm-none-eabi-gcc --version shows 9.x
Cause: older systems such as Ubuntu 20.04 ship an outdated default version
Fix: this tutorial uses Ubuntu 22.04 (default 10.3+); on older systems you can install the xpack toolchain
🔧 cmake: command not found
Cause: CMake is not installed
Fix: sudo apt install -y cmake ninja-build
🔧 Cloning the official repository is slow / fails
Cause: unstable network
Fix: retry; or git clone --depth 1 https://github.com/Ai-Thinker-Open/emMCP.git (fetches only the latest revision)
🔧 Running cmake --preset Debug outside the project directory errors out
Cause: the preset file lives in the project root directory
Fix: run cd ~/DOCS_TEST1 first
🔧 Build error No CMAKE_C_COMPILER
Cause: the cross-compiler is not installed or not on PATH
Fix: sudo apt install -y gcc-arm-none-eabi, then reopen the terminal
🔧 The first build takes a long time
Cause: a full build of several hundred files
Fix: this is normal; later incremental builds take only a few seconds
🔧 Rebuilding after changing the code
Cause: —
Fix: just run cmake --build build/Debug (no need to configure again)
🔧 The artifact name is not your own project name
Cause: CMAKE_PROJECT_NAME is not what you expect
Fix: the base project artifact is named 9Mod_MCPBorad.bin; to rename it, change set(CMAKE_PROJECT_NAME ...) in CMakeLists.txt and run cmake --preset Debug again
🔧 Antivirus deletes the build artifacts
Cause: a false positive from Windows Defender
Fix: add the project directory to the allow list, or trust builds done inside WSL
🔧 The serial port / USB device cannot be mapped into WSL (the serial assistant cannot open the COM port)
Cause: by default WSL2 cannot access Windows serial devices directly
Fix: use the community tool Seahi-Serial to do the mapping: https://github.com/SeaHi-Mo/Seahi-Serial (mounts the COM port into WSL; works for serial debugging and the ST-Link)
Can't flash inside WSL?
By default WSL2 cannot see USB devices on Windows (the ST-Link is plugged into Windows). Map the ST-Link into WSL with Seahi-Serial (installed in step ⑤ of Software Setup), then flash using Method 1 (Cortex-Debug GUI) or Method 2 (OpenOCD command line) from step ②.

