Microquine: self-replicating microcontroller code
In this project, we explore self-replication of microcontroller code. The code can jump hosts by simply streaming its own bytes on a UART port.
We picked an RP2040 microcontroller equipped with Micropython for the following reasons:
- As an interpreted language, it offers self-reflection at no extra cost
- The Python interpreter (REPL) can be made available directly on the UART port of the RP2040
- Sending a
CTRL-C
(=\x03
) character resets the target microcontroller and gets it ready for code injection, no matter its current state
Board
The board we built for these experiments is a xiao RP2040 with a single cell LiPo battery, a piezo buzzer and UART connectors:
The LiPo battery is mounted in the back, in a 3D printed enclosure. Thanks to a specific charging manager IC, it can be charged directly from the USB connector's 5V.
Micropython firmware
For the purpose of this project, we use a version of Micropython in which the REPL can talk to the UART port, in addition to the usual USB CDC port.
You can find a .uf2
build of this firmware here.
You can install Micropython on the board by resetting the xiao RP2040 and dragging the .uf2
file onto the flash drive that shows up.
To verify that the REPL is available on the RP2040's UART port, you can connect a USB-to-serial adapter directly to it and power the board through its battery alone:
The USB-to-serial adapter should be set to a baudrate of 115200
. If successful, you'll be greeted by the REPL as if you were directly connected to the RP2040 through its native USB port.