[−][src]Crate kernel
Core Tock Kernel
The kernel crate implements the core features of Tock as well as shared code that many chips, capsules, and boards use. It also holds the Hardware Interface Layer (HIL) definitions.
Most unsafe
code is in this kernel crate.
Core Kernel Visibility
As the root crate in the Tock operating system, this crate serves multiple purposes:
-
It includes the logic for the core kernel, including process management, grants, scheduling, etc.
-
It includes important interfaces for hardware and other device abstractions. These are generally in the HIL and platform folders.
-
It includes utility functions used elsewhere in the kernel, generally by multiple different crates such that it makes sense to have shared implementations in the core kernel crate.
Because of these different features of the core kernel, managing visibility of the various objects and functions is a bit tricky. In general, the kernel crate only exposes what it absolutely needs to. However, there are three cases where resources in this crate must be exposed.
-
The shared utility functions and structs must be exposed. These are marked
pub
and are used by many other kernel crates.Some utility objects and abstractions, however, expose memory unsafe behavior. These are marked as
unsafe
, and require anunsafe
block to use them. One example of this isStaticRef
which is used for accessing memory-mapped I/O registers. Since accessing the addresses through just a memory address is potentially very unsafe, instantiating aStaticRef
requires anunsafe
block. -
The core kernel types generally have to be exposed as other layers of the OS need to use them. However, generally only a very small interface is exposed, and using that interface cannot compromise the overall system or the core kernel. These functions are also marked
pub
. For example, theAppSlice
abstraction must be exposed to capsules to use shared memory between a process and the kernel. However, the constructor is not public, and the API exposed to capsules is very limited and confined by the Rust type system. The constructor and other sensitive interfaces are restricted to use only inside the kernel crate and are markedpub(crate)
.In some cases, more sensitive core kernel interfaces must be exposed. For example, the kernel exposes a function for starting the main scheduling loop in the kernel. Since board crates must be able to start this loop after all initialization is finished, the kernel loop function must be exposed and marked
pub
. However, this interface is not generally safe to use, since starting the loop a second time would compromise the stability of the overall system. It's also not necessarily memory unsafe to call the start loop function again, so we do not mark it asunsafe
. Instead, we require that the caller hold aCapability
to call the public but sensitive functions. More information is incapabilities.rs
. This allows the kernel crate to still expose functions as public while restricting their use. Another example of this is theGrant
constructor, which must be called outside of the core kernel, but should not be called except during the board setup. -
Certain internal core kernel interfaces must also be exposed. These are needed for extensions of the core kernel that happen to be implemented in crates outside of the kernel crate. For example, additional implementations of
ProcessType
may live outside of the kernel crate. To successfully implement a newProcessType
requires access to certain in-core-kernel APIs, and these must be markedpub
so that outside crates can access them.These interfaces are highly sensitive, so again we require the caller hold a Capability to call them. This helps restrict their use and makes it very clear that calling them requires special permissions. Additionally, to differentiate these interfaces, which are for external extensions of core kernel functionality, from the other public but sensitive interfaces (item 2 above), we append the name
_external
to the function name.One note is that there are currently very few extensions to the core kernel that live outside of the kernel crate. That means we have not necessarily created
_extern
functions for all the interfaces needed for this use case. It is likely we will have to create new interfaces as new use cases are discovered.
Modules
capabilities | Special restricted capabilities. |
common | Common operations and types in Tock. |
component | Components extend the functionality of the Tock kernel through a simple factory method interface. |
debug | Support for in-kernel debugging. |
hil | Public traits for interfaces between Tock components. |
introspection | Mechanism for inspecting the status of the kernel. |
ipc | Inter-process communication mechanism for Tock. |
mpu | Interface for configuring the Memory Protection Unit. |
procs | Publicly available process-related objects. |
syscall | Tock syscall number definitions and arch-agnostic interface trait. |
watchdog | Interface for configuring a watchdog |
Macros
count_expressions | Count the number of passed expressions. Useful for constructing variable sized arrays in other macros. Taken from the Little Book of Rust Macros |
create_capability | Create an object with the given capability. |
debug | In-kernel |
debug_enqueue | This macro prints a new line to an internal ring buffer, the contents of
which are only flushed with |
debug_flush_queue | This macro flushes the contents of the debug queue into the regular debug output. |
debug_gpio | In-kernel gpio debugging, accepts any GPIO HIL method |
debug_verbose | In-kernel |
static_buf | Allocates a statically-sized global array of memory for data structures but does not initialize the memory. |
static_init | Allocates a statically-sized global array of memory and initializes the memory for a particular data structure. |
static_init_half | This macro is deprecated. You should migrate to using |
storage_volume | Allocates space in the kernel image for on-chip non-volatile storage. |
Structs
AppId | Userspace app identifier. |
AppSlice | Buffer of memory shared from an app to the kernel. |
Callback | Type for calling a callback in a process. |
CoopProcessNode | A node in the linked list the scheduler uses to track processes |
CooperativeSched | Cooperative Scheduler |
DynamicGrant | Grant which was dynamically allocated in a particular app's memory. |
Grant | Region of process memory reserved for the kernel. |
Kernel | Main object for the kernel. Each board will need to create one. |
MLFQProcessNode | Nodes store per-process state |
MLFQSched | |
NoClockControl | Helper struct for interfaces that expect clocks, but have no clock control. |
PrioritySched | Priority scheduler based on the order of processes in the |
Private | Type for specifying an AppSlice is hidden from the kernel. |
RoundRobinProcessNode | A node in the linked list the scheduler uses to track processes Each node holds a pointer to a slot in the processes array |
RoundRobinSched | Round Robin Scheduler |
Shared | Type for specifying an AppSlice is shared with the kernel. |
VirtualSchedulerTimer | Implementation of SchedulerTimer trait on top of a virtual alarm. |
Enums
ReturnCode | Standard return errors in Tock. |
Statics
NO_CLOCK_CONTROL | Instance of NoClockControl for things that need references to
|
Traits
Chip | Interface for individual MCUs. |
ClockInterface | Generic operations that clock-like things are expected to support. |
Driver |
|
InterruptService | Interface for handling interrupts and deferred calls on a hardware chip. |
Platform | Interface for individual boards. |
Scheduler | Trait which any scheduler must implement. |
SchedulerTimer | Interface for the system scheduler timer. |