Appendix C: Built-in Types and Classes
The transpiler provides the following types, classes, and instances. None of
them requires an import, and their names cannot be redefined.
Generic value types
| Type |
Variants / contents |
Purpose |
Option<T> |
Some(T), None |
A value that may be absent |
Status<T> |
Success, Failure(T) |
Outcome of an operation with no produced value |
Result<T; E> |
Ok(T), Error(E) |
Outcome of a computation that produces a value |
box T |
owned block holding a T |
Linear handle to pool memory |
Structures and enumerations
| Type |
Contents |
Purpose |
TimeVal |
tv_sec, tv_usec |
Time representation |
SysPrintBase |
Decimal, Hexadecimal |
Numeric base for the print services |
Exception |
EActionFailure, EMsgQueueSendError, EMsgQueueRecvError, EArrayIndexOutOfBounds, EArraySliceOutOfBounds, EArraySliceNegativeRange, EArraySliceInvalidRange, EShiftAmountOutOfBounds, EArithmeticOverflow, EDivisionByZero, ERuntimeFailure, EProcessorFault, EKernelFailure, EStackOverflow |
Runtime exception delivered by system_except |
ExceptSource |
Task(usize), Handler(usize) |
The entity whose action failed, in EActionFailure |
ERuntimeFailure(u32, i32) reports a failure of the runtime itself, which the
application cannot handle. The first value is the operation that failed:
| Operation |
Value |
| Taking a mutex |
0 |
| Giving a mutex back |
1 |
| Arming a periodic timer |
2 |
| Making a task ready to run |
3 |
| Returning a block to its pool |
4 |
| Dispatching an event to the action of a task |
5 |
| Dispatching an interrupt to its handler |
6 |
The i32 that ERuntimeFailure, EMsgQueueSendError and EMsgQueueRecvError
carry is the cause of the failure, with the same value on every operating
system:
| Cause |
Value |
| Identifier out of range |
200 |
| The queue is full |
201 |
| Receiving from the queue failed |
202 |
| No memory for the message |
203 |
| The message is a null pointer |
204 |
| Another task holds the mutex |
205 |
| The caller does not hold the mutex |
206 |
| The caller is above the ceiling of the mutex |
207 |
| The timer cannot be armed |
208 |
| The task cannot be made ready to run |
209 |
| The address is not the start of a block of the pool |
210 |
| No handler is registered for the interrupt |
211 |
| Any other error of the operating system |
999 |
Three variants report faults that the runtime does not detect by itself but
receives from the processor or from the operating system. Their values are
those of the platform, so they are decoded with the platform at hand:
EProcessorFault(u32, u32, usize, usize) is a fault of the processor. Its
values are the exception number of the architecture, the fault status
register (0 when the architecture has none), the address of the instruction
that failed and the faulting address (0 when the architecture gives none).
On the Cortex-A9 of the Zynq-7000 they come from the exception frame of
RTEMS and from DFSR and DFAR, or IFSR and IFAR; on the Cortex-M4 of
the Nucleo, from the HardFault with CFSR and MMFAR or BFAR; on LEON3,
from the trap type and its program counter; on posix-gcc, from the signal,
its si_code and si_addr.
EKernelFailure(u32, usize) is a fatal error raised by the operating system
itself, with its source and code. On RTEMS they are the source and the code
of the fatal error; on FreeRTOS the source 1 is a failed assertion of the
kernel, and its code is the address of the assertion.
EStackOverflow(usize) is a stack overflow that the operating system
detects, with the identifier of the task, or the largest value of usize
when the stack does not belong to a task of the application. RTEMS 6 checks
the stacks at every context switch, and FreeRTOS does the same with
configCHECK_FOR_STACK_OVERFLOW. RTEMS 5 does not check them.
Resource classes
Instances of these classes are declared in the application module:
| Class |
Declaration |
Access port type |
Pool<T; N> |
resource p : Pool<T; N>; |
access Allocator<T> |
Atomic<T> |
resource a : Atomic<T> = { value = ... }; |
access AtomicAccess<T> |
AtomicArray<T; N> |
resource a : AtomicArray<T; N> = { values = [...] }; |
access AtomicArrayAccess<T; N> |
Each access port type offers the following operations:
| Port type |
Operations |
Allocator<T> |
alloc(&mut Option<box T>), free(box T) |
AtomicAccess<T> |
load(&mut T), store(T) |
AtomicArrayAccess<T; N> |
load_index(usize, &mut T), store_index(usize, T) |
Channels and emitters
| Class |
Declaration |
MsgQueue<T; N> |
channel c : MsgQueue<T; N>; |
PeriodicTimer |
emitter e : PeriodicTimer = { period = { tv_sec = ..., tv_usec = ... } }; |
Built-in event sources
These emitters exist without being declared; a sink port is wired to them
directly:
| Name |
Event payload |
Fires |
system_init |
TimeVal |
Once, at system start-up, when enable-system-init is set; handlers only |
system_except |
Exception |
When the runtime raises an exception, when enable-system-except is set; handlers only |
irq_N |
u32 (vector) |
On hardware interrupt N (per platform) |
kbd_irq |
u32 |
On console input (posix-gcc, when enable-kbd-irq is set) |
The system interface
The system_entry instance implements the SystemAPI interface and is
deployed when enable-system-port is set in termina.yaml. It is reached
through a port declared access SystemAPI and wired with
<-> system_entry. Its procedures are the following:
| Group |
Procedures |
Typical call |
| Time |
clock_get_uptime, delay_in |
clock_get_uptime(&mut now) |
| Output |
print, println, print_char |
println(&msg) |
| Output (numeric) |
print_<T> and println_<T> for every integer type, plus print_f32/f64 and println_f32/f64 |
println_u32(value, base) |
| Input |
read |
read(&mut buf, &mut nread) |
The arrays that print, println and read take have the sizes set by
sys-print-output-buffer-size and sys-read-input-buffer-size in
termina.yaml, 256 by default, and an array of any other size is rejected.
Prelude functions
| Function |
Signature |
Purpose |
f32_to_bits |
(f32) -> u32 |
Bit pattern of a single-precision value |
f32_from_bits |
(u32) -> f32 |
Single-precision value from a bit pattern |
f64_to_bits |
(f64) -> u64 |
Bit pattern of a double-precision value |
f64_from_bits |
(u64) -> f64 |
Double-precision value from a bit pattern |