|
K-FSW ec10f94
Modular flight software on Zephyr, for small satellites
|
A Zephyr board selects the SoC, devices and flash runner. A K-FSW target adds the application configuration and tool defaults under config/targets/; for example rpi_pico_w maps to rpi_pico/rp2040/w.
| Target | Zephyr board | Default composition | Tested |
|---|---|---|---|
linux | native_sim/native/64 | Shell, storage, parameters, persistence, CSP UART/KISS, remote parameters, FTP | Software tests in CI |
nucleo_l496zg | nucleo_l496zg | Same as Linux; shell on ST-LINK, CSP on USART3 | CI build; boot, storage, UART/KISS, CSP, remote parameters and FTP on the bench |
frdm_k64f | frdm_k64f/mk64f12 | Shell only | Boot and shell on the board |
rpi_pico_w | rpi_pico/rp2040/w | USB CDC ACM shell only | Boot and shell on the board |
Only Linux and the NUCLEO are built in CI.
Every target reports its chip's unique ID: as unit= in the boot marker, in status and version, and as hw_id in the board table. It is 96 bits on the STM32L496, 128 on the Kinetis K64 and 64 on the RP2040. The CSP model is the board target, so csp ident names the hardware too.

In this recording the FRDM and the Pico run bench configurations with CSP, on CAN and behind a UHF radio. The frdm_k64f and rpi_pico_w targets in the table are shell only.
KFSW-Linux is the application built for Zephyr's 64-bit native simulator. It compiles the same sources as the NUCLEO build, on simulated devices. Use it for software tests; measure timing, interrupt load and flash behaviour on the MCU.
The executable is build/linux/zephyr/zephyr.exe, and the runner gives it build/linux/kfsw-storage.bin as flash; tests use their own flash files. The shell uses stdin/stdout. A line such as
is the CSP UART, not the console.
CI builds the target and a composition without CSP. Twister runs the unit tests, the integration and Robot tests start one or two full processes, and Valgrind checks a normal boot and one with a corrupted snapshot. tests/config/linux-node2.conf configures the second test node.
The NUCLEO build enables storage, local and remote parameters, persistence, CSP, UART/KISS and FTP. Flash is split into a 960 KiB application partition and a 64 KiB LittleFS partition.
| Connection | Hardware | Use |
|---|---|---|
| Debug console | ST-LINK virtual COM, LPUART1 | Shell, logs and boot markers |
| CSP link | USART3, PD8 TX and PD9 RX | 115200 8N1 KISS |
CSP reception is interrupt driven. The NUCLEO is node 2 and sends traffic for every other node to the KISS interface.
boton_test is not in the default image. Build it with:
The overlay maps the USER button and the green, blue and red LEDs (LD1 to LD3) to the module's chosen properties, so the pins stay in devicetree. The button is debounced for 30 ms on the system workqueue, and its values are in table 67. The manual test is in tests/hil/boton-test/.
csp clock set <seconds> sets the wall time. Without an RTC the time is kept in RAM and lost at reset, and samples collected after the reset have a zero timestamp.
config/profiles/nucleo-clock.conf and nucleo-clock.overlay enable the RTC. It runs from the low-speed oscillator, keeps counting across resets and low-power states, and survives a power loss when VBAT is connected.
The image keeps a short note across a restart and watches the supply voltage, so a node can report why it went down. param get last_reason, last_detail and last_uptime_ms read it, and the note is cleared once reported.
The bootloader is not in the default image. Build it with sysbuild:
| Partition | Address | Size |
|---|---|---|
boot_partition | 0x000000 | 64 KB |
slot0_partition | 0x010000 | 352 KB |
slot1_partition | 0x068000 | 352 KB |
kfsw_golden_partition | 0x0C0000 | 192 KB, reserved |
kfsw_storage_partition | 0x0F0000 | 64 KB |
The bootloader and the application use the same flash map overlay. The storage partition stays at 0xF0000, so an existing filesystem survives the move to MCUboot; the rollback test checks that a stored value is still there after every swap. The golden partition is reserved for a recovery image.
The signing key is private and kept outside the repository. With KFSW_MCUBOOT_KEY the build puts its public key in the bootloader and signs the application. Without it MCUboot uses the development key from its own repository, which anyone can sign with; the rollback test checks for this.
Bootloader settings go in app/sysbuild.conf as SB_CONFIG_* symbols. Sysbuild overrides settings placed in a fragment on the bootloader image.
The hardware watchdog is in the default image, with an 8000 ms timeout, armed at start. A watchdog that waits for a ground command does not cover a hang before the first pass, and the STM32 independent watchdog cannot be disarmed once started. The overlay binds it to kfsw,watchdog, because the board's watchdog0 alias is the window watchdog, which resets when it is fed too early and has a much shorter timeout. The independent watchdog runs from the low-speed oscillator, goes up to about 32 s and keeps running in most low-power states.
The watchdog is armed after all services have started, so a slow boot isn't reset before the shell is up.
Use a stable serial path if the default device is wrong:
To debug, start the server in one terminal and the client in another:
The scripts build first when the ELF is missing.
The boot test checks that the ST-LINK is there, builds, flashes, captures the console and waits for @BOOT and @READY. The UART/KISS test adds an FTDI cable and a KFSW-Linux peer, and checks ping, uart test, storage, a remote parameter, 4 KiB and 16 KiB transfers and the KISS counters; see CSP and links. The Holybro profile sets USART3 to 57600 baud for the radio.
The frdm_k64f target maps to frdm_k64f/mk64f12 and uses the OpenSDA serial console and the OpenOCD runner. CSP, parameters, persistence, FTP, storage and the filesystem are disabled.
The test builds, flashes, waits for kfsw:~$ and runs status, version and help.
The rpi_pico_w target maps to rpi_pico/rp2040/w. Its overlay puts the console and shell on USB CDC ACM, and the shell waits for DTR so no output is lost before a terminal is open. CSP, parameters, persistence, FTP, storage and Wi-Fi are not enabled.
The target uses Zephyr's UF2 runner. If the UF2 has to be copied by hand, for example through usbipd, flash it first and run the test with KFSW_FLASH=0:
tests/hil/shell-smoke.sh has the test steps, and each target's .env file has the board details:
A new shell target only needs its own .env file, unless its hardware behaves differently.
A new target needs:
config/targets/<name>.env with the board and tool settings;app/boards/<board>.conf with the default composition;Moving the NUCLEO configuration to another board also means checking the storage layout, UART wiring, flash runner, console and memory sizes.