ChibiOS/RT
5.1.0
|
ChibiOS/RT Kernel Concepts
ChibiOS/RT APIs are all named following this convention: ch<group><action><suffix>(). The possible groups are: Sys, Sch, Time, VT, Thd, Sem, Mtx, Cond, Evt, Msg, Reg, SequentialStream, IO, IQ, OQ, Dbg, Core, Heap, Pool.
The suffix can be one of the following:
Examples: chThdCreateStatic()
, chSemSignalI()
, chIQGetTimeout()
.
In ChibiOS/RT there are three logical interrupt classes:
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.
When using ChibiOS/RT the system can be in one of the following logical operating states:
chSysInit()
. This state is entered after a physical reset.chSysDisable()
or chSysEnable()
in order to change state.chSysSuspend()
or chSysEnable()
in order to change state.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.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:
Note, the SFI, Halted and SNMI states were not shown because those are reachable from most states:
The strategy is very simple the currently ready thread with the highest priority is executed. If more than one thread with equal priority are eligible for execution then they are executed in a round-robin way, the CPU time slice constant is configurable. The ready list is a double linked list of threads ordered by priority.
Note that the currently running thread is not in the ready list, the list only contains the threads ready to be executed but still actually waiting.
The image shows how threads can change their state in ChibiOS/RT.
Priorities in ChibiOS/RT are a contiguous numerical range but the initial and final values are not enforced.
The following table describes the various priority boundaries (from lowest to highest):
IDLEPRIO
, this is the lowest priority level and is reserved for the idle thread, no other threads should share this priority level. This is the lowest numerical value of the priorities space.LOWPRIO
, the lowest priority level that can be assigned to an user thread.NORMALPRIO
, this is the central priority level for user threads. It is advisable to assign priorities to threads as values relative to NORMALPRIO
, as example NORMALPRIO-1 or NORMALPRIO+4, this ensures the portability of code should the numerical range change in future implementations.HIGHPRIO
, the highest priority level that can be assigned to an user thread.ABSPRO
, absolute maximum software priority level, it can be higher than HIGHPRIO
but the numerical values above HIGHPRIO
up to ABSPRIO
(inclusive) are reserved. This is the highest numerical value of the priorities space.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, usually 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:
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).