Experimental Zig-based CoAP node for the HiFive1 RISC-V board.
This repository is intended to provide a simple sample application for experimenting with the Zig programming language on freestanding RISC-V. The application targets the SiFive FE310-G000 or more specifically the HiFive 1. While possible to run the application on "real hardware", it can also be run using QEMU. In both cases it is possible to toggle an LED using CoAP over SLIP.
To experiment with external dependencies in Zig, this application provides a very bare bone implementation of CoAP using zoap. Since implementing an entire UDP/IP stack from scratch is out-of-scope, this repository transports CoAP packets directly over SLIP.
Unfortunately, the QFN48 package of the FE310-G000 (as used by the
HiFive1) does not support the UART1. For this reason, the application
multiplexes diagnostic messages and CoAP frames over the same UART
(UART0) using Slipmux. For this purpose, a Go-based
multiplexer for the development system is available in the ./slipmux
subdirectory.
For building the software and the associated Slipmux tooling, the following software is required:
- Zig
0.9.1
- Go for compiling the
./slipmux
tool - A CoAP client, e.g.
coap-client(1)
from libcoap - QEMU (
qemu-system-riscv32
) for emulating a HiFive1 (optional)
For flashing to real hardware, the following software is required:
- riscv-openocd
- GDB with 32-bit RISC-V support
The Zig build system is used for building the application, the
configuration is available in build.zig
. To build the application run:
$ zig build
This will create a freestanding RISC-V ELF binary zig-out/bin/main
.
If the image should be booted on real hardware, building in the
ReleaseSmall
build mode may be desirable:
$ zig build -Drelease-small
Furthermore, the Slipmux multiplexer needs to be compiled using the following commands in order to receive diagnostic messages from the device and send CoAP messages to the device:
$ cd slipmux && go build -trimpath
In order to simulate a serial device, which can be used with the
./slipmux
tool, QEMU must be started as follows:
$ qemu-system-riscv32 -M sifive_e -nographic -kernel zig-out/bin/main -serial pty
QEMU will print the allocated PTY path to standard output. In a separate
terminal the ./slipmux
tool can then be started as follows:
$ ./slipmux/slipmux :2342 <PTY allocated by QEMU>
This will create a UDP Socket on localhost:2342
, CoAP packets send to
this socket are converted into Slipmux CoAP frames and forwarded to the
emulated HiFive1 over the allocated PTY. CoAP packets can be send using
any CoAP client, e.g. using coap-client(1)
from libcoap:
$ coap-client -N -m put coap://[::1]:2342/on
$ coap-client -N -m put coap://[::1]:2342/off
In QEMU, this will cause debug messages to appear in the terminal window
were ./slipmux
is running. On real hardware, it will also cause the
red LED to be toggled.
The binary can be flashed to real hardware using OpenOCD and gdb. For this purpose, a shell script is provided. In order to flash a compiled binary run the following command:
$ ./flash
After flashing the device, interactions through CoAP are possible using
the instructions given for QEMU above. However, with real hardware
./slipmux
needs to be passed the TTY device for the HiFive1 (i.e.
/dev/ttyUSB0
).
To debug errors on real hardware start OpenOCD using openocd -f openocd.cfg
. In a separate terminal start a gdb version with RISC-V
support (e.g. gdb-multiarch) as follows:
$ gdb-multiarch -ex 'target extended-remote :3333' zig-out/bin/main
A pre-commit git hook for checking if files are properly formated is
provided in .githooks
. It can be activated using:
$ git config --local core.hooksPath .githooks
The application uses slightly modified linker scripts and assembler
startup code copied from the RIOT operating system. Unless
otherwise noted code written by myself is licensed under
AGPL-3.0-or-later
. Refer to the license headers of the different files
for more information.