https://github.com/marcinbor85/microshell
MicroShell is a lightweight pure C implementation of shell emulator dedicated for embedded bare-metal systems.
https://github.com/marcinbor85/microshell
arduino bash cli embedded esp32 filesystem path root serial shell stm32 terminal vt100
Last synced: 27 days ago
JSON representation
MicroShell is a lightweight pure C implementation of shell emulator dedicated for embedded bare-metal systems.
- Host: GitHub
- URL: https://github.com/marcinbor85/microshell
- Owner: marcinbor85
- License: mit
- Created: 2021-04-08T19:04:46.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2024-06-20T12:20:57.000Z (over 1 year ago)
- Last Synced: 2024-06-24T01:03:17.396Z (over 1 year ago)
- Topics: arduino, bash, cli, embedded, esp32, filesystem, path, root, serial, shell, stm32, terminal, vt100
- Language: C
- Homepage: https://microshell.pl
- Size: 630 KB
- Stars: 223
- Watchers: 14
- Forks: 32
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-embedded-software - microshell - Lightweight pure C implementation of virtual shell, compatible with VT100 terminal. Support root tree, run-time mounting paths, global commands, and much more. (User Interface / CLI)
README
[](https://travis-ci.org/marcinbor85/microshell)
[](https://codecov.io/gh/marcinbor85/microshell)
# 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](https://microshell.pl/)\
[LIVE DEMO](https://microshell.pl/demo) <- needs PC web browser (not mobile)

## 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:
```sh
git submodule update --init
```
Build, test and run DEMO:
```sh
cmake -Bbuild .
cd build
make
make test
make coverage
./bin/demo
```
## Usage
Define I/O interface:
```c
// non-blocking read interface
static int ush_read(struct ush_object *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 ush_write(struct ush_object *self, char ch)
{
// should be implemented as a FIFO
return (Serial.write(ch) == 1);
}
// I/O interface descriptor
static const struct ush_io_interface ush_iface = {
.read = ush_read,
.write = ush_write,
};
```
Define shell descriptor and shell instance:
```c
// working buffers allocations (size could be customized)
#define BUF_IN_SIZE 32
#define BUF_OUT_SIZE 32
#define PATH_MAX_SIZE 32
static char ush_in_buf[BUF_IN_SIZE];
static char ush_out_buf[BUF_OUT_SIZE];
// microshell instance handler
static struct ush_object ush;
// microshell descriptor
static const struct ush_descriptor ush_desc = {
.io = &ush_iface, // I/O interface pointer
.input_buffer = ush_in_buf, // working input buffer
.input_buffer_size = sizeof(ush_in_buf), // working input buffer size
.output_buffer = ush_out_buf, // working output buffer
.output_buffer_size = sizeof(ush_out_buf), // working output buffer size
.path_max_length = PATH_MAX_SIZE, // path maximum length (stack)
.hostname = "arduino", // hostname (in prompt)
};
// root directory handler
static struct ush_node_object root;
```
Setup and run:
```c
void setup()
{
// initialize I/O interface
Serial.begin(115200UL);
// initialize microshell instance
ush_init(&ush, &ush_desc);
// mount root directory (root must be first)
ush_node_mount(&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!\
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EQJAX25PAQKCS)