1# zig-riscv-embedded23Experimental [Zig][zig website]-based [CoAP][rfc7252] node for the [HiFive1][hifive1 website] RISC-V board.4567## Status89This repository is intended to provide a simple sample application for10experimenting with the Zig programming language on freestanding RISC-V.11The application targets the [SiFive FE310-G000][fe310 manual] or more12specifically the [HiFive 1][hifive1 website]. While possible to run the13application on "real hardware", it can also be run using QEMU. In both14cases it is possible to toggle an LED using [CoAP][rfc7252] over15[SLIP][rfc1055].1617## CoAP over SLIP1819To experiment with external dependencies in Zig, this application20provides a very bare bone implementation of [CoAP][rfc7252] using21[zoap][zoap github]. Since implementing an entire UDP/IP stack from22scratch is out-of-scope, this repository transports CoAP packets23directly over [SLIP][rfc1055].2425Unfortunately, the QFN48 package of the FE310-G000 (as used by the26HiFive1) does not support the UART1. For this reason, the application27multiplexes diagnostic messages and CoAP frames over the same UART28(UART0) using [Slipmux][slipmux]. For this purpose, a Go-based29multiplexer for the development system is available in the `./slipmux`30subdirectory.3132## Dependencies3334For building the software and the associated Slipmux tooling, the35following software is required:3637* Zig `0.9.1`38* [Go][golang web] for compiling the `./slipmux` tool39* A CoAP client, e.g. `coap-client(1)` from [libcoap][libcoap github]40* QEMU (`qemu-system-riscv32`) for emulating a HiFive1 (optional)4142For flashing to real hardware, the following software is required:4344* [riscv-openocd][riscv-openocd]45* [GDB][gdb web] with 32-bit RISC-V support4647## Building4849The Zig build system is used for building the application, the50configuration is available in `build.zig`. To build the application run:5152 $ zig build5354This will create a freestanding RISC-V ELF binary `zig-out/bin/main`.55If the image should be booted on real hardware, building in the56`ReleaseSmall` [build mode][zig build modes] may be desirable:5758 $ zig build -Drelease-small5960Furthermore, the Slipmux multiplexer needs to be compiled using the61following commands in order to receive diagnostic messages from the62device and send CoAP messages to the device:6364 $ cd slipmux && go build -trimpath6566## Booting in QEMU6768In order to simulate a serial device, which can be used with the69`./slipmux` tool, QEMU must be started as follows:7071 $ qemu-system-riscv32 -M sifive_e -nographic -kernel zig-out/bin/main -serial pty7273QEMU will print the allocated PTY path to standard output. In a separate74terminal the `./slipmux` tool can then be started as follows:7576 $ ./slipmux/slipmux :2342 <PTY allocated by QEMU>7778This will create a UDP Socket on `localhost:2342`, CoAP packets send to79this socket are converted into Slipmux CoAP frames and forwarded to the80emulated HiFive1 over the allocated PTY. CoAP packets can be send using81any CoAP client, e.g. using `coap-client(1)` from [libcoap][libcoap github]:8283 $ coap-client -N -m put coap://[::1]:2342/on84 $ coap-client -N -m put coap://[::1]:2342/off8586In QEMU, this will cause debug messages to appear in the terminal window87were `./slipmux` is running. On real hardware, it will also cause the88red LED to be toggled.8990## Booting on real hardware9192The binary can be flashed to real hardware using OpenOCD and gdb. For93this purpose, a shell script is provided. In order to flash a compiled94binary run the following command:9596 $ ./flash9798After flashing the device, interactions through CoAP are possible using99the instructions given for QEMU above. However, with real hardware100`./slipmux` needs to be passed the TTY device for the HiFive1 (i.e.101`/dev/ttyUSB0`).102103To debug errors on real hardware start OpenOCD using `openocd -f104openocd.cfg`. In a separate terminal start a gdb version with RISC-V105support (e.g. [gdb-multiarch][gdb-multiarch alpine]) as follows:106107 $ gdb-multiarch -ex 'target extended-remote :3333' zig-out/bin/main108109## Development110111A pre-commit git hook for checking if files are properly formated is112provided in `.githooks`. It can be activated using:113114 $ git config --local core.hooksPath .githooks115116## License117118The application uses slightly modified linker scripts and assembler119startup code copied from the [RIOT][riot fe310] operating system. Unless120otherwise noted code written by myself is licensed under121`AGPL-3.0-or-later`. Refer to the license headers of the different files122for more information.123124[zig website]: https://ziglang.org/125[zig build modes]: https://ziglang.org/documentation/master/#Build-Mode126[qemu website]: https://www.qemu.org/127[fe310 manual]: https://static.dev.sifive.com/FE310-G000.pdf128[hifive1 website]: https://www.sifive.com/boards/hifive1129[riot fe310]: https://github.com/RIOT-OS/RIOT/tree/master/cpu/fe310130[slipmux]: https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03131[rfc7252]: https://datatracker.ietf.org/doc/html/rfc7252132[rfc1055]: https://datatracker.ietf.org/doc/html/rfc1055133[libcoap github]: https://github.com/obgm/libcoap134[golang web]: https://golang.org135[zoap github]: https://github.com/nmeum/zoap136[riscv-openocd]: https://github.com/riscv/riscv-openocd137[gdb web]: https://www.gnu.org/software/gdb/138[gdb-multiarch alpine]: https://pkgs.alpinelinux.org/package/edge/main/x86_64/gdb-multiarch