marcinbor85
microshell
C

MicroShell is a lightweight pure C implementation of shell emulator dedicated for embedded bare-metal systems.

Last updated Jun 16, 2026
360
Stars
55
Forks
8
Issues
0
Stars/day
Attention Score
42
Language breakdown
C 97.3%
CMake 1.6%
HTML 0.6%
JavaScript 0.4%
CSS 0.1%
Dockerfile 0.1%
โ–ธ Files click to expand
README

Build Status codecov

MicroShell

Lightweight pure C implementation of virtual shell, compatible with VT100 terminal. Support root tree, run-time mounting paths, global commands, and much more. Works out-of-the-box on Arduino-compatible boards. Dedicated for bare-metal embedded systems. Thanks to the asynchronous architecture it does not block operations and can be easily implemented even on small microcontrollers with relatively small resources.

Project Homepage\ LIVE DEMO <- needs PC web browser (not mobile)

alt text

Features

  • names autocompletation (do You like a TAB-functionality on You favorite bash shell?)
  • no dynamic allocations (no memory leaks - no problem)
  • hardware independent (works just as well on AVR, PIC, STM32, ESP32 as it on x86 or RPI)
  • rich set of examples (available in the Arduino Library Manager)
  • pure C source code (works on rich set of compilers)
  • backspace key feature (simply works)
  • compatible vith VT100 standard (works out of the box with default putty configuration)
  • easy to extend (adding more "weird" features it has never been easier)
  • buildin commands (must-have, basic support of LS, CAT, PWD, HELP, XXD, ECHO)
  • scalable (configuration allows You to exclude unnecessary modules from building)
  • translation-ready (do You want Hindi translation? no problem!)
  • no internal buffers (support unlimited data stream lengths)
  • no static variables (possibility to use multiple independent shells in single system)
  • object oriented architecture (pointers attack!)
  • support root tree with static virtual files with callbacks (full customization)
  • extremely simple to integrate (only 1 simple interface with IO operations)
  • asynchronous architecture (static callbacks is not a problem)
  • non-blocking api (You just need to call one non-blocking function on main loop)
  • unit and functional tests (for greater certainty that nothing will break down)

Build

In case you didn't use git clone --recursive you'll need to manually pull in additional submodules with:

git submodule update --init

Build, test and run DEMO:

cmake -Bbuild .
cd build
make
make test
make coverage
./bin/demo

Usage

Define I/O interface:

// non-blocking read interface
static int ushread(struct ushobject self, char ch)
{
    // should be implemented as a FIFO
    if (Serial.available() > 0) {
        *ch = Serial.read();
        return 1;
    }
    return 0;
}

// non-blocking write interface static int ushwrite(struct ushobject *self, char ch) { // should be implemented as a FIFO return (Serial.write(ch) == 1); }

// I/O interface descriptor static const struct ushiointerface ush_iface = { .read = ush_read, .write = ush_write, };

Define shell descriptor and shell instance:

// working buffers allocations (size could be customized)
#define BUFINSIZE    32
#define BUFOUTSIZE   32
#define PATHMAXSIZE  32

static char ushinbuf[BUFINSIZE]; static char ushoutbuf[BUFOUTSIZE];

// microshell instance handler static struct ush_object ush;

// microshell descriptor static const struct ushdescriptor ushdesc = { .io = &ush_iface, // I/O interface pointer .inputbuffer = ushin_buf, // working input buffer .inputbuffersize = sizeof(ushinbuf), // working input buffer size .outputbuffer = ushout_buf, // working output buffer .outputbuffersize = sizeof(ushoutbuf), // working output buffer size .pathmaxlength = PATHMAXSIZE, // path maximum length (stack) .hostname = "arduino", // hostname (in prompt) };

// root directory handler static struct ushnodeobject root;

Setup and run:

void setup()
{
    // initialize I/O interface
    Serial.begin(115200UL);

// initialize microshell instance ushinit(&ush, &ushdesc);

// mount root directory (root must be first) ushnodemount(&ush, "/", &root, NULL, 0);

// mount other directories here // ... }

void loop() { // non-blocking microshell service ush_service(&ush);

// do other non-blocking stuff here // ... }

Contribution

If You want to contribute this project - excellent! Fork it, make bugs, and send a PR :)\ If You want to support me in developing this project - please donate!\ paypal

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท marcinbor85/microshell ยท Updated daily from GitHub