Flashing Simplicity Studio Firmware to XIAO MG24 Without a J-Link
How to use the Arduino toolchain’s OpenOCD to flash Matter, OpenThread, or any Simplicity Studio 6 binary to the Seeed Studio XIAO MG24…
Flashing Simplicity Studio Firmware to XIAO MG24 Without a J-Link
How to use the Arduino toolchain’s OpenOCD to flash Matter, OpenThread, or any Simplicity Studio 6 binary to the Seeed Studio XIAO MG24 over USB
Photo by Anne Nygård on Unsplash
The Problem
The Seeed Studio XIAO MG24 is one of the cheapest and most compact EFR32MG24 boards on the market. It is perfect for Matter over Thread, low-power IoT, and OpenThread RCP applications. But there is a catch:
- Simplicity Studio does not list the XIAO MG24 as a supported board. You cannot select it from the board picker.
- The XIAO ships with an Arduino UF2 bootloader, which is great for Arduino IDE users, but it cannot accept raw
.hexor.gblfiles produced by Simplicity Studio. - The official Silicon Labs documentation assumes you own a J-Link debugger or a Silicon Labs dev kit with an onboard debugger. Most hobbyists and small teams do not have one lying around.
So you are stuck: you build a low-power Matter Sleepy End Device in Simplicity Studio, but you have no way to flash it.
The Solution
You already have everything you need. When you install the Silicon Labs Arduino Core, it bundles OpenOCD and the CMSIS-DAP drivers. The XIAO MG24 has an onboard SAMD11 chip that acts as a CMSIS-DAP debugger. That means the USB port you use for Arduino uploads is also a full SWD debugger — you just need to call OpenOCD manually instead of letting the Arduino IDE do it for you.
This guide shows the exact workflow, from project creation to flashing, without buying any extra hardware.
Prerequisites
- macOS, Linux, or Windows (this guide uses macOS paths)
- Simplicity Studio v6 installed
- Arduino IDE 2.x or later with the Silicon Labs Arduino Core installed
- Add this URL to Arduino IDE Preferences → Additional Board Manager URLs:
https://siliconlabs.github.io/arduino/package_arduinosilabs_index.json - Install the board package for Silicon Labs EFR32 boards
- A Seeed Studio XIAO MG24 (or MG24 Sense)
- A USB-C cable
Step 1: Create Your Project in Simplicity Studio
- Open Simplicity Studio v6.
- Create a new Solution → Silicon Labs Project Wizard.
- When asked for the target, you have two options:
- Option A (Chip target): Select
EFR32MG24B220F1536IM48(or the exact part number on your XIAO). - Option B (Board target): Select
BRD4187C(Radio Board). This board uses the same chip and the pinout matches the XIAO MG24 for UART and basic GPIO.
- Choose your SDK and example (e.g., Matter Window Covering, OpenThread RCP, or any other).
- Build the project with the default configuration.
Note: If you are building a Matter project, Simplicity Studio will generate two sub-projects: your Application and a Bootloader. You need to flash both.
Step 2: Locate the Build Outputs
Simplicity Studio v6 does not place build artifacts inside the project folder. They live in a parallel _cmake directory or inside the project's cmake_gcc/build folder.
Run this command to find your .hex files:
find ~/SimplicityStudio/v6_workspace -name "*.hex" 2>/dev/null
Typical locations look like this:
~/SimplicityStudio/v6_workspace/YourSolution/YourProject/cmake_gcc/build/base/YourProject.hex
~/SimplicityStudio/v6_workspace/YourSolution/YourBootloader/cmake_gcc/build/base/YourBootloader.hex
Or at the solution level:
~/SimplicityStudio/v6_workspace/YourSolution/YourSolution_cmake/build/base/...
Take note of the full paths. You will need them for the flash script.
Step 3: Locate the Arduino OpenOCD Binary
When you installed the Silicon Labs Arduino Core, it downloaded OpenOCD to a hidden folder. On macOS, it lives here:
~/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/bin/openocd
The OpenOCD scripts (interface configs, target configs) are next to it:
~/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/share/openocd/scripts
On Linux, replace ~/Library/Arduino15 with ~/.arduino15. On Windows, look in %%LOCALAPPDATA%%\Arduino15\packages\SiliconLabs\tools\openocd\.
We will use the cmsis-dap.cfg interface (for the onboard SAMD11 debugger) and the efm32s2_g23.cfg target (which covers the EFR32MG24 Series 2 Cortex-M33 core).
Step 4: Flash the Firmware
Manual Flash (One-Off)
Flash the Bootloader first (required for Matter OTA and proper boot):
OPENOCD="$HOME/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/bin/openocd"
SCRIPTS="$HOME/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/share/openocd/scripts"
$OPENOCD -s "$SCRIPTS" \
-f interface/cmsis-dap.cfg \
-f target/efm32s2_g23.cfg \
-c "adapter speed 1000" \
-c "init; reset_config srst_nogate; reset halt" \
-c "program {/FULL/PATH/TO/YourBootloader.hex} verify" \
-c "reset; exit"
Then flash the Application:
$OPENOCD -s "$SCRIPTS" \
-f interface/cmsis-dap.cfg \
-f target/efm32s2_g23.cfg \
-c "adapter speed 1000" \
-c "init; reset_config srst_nogate; reset halt" \
-c "program {/FULL/PATH/TO/YourApp.hex} verify" \
-c "reset; exit"
If everything works, you will see output like this:
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2886:0x0062
Info : [efm32s2.cpu] Cortex-M33 r0p4 processor detected
** Programming Started **
Info : detected part: MG24B220, rev 22
Info : flash size = 1536 KiB
** Programming Finished **
** Verify Started **
** Verified OK **
Automated Flash Script
Save this as flash_xiao.sh, make it executable (chmod +x flash_xiao.sh), and run it whenever you rebuild:
#!/bin/zsh
# Path to the OpenOCD binary bundled with the Silicon Labs Arduino core
OPENOCD="$HOME/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/bin/openocd"
# Path to OpenOCD interface/target scripts
SCRIPTS="$HOME/Library/Arduino15/packages/SiliconLabs/tools/openocd/0.12.0-arduino1-static/share/openocd/scripts"
# UPDATE THESE PATHS to match your Simplicity Studio build outputs
HEX_BL="$HOME/SimplicityStudio/v6_workspace/MatterWindowCoverOverThreadSolution/Matter-Bootloader/cmake_gcc/build/base/Matter-Bootloader.hex"
HEX_APP="$HOME/SimplicityStudio/v6_workspace/MatterWindowCoverOverThreadSolution/MatterWindowCoverOverThread/cmake_gcc/build/base/MatterWindowCoverOverThread.hex"
for f in "$HEX_BL" "$HEX_APP"; do
if [[ ! -f "$f" ]]; then
echo "ERROR: File not found: $f"
echo "Run: find ~/SimplicityStudio/v6_workspace -name '*.hex' to locate your build outputs."
exit 1
fi
echo ">>> Flashing $f"
$OPENOCD -s "$SCRIPTS" -f interface/cmsis-dap.cfg -f target/efm32s2_g23.cfg \
-c "adapter speed 1000" \
-c "init; reset_config srst_nogate; reset halt" \
-c "program {$f} verify" \
-c "reset; exit"
done
echo ">>> Done. Your XIAO MG24 is now running Simplicity Studio firmware."
Important syntax notes:
- The
{path}syntax inside theprogramcommand is required by OpenOCD. Do not put spaces inside the braces. - If your path contains spaces, the braces handle it correctly; do not add extra quotes inside the
-cstring.
Step 5: Verify the Device
After flashing, the XIAO MG24 will no longer appear as a USB mass storage device (the Arduino UF2 bootloader is gone). Instead, it boots directly into your Simplicity Studio application.
- Open a serial monitor at 115200 baud to the XIAO’s USB CDC port.
- For Matter projects, you should see commissioning messages and a QR code URL.
- For OpenThread RCP projects, the device will enumerate as a serial port ready for
ot-daemonor Home Assistant.
If you need to go back to Arduino later, simply reflash the Arduino bootloader .hex using the exact same OpenOCD command.
Why This Works
The XIAO MG24’s SAMD11 companion chip is not just a USB-to-UART bridge. It implements the CMSIS-DAP protocol, which exposes full SWD (Serial Wire Debug) access to the EFR32MG24 over USB. The Arduino IDE already uses this interface under the hood every time you click Upload. By calling OpenOCD directly, we bypass the Arduino IDE and flash whatever binary we want — including Simplicity Studio’s Gecko Bootloader and Matter applications.
This is the same mechanism used by the official XIAO Debug Mate, except the debugger is already on the board.
Going Further: Low Power
Now that you are free from the Arduino stack, you can enable true low-power modes:
- Build as a Matter Sleepy End Device (SED) or Intermittently Connected Device (ICD).
- Configure OpenThread MTD (Minimal Thread Device) with polled reception.
- Use EM2 deep sleep with RAM retention.
Real-world measurements on the MG24 in EM2 with Matter ICD achieve ~60–80 µA average consumption — impossible to reach from the Arduino Matter stack, which keeps the radio in always-on router mode.
Troubleshooting
SymptomFixError: couldn't open ...hexCheck the file path. Use find to locate the hex. Remove any trailing spaces inside the {}.Cannot connect to J-LinkYou are using commander instead of openocd. Use the OpenOCD commands above.Error: No device foundMake sure the XIAO is plugged in and the USB cable carries data (not charge-only).zsh: command not found: \nA trailing quote or newline leaked into your shell command. Copy the one-liner carefully.Device bricks after flashPull PC1 low during reset to enter a safe loop, then reflash. Add a watchdog or safe-mode pin in your firmware.
Summary
You do not need a J-Link, a Debug Mate, or any extra hardware to flash Simplicity Studio firmware to the XIAO MG24. The Arduino Core already gives you OpenOCD and the onboard SAMD11 already gives you SWD. The only missing piece was knowing the right target (efm32s2_g23.cfg) and the right command syntax.
Now you can build professional, low-power Matter and OpenThread applications in Simplicity Studio and deploy them on a $10 board with nothing but a USB cable.
Happy flashing.
메타데이터
- post_id
- abcfa2dceeaf
- slug
- flashing-simplicity-studio-firmware-to-xiao-mg24-without-a-j-link-abcfa2dceeaf
- url
- https://medium.com/@satyam.khadka123/flashing-simplicity-studio-firmware-to-xiao-mg24-without-a-j-link-abcfa2dceeaf
- canonical_url
- https://medium.com/@satyam.khadka123/flashing-simplicity-studio-firmware-to-xiao-mg24-without-a-j-link-abcfa2dceeaf
- author_url
- https://medium.com/@satyam.khadka123
- status
- ok
- fetched_at
- 2026-06-09 15:37:30