Nil RTOS Kernel Concepts
Ignore the Rest of this Page
This page has not been edited for Nil RTOS.
Naming Conventions
Nil RTOS APIs are all named following this convention: nil<group><action><suffix>(). The possible groups are: Sys, Thd, Sem.
API Name Suffixes
The suffix can be one of the following:
- None, APIs without any suffix can be invoked only from the user code in the Normal state unless differently specified. See System States.
- "I", I-Class APIs are invokable only from the I-Locked or S-Locked states. See System States.
- "S", S-Class APIs are invokable only from the S-Locked state. See System States.
Examples: nilThdSleep(), nilSemSignalI(), nilSysHalt().
Interrupt Classes
In ChibiOS/RT there are three logical interrupt classes:
- Regular Interrupts. Maskable interrupt sources that cannot preempt (small parts of) the kernel code and are thus able to invoke operating system APIs from within their handlers. The interrupt handlers belonging to this class must be written following some rules. See the web article How to write interrupt handlers.
- Fast Interrupts. Maskable interrupt sources with the ability to preempt the kernel code and thus have a lower latency and are less subject to jitter, see the web article Response Time and Jitter. Such sources are not supported on all the architectures.
Fast interrupts are not allowed to invoke any operating system API from within their handlers. Fast interrupt sources may, however, pend a lower priority regular interrupt where access to the operating system is possible.
- Non Maskable Interrupts. Non maskable interrupt sources are totally out of the operating system control and have the lowest latency. Such sources are not supported on all the architectures.
The mapping of the above logical classes into physical interrupts priorities is, of course, port dependent. See the documentation of the various ports for details.
System States
When using ChibiOS/RT the system can be in one of the following logical operating states:
- Init. When the system is in this state all the maskable interrupt sources are disabled. In this state it is not possible to use any system API except
chSysInit(). This state is entered after a physical reset.
- Normal. All the interrupt sources are enabled and the system APIs are accessible, threads are running.
- Suspended. In this state the fast interrupt sources are enabled but the regular interrupt sources are not. In this state it is not possible to use any system API except
chSysDisable() or chSysEnable() in order to change state.
- Disabled. When the system is in this state both the maskable regular and fast interrupt sources are disabled. In this state it is not possible to use any system API except
chSysSuspend() or chSysEnable() in order to change state.
- Sleep. Architecture-dependent low power mode, the idle thread goes in this state and waits for interrupts, after servicing the interrupt the Normal state is restored and the scheduler has a chance to reschedule.
- S-Locked. Kernel locked and regular interrupt sources disabled. Fast interrupt sources are enabled. S-Class and I-Class APIs are invokable in this state.
- I-Locked. Kernel locked and regular interrupt sources disabled. I-Class APIs are invokable from this state.
- Serving Regular Interrupt. No system APIs are accessible but it is possible to switch to the I-Locked state using
chSysLockFromIsr() and then invoke any I-Class API. Interrupt handlers can be preemptable on some architectures thus is important to switch to I-Locked state before invoking system APIs.
- Serving Fast Interrupt. System APIs are not accessible.
- Serving Non-Maskable Interrupt. System APIs are not accessible.
- Halted. All interrupt sources are disabled and system stopped into an infinite loop. This state can be reached if the debug mode is activated and an error is detected or after explicitly invoking
chSysHalt().
Note that the above states are just Logical States that may have no real associated machine state on some architectures. The following diagram shows the possible transitions between the states:
Scheduling
The strategy is very simple the currently ready thread with the highest priority is executed.
A thread's priority is determined by its position in the thread table with higest priority first.
Thread States
Priority Levels
Thread Working Area
Each thread has its own stack, a Thread structure and some preemption areas. All the structures are allocated into a "Thread Working Area", a thread private heap, statically declared in your code. Threads do not use any memory outside the allocated working area except when accessing static shared data.
Note that the preemption area is only present when the thread is not running (switched out), the context switching is done by pushing the registers on the stack of the switched-out thread and popping the registers of the switched-in thread from its stack. The preemption area can be divided in up to three structures:
- External Context.
- Interrupt Stack.
- Internal Context.
See the port documentation for details, the area may change on the various ports and some structures may not be present (or be zero-sized).