slint/examples/mcu-board-support
2025-06-26 13:30:43 +00:00
..
esp32_s3_box_3 [autofix.ci] apply automated fixes 2025-04-15 11:32:27 +02:00
pico2_st7789 ci: Format toml files 2025-04-02 11:03:41 +02:00
pico_st7789 ci: Format toml files 2025-04-02 11:03:41 +02:00
stm32h735g ci: Format toml files 2025-04-02 11:03:41 +02:00
stm32u5g9j_dk2 ci: Format toml files 2025-04-02 11:03:41 +02:00
build.rs Initial support for the stm32u5g9j-dk2 2025-03-18 13:02:01 +01:00
Cargo.toml Bump version number to 1.13.0 2025-06-26 13:30:43 +00:00
embassy.rs Simplify defmt::println call for debug_log implementation 2025-03-20 13:51:47 +01:00
esp32_s3_box_3.rs [autofix.ci] apply automated fixes 2025-04-15 11:32:27 +02:00
lib.rs Introduce a prelude to mcu-board-support to make esp-hal available when the entry point comes from esp_hal::main 2025-04-15 11:32:27 +02:00
pico2_st7789.rs MCU pico2: increase heap size 2025-05-20 07:45:22 +02:00
pico_st7789.rs pico_st7789: Turn on backlight after first frame is drawn (#7482) 2025-01-29 18:41:38 +01:00
profiler.rs Domain: slint-ui.com -> slint.dev 2023-06-16 10:55:08 +02:00
README.md muc-board-support: doc - fix tasks.json 2025-05-23 11:40:25 +02:00
stm32h735g.rs link_section needs unsafe with edition 2024 2025-03-31 17:35:22 +02:00
stm32u5g9j_dk2.rs Separate the stm32 independent part of the slint::platform::Platform impl from stm32 specific bits 2025-03-20 13:51:47 +01:00

Slint MCU backend

See also the MCU docs

How to use

This crate re-export a entry attribute macro to apply to the main function, and a init() function that should be called before creating the Slint UI.

In order to use this backend, the final program must depend on both slint and mcu-board-support. The main.rs will look something like this

#![no_std]
#![cfg_attr(not(feature = "simulator"), no_main)]
slint::include_modules!();

#[allow(unused_imports)]
use mcu_board_support::prelude::*;

#[mcu_board_support::entry]
fn main() -> ! {
    mcu_board_support::init();
    MainWindow::new().run();
    panic!("The event loop should not return");
}

Since mcu-board-support is at the moment an internal crate not uploaded to crates.io, you must use the git version of slint, slint-build, and mcu-board-support

[dependencies]
slint = { git = "https://github.com/slint-ui/slint", default-features = false }
mcu-board-support = { git = "https://github.com/slint-ui/slint" }
# ...
[build-dependencies]
slint-build = { git = "https://github.com/slint-ui/slint" }

In your build.rs, you must include a call to slint_build::print_rustc_flags().unwrap() to set some of the flags.

Run the demo:

The simulator

cargo run -p printerdemo_mcu --features=simulator --release

On the Raspberry Pi Pico

Build the demo with:

cargo build -p printerdemo_mcu --no-default-features --features=mcu-board-support/pico-st7789 --target=thumbv6m-none-eabi --release

The resulting file can be flashed conveniently with elf2uf2-rs. Install it using cargo install:

cargo install elf2uf2-rs

Then upload the demo to the Raspberry Pi Pico: push the "bootsel" white button on the device while connecting the micro-usb cable to the device, this connect some storage where you can store the binary.

Or from the command on linux: (connect the device while pressing the "bootsel" button.

# If you're on Linux: mount the device
udisksctl mount -b /dev/sda1
# upload
elf2uf2-rs -d target/thumbv6m-none-eabi/release/printerdemo_mcu

On the Raspberry Pi Pico2

Build the demo with:

cargo build -p printerdemo_mcu --no-default-features --features=mcu-board-support/pico2-st7789 --target=thumbv8m.main-none-eabihf --release

The resulting file can be flashed conveniently with picotool. You should build it from source.

Then upload the demo to the Raspberry Pi Pico: push the "bootsel" white button on the device while connecting the micro-usb cable to the device, this connects some USB storage on your workstation where you can store the binary.

Or from the command on linux (connect the device while pressing the "bootsel" button):

# If you're on Linux: mount the device
udisksctl mount -b /dev/sda1
# upload
picotool load -u -v -x -t elf target/thumbv8m.main-none-eabihf/release/printerdemo_mcu

Using probe-rs

This requires probe-rs and to connect the pico via a probe (for example another pico running the probe).

Then you can simply run with cargo run

CARGO_TARGET_THUMBV6M_NONE_EABI_LINKER="flip-link" CARGO_TARGET_THUMBV6M_NONE_EABI_RUNNER="probe-rs run --chip RP2040" cargo run -p printerdemo_mcu --no-default-features --features=mcu-board-support/pico-st7789 --target=thumbv6m-none-eabi --release

Flashing and Debugging the Pico with probe-rs's VSCode Plugin

Install probe-rs-debugger and the VSCode plugin as described here.

Add this build task to your .vscode/tasks.json:

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "cargo",
			"command": "build",
			"args": [
				"--package=printerdemo_mcu",
				"--no-default-features",
				"--features=mcu-board-support/pico-st7789",
				"--target=thumbv6m-none-eabi",
				"--profile=release-with-debug"
			],
			"problemMatcher": [
				"$rustc"
			],
			"group": "build",
			"label": "build mcu demo for pico"
		},
	]
}

The release-with-debug profile is needed, because the debug build does not fit into flash.

You can define it like this in your top level Cargo.toml:

[profile.release-with-debug]
inherits = "release"
debug = true

Now you can add the launch configuration to .vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "preLaunchTask": "build mcu demo for pico",
            "type": "probe-rs-debug",
            "request": "launch",
            "name": "Flash and Debug MCU Demo",
            "cwd": "${workspaceFolder}",
            "connectUnderReset": false,
            "chip": "RP2040",
            "flashingConfig": {
                "flashingEnabled": true,
                "resetAfterFlashing": true,
                "haltAfterReset": true
            },
            "coreConfigs": [
                {
                    "coreIndex": 0,
                    "rttEnabled": true,
                    "programBinary": "./target/thumbv6m-none-eabi/release-with-debug/printerdemo_mcu"
                }
            ]
        },
    ]
}

This was tested using a second Raspberry Pi Pico programmed as a probe with DapperMime.

STM32H735G-DK

Using probe-rs.

CARGO_PROFILE_RELEASE_OPT_LEVEL=s CARGO_TARGET_THUMBV7EM_NONE_EABIHF_RUNNER="probe-rs run --chip STM32H735IGKx" cargo run -p printerdemo_mcu --no-default-features  --features=mcu-board-support/stm32h735g --target=thumbv7em-none-eabihf --release

STM32U5G9J-DK2

cargo build -p mcu-board-support --target=thumbv8m.main-none-eabihf --features stm32u5g9j-dk2 --no-default-features Using probe-rs.

CARGO_PROFILE_RELEASE_OPT_LEVEL=s CARGO_TARGET_THUMBV8M_MAIN_NONE_EABIHF_RUNNER="probe-rs run --chip STM32U5G9ZJTxQ" cargo run -p printerdemo_mcu --no-default-features  --features=mcu-board-support/stm32u5g9j-dk2 --target=thumbv8m.main-none-eabihf --release

ESP32

Prerequisites

When flashing, with esplash, you will be prompted to select a USB port. If this port is always the same, then you can also pass it as a parameter on the command line to avoid the prompt. For example if /dev/ttyUSB1 is the device file for your port, the command line changes to espflash --monitor /dev/ttyUSB1 path/to/binary/to/flash_and_monitor.

ESP32-S3-Box

To compile and run the demo:

CARGO_PROFILE_RELEASE_OPT_LEVEL=s cargo +esp run -p printerdemo_mcu --target xtensa-esp32s3-none-elf --no-default-features --features=mcu-board-support/esp32-s3-box-3 --release --config examples/mcu-board-support/esp32_s3_box_3/cargo-config.toml