Skip to content

MicroCli is a simple async CLI implementation for embedded systems in Rust

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

LinkWanna/microcli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MicroCli

MicroCli is a lightweight, fully asynchronous Rust terminal implementation compatible with VT100 terminals. It is designed specifically for bare-metal embedded systems. By leveraging Rust's async features, MicroCli can run efficiently even on microcontrollers with extremely limited resources.

Features

  • Broad microcontroller compatibility: Leveraging embedded-hal, MicroCli supports a comprehensive range of microcontrollers, including stm32, nRF, rp2040(w), esp32, etc
  • Asynchronous architecture: Thanks to its asynchronous design, MicroCli does not block operations, making it suitable for small microcontrollers with limited resources.
  • VT100 compatibility: MicroCli is compatible with VT100 terminals, ensuring seamless integration with standard terminal emulators.
  • No dynamic memory allocation: MicroCli avoids dynamic memory allocation, preventing memory leaks and ensuring stability in resource-constrained environments.
  • Extensible: MicroCli is designed to be easily extendable, allowing developers to add custom features as needed.

Usage

Due to its asynchronous nature, MicroCli requires an async executor like Embassy to run. Below is an example of how to set up and use MicroCli on an STM32F103C8T6 microcontroller.

/// Declare your async command handler functions
async fn led_cmd1<'a>(cli: &mut MCli<'a, BufferedUartTx<'a>, BufferedUartRx<'a>>) {
    let argv = cli.argv();
    // usage: led[1|2] on|off|toggle
    if argv.len() != 2 {
        cli.write(b"usage: led[1|2] on|off|toggle\r\n")
            .await
            .expect("write failed");
        return;
    }

    match argv[1] {
        b"on" => CNT_CHANNEL.try_send((1, LedCommand::On)).ok(),
        b"off" => CNT_CHANNEL.try_send((1, LedCommand::Off)).ok(),
        b"toggle" => CNT_CHANNEL.try_send((1, LedCommand::Toggle)).ok(),
        _ => None,
    };
}
async fn led_cmd2<'a>(cli: &mut MCli<'a, BufferedUartTx<'a>, BufferedUartRx<'a>>) {
    let argv = cli.argv();
    // usage: led[1|2] on|off|toggle
    if argv.len() != 2 {
        cli.write(b"usage: led[1|2] on|off|toggle\r\n")
            .await
            .expect("write failed");
        return;
    }

    match argv[1] {
        b"on" => CNT_CHANNEL.try_send((2, LedCommand::On)).ok(),
        b"off" => CNT_CHANNEL.try_send((2, LedCommand::Off)).ok(),
        b"toggle" => CNT_CHANNEL.try_send((2, LedCommand::Toggle)).ok(),
        _ => None,
    };
}

/// Define your CLI task using the cli_runner! macro
cli_runner!(
    pub async fn cli_inner_task(
        tx: BufferedUartTx<'_>,
        rx: BufferedUartRx<'_>
    );

    host = "F103C8TC6",
    cli_size = 32,
    commands = [
        ("led1", "Control LED 1") => led_cmd1,
        ("led2", "Control LED 2") => led_cmd2,
    ]
);

/// Spawn the CLI task in your executor and run cli_inner_task inside it
#[embassy_executor::task]
async fn cli_task(tx: BufferedUartTx<'static>, rx: BufferedUartRx<'static>) {
    cli_inner_task(tx, rx).await;
}

Once you have set up the CLI task, you can interact with it using a terminal emulator like picocom, minicom, or screen. Below is an example of how to use picocom to connect to the microcontroller and interact with the CLI.

# Example terminal session using picocom
$ picocom -b 115200 /dev/ttyUSB0
[F103C8TC6]$
[F103C8TC6]$ help
Available commands:
  help                  - list available commands
  led1                  - Control LED 1
  led2                  - Control LED 2
[F103C8TC6]$ led
Unavailable commands
[F103C8TC6]$ led1
usage: led[1|2] on|off|toggle
[F103C8TC6]$ led1 on
[F103C8TC6]$ led1 off
[F103C8TC6]$ led2 toggle
[F103C8TC6]$ help
Available commands:
  help                  - list available commands
  led1                  - Control LED 1
  led2                  - Control LED 2
[F103C8TC6]$

About

MicroCli is a simple async CLI implementation for embedded systems in Rust

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages