# MCUmgr Client for Zephyr

[![Crates.io](https://img.shields.io/crates/v/mcumgr-toolkit)](https://crates.io/crates/mcumgr-toolkit)
[![PyPI - Version](https://img.shields.io/pypi/v/mcumgr-toolkit)](https://pypi.org/project/mcumgr-toolkit/)
[![Crates.io](https://img.shields.io/crates/d/mcumgr-toolkit)](https://crates.io/crates/mcumgr-toolkit)
[![License](https://img.shields.io/crates/l/mcumgr-toolkit)](https://github.com/Finomnis/mcumgr-toolkit/blob/main/LICENSE-MIT)
[![Build Status](https://img.shields.io/github/actions/workflow/status/Finomnis/mcumgr-toolkit/ci.yml?branch=main)](https://github.com/Finomnis/mcumgr-toolkit/actions/workflows/ci.yml?query=branch%3Amain)
[![docs.rs](https://img.shields.io/docsrs/mcumgr-toolkit)](https://docs.rs/mcumgr-toolkit)
[![Coverage Status](https://img.shields.io/codecov/c/github/Finomnis/mcumgr-toolkit)](https://app.codecov.io/github/Finomnis/mcumgr-toolkit)

This crate provides a full Rust-based software suite for Zephyr's [MCUmgr protocol](https://docs.zephyrproject.org/latest/services/device_mgmt/mcumgr.html).

It might be compatible with other MCUmgr/SMP-based systems, but it is developed with Zephyr in mind.

Specifically, it provides:

- [`mcumgrctl`](https://crates.io/crates/mcumgrctl), a CLI tool for running MCUmgr actions via command line
- A [Rust library](https://crates.io/crates/mcumgr-toolkit) that supports all Zephyr MCUmgr commands
- A [Python interface](https://pypi.org/project/mcumgr-toolkit/) for the library

Its primary design goals are:
- Completeness
  - cover all use cases of Zephyr's MCUmgr
  - for implementation progress, see this [tracking issue](https://github.com/Finomnis/mcumgr-toolkit/issues/32)
- Performance
  - use static memory and large buffers to prioritize performance
    over memory footprint
  - see further down for more information regarding performance
    optimizations required on Zephyr side


## Usage Example

```rust no_run
use mcumgr_toolkit::MCUmgrClient;
use std::time::Duration;

fn main() {
    let serial = serialport::new("COM42", 115200).open().unwrap();

    let mut client = MCUmgrClient::new_from_serial(serial);
    client.use_auto_frame_size().unwrap();

    println!("{:?}", client.os_echo("Hello world!").unwrap());
}
```

```none
"Hello world!"
```

## Installation as command line tool

```none
cargo install mcumgrctl
```

### Usage examples

List all available USB serial ports:

```none
$ mcumgrctl --usb-serial

Available USB serial ports:

 - 2fe3:0004:0 (/dev/ttyACM0) - Zephyr Project CDC ACM serial backend
```

> [!TIP]
> `2fe3:0004` is the default VID/PID of Zephyr samples.

Run a simple connection test:

```none
$ mcumgrctl --usb-serial 2fe3:0004
Device alive and responsive.
```

You can also use a normal serial port descriptor:

```none
$ mcumgrctl --serial COM42
Device alive and responsive.
```

Or even a regular expression if you want:

```none
$ mcumgrctl --usb-serial "2fe3:.*"
Device alive and responsive.
```

> [!TIP]
> Use `mcumgrctl -u .` if you only have a single USB serial device connected.

Perform a firmware update:

```none
$ mcumgrctl -u . firmware update zephyr.signed.encrypted.bin
Detecting bootloader ...
Found bootloader: MCUboot
Parsing firmware image ...
Querying device state ...
Update: 1.2.3.4-f0a745b8 -> 1.2.3.5-79f50793
Uploading new firmware ...
Activating new firmware ...
Triggering device reboot ...
Success.
Device should reboot with new firmware.
```

Or show device information:

```none
$ mcumgrctl -u . os application-info

OS/Application Info:
    Kernel name:       Zephyr
    Node name:         unknown
    Kernel release:    v4.3.0-3-gc87e528897ea
    Kernel version:    4.3.0
    Build time:        Sat Jan 24 10:39:08 2026
    Machine:           arm
    Processor:         cortex-m4
    Hardware platform: nrf52840dongle/nrf52840/bare
    Operating system:  Zephyr
```

For more information, run `mcumgrctl --help`.

### Autocomplete

Shell autocomplete is provided through [`clap_complete::env`](https://docs.rs/clap_complete/latest/clap_complete/env/index.html).
Read its documentation for more information on how to use it.

## Usage as a library

To use this library in your project, enter your project directory and run:

```none
cargo add mcumgr-toolkit
```

## Performance

Zephyr's default buffer sizes are quite small and reduce the read/write performance drastically.

The central most important setting is [`MCUMGR_TRANSPORT_NETBUF_SIZE`](https://github.com/zephyrproject-rtos/zephyr/blob/v4.2.1/subsys/mgmt/mcumgr/transport/Kconfig#L40). Its default of 384 bytes is very limiting, both for performance and as cutoff for large responses, like `os task_statistics` or some shell commands.

Be aware that changing this value also requires an increase of `MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE` to prevent overflow crashes.

In practice, I found that the following values work quite well (on i.MX RT1060)
and give me 410 KB/s read and 120 KB/s write throughput, which is an order of magnitude faster than the default settings.

```kconfig
CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=4096
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=8192
```

If the experience differs on other chips, please open an issue and let me know.

## Contributions

Contributions are welcome!

I primarily wrote this crate for myself, so any ideas for improvements are greatly appreciated.
