doc: create new Hardware Support section

Add new hardware section and move all related content from old
structure.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2022-04-05 10:58:04 -04:00 committed by Carles Cufí
commit df033b28de
49 changed files with 16 additions and 9 deletions

View file

@ -0,0 +1,88 @@
Zephyr support status on ARC processors
#######################################
Overview
********
This page describes current state of Zephyr for ARC processors and some future
plans. Please note that
* plans are given without exact deadlines
* software features require corresponding hardware to be present and
configured the proper way
* not all the features can be enabled at the same time
Support status
**************
Legend:
**Y** - yes, supported; **N** - no, not supported; **WIP** - Work In Progress;
**TBD** - to be decided
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| | **Processor families** |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| | **EM** | **HS3x/4x** | **EV** | **HS6x** |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Port status | upstreamed | upstreamed | WIP | upstreamed |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| **Features** |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Closely coupled memories (ICCM, DCCM) [#f1]_ | Y | Y | TBD | TBD |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Execution with caches - Instruction/Data, L1/L2 caches | Y | Y | Y | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Hardware-assisted unaligned memory access | Y [#f2]_ | Y | TBD | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Regular interrupts with multiple priority levels, direct interrupts | Y | Y | TBD | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Fast interrupts, separate register banks for fast interrupts | Y | Y | TBD | N |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Hardware floating point unit (FPU) | Y | Y | N | TBD |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Symmetric multiprocessing (SMP) support, switch-based | N/A | Y | TBD | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Hardware-assisted stack checking | Y | Y | TBD | N |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Hardware-assisted atomic operations | N/A | Y | TBD | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| DSP ISA | Y | N [#f3]_ | TBD | TBD |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| DSP AGU/XY extensions | N [#f3]_ | N [#f3]_ | TBD | TBD |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Userspace | Y | Y | N | TBD |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Memory protection unit (MPU) | Y | Y | TBD | N |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| Memory management unit (MMU) | N/A | N | N/A | N |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| SecureShield | Y | N/A | N/A | N/A |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| **Toolchains** |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| GNU (open source GCC-based) | Y | Y | N | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| MetaWare (proprietary Clang-based) | Y | Y | Y | WIP [#f4]_ |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| **Simulators** |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| QEMU (open source) [#f5]_ | Y | Y | N | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
| nSIM (proprietary, provided by MetaWare Development Tools) | Y | Y | Y | Y |
+---------------------------------------------------------------------+------------+-------------+--------+------------+
Notes
*****
.. [#f1] usage of CCMs is limited on SMP systems
.. [#f2] except the systems with secure features (SecureShield) due to HW
limitation
.. [#f3] We only support save/restore ACCL/ACCH registers in task's context.
Rest of DSP/AGU registers save/restore isn't implemented but kernel
itself does not use these registers. This allows single task per
core to use DSP/AGU safely.
.. [#f4] MetaWare toolchain supports building for ARCv3 HS6x, however, it's
not integrated to Zephyr itself
.. [#f5] QEMU doesn't support all the ARC processor's HW features. For the
detailed info please check the ARC QEMU documentation

View file

@ -0,0 +1,691 @@
.. _arm_cortex_m_developer_guide:
Arm Cortex-M Developer Guide
############################
Overview
********
This page contains detailed information about the status of the Arm Cortex-M
architecture porting in the Zephyr RTOS and describes key aspects when
developing Zephyr applications for Arm Cortex-M-based platforms.
Key supported features
**********************
The table below summarizes the status of key OS features in the different
Arm Cortex-M implementation variants.
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | | **Processor families** |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Architecture variant | | Arm v6-M | Arm v7-M | Arm v8-M | Arm v8.1-M |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | | **M0/M1** | **M0+** | **M3** | **M4** | **M7** | **M23** | **M33** | **M55** |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| **OS Features** | | |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Programmable fault | | | | | | | | | |
| IRQ priorities | | Y | N | Y | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Single-thread kernel support | | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Thread local storage support | | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Interrupt handling | | |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | Regular interrupts | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | Dynamic interrupts | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | Direct interrupts | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | Zero Latency interrupts | N | N | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| CPU idling | | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Native system timer (SysTick) | | N [#f1]_ | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Memory protection | | |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | User mode | N | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | HW stack protection (MPU) | N | N | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | HW-assisted stack limit checking | N | N | N | N | N |Y [#f2]_ | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| HW-assisted null-pointer | | | | | | | | | |
| dereference detection | | N | N | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| HW-assisted atomic operations | | N | N | Y | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
|Support for non-cacheable regions| | N | N | Y | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Execute SRAM functions | | N | N | Y | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Floating Point Services | | N | N | N | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| DSP ISA | | N | N | N | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Trusted-Execution | |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | Native TrustZone-M support | N | N | N | N | N | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| | TF-M integration | N | N | N | N | N | N | Y | N |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| Code relocation | | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| SW-based vector table relaying | | Y | Y | Y | Y | Y | Y | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
| HW-assisted timing functions | | N | N | Y | Y | Y | N | Y | Y |
+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+
Notes
=====
.. [#f1] SysTick is optional in Cortex-M1
.. [#f2] Stack limit checking only in Secure builds in Cortex-M23
OS features
***********
Threads
=======
Thread stack alignment
----------------------
Each Zephyr thread is defined with its own stack memory. By default, Cortex-M enforces a double word thread stack alignment, see
:kconfig:option:`CONFIG_STACK_ALIGN_DOUBLE_WORD`. If MPU-based HW-assisted stack overflow detection (:kconfig:option:`CONFIG_MPU_STACK_GUARD`)
is enabled, thread stacks need to be aligned with a larger value, reflected by :kconfig:option:`CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE`.
In Arm v6-M and Arm v7-M architecture variants, thread stacks are additionally required to be align with a value equal to their size,
in applications that need to support user mode (:kconfig:option:`CONFIG_USERSPACE`). The thread stack sizes in that case need to be a power
of two. This is all reflected by :kconfig:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`, that is enforced in Arm v6-M and Arm v7-M
builds with user mode support.
Stack pointers
--------------
While executing in thread mode the processor is using the Process Stack Pointer (PSP). The processor uses the Main Stack Pointer (MSP)
while executing in handler mode, that is, while servicing exceptions and HW interrupts. Using PSP in thread mode *facilitates thread
stack pointer manipulation* during thread context switching, without affecting the current execution context flow in
handler mode.
In Arm Cortex-M builds a single interrupt stack memory is shared among exceptions and interrupts. The size of the interrupt stack needs
to be selected taking into consideration nested interrupts, each pushing an additional stack frame. Developers can modify the interrupt
stack size using :kconfig:option:`CONFIG_ISR_STACK_SIZE`.
The interrupt stack is also used during early boot so the kernel can initialize the main thread's stack before switching to the main thread.
Thread context switching
========================
In Arm Cortex-M builds, the PendSV exception is used in order to trigger a context switch to a different thread.
PendSV exception is always present in Cortex-M implementations. PendSV is configured with the lowest possible
interrupt priority level, in all Cortex-M variants. The main reasons for that design are
* to utilize the tail chaining feature of Cortex-M processors, and thus limit the number of context switch
operations that occur.
* to not impact the interrupt latency observed by HW interrupts.
As a result, context switch in Cortex-M is non-atomic, i.e. it may be *preempted* by HW interrupts,
however, a context-switch operation must be completed before a new thread context-switch may start.
Typically a thread context-switch will perform the following operations
* When switching-out the current thread, the processor stores
* the callee-saved registers (R4 - R11) in the thread's container for callee-saved registers,
which is located in kernel memory
* the thread's current operation *mode*
* user or privileged execution mode
* presence of an active floating point context
* the EXC_RETURN value of the current handler context (PendSV)
* the floating point callee-saved registers (S16 - S31) in the thread's container for FP
callee-saved registers, if the current thread has an active FP context
* the PSP of the current thread which points to the beginning of the current thread's exception
stack frame. The latter contains the caller-saved context and the return address of the switched-out
thread.
* When switching-in a new thread the processor
* restores the new thread's callee-saved registers from the thread's
container for callee-saved registers
* restores the new thread's operation *mode*
* restores the FP callee-saved registers if the switched-in thread had
an active FP context before being switched-out
* re-programs the dynamic MPU regions to allow a user thread access its stack and application
memories, and/or programs a stack-overflow MPU guard at the bottom of the thread's
privileged stack
* restores the PSP for the incoming thread and re-programs the stack pointer limit
register (if applicable, see :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD`)
* optionally does a stack limit checking for the switched-in thread, if
sentinel-based stack limit checking is enabled (see :kconfig:option:`CONFIG_STACK_SENTINEL`).
PendSV exception return sequence restores the new thread's caller-saved registers and the
return address, as part of unstacking the exception stack frame.
The implementation of the context-switch mechanism is present in
:file:`arch/arm/core/aarch32/swap_helper.S`.
Stack limit checking (Arm v8-M)
-------------------------------
Armv8-M and Armv8.1-M variants support stack limit checking using the MSPLIM and PSPLIM
core registers. The feature is enabled when :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD` is set.
When stack limit checking is enabled, both the thread's privileged or user stack, as well
as the interrupt stack are guarded by PSPLIM and MSPLIM registers, respectively. MSPLIM is
configured *once* during kernel boot, while PSLIM is re-programmed during every thread
context-switch or during system calls, when the thread switches from using its default
stack to using its privileged stack, and vice versa. PSPLIM re-programming
* has a relatively low runtime overhead (programming is done with MSR instructions)
* does not impact interrupt latency
* does not require any memory areas to be reserved for stack guards
* does not make use of MPU regions
It is, therefore, considered as a lightweight but very efficient stack overflow
detection mechanism in Cortex-M applications.
Stack overflows trigger the dedicated UsageFault exception provided by Arm v8-M.
Interrupt handling features
===========================
This section describes certain aspects around exception and interrupt
handling in Arm Cortex-M.
Interrupt priority levels
-------------------------
The number of available (configurable) interrupt priority levels is
determined by the number of implemented interrupt priority bits in
NVIC; this needs to be described for each Cortex-M platform using
DeviceTree:
.. code-block:: devicetree
&nvic {
arm,num-irq-priority-bits = <#priority-bits>;
};
Reserved priority levels
------------------------
A number of interrupt priority levels are reserved for the OS.
By design, system fault exceptions have the highest priority level. In
*Baseline* Cortex-M, this is actually enforced by hardware, as HardFault
is the only available processor fault exception, and its priority is
higher than any configurable exception priority.
In *Mainline* Cortex-M, the available fault exceptions (e.g. MemManageFault,
UsageFault, etc.) are assigned the highest *configurable* priority level.
(:kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS` signifies explicitly
that the Cortex-M implementation supports configurable fault priorities.)
This priority level is never shared with HW interrupts (an exception to
this rule is described below). As a result, processor faults occurring in regular
ISRs will be handled by the corresponding fault handler and will not escalate to
a HardFault, *similar to processor faults occurring in thread mode*.
SVC exception is normally configured with the highest configurable priority level
(an exception to this rule will be described below).
SVCs are used by the Zephyr kernel to dispatch system calls, trigger runtime
system errors (e.g. Kernel oops or panic), or implement IRQ offloading.
In Baseline Cortex-M the priority level of SVC may be shared with other exceptions
or HW interrupts that are also given the highest configurable priority level (As a
result of this, kernel runtime errors during interrupt handling will escalate to
HardFault. Additional logic in the fault handling routines ensures that such
runtime errors are detected successfully).
In Mainline Cortex-M, however, the SVC priority level is *reserved*, thus normally it
is only shared with the fault exceptions of configurable priority. This simplifies the
fault handling routines in Mainline Cortex-M architecture, since runtime kernel errors
are serviced by the SVC handler (i.e no HardFault escalation, even if the kernel errors
occur in ISR context).
HW interrupts in Mainline Cortex-M builds are allocated a priority level lower than the SVC.
One exception to the above rules is when Zephyr applications support Zero Latency Interrupts
(ZLIs). Such interrupts are designed to have a priority level higher than any HW or system
interrupt. If the ZLI feature is enabled in Mainline Cortex-M builds (see
:kconfig:option:`CONFIG_ZERO_LATENCY_IRQS`), then
* ZLIs are assigned the highest configurable priority level
* SVCs are assigned the second highest configurable priority level
* Regular HW interrupts are assigned priority levels lower than SVC.
The priority level configuration in Cortex-M is implemented in
:file:`include/arch/arm/aarch32/exc.h`.
Locking and unlocking IRQs
--------------------------
In Baseline Cortex-M locking interrupts is implemented using the PRIMASK register.
.. code-block:: c
arch_irq_lock()
will set the PRIMASK register to 1, eventually, masking all IRQs with configurable
priority. While this fulfils the OS requirement of locking interrupts, the consequence
is that kernel runtime errors (triggering SVCs) will escalate to HardFault.
In Mainline Cortex-M locking interrupts is implemented using the BASEPRI register (Mainline
Cortex-M builds select :kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_BASEPRI` to signify that BASEPRI register is
implemented.). By modifying BASEPRI (or BASEPRI_MAX) arch_irq_lock() masks all system and HW
interrupts with the exception of
* SVCs
* processor faults
* ZLIs
This allows zero latency interrupts to be triggered inside OS critical sections.
Additionally, this allows system (processor and kernel) faults to be handled by Zephyr
in *exactly the same way*, regardless of whether IRQs have been locked or not when the
error occurs. It also allows for system calls to be dispatched while IRQs are locked.
.. note::
Mainline Cortex-M fault handling is designed and configured in a way that all processor
and kernel faults are handled by the corresponding exception handlers and never result
in HardFault escalation. In other words, a HardFault may only occur in Zephyr applications
that have modified the default fault handling configurations. The main reason for this
design was to reserve the HardFault exception for handling exceptional error conditions
in safety critical applications.
Dynamic direct interrupts
-------------------------
Cortex-M builds support the installation of direct interrupt service routines during
runtime. Direct interrupts are designed for performance-critical interrupt
handling and do not go through all of the common Zephyr interrupt handling
code.
Direct dynamic interrupts are enabled via switching on
:kconfig:option:`CONFIG_DYNAMIC_DIRECT_INTERRUPTS`.
Note that enabling direct dynamic interrupts requires enabling support for
dynamic interrupts in the kernel, as well (see :kconfig:option:`CONFIG_DYNAMIC_INTERRUPTS`).
Zero Latency interrupts
-----------------------
As described above, in Mainline Cortex-M applications, the Zephyr kernel reserves
the highest configurable interrupt priority level for its own use (SVC). SVCs will
not be masked by interrupt locking. Zero-latency interrupt can be used to set up
an interrupt at the highest interrupt priority which will not be blocked by interrupt
locking. To use the ZLI feature :kconfig:option:`CONFIG_ZERO_LATENCY_IRQS` needs to be enabled.
Zero latency IRQs have minimal interrupt latency, as they will always preempt regular HW
or system interrupts.
Note, however, that since ZLI ISRs will run at a priority level higher than the kernel
exceptions they **cannot use** any kernel functionality. Additionally, since the ZLI
interrupt priority level is equal to processor fault priority level, faults occurring
in ZLI ISRs will escalate to HardFault and will not be handled in the same way as regular
processor faults. Developers need to be aware of this limitation.
CPU Idling
==========
The Cortex-M architecture port implements both k_cpu_idle()
and k_cpu_atomic_idle(). The implementation is present in
:file:`arch/arm/core/aarch32/cpu_idle.S`.
In both implementations, the processor
will attempt to put the core to low power mode.
In k_cpu_idle() the processor ends up executing WFI (Wait For Interrupt)
instruction, while in k_cpu_atomic_idle() the processor will
execute a WFE (Wait For Event) instruction.
When using the CPU idling API in Cortex-M it is important to note the
following:
* Both k_cpu_idle() and k_cpu_atomic_idle() are *assumed* to be invoked
with interrupts locked. This is taken care of by the kernel if the APIs
are called by the idle thread.
* After waking up from low power mode, both functions will *restore*
interrupts unconditionally, that is, regardless of the interrupt lock
status before the CPU idle API was called.
The Zephyr CPU Idling mechanism is detailed in :ref:`cpu_idle`.
Memory protection features
==========================
This section describes certain aspects around memory protection features
in Arm Cortex-M applications.
User mode system calls
----------------------
User mode is supported in Cortex-M platforms that implement the standard (Arm) MPU
or a similar core peripheral logic for memory access policy configuration and
control, such as the NXP MPU for Kinetis platforms. (Currently,
:kconfig:option:`CONFIG_ARCH_HAS_USERSPACE` is selected if :kconfig:option:`CONFIG_ARM_MPU` is enabled
by the user in the board default Kconfig settings).
A thread performs a system call by triggering a (synchronous) SVC exception, where
* up to 5 arguments are placed on registers R1 - R5
* system call ID is placed on register R6.
The SVC Handler will branch to the system call preparation logic, which will perform
the following operations
* switch the thread's PSP to point to the beginning of the thread's privileged
stack area, optionally reprogramming the PSPLIM if stack limit checking is enabled
* modify CONTROL register to switch to privileged mode
* modify the return address in the SVC exception stack frame, so that after exception
return the system call dispatcher is executed (in thread privileged mode)
Once the system call execution is completed the system call dispatcher will restore the
user's original PSP and PSPLIM and switch the CONTROL register back to unprivileged mode
before returning back to the caller of the system call.
System calls execute in thread mode and can be preempted by interrupts at any time. A
thread may also be context-switched-out while doing a system call; the system call will
resume as soon as the thread is switched-in again.
The system call dispatcher executes at SVC priority, therefore it cannot be preempted
by HW interrupts (with the exception of ZLIs), which may observe some additional interrupt
latency if they occur during a system call preparation.
MPU-assisted stack overflow detection
-------------------------------------
Cortex-M platforms with MPU may enable :kconfig:option:`CONFIG_MPU_STACK_GUARD` to enable the MPU-based
stack overflow detection mechanism. The following points need to be considered when enabling the
MPU stack guards
* stack overflows are triggering processor faults as soon as they occur
* the mechanism is essential for detecting stack overflows in supervisor threads, or
user threads in privileged mode; stack overflows in threads in user mode will always be
detected regardless of :kconfig:option:`CONFIG_MPU_STACK_GUARD` being set.
* stack overflows are always detected, however, the mechanism does not guarantee that
no memory corruption occurs when supervisor threads overflow their stack memory
* :kconfig:option:`CONFIG_MPU_STACK_GUARD` will normally reserve one MPU region for programming
the stack guard (in certain Arm v8-M configurations with :kconfig:option:`CONFIG_MPU_GAP_FILLING`
enabled 2 MPU regions are required to implement the guard feature)
* MPU guards are re-programmed at every context-switch, adding a small overhead to the
thread swap routine. Compared, however, to the :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD` feature,
no re-programming occurs during system calls.
* When :kconfig:option:`CONFIG_HW_STACK_PROTECTION` is enabled on Arm v8-M platforms the native
stack limit checking mechanism is used by default instead of the MPU-based stack overflow
detection mechanism; users may override this setting by manually enabling :kconfig:option:`CONFIG_MPU_STACK_GUARD`
in these scenarios.
Memory map and MPU considerations
=================================
Fixed MPU regions
-----------------
By default, when :kconfig:option:`CONFIG_ARM_MPU` is enabled a set of *fixed* MPU regions
are programmed during system boot.
* One MPU region programs the entire flash area as read-execute.
User can override this setting by enabling :kconfig:option:`CONFIG_MPU_ALLOW_FLASH_WRITE`,
which programs the flash with RWX permissions. If :kconfig:option:`CONFIG_USERSPACE` is
enabled unprivileged access on the entire flash area is allowed.
* One MPU region programs the entire SRAM area with privileged-only
RW permissions. That is, an MPU region is utilized to disallow execute permissions on
SRAM. (An exception to this setting is when :kconfig:option:`CONFIG_MPU_GAP_FILLING` is disabled (Arm v8-M only);
in that case no SRAM MPU programming is done so the access is determined by the default
Arm memory map policies, allowing for privileged-only RWX permissions on SRAM).
* All the memory regions defined in the devicetree with the compatible
:dtcompatible:`zephyr,memory-region` and at least the property
``zephyr,memory-region-mpu`` defining the MPU permissions for the memory region.
See the next section for more details.
The above MPU regions are defined in :file:`soc/arm/common/arm_mpu_regions.c`.
Alternative MPU configurations are allowed by enabling :kconfig:option:`CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS`.
When enabled, this option signifies that the Cortex-M SoC will define and
configure its own fixed MPU regions in the SoC definition.
Fixed MPU regions defined in devicetree
---------------------------------------
The user can define memory regions to be allocated and created in the linker
script using nodes with the :dtcompatible:`zephyr,memory-region` devicetree
compatible. When the property ``zephyr,memory-region-mpu`` is present in such
a node, a new MPU region will be allocated and programmed during system
boot.
The property ``zephyr,memory-region-mpu`` is a string carrying the attributes
for the MPU region. It is converted to a C token for use defining the attributes
of the MPU region.
For example, to define a new non-cacheable memory region in devicetree:
.. code-block:: devicetree
sram_no_cache: memory@20300000 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x20300000 0x100000>;
zephyr,memory-region = "SRAM_NO_CACHE";
zephyr,memory-region-mpu = "RAM_NOCACHE";
};
This will automatically create a new MPU entry in
:zephyr_file:`soc/arm/common/arm_mpu_regions.c` with the correct name, base,
size and attributes gathered directly from the devicetree. See
:zephyr_file:`include/linker/devicetree_regions.h` for more details.
Static MPU regions
------------------
Additional *static* MPU regions may be programmed once during system boot. These regions
are required to enable certain features
* a RX region to allow execution from SRAM, when :kconfig:option:`CONFIG_ARCH_HAS_RAMFUNC_SUPPORT` is
enabled and users have defined functions to execute from SRAM.
* a RX region for relocating text sections to SRAM, when :kconfig:option:`CONFIG_CODE_DATA_RELOCATION_SRAM` is enabled
* a no-cache region to allow for a none-cacheable SRAM area, when :kconfig:option:`CONFIG_NOCACHE_MEMORY` is enabled
* a possibly unprivileged RW region for GCOV code coverage accounting area, when :kconfig:option:`CONFIG_COVERAGE_GCOV` is enabled
* a no-access region to implement null pointer dereference detection, when :kconfig:option:`CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU` is enabled
The boundaries of these static MPU regions are derived from symbols exposed by the linker, in
:file:`include/linker/linker-defs.h`.
Dynamic MPU regions
-------------------
Certain thread-specific MPU regions may be re-programmed dynamically, at each thread context switch:
* an unprivileged RW region for the current thread's stack area (for user threads)
* a read-only region for the MPU stack guard
* unprivileged RW regions for the partitions of the current thread's application memory
domain.
Considerations
--------------
The number of available MPU regions for a Cortex-M platform is a limited resource.
Most platforms have 8 MPU regions, while some Cortex-M33 or Cortex-M7 platforms may
have up to 16 MPU regions. Therefore there is a relatively strict limitation on how
many fixed, static and dynamic MPU regions may be programmed simultaneously. For platforms
with 8 available MPU regions it might not be possible to enable all the aforementioned
features that require MPU region programming. In most practical applications, however,
only a certain set of features is required and 8 MPU regions are, in many cases, sufficient.
In Arm v8-M processors the MPU architecture does not allow programmed MPU regions to
overlap. :kconfig:option:`CONFIG_MPU_GAP_FILLING` controls whether the fixed MPU region
covering the entire SRAM is programmed. When it does, a full SRAM area partitioning
is required, in order to program the static and the dynamic MPU regions. This increases
the total number of required MPU regions. When :kconfig:option:`CONFIG_MPU_GAP_FILLING` is not
enabled the fixed MPU region covering the entire SRAM is not programmed, thus, the static
and dynamic regions are simply programmed on top of the always-existing background region
(full-SRAM partitioning is not required).
Note, however, that the background SRAM region allows execution from SRAM, so when
:kconfig:option:`CONFIG_MPU_GAP_FILLING` is not set Zephyr is not protected against attacks
that attempt to execute malicious code from SRAM.
Floating point Services
=======================
Both unshared and shared FP registers mode are supported in Cortex-M (see
:ref:`float_v2` for more details).
When FPU support is enabled in the build
(:kconfig:option:`CONFIG_FPU` is enabled), the
sharing FP registers mode (:kconfig:option:`CONFIG_FPU_SHARING`)
is enabled by default. This is done as some compiler configurations
may activate a floating point context by generating FP instructions
for any thread, regardless of whether floating point calculations are
performed, and that context must be preserved when switching such
threads in and out.
The developers can still disable the FP sharing mode in their
application projects, and switch to Unshared FP registers mode,
if it is guaranteed that the image code does not generate FP
instructions outside the single thread context that is allowed
(and supposed) to do so.
Under FPU sharing mode, the callee-saved FPU registers are saved
and restored in context-switch, if the corresponding threads have
an active FP context. This adds some runtime overhead on the swap
routine. In addition to the runtime overhead, the sharing FPU mode
* requires additional memory for each thread to save the callee-saved
FP registers
* requires additional stack memory for each thread, to stack the caller-saved
FP registers, upon exception entry, if an FP context is active. Note, however,
that since lazy stacking is enabled, there is no runtime overhead of FP context
stacking in regular interrupts (FP state preservation is only activated in the
swap routine in PendSV interrupt).
Misc
****
Chain-loadable images
=====================
Cortex-M applications may either be standalone images or chain-loadable, for instance,
by a bootloader. Application images chain-loadable by bootloaders (or other applications)
normally occupy a specific area in the flash denoted as their *code partition*.
:kconfig:option:`CONFIG_USE_DT_CODE_PARTITION` will ensure that a Zephyr chain-loadable image
will be linked into its code partition, specified in DeviceTree.
HW initialization at boot
-------------------------
In order to boot properly, chain-loaded applications may require that the core Arm
hardware registers and peripherals are initialized in their reset values. Enabling
:kconfig:option:`CONFIG_INIT_ARCH_HW_AT_BOOT` Zephyr to force the initialization of the
internal Cortex-M architectural state during boot to the reset values as specified
by the corresponding Arm architecture manual.
Software vector relaying
------------------------
In Cortex-M platforms that implement the VTOR register (see :kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_VTOR`),
chain-loadable images relocate the Cortex-M vector table by updating the VTOR register with the offset
of the image vector table.
Baseline Cortex-M platforms without VTOR register might not be able to relocate their
vector table which remains at a fixed location. Therefore, a chain-loadable image will
require an alternative way to route HW interrupts and system exceptions to its own vector
table; this is achieved with software vector relaying.
When a bootloader image enables :kconfig:option:`CONFIG_SW_VECTOR_RELAY`
it is able to relay exceptions and interrupts based on a vector table
pointer that is set by the chain-loadable application. The latter sets
the :kconfig:option:`CONFIG_SW_VECTOR_RELAY_CLIENT` option to instruct the boot
sequence to set the vector table pointer in SRAM so that the bootloader can
forward the exceptions and interrupts to the chain-loadable image's software
vector table.
While this feature is intended for processors without VTOR register, it
may also be used in Mainline Cortex-M platforms.
Code relocation
===============
Cortex-M support the code relocation feature. When
:kconfig:option:`CONFIG_CODE_DATA_RELOCATION_SRAM` is selected,
Zephyr will relocate .text, data and .bss sections
from the specified files and place it in SRAM. It is
possible to relocate only parts of the code sections
into SRAM, without relocating the whole image text
and data sections. More details on the code relocation
feature can be found in :ref:`code_data_relocation`.
Linking Cortex-M applications
*****************************
Most Cortex-M platforms make use of the default Cortex-M
GCC linker script in :file:`include/arch/arm/aarch32/cortex-m/scripts/linked.ld`,
although it is possible for platforms to use a custom linker
script as well.
CMSIS
*****
Cortex-M CMSIS headers are hosted in a standalone module repository:
`zephyrproject-rtos/cmsis <https://github.com/zephyrproject-rtos/cmsis>`_.
:kconfig:option:`CONFIG_CPU_CORTEX_M` selects :kconfig:option:`CONFIG_HAS_CMSIS_CORE` to signify that
CMSIS headers are available for all supported Cortex-M variants.
Testing
*******
A list of unit tests for the Cortex-M porting and miscellaneous features
is present in :file:`tests/arch/arm/`. The tests suites are continuously
extended and new test suites are added, in an effort to increase the coverage
of the Cortex-M architecture support in Zephyr.
QEMU
****
We use QEMU to verify the implemented features of the Cortex-M architecture port in Zephyr.
Adequate coverage is achieved by defining and utilizing a list of QEMU targets,
each with a specific architecture variant and Arm peripheral support list.
The table below lists the QEMU platform targets defined in Zephyr
along with the corresponding Cortex-M implementation variant and the peripherals
these targets emulate.
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| | **QEMU target** |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| Architecture variant | Arm v6-M | Arm v7-M | Arm v8-M | Arm v8.1-M |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| | **qemu_cortex_m0** | **qemu_cortex_m3** | **mps2_an385** | **mps2_an521** | **mps3_an547** |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| **Emulated features** | |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| NVIC | Y | Y | Y | Y | Y |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| BASEPRI | N | Y | Y | Y | Y |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| SysTick | N | Y | Y | Y | Y |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| MPU | N | N | Y | Y | Y |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| FPU | N | N | N | Y | N |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| SPLIM | N | N | N | Y | Y |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
| TrustZone-M | N | N | N | Y | N |
+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
Maintainers & Collaborators
***************************
The status of the Arm Cortex-M architecture port in Zephyr is: *maintained*.
The updated list of maintainers and collaborators for Cortex-M can be found
in :file:`MAINTAINERS.yml`.

View file

@ -0,0 +1,11 @@
.. _arch:
Architecture-related Guides
###########################
.. toctree::
:maxdepth: 1
arc-support-status.rst
arm_cortex_m.rst
x86.rst

124
doc/hardware/arch/x86.rst Normal file
View file

@ -0,0 +1,124 @@
.. _x86_developer_guide:
x86 Developer Guide
###################
Overview
********
This page contains information on certain aspects when developing for
x86-based platforms.
Virtual Memory
**************
During very early boot, page tables are loaded so technically the kernel
is executing in virtual address space. By default, physical and virtual
memory are identity mapped and thus giving the appearance of execution
taking place in physical address space. The physical address space is
marked by kconfig :kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` and
:kconfig:option:`CONFIG_SRAM_SIZE` while the virtual address space is marked by
:kconfig:option:`CONFIG_KERNEL_VM_BASE` and :kconfig:option:`CONFIG_KERNEL_VM_SIZE`.
Note that :kconfig:option:`CONFIG_SRAM_OFFSET` controls where the Zephyr kernel
is being placed in the memory, and its counterpart
:kconfig:option:`CONFIG_KERNEL_VM_OFFSET`.
Separate Virtual Address Space from Physical Address Space
==========================================================
On 32-bit x86, it is possible to have separate physical and virtual
address space. Code and data are linked in virtual address space,
but are still loaded in physical memory. However, during boot, code
and data must be available and also addressable in physical address
space before ``vm_enter`` inside :file:`arch/x86/core/ia32/crt0.S`.
After ``vm_enter``, code execution is done via virtual addresses
and data can be referred via their virtual addresses. This is
possible as the page table generation script
(:file:`arch/x86/gen_mmu.py`) identity maps the physical addresses
at the page directory level, in addition to mapping virtual addresses
to the physical memory. Later in the boot process,
the entries for identity mapping at the page directory level are
cleared in :c:func:`z_x86_mmu_init()`, effectively removing
the identity mapping of physical memory. This unmapping must be done
for userspace isolation or else they would be able to access
restricted memory via physical addresses. Since the identity mapping
is done at the page directory level, there is no need to allocate
additional space for the page table. However, additional space may
still be required for additional page directory table.
There are restrictions on where virtual address space can be:
- Physical and virtual address spaces must be disjoint. This is
required as the entries in page directory table will be cleared.
If they are not disjoint, it would clear the entries needed for
virtual addresses.
- If :kconfig:option:`CONFIG_X86_PAE` is enabled (``=y``), each address space
must reside in their own 1GB region, due to each entry of PDP
(Page Directory Pointer) covers 1GB of memory. For example:
- Assuming ``CONFIG_SRAM_OFFSET`` and ``CONFIG_KERNEL_VM_OFFSET``
are both ``0x0``.
- ``CONFIG_SRAM_BASE_ADDRESS == 0x00000000`` and
``CONFIG_KERNEL_VM_BASE = 0x40000000`` is valid, while
- ``CONFIG_SRAM_BASE_ADDRESS == 0x00000000`` and
``CONFIG_KERNEL_VM_BASE = 0x20000000`` is not.
- If :kconfig:option:`CONFIG_X86_PAE` is disabled (``=n``), each address space
must reside in their own 4MB region, due to each entry of PD
(Page Directory) covers 4MB of memory.
- Both ``CONFIG_SRAM_BASE_ADDRESS`` and ``CONFIG_KERNEL_VM_BASE``
must also align with the starting addresses of targeted regions.
Specifying Additional Memory Mappings at Build Time
***************************************************
The page table generation script (:file:`arch/x86/gen_mmu.py`) generates
the necessary multi-level page tables for code execution and data access
using the kernel image produced by the first linker pass. Additional
command line arguments can be passed to the script to generate additional
memory mappings. This is useful for static mappings and/or device MMIO
access during very early boot. To pass extra command line arguments to
the script, populate a CMake list named ``X86_EXTRA_GEN_MMU_ARGUMENTS``
in the board configuration file. Here is an example:
.. code-block:: cmake
set(X86_EXTRA_GEN_MMU_ARGUMENTS
--map 0xA0000000,0x2000
--map 0x80000000,0x400000,LWUX,0xB0000000)
The argument ``--map`` takes the following value:
``<physical address>,<size>[,<flags:LUWX>[,<virtual address>]]``, where:
- ``<physical address>`` is the physical address of the mapping. (Required)
- ``<size>`` is the size of the region to be mapped. (Required)
- ``<flags>`` is the flag associated with the mapping: (Optional)
- ``L``: Large page at the page directory level.
- ``U``: Allow userspace access.
- ``W``: Read/write.
- ``X``: Allow execution.
- ``D``: Cache disabled.
- Default is small page (4KB), supervisor only, read only, and
execution disabled.
- ``<virtual address`` is the virtual address of the mapping. (Optional)
Note that specifying additional memory mappings requires larger storage
space for the pre-allocated page tables (both kernel and per-domain
tables). :kconfig:option:`CONFIG_X86_EXTRA_PAGE_TABLE_PAGES` is needed to
specify how many more memory pages to be reserved for the page tables.
If the needed space is not exactly the same as required space,
the ``gen_mmu.py`` script will print out a message indicating what
needs to be the value for the kconfig.

10
doc/hardware/index.rst Normal file
View file

@ -0,0 +1,10 @@
.. _hardware_support:
Hardware Support
################
.. toctree::
:maxdepth: 1
arch/index.rst
peripherals/index.rst

View file

@ -0,0 +1,13 @@
.. _adc_api:
ADC
###
Overview
********
API Reference
*************
.. doxygengroup:: adc_interface

View file

@ -0,0 +1,21 @@
.. _audio_codec_api:
Audio Codec
###########
Overview
********
The Audio Codec API provides access to digital audio codecs.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_AUDIO_CODEC`
API Reference
*************
.. doxygengroup:: audio_codec_interface

View file

@ -0,0 +1,21 @@
.. _audio_dmic_api:
Audio DMIC
##########
Overview
********
The audio DMIC interface provides access to digital microphones.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_AUDIO_DMIC`
API Reference
*************
.. doxygengroup:: audio_dmic_interface

View file

@ -0,0 +1,24 @@
.. _i2s_api:
I2S
####
Overview
********
The I2S (Inter-IC Sound) API provides support for the standard I2S interface
as well as common non-standard extensions such as PCM Short/Long Frame Sync
and Left/Right Justified Data Formats.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_I2S`
API Reference
*************
.. doxygengroup:: i2s_interface

View file

@ -0,0 +1,11 @@
.. _audio_reference:
Audio
#####
.. toctree::
:maxdepth: 1
codec.rst
dmic.rst
i2s.rst

View file

@ -0,0 +1,22 @@
.. _clock_control_api:
Clock Control
#############
Overview
********
The clock control API provides access to clocks in the system, including the
ability to turn them on and off.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_CLOCK_CONTROL`
API Reference
*************
.. doxygengroup:: clock_control_interface

View file

@ -0,0 +1,13 @@
.. _counter_api:
Counter
#######
Overview
********
API Reference
*************
.. doxygengroup:: counter_interface

View file

@ -0,0 +1,21 @@
.. _dac_api:
DAC
###
Overview
********
The DAC API provides access to Digital-to-Analog Converter (DAC) devices.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_DAC`
API Reference
*************
.. doxygengroup:: dac_interface

View file

@ -0,0 +1,33 @@
.. comment
not documenting
.. doxygengroup:: display_interfaces
.. _display_api:
Display Interface
#################
API Reference
*************
Generic Display Interface
=========================
.. doxygengroup:: display_interface
Grove LCD Display
=================
.. doxygengroup:: grove_display
BBC micro:bit Display
=====================
.. doxygengroup:: mb_display
Monochrome Character Framebuffer
================================
.. doxygengroup:: monochrome_character_framebuffer

View file

@ -0,0 +1,13 @@
.. _dma_api:
DMA
###
Overview
********
API Reference
*************
.. doxygengroup:: dma_interface

View file

@ -0,0 +1,13 @@
.. _ec_host_cmd_periph_api:
EC Host Command
###############
Overview
********
API Reference
*************
.. doxygengroup:: ec_host_cmd_periph_interface

View file

@ -0,0 +1,9 @@
.. _edac_api:
Error Detection And Correction (EDAC)
#####################################
API Reference
*************
.. doxygengroup:: edac

View file

@ -0,0 +1,25 @@
.. _eeprom_api:
EEPROM
######
Overview
********
The EEPROM API provides read and write access to Electrically Erasable
Programmable Read-Only Memory (EEPROM) devices.
EEPROMs have an erase block size of 1 byte, a long lifetime, and allow
overwriting data on byte-by-byte access.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_EEPROM`
API Reference
*************
.. doxygengroup:: eeprom_interface

View file

@ -0,0 +1,17 @@
.. _entropy_api:
Entropy
#######
Overview
********
The entropy API provides functions to retrieve entropy values from
entropy hardware present on the platform. The entropy APIs are provided
for use by the random subsystem and cryptographic services. They are not
suitable to be used as random number generation functions.
API Reference
*************
.. doxygengroup:: entropy_interface

View file

@ -0,0 +1,27 @@
.. _espi_api:
eSPI
####
Overview
********
The eSPI (enhanced serial peripheral interface) is a serial bus that is
based on SPI. It also features a four-wire interface (receive, transmit, clock
and slave select) and three configurations: single IO, dual IO and quad IO.
The technical advancements include lower voltage signal levels (1.8V vs. 3.3V),
lower pin count, and the frequency is twice as fast (66MHz vs. 33MHz)
Because of its enhancements, the eSPI is used to replace the LPC
(lower pin count) interface, SPI, SMBus and sideband signals.
See `eSPI interface specification`_ for additional details.
API Reference
*************
.. doxygengroup:: espi_interface
.. _eSPI interface specification:
https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0_cb.pdf

View file

@ -0,0 +1,28 @@
.. _flash_api:
Flash
#####
Overview
********
**Flash offset concept**
Offsets used by the user API are expressed in relation to
the flash memory beginning address. This rule shall be applied to
all flash controller regular memory that layout is accessible via
API for retrieving the layout of pages (see option:`CONFIG_FLASH_PAGE_LAYOUT`).
An exception from the rule may be applied to a vendor-specific flash
dedicated-purpose region (such a region obviously can't be covered under
API for retrieving the layout of pages).
User API Reference
******************
.. doxygengroup:: flash_interface
Implementation interface API Reference
**************************************
.. doxygengroup:: flash_internal_interface

View file

@ -0,0 +1,22 @@
.. _gna_api:
GNA
###
Overview
********
The GNA API provides access to Intel's Gaussian Mixture Model and Neural Network
Accelerator (GNA).
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_INTEL_GNA`
API Reference
*************
.. doxygengroup:: gna_interface

View file

@ -0,0 +1,20 @@
.. _gpio_api:
GPIO
####
Overview
********
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_GPIO`
API Reference
*************
.. doxygengroup:: gpio_interface

View file

@ -0,0 +1,28 @@
.. _hwinfo_api:
Hardware Information
####################
Overview
********
The HW Info API provides access to hardware information such as device
identifiers and reset cause flags.
Reset cause flags can be used to determine why the device was reset; for
example due to a watchdog timeout or due to power cycling. Different devices
support different subset of flags. Use
:c:func:`hwinfo_get_supported_reset_cause` to retrieve the flags that are
supported by that device.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_HWINFO`
API Reference
*************
.. doxygengroup:: hwinfo_interface

View file

@ -0,0 +1,68 @@
.. _i2c_api:
I2C
####
Overview
********
.. note::
Zephyr recognizes the need to change the terms "master" and "slave"
used in the current `I2C Specification <i2c-specification>`_. This
will be done when the conditions identified in
:ref:`coding_guideline_inclusive_language` have been met. Existing
documentation, data structures, functions, and value symbols in code
are likely to change at that point.
`I2C <i2c-specification>`_ (Inter-Integrated Circuit, pronounced "eye
squared see") is a commonly-used two-signal shared peripheral interface
bus. Many system-on-chip solutions provide controllers that communicate
on an I2C bus. Devices on the bus can operate in two roles: as a
"master" that initiates transactions and controls the clock, or as a
"slave" that responds to transaction commands. A I2C controller on a
given SoC will generally support the master role, and some will also
support the slave mode. Zephyr has API for both roles.
.. _i2c-master-api:
I2C Master API
==============
Zephyr's I2C master API is used when an I2C peripheral controls the bus,
in particularly the start and stop conditions and the clock. This is
the most common mode, used to interact with I2C devices like sensors and
serial memory.
This API is supported in all in-tree I2C peripheral drivers and is
considered stable.
.. _i2c-slave-api:
I2C Slave API
================
Zephyr's I2C slave API is used when an I2C peripheral responds to
transactions initiated by a different controller on the bus. It might
be used for a Zephyr application with transducer roles that are
controlled by another device such as a host processor.
This API is supported in very few in-tree I2C peripheral drivers. The
API is considered experimental, as it is not compatible with the
capabilities of all I2C peripherals supported in master mode.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_I2C`
API Reference
*************
.. doxygengroup:: i2c_interface
.. _i2c-specification:
https://www.nxp.com/docs/en/user-guide/UM10204.pdf

View file

@ -0,0 +1,12 @@
.. _i2c_eeprom_slave_api:
I2C EEPROM Slave
################
Overview
********
API Reference
**************
.. doxygengroup:: i2c_eeprom_slave_api

View file

@ -0,0 +1,44 @@
.. _api_peripherals:
Peripherals
###########
.. toctree::
:maxdepth: 1
adc.rst
audio/index.rst
counter.rst
clock_control.rst
dac.rst
display/index.rst
dma.rst
ec_host_cmd_periph.rst
edac/index.rst
eeprom.rst
entropy.rst
flash.rst
gna.rst
gpio.rst
hwinfo.rst
i2c_eeprom_slave.rst
i2c.rst
ipm.rst
kscan.rst
led.rst
mbox.rst
pinmux.rst
pwm.rst
ps2.rst
peci.rst
regulators.rst
reset.rst
rtc.rst
sensor.rst
spi.rst
tcpc.rst
uart.rst
mdio.rst
watchdog.rst
video.rst
espi.rst

View file

@ -0,0 +1,13 @@
.. _ipm_api:
IPM
###
Overview
********
API Reference
*************
.. doxygengroup:: ipm_interface

View file

@ -0,0 +1,31 @@
.. _kscan_api:
KSCAN
#####
Overview
********
The kscan driver (keyboard scan matrix) is used for detecting a key press in a
connected matrix keyboard or any device with buttons such as joysticks.
Typically, matrix keyboards are implemented using a two-dimensional
configuration in order to sense several keys. This allows interfacing to
many keys through fewer physical pins. Keyboard matrix
drivers read the rows while applying power through the columns one at a time
with the purpose of detecting key events.
There is no correlation between the physical and electrical layout of keys.
For, example, the physical layout may be one array of 16 or fewer keys, which
may be electrically connected to a 4 x 4 array. In addition, key values are
defined by a keymap provided by the keyboard manufacturer.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_KSCAN`
API Reference
*************
.. doxygengroup:: kscan_interface

View file

@ -0,0 +1,31 @@
.. _led_api:
LED
###
Overview
********
The LED API provides access to Light Emitting Diodes, both in individual and
strip form.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_LED`
* :kconfig:option:`CONFIG_LED_STRIP`
API Reference
*************
LED
===
.. doxygengroup:: led_interface
LED Strip
=========
.. doxygengroup:: led_strip_interface

View file

@ -0,0 +1,18 @@
.. _mbox_api:
MBOX
####
Overview
********
An MBOX device is a peripheral capable of passing signals (and data depending
on the peripheral) between CPUs and clusters in the system. Each MBOX instance
is providing one or more channels, each one targeting one other CPU cluster
(multiple channels can target the same cluster).
API Reference
*************
.. doxygengroup:: mbox_interface

View file

@ -0,0 +1,20 @@
.. _mdio_api:
MDIO
####
Overview
********
MDIO is a bus that is commonly used to communicate with ethernet PHY devices.
Many ethernet MAC controllers also provide hardware to communicate over MDIO
bus with a peripheral device.
This API is intended to be used primarily by PHY drivers but can also be
used by user firmware.
API Reference
*************
.. doxygengroup:: mdio_interface
:project: Zephyr

View file

@ -0,0 +1,27 @@
.. _peci_api:
PECI
####
Overview
********
The Platform Environment Control Interface, abbreviated as PECI,
is a thermal management standard introduced in 2006
with the Intel Core 2 Duo Microprocessors.
The PECI interface allows external devices to read processor temperature,
perform processor manageability functions, and manage processor interface
tuning and diagnostics.
The PECI bus driver APIs enable the interaction between Embedded
Microcontrollers and CPUs.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_PECI`
API Reference
*************
.. doxygengroup:: peci_interface

View file

@ -0,0 +1,13 @@
.. _pinmux_api:
Pinmux
######
Overview
********
API Reference
*************
.. doxygengroup:: pinmux_interface

View file

@ -0,0 +1,27 @@
.. _ps2_api:
PS/2
####
Overview
********
The PS/2 connector first hit the market in 1987 on
IBM's desktop PC line of the same name before
becoming an industry-wide standard for mouse and
keyboard connections. Starting around 2007, USB
superseded PS/2 and is the modern peripheral device
connection standard. For legacy support on boards
with a PS/2 connector, Zephyr provides these PS/2 driver APIs.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_PS2`
API Reference
*************
.. doxygengroup:: ps2_interface

View file

@ -0,0 +1,13 @@
.. _pwm_api:
PWM
###
Overview
********
API Reference
*************
.. doxygengroup:: pwm_interface

View file

@ -0,0 +1,43 @@
.. _regulator_api:
Regulators
##########
This subsystem provides control of voltage and current regulators. A
common example is a GPIO that controls a transistor that supplies
current to a device that is not always needed.
Conceptually regulators have two modes: off and on. A transition
between modes may involve a time delay, so operations on regulators are
inherently asynchronous. To maximize flexibility the
:ref:`resource_mgmt_onoff` infrastructure is used in the generic API for
the regulator subsystem. Nodes with a devicetree compatible of
``regulator-fixed`` are the most common flexible regulators.
In some cases the transitions are close enough to instantaneous that the
the asynchronous driver implementation is not needed, and the resource
cost in RAM is not justified. Such a regulator still uses the
asynchronous API, but may be implemented internally in a way that
ensures the result of the operation is presented before the transition
completes. Zephyr recognizes devicetree nodes with a compatible of
``regulator-fixed-sync`` as devices with synchronous transitions.
The ``vin-supply`` devicetree property is used to identify the
regulator(s) that a devicetree node directly depends on. Within the
driver for the node the regulator API is used to issue requests for
power when the device is to be active, and release the power request
when the device shuts down.
The simplest case where a regulator is needed is one where there is only
one client. For those situations the cost of using even the optimized
synchronous regulator device infrastructure is not justified, and the
``supply-gpios`` devicetree property should be used. There is no device
interface to these regulators as they are entirely controlled within the
driver for the corresponding node, e.g. a sensor.
.. _regulator_api_reference:
API Reference
**************
.. doxygengroup:: regulator_interface

View file

@ -0,0 +1,28 @@
.. _reset_api:
Reset Controller
################
Overview
********
Reset controllers are units that control the reset signals to multiple
peripherals. The reset controller API allows peripheral drivers to request
control over their reset input signals, including the ability to assert,
deassert and toggle those signals. Also, the reset status of the reset input
signal can be checked.
Mainly, the assert and deassert API functions are optional because in most
cases we want to toggle the reset signals.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_RESET`
API Reference
*************
.. doxygengroup:: reset_controller_interface

View file

@ -0,0 +1,16 @@
.. _rtc_api:
RTC
###
Overview
********
This is a placeholder for API specific to real-time clocks. Currently
all RTC peripherals are implemented through :ref:`counter_api` with
device-specific API for counters with real-time support.
API Reference
*************
.. doxygengroup:: rtc_interface

View file

@ -0,0 +1,117 @@
.. _sensor_api:
Sensors
#######
The sensor subsystem exposes an API to uniformly access sensor devices.
Common operations are: reading data and executing code when specific
conditions are met.
Basic Operation
***************
Channels
========
Fundamentally, a channel is a quantity that a sensor device can measure.
Sensors can have multiple channels, either to represent different axes of
the same physical property (e.g. acceleration); or because they can measure
different properties altogether (ambient temperature, pressure and
humidity). Complex sensors cover both cases, so a single device can expose
three acceleration channels and a temperature one.
It is imperative that all sensors that support a given channel express
results in the same unit of measurement. Consult the
:ref:`sensor_api_reference` for all supported channels, along with their
description and units of measurement:
Values
======
Sensor devices return results as :c:struct:`sensor_value`. This
representation avoids use of floating point values as they may not be
supported on certain setups.
Fetching Values
===============
Getting a reading from a sensor requires two operations. First, an
application instructs the driver to fetch a sample of all its channels.
Then, individual channels may be read. In the case of channels with
multiple axes, they can be read in a single operation by supplying
the corresponding :literal:`_XYZ` channel type and a buffer of 3
:c:struct:`sensor_value` objects. This approach ensures consistency
of channels between reads and efficiency of communication by issuing a
single transaction on the underlying bus.
Below is an example illustrating the usage of the BME280 sensor, which
measures ambient temperature and atmospheric pressure. Note that
:c:func:`sensor_sample_fetch` is only called once, as it reads and
compensates data for both channels.
.. literalinclude:: ../../../samples/sensor/bme280/src/main.c
:language: c
:lines: 12-
:linenos:
Configuration and Attributes
****************************
Setting the communication bus and address is considered the most basic
configuration for sensor devices. This setting is done at compile time, via
the configuration menu. If the sensor supports interrupts, the interrupt
lines and triggering parameters described below are also configured at
compile time.
Alongside these communication parameters, sensor chips typically expose
multiple parameters that control the accuracy and frequency of measurement.
In compliance with Zephyr's design goals, most of these values are
statically configured at compile time.
However, certain parameters could require runtime configuration, for
example, threshold values for interrupts. These values are configured via
attributes. The example in the following section showcases a sensor with an
interrupt line that is triggered when the temperature crosses a threshold.
The threshold is configured at runtime using an attribute.
Triggers
********
:dfn:`Triggers` in Zephyr refer to the interrupt lines of the sensor chips.
Many sensor chips support one or more triggers. Some examples of triggers
include: new data is ready for reading, a channel value has crossed a
threshold, or the device has sensed motion.
To configure a trigger, an application needs to supply a
:c:struct:`sensor_trigger` and a handler function. The structure contains the
trigger type and the channel on which the trigger must be configured.
Because most sensors are connected via SPI or I2C busses, it is not possible
to communicate with them from the interrupt execution context. The
execution of the trigger handler is deferred to a thread, so that data
fetching operations are possible. A driver can spawn its own thread to fetch
data, thus ensuring minimum latency. Alternatively, multiple sensor drivers
can share a system-wide thread. The shared thread approach increases the
latency of handling interrupts but uses less memory. You can configure which
approach to follow for each driver. Most drivers can entirely disable
triggers resulting in a smaller footprint.
The following example contains a trigger fired whenever temperature crosses
the 26 degree Celsius threshold. It also samples the temperature every
second. A real application would ideally disable periodic sampling in the
interest of saving power. Since the application has direct access to the
kernel config symbols, no trigger is registered when triggering was disabled
by the driver's configuration.
.. literalinclude:: ../../../samples/sensor/mcp9808/src/main.c
:language: c
:lines: 12-
:linenos:
.. _sensor_api_reference:
API Reference
**************
.. doxygengroup:: sensor_interface

View file

@ -0,0 +1,13 @@
.. _spi_api:
SPI
###
Overview
********
API Reference
*************
.. doxygengroup:: spi_interface

View file

@ -0,0 +1,57 @@
.. _tcpc_api:
TCPC
####
Overview
********
`TCPC <tcpc-specification>`_ (USB Type-C Port Controller)
The TCPC is a device used to simplify the implementation of a USB-C system
by providing the following three function:
* VBUS and VCONN control `USB Type-C <usb-type-c-specification>`_:
The TCPC may provide a Source device, the mechanism to control VBUS sourcing,
and a Sink device, the mechanism to control VBUS sinking. A similar mechanism
is provided for the control of VCONN.
* CC control and sensing:
The TCPC implements logic for controlling the CC pin pull-up and pull-down
resistors. It also provides a way to sense and report what resistors are
present on the CC pin.
* Power Delivery message reception and transmission `USB Power Delivery <usb-pd-specification>`_:
The TCPC sends and receives messages constructed in the TCPM and places them
on the CC lines.
.. _tcpc-api:
TCPC API
========
The TCPC device driver functions as the liaison between the TCPC device and the
application software; this is accomplished by the Zephyr's API provided by the
device driver that's used to communicate with and control the TCPC device.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_USBC_TCPC_DRIVER`
API Reference
*************
.. doxygengroup:: usb_type_c
.. doxygengroup:: usb_type_c_port_controller_api
.. doxygengroup:: usb_power_delivery
.. _tcpc-specification:
https://www.usb.org/document-library/usb-type-cr-port-controller-interface-specification
.. _usb-type-c-specification:
https://www.usb.org/document-library/usb-type-cr-cable-and-connector-specification-revision-21
.. _usb-pd-specification:
https://www.usb.org/document-library/usb-power-delivery

View file

@ -0,0 +1,74 @@
.. _uart_api:
UART
####
Overview
********
Zephyr provides three different ways to access the UART peripheral. Depending
on the method, different API functions are used according to below sections:
1. :ref:`uart_polling_api`
2. :ref:`uart_interrupt_api`
3. :ref:`uart_async_api` using :ref:`dma_api`
Polling is the most basic method to access the UART peripheral. The functions
are blocking and the thread waits until a character is sent or received.
With the Interrupt-driven API, possibly slow communication can happen in the
background while the thread continues with other tasks. The Kernel's
:ref:`kernel_data_passing_api` features can be used to communicate between
the thread and the UART driver.
The Asynchronous API allows to read and write data in the background using DMA
without interrupting the MCU at all. However, the setup is more complex
than the other methods.
Configuration Options
*********************
Most importantly, the Kconfig options define whether the polling API (default),
the interrupt-driven API or the asynchronous API can be used. Only enable the
features you need in order to minimize memory footprint.
Related configuration options:
* :kconfig:option:`CONFIG_SERIAL`
* :kconfig:option:`CONFIG_UART_INTERRUPT_DRIVEN`
* :kconfig:option:`CONFIG_UART_ASYNC_API`
* :kconfig:option:`CONFIG_UART_WIDE_DATA`
* :kconfig:option:`CONFIG_UART_USE_RUNTIME_CONFIGURE`
* :kconfig:option:`CONFIG_UART_LINE_CTRL`
* :kconfig:option:`CONFIG_UART_DRV_CMD`
API Reference
*************
.. doxygengroup:: uart_interface
.. _uart_polling_api:
Polling API
===========
.. doxygengroup:: uart_polling
.. _uart_interrupt_api:
Interrupt-driven API
====================
.. doxygengroup:: uart_interrupt
.. _uart_async_api:
Asynchronous API
================
.. doxygengroup:: uart_async

View file

@ -0,0 +1,58 @@
.. _video_api:
Video
#####
The video driver API offers a generic interface to video devices.
Basic Operation
***************
Video Device
============
A video device is the abstraction of a hardware or software video function,
which can produce, process, consume or transform video data. The video API is
designed to offer flexible way to create, handle and combine various video
devices.
Endpoint
========
Each video device can have one or more endpoints. Output endpoints configure
video output function and generate data. Input endpoints configure video input
function and consume data.
Video Buffer
============
A video buffer provides the transport mechanism for the data. There is no
particular requirement on the content. The requirement for the content is
defined by the endpoint format. A video buffer can be queued to a device
endpoint for filling (input ep) or consuming (output ep) operation, once
the operation is achieved, buffer can be dequeued for post-processing,
release or reuse.
Controls
========
A video control is accessed and identified by a CID (control identifier). It
represents a video control property. Different devices will have different
controls available which can be generic, related to a device class or vendor
specific. The set/get control functions provide a generic scalable interface
to handle and create controls.
Configuration Options
*********************
Related configuration options:
* :kconfig:option:`CONFIG_VIDEO`
API Reference
*************
.. doxygengroup:: video_interface
.. doxygengroup:: video_controls

View file

@ -0,0 +1,13 @@
.. _watchdog_api:
Watchdog
########
Overview
********
API Reference
*************
.. doxygengroup:: watchdog_interface