Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
micro-repl
Advanced tools
An easy, SerialPort or Xterm.js based, MicroPython REPL for micro controllers
Social Media Photo by Luca J on Unsplash
An easy, SerialPort based, MicroPython REPL for micro controllers.
It is very likely that your MicroPython based board works too but these have been manually, and personally, tested during the development of this module:
dfu-util -a 0 -d 0x2341:0x0070 -D ./ARDUINO_NANO_ESP32-X.app-bin
to install MicroPython on it: app-bin downloadThe currently maintained and developed export is micro-repl/serial
(previously known as board) which supports the following features:
name
showed as soon as connected and associated to the board instanceondata(buffer:Uint8Array)
passes along, while interacting, every single char the user is asking foreval
method, if awaited and the end of the code has a reference or an expression, will return that value, if any, beside evaluating code without showing it on REPL shell. If the extra options
reference hidden
value is false
, it also shows the evaluated code while streaming it to the board.paste
method to pass along code in "paste mode" with ease, where raw: true
is also availableThe micro-repl/board
alias still exists but it's now micro-repl/serial
instead, to eventually allow micro-repl/bt
and others within the same ease of use.
The easiest way to use micro-repl/serial
is via CDN:
<script type="module">
import Serial from 'https://esm.run/micro-repl/serial';
// either Serial(...) or new Serial(...)
const board = Serial({
// all optionals
baudRate: 9600, // defaults to 115200
onconnect() { console.info('connected') },
ondisconnect() { console.warn('disconnected') },
onerror(error) { console.error(error) },
ondata(buffer) { },
// pass a different JSON parser if needed: json.loads,
// as example, would return directly Python references
onresult: JSON.parse,
});
// to connect a board a user action/gesture is needed
document.getElementById('repl').onclick = async event => {
event.preventDefault();
// connect the board to a DOM element to show the terminal
await board.connect(event.target);
};
</script>
<div id="repl"></div>
Documented via JSDoc TS, these are all explicit TS details around this module's API.
These are all optional fields that can be passed when creating a new Serial.
type MicroREPLOptions = {
// default: 115200
baudRate?: number | undefined;
// default: 'buffer'
dataType?: 'buffer' | 'string';
// default: console.error
onerror?: ((error: Error) => void) | undefined;
// default: () => void - notifies when the board is connected
onconnect?: (() => void) | undefined;
// default: () => void - notifies when the board is disconnected/lost
ondisconnect?: (() => void) | undefined;
// default: () => void - receives all data from the terminal
ondata?: ((buffer: Uint8Array) => void) | undefined;
// allow terminal easy-theme setup - if values are "infer"
// these are retrieved via computed style / CSS values
// for background (or background-color) and color (as foreground)
// default: { background: "#191A19", foreground: "#F5F2E7" }
theme?: {
background: string;
foreground: string;
} | undefined;
}
A serial board can be created via new Serial(options)
or just direct Serial(options)
( which is more Pythonic ) and its returned reference is always an instanceof Serial
.
type MicroREPLSerialBoard = {
// `true` when connected, `false` otherwise
readonly connected: boolean;
// the passed `baudRate` option
readonly baudRate: number;
// the connected board name
readonly name: string;
// the Terminal reference once connected
readonly terminal: xterm.Terminal;
// ⚠️ must be done on user action !!!
// connects the board and show the REPL in the specified `target`
// `target` can be either a DOM Element or an element ID or a CSS selector.
connect: (target: Element | string) => Promise<MicroREPLSerialBoard | void>;
// disconnect the board and invoke ondisconnect
disconnect: () => Promise<void>;
// soft-reset the board and put it back into REPL mode
reset: () => Promise<void>;
// write any string directly to the board
write: (code: string) => Promise<void>;
// eval any code (no output while processing)
// if the end of the `code` is a reference, it tries
// to json serialize it and parse it back as result.
// if the options.hidden is `false` it shows the input
// while evaluating code.
eval: (code: string, options?: { hidden:boolean }) => Promise<any>;
// enter paste mode, write all code, then exit from paste mode
paste: (code: string, options?: { hidden:boolean, raw:boolean }) => Promise<void>;
// upload content as text or `File` and save it as `path` name
upload: (path: string, content: string | File, on_progress?: (current:number, total:number) => void) => Promise<void>;
}
Please note that board.write(code)
requires \r\n
at the end if you want your code to be executed.
Please also note this is not the same as board.terminal.write(...)
because the terminal depends on writes on the board, not vice-versa.
WARNING
Please note this module is experimental. The current exports might change if actually the board reference is the best option this module offers (and I am definitively leading toward this conclusion).
If you are on Linux and you can't see your Prime you can try to force-enable it by writing the following content into /etc/udev/rules.d/50-myusb.rules
:
KERNEL=="ttyACM[0-9]*",MODE="0666"
After a reboot, this instruction should enable it and you should see it selectable.
This project has been inspired by pyrepl-js but because I think React and TypeScript, plus the rest of the logic, was a bit too much for a basic core REPL, I've decided to create a minimal JS standard module able to do pretty much the same in way less code to maintain. Feel free to use that project if you want a more rich UI around the connection, events instead of just promises to deal with unbuffered data as sent by the controller, and everything else in there which I didn't need to create those live demoes.
deprecated
Once a repl
has been successfully initialized, it offers this API:
// The default export TS signature
({ baudRate, onceClosed, }?: {
baudRate: number; // default: 115200
onceClosed(error: Error | null): void;
}) => Promise<{
readonly active: boolean;
readonly result: Promise<string>;
readonly output: Promise<string>;
write: (code: string) => Promise<...>;
close: () => Promise<...>;
}>
boolean
- it's true
when the REPL is active and running, false
otherwise.Promise<string>
- it contains the last line produced by the last executed code.Promise<string>
- it awaits for the last executed code to execute and returns whatever that code produced, including the written code itself. Please note this throws an error if the active
state is not true
.(code:string) => Promise<void>
- it writes code to the boards' REPL and it fulfills after all code has been sent. Please note this throws an error if the active
state is not true
.() => Promise<void>
- it detaches all streams and gracefully clean up the repl
state right before disconnecting it.// check the board status
repl.active; // true
// write code into the REPL
await repl.write('print("Hello MicroPython")');
// wait/check the produced REPL outcome
await repl.output;
/**
* >>> print("Hello MicroPython")
* Hello MicroPython
*/
// check the result (last printed line of the REPL)
await repl.result; // "Hello MicroPython"
// disconnect the board
await repl.close();
// check the board status again
repl.active; // false
FAQs
An easy, SerialPort or Xterm.js based, MicroPython REPL for micro controllers
We found that micro-repl demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.