Note: work in progress, sketchy for now.
Oberon RTS consists of the following modules.
No major changes with respect to Embedded Oberon.
- Kernel: heap memory allocation, garbage collection, SD card IO. Allows to set the stack size.
- FileDir, Files: file system
- Modules: dynamic module loader-linker. Gets stack size from Kernel. Clears out unused slots at the top of the module memory space when a module, is discarded with Modules.Free.
Modules other than the Inner Core, but required to boot and operate Oberon RTS, are considered to be part of the Outer Core.
Outer Core modules based on Embedded Oberon:
Oberon: entry point for the Outer Core to “put together” and start the system. Sets up the system processes: scheduler, command handler, garbage collector, and audit process. The Loop and the command handling are moved to module Threads and Cmds, respectively.
System: system commands. System.ShowModules and System.Watch are extended, plus a new command System.ShowProcesses. The trap and abort handlers have been moved to module Errors.
Texts: formatted text output and input. In EO, the writer, usually denoted using parameter
W, is a dummy, as all output is hardwired to the Astrobe terminal. In Oberon RTS, output can be directed to different outputs, and parameter
Wdenotes an actual Texts.Writer, which needs to be created and initialialised. Module Console creates and exports such a writer to the Astrobe terminal.
Input: replaced by Console.
Upload: transfer files from host PC to target’s SD card, rewritten for buffered RS232, and the corresponding drivers (see below). The transfer protocol still has the known timeout issues when uploading many files, as this needs a change to the Astrobe IDE.
Added modules in Oberon RTS:
Console: read from, and write to, the Astrobe terminal, using a buffered serial RS232 device. As mentioned above, a
Texts.Writeris created and exported for all modules that need to write to the terminal.
Cmds: implements the process code to read and execute Oberon commands. Also, as in EO, the upload of modules is handled (using module Upload). In addition, if set-up and armed accordingly, start-up commands are read from the selected start-up command table (see module Start).
Threads: implements the process scheduler, and provides all definitions and procedures to create, initialise, and otherwise manage system and control processes1.
Coroutines: simple coroutines to implement the processes. The stack monitor and calltrace stacks are set during the coroutine transfer, too.
ProcTimers, ProcDelay, ProcDevsig: drivers for control devices in the FPGA for periodic timing, delay, and device-signals for process scheduling. Each process has its own set of these hardware devices.
Errors: run-time error handling, trap and abort handlers. These handlers are substantially changed for a more elaborate error handling.
Interrupts: driver for the multi-channel interrupt controller, as well as installing and enabling interrupts in general. Used for the various interrupts upon run-time errors, such as stack overflow, or the watchdog.
Start: upon system reset, the command handling process will read start-up commands from “reset-surviving” tables in the FPGA, eg. to automatically (re-)start a control program when recovering from a run-time error. More than one start-up tables are available, to allow several control programs, eg. for different modes.
SysCtrl: read and write the System Control Register SCR.
RS232dev, RS232b: buffered serial device.
These modules are not strictly part of the system, but are currently in use. That is, the system could be modified to not make use of them.
Log, LogOut: FPGA-based logger. Defined events with its corresponding data can be logged in a circular buffer in the FPGA with module Log. Module LogOut provides commands to “translate” the event data into readable text, and output them on the console.
StackMonitor: driver for the stack overflow monitor in the FPGA.
Calltrace: driver and output command for the procedure calltrace device in the FPGA.
Watchdog: driver for the watchdog device in the FPGA.
ProcMonitor: driver for the process execution monitor in the FPGA.
RTC: driver for the hardware real-time clock.
SPIdev, various SPI drivers: extended SPI device.
- The boot loader loads the boot file with the Inner Core from the SD card and terminates with a branch to address 0.
- The branch to address 0 transfers control to the body of Modules, which initialises the bodies of Files, Kernel, and FileDir (in this order). This establishes a working file system. From here on, the compiled modules of the Outer Core can be loaded from the SD card.
- Then Modules loads Oberon, which via import loads Threads, Cmds, Console, SysCtrl, Errors, Log, StackMonitor, Log, and RTC.
- Oberon installs the real time clock RTC, which is needed for the start-up logging.
- Oberon creates and installs garbage collector system process (defined in Oberon).
- Oberon creates and installs the audit process (defined in Threads).
- Oberon creates and installs the command handler system process (defined in Cmds).
- Oberon installs the trap and abort handlers, plus the error interrupt handlers (defined in Errors).
- Oberon transfers control to the scheduler (defined in Threads).
- The scheduler will start to execute the above system processes.
- The command system process executes the commands found in the selected start-up table, eg. to start a control program with its processes.
- After the system runs without errors for a defined period of time, the audit process will reset any error state.
Notably absent fomr the start-up sequence is module System, which is not required of for a working system, and will be loaded as any other module when a command in System is executed.
All important steps are logged.
Here’s a typical log output of a system start-up:
Running System.ShowProcesses right after start-up:
The module name could or should be Processes, but has “survived” from the experimental phase when I also had a module Tasks to implement the processes, using the same (more or less same) data structures and procedures. To this day, all system modules use
IMPORT Procs := Threads. ↩︎