Serverless MCU Lambdas
I want to learn more about bare metal MCU programming. So I came with a crazy idea: instead of emulating webassembly, let’s emulate a RiscV MCU in serverless style.
REST API
Serverless means HTTP REST usually. Let’s have a very simple API.
PUT /mcu
> ... ROM binary ...
GET /mcu
< ... ROM binary ...
POST /mcu
> ... IN binary ...
< ... OUT binary ...
Each call has 2 optional params : /mcu[/rom-uuid[/ram-uuid]]
.
They represent the ROM and the RAM. The ROM is autogenerated after a PUT
and the RAM is autogenerated after a POST
. The UUID are sent via Set-Cookie
headers. This enables to transparently benefit of those, since the parameters are also picked from cookies.
URL parameters obviously have precedence over cookie ones.
The RAM uuid enables to chain multiple calls. Think of it as a session. Per default it is all zero initialized.
There is no encoding of binary content, as the HTTP layer takes eventually care of it. So TLS and Deflate are possible, even recommended.
HTTP Server
I went the simplest road ever : CGI.
Actually lighttpd
and /bin/sh
. Those setup the ROM, RAM and IO. Then they delegate to rv32im
for the real execution.
rv32im Emulator
Launching is very easy.
rv32im /rom.file /ram.file /io/in.file /io/out.file
The ROM and IN file are R/O, the RAM is R/W and the OUT file is W/O.
The idea being that everything can be mmap inside the emulator address space so it offers nice memory protection, along with adequate performance since no copy takes place.
The emulator can then use those files in place and not worry about the filesystem. It is up to the caller to have correct file sizes.
Initial size is 32MiB for every file. The files are zero-padded or zero-truncated.
The number of CPU cycles is also capped, along with the maximum execution time. As soon as the POWER DOWN
sequence is started or timeout happens, execution is stopped and the reply is sent.