Basis: Astrobe for RISC5 and Embedded Project Oberon
Oberon RTS is an extension of Embedded Project Oberon. The Oberon sources, the Verilog sources, and not least the image boot file are the starting point to get off the ground.
This principle extends analogously to the Astrobe for RISC5 toolset: the Oberon compiler and builder, the uploader, and the terminal, including the user interaction via the latter.
In general, Embedded Project Oberon shall only be changed where essentially necessary. The goal is to remain compatible with forthcoming versions of Embedded Project Oberon.
Here’s the envisioned getting-started procedure:
- Install Embedded Project Oberon as described in Astrobe’s documentation.
- Check the functionality of the FPGA-board/Embedded Project Oberon/Astrobe tools combo.
- Create a RISC5 processor configuration file with the Oberon RTS Verilog files.
- Reprogram the FPGA board with the new RISC5 processor design for Oberon RTS.
- Restart the FPGA, booting Embedded Project Oberon.
- Compile the Oberon RTS sources with Astrobe.
- Upload the compiled Oberon RTS modules to the FPGA board.
- Restart the FPGA, booting Oberon RTS.
Note point 5: the FPGA for Oberon RTS shall support (stock) Embedded Project Oberon as well. It’s the fallback, that is, it’s always possible to boot the original SD card image, and start over. As mentioned here, the system files must be consistent regarding keys (module versions), and while experimenting it’s easy to mess up. It’s permissible to have a “compatibility switch” on the FPGA board, should that be useful.
RISC5 CPU vs. Peripherals
Astrobe’s compiler generates code for the RISC5 CPU, as defined by the corresponding Verilog design files. Consequently, this CPU is a given.
All peripheral devices are fair game for change and extension, within the constraints that
- they must interact with the RISC5 CPU (bus protocol),
- the interaction with the Astrobe tools must be conserved, and
- the system must boot from Astrobe’s boot image containing the linked Inner Core.
FPGA and Oberon RTS
The FPGA with its RISC5 CPU and the on-chip peripherals is part of Oberon RTS. When considering a system for a specific use case, a specific control program, the FPGA should be configured accordingly, containing just the required building blocks, both standard and possibly custom ones. The corresponding modules of Oberon RTS need to be selected, and possibly adapted for the problem-specific RISC5 processor.
Oberon RTS most likely will require one or more extensions to the base FPGA as defined and provided by Embedded Project Oberon, such as for scheduler support, while others are solely problem domain dependent, for example different kinds of RS232 or SPI devices.
This approach requires Oberon and Verilog skills. The goal is not to be able to install Oberon RTS and edit some configuration files. The coupling between the FPGA and Oberon RTS on the lowest level of device drivers should result in less overhead, but is somewhat more demanding on the designer and programmer of control systems for Oberon RTS.
Hardware Abstraction
The Oberon code contains many direct references to FPGA implementation specifics, too many for my taste, in particular IO addresses as well as control and status bits. While it’s not a goal to rectify this situation in general, extensions and changes should refrain from this design and coding approach, and introduce simple abstraction, or configuration, modules that represent the hardware specifics.
Ideally, a change of the FPGA implementation should only require to recompile these configuration modules, maybe also the corresponding driver modules, but not system or program modules – of course only as long as the changed FPGA implementation does not require changes of the configuration and driver modules’ exported (public) interface.
SD Card: Safe and Reliable
The file system and storage on the SD card is considered safe and reliable for now.
Interference by Console and File IO
The potential interference on real-time behaviour of console IO, as well as reading and writing the file system, due to their blocking implementation, is neglected for now.
Non-blocking console IO can probably be implemented without bigger problems. Non-blocking file IO might pose a headache. Then again, a control program, once loaded and running, should not require anymore file loading, except for a system reload in an error situation. Error logging can possibly be implemented without even writing to files, if based on defined error codes, which don’t require a lot of storage, so an FPGA-based solution might suffice. A program could then read and interpret the error codes into actual error messages.
Interference by the Garbage Collector
The potential interference by the GC is neglected for now.
A control program, once loaded and running does not allocate and abandon lots of dynamic memory. So this may or may not be an actual issue.