diff --git a/doc/conf.py b/doc/conf.py index aeccbd204b07d..212ba400a9e06 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -103,8 +103,6 @@ todo_include_todos = False -numfig = True - nitpick_ignore = [ # ignore C standard identifiers (they are not defined in Zephyr docs) ("c:identifier", "FILE"), diff --git a/doc/connectivity/bluetooth/bluetooth-audio-arch.rst b/doc/connectivity/bluetooth/bluetooth-audio-arch.rst index 6633aaf40cd38..f7bc347b8cdde 100644 --- a/doc/connectivity/bluetooth/bluetooth-audio-arch.rst +++ b/doc/connectivity/bluetooth/bluetooth-audio-arch.rst @@ -66,13 +66,12 @@ The Common Audio Profile introduces restrictions and requirements on the lower l The procedures in CAP works on one or more streams for one or more devices. Is it thus possible via CAP to do a single function call to setup multiple streams across multiple devices. -:numref:`bluetooth_audio_arch_cap_proc` shows a complete structure of the procedures in CAP and -how they correspond to procedures from the other profiles. The circles with I, A and C show whether -the procedure has active involvement or requirements from the CAP Initiator, CAP Accept and CAP -Commander roles respectively. +The figure below shows a complete structure of the procedures in CAP and how +they correspond to procedures from the other profiles. The circles with I, A +and C show whether the procedure has active involvement or requirements from +the CAP Initiator, CAP Accept and CAP Commander roles respectively. .. _bluetooth_audio_arch_cap_proc: -.. figure:: img/cap_proc.svg :align: center :alt: Common Audio Profile Procedures diff --git a/doc/hardware/pinctrl/index.rst b/doc/hardware/pinctrl/index.rst index 3c4bf0e59db1e..287d86009337f 100644 --- a/doc/hardware/pinctrl/index.rst +++ b/doc/hardware/pinctrl/index.rst @@ -23,22 +23,20 @@ debouncing, low-power modes, etc. The way pin control is implemented in hardware is vendor/SoC specific. It is common to find a *centralized* approach, that is, all pin configuration parameters are controlled by a single hardware block (typically named pinmux), -including signal mapping. :numref:`pinctrl-hw-cent-control` illustrates this -approach. ``PX0`` can be mapped to ``UART0_TX``, ``I2C0_SCK`` or ``SPI0_MOSI`` -depending on the ``AF`` control bits. Other configuration parameters such as -pull-up/down are controlled in the same block via ``CONFIG`` bits. This model is -used by several SoC families, such as many from NXP and STM32. - -.. _pinctrl-hw-cent-control: +including signal mapping. The figure below illustrates this approach. ``PX0`` +can be mapped to ``UART0_TX``, ``I2C0_SCK`` or ``SPI0_MOSI`` depending on the +``AF`` control bits. Other configuration parameters such as pull-up/down are +controlled in the same block via ``CONFIG`` bits. This model is used by several +SoC families, such as many from NXP and STM32. .. figure:: images/hw-cent-control.svg Example of pin control centralized into a single per-pin block Other vendors/SoCs use a *distributed* approach. In such case, the pin mapping -and configuration are controlled by multiple hardware blocks. -:numref:`pinctrl-hw-dist-control` illustrates a distributed approach where pin -mapping is controlled by peripherals, such as in Nordic nRF SoCs. +and configuration are controlled by multiple hardware blocks. The figure below +illustrates a distributed approach where pin mapping is controlled by +peripherals, such as in Nordic nRF SoCs. .. _pinctrl-hw-dist-control: @@ -75,12 +73,10 @@ depending on the operating conditions, for example, to enable a low-power mode when suspending the device. Such requirements are modeled using **states**, a concept that has been adapted from the one in the Linux kernel. Each device driver owns a set of states. Each state has a unique name and contains a full -pin configuration set (see :numref:`pinctrl-states-model`). This effectively -means that states are independent of each other, so they do not need to be -applied in any specific order. Another advantage of the state model is that it -isolates device drivers from pin configuration. - -.. _pinctrl-states-model: +pin configuration set (see the figure below). This effectively means that +states are independent of each other, so they do not need to be applied in any +specific order. Another advantage of the state model is that it isolates device +drivers from pin configuration. .. table:: Example pin configuration encoded using the states model :align: center @@ -106,10 +102,8 @@ The name assigned to pin control states or the number of them is up to the device driver requirements. In many cases a single state applied at initialization time will be sufficient, but in some other cases more will be required. In order to make things consistent, a naming convention has been -established for the most common use cases. :numref:`pinctrl-states-standard` -details the standardized states and its purpose. - -.. _pinctrl-states-standard: +established for the most common use cases. The figure below details the +standardized states and its purpose. .. table:: Standardized state names :align: center diff --git a/doc/services/logging/index.rst b/doc/services/logging/index.rst index a14e5bf02640d..5258c3844ec97 100644 --- a/doc/services/logging/index.rst +++ b/doc/services/logging/index.rst @@ -535,23 +535,21 @@ There are three types of domains in a multi-domain system: See the following image for an example of a multi-domain setup: -.. _logging-multidomain-example: - .. figure:: images/multidomain.png Multi-domain example In this architecture, a link can handle multiple domains. -For example, let's consider an SoC with two ARM Cortex-M33 cores with TrustZone: cores A and B (see -:numref:`logging-multidomain-example`). There are four domains in the system, as +For example, let's consider an SoC with two ARM Cortex-M33 cores with TrustZone: cores A and B (see the example illustrated above). There are four domains in the system, as each core has both a Secure and a Nonsecure domain. If *core A nonsecure* (A_NS) is the root domain, it has two links: one to *core A secure* (A_NS-A_S) and one to *core B nonsecure* (A_NS-B_NS). *B_NS* domain has one link, to *core B secure* *B_NS-B_S*), and a backend to *A_NS*. -Since in all instances there is a standard logging subsystem, it is always possible -to have multiple backends and simultaneously output messages to them. An example of this is shown -on :numref:`logging-multidomain-example` as a dotted UART backend on the *B_NS* domain. +Since in all instances there is a standard logging subsystem, it is always +possible to have multiple backends and simultaneously output messages to them. +An example of this is shown in the illustration above as a dotted UART backend +on the *B_NS* domain. Domain ID --------- @@ -569,10 +567,9 @@ The first link has the offset set to 1. The following offset equals the previous link offset plus the number of domains in the previous link. -The following example is shown on :numref:`logging-domain-ids-example`, where -the assigned ``domain_ids`` are shown for each domain: +The following example is shown below, where the assigned ``domain_ids`` are +shown for each domain: -.. _logging-domain-ids-example: .. figure:: images/domain_ids.png Domain IDs assigning example diff --git a/doc/services/pm/device_runtime.rst b/doc/services/pm/device_runtime.rst index ea60c76ceec88..8ef1ecaf92138 100644 --- a/doc/services/pm/device_runtime.rst +++ b/doc/services/pm/device_runtime.rst @@ -84,11 +84,8 @@ increase device usage count and resume the device if necessary. Similarly, the :c:func:`pm_device_runtime_put` function can be used to indicate that the device is no longer needed. This function will decrease the device usage count and suspend the device if necessary. It is worth to note that in both cases, the -operation is carried out synchronously. The sequence diagram shown in -:numref:`pm_device_runtime_sync_ops` illustrates how a device can use this API -and the expected sequence of events. - -.. _pm_device_runtime_sync_ops: +operation is carried out synchronously. The sequence diagram shown below +illustrates how a device can use this API and the expected sequence of events. .. figure:: images/devr-sync-ops.svg @@ -103,10 +100,7 @@ slow bus. For this reason the device drivers can also make use of the :c:func:`pm_device_runtime_put_async` function. This function will schedule the suspend operation, again, if device is no longer used. The suspension will then be carried out when the system work queue gets the chance to run. The -sequence diagram in :numref:`pm_device_runtime_async_ops` illustrates this -scenario. - -.. _pm_device_runtime_async_ops: +sequence diagram shown below illustrates this scenario. .. figure:: images/devr-async-ops.svg diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 0443a70c2f968..d76383647a656 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -12,28 +12,26 @@ The :dfn:`Zephyr message bus - Zbus` is a lightweight and flexible message bus e Concepts ******** -Threads can broadcast messages to all interested observers using zbus. Many-to-many communication is possible. The bus implements message-passing and publish/subscribe communication paradigms that enable threads to communicate synchronously or asynchronously through shared memory. The communication through zbus is channel-based, where threads publish and read to and from using messages. Additionally, threads can observe channels and receive notifications from the bus when the channels are modified. :numref:`zbus common` shows an example of a typical application using zbus in which the application logic (hardware independent) talks to other threads via message bus. Note that the threads are decoupled from each other because they only use zbus' channels and do not need to know each other to talk. +Threads can broadcast messages to all interested observers using zbus. Many-to-many communication is possible. The bus implements message-passing and publish/subscribe communication paradigms that enable threads to communicate synchronously or asynchronously through shared memory. The communication through zbus is channel-based, where threads publish and read to and from using messages. Additionally, threads can observe channels and receive notifications from the bus when the channels are modified. The figure below shows an example of a typical application using zbus in which the application logic (hardware independent) talks to other threads via message bus. Note that the threads are decoupled from each other because they only use zbus' channels and do not need to know each other to talk. -.. _zbus common: .. figure:: images/zbus_overview.svg :alt: zbus usage overview :width: 75% A typical zbus application architecture. -:numref:`zbus anatomy` illustrates zbus' anatomy. The bus comprises: +The bus comprises: * Set of channels that consists of a unique identifier, its control metadata information, and the message itself; * :dfn:`Virtual distributed event dispatcher` (VDED), the bus logic responsible for sending notifications to the observers. The VDED logic runs inside the publishing action in the same thread context, giving the bus an idea of a distributed execution. When a thread publishes to a channel, it also propagates the notifications to the observers; * Threads (subscribers) and callbacks (listeners) publishing, reading, and receiving notifications from the bus. -.. _zbus anatomy: .. figure:: images/zbus_anatomy.svg :alt: Zbus anatomy :width: 70% - Zbus internals details. + Zbus anatomy. The bus makes the publish, read, and subscribe actions available over channels. Publishing and reading are available in all RTOS thread contexts. However, it cannot run inside Interrupt Service Routines (ISR) because it uses mutexes to control channels access, and mutexes cannot work appropriately inside ISRs. The publish and read operations are simple and fast; the procedure is a mutex locking followed by a memory copy to and from a shared memory region and then a mutex unlocking. Another essential aspect of zbus is the observers, which can be: @@ -41,10 +39,9 @@ The bus makes the publish, read, and subscribe actions available over channels. * Dynamic; it can be added and removed to and from a channel at runtime. -For illustration purposes, suppose a usual sensor-based solution in :numref:`zbus operations`. When the timer is triggered, it pushes an action to a work queue that publishes to the ``Start trigger`` channel. As the sensor thread subscribed to the ``Start trigger`` channel, it fetches the sensor data. Notice the VDED executes the blink callback because it also listens to the ``Start trigger`` channel. When the sensor data is ready, the sensor thread publishes it to the ``Sensor data`` channel. The core thread, as a ``Sensor data`` channel subscriber, processes the sensor data and stores it in an internal sample buffer. It repeats until the sample buffer is full; when it happens, the core thread aggregates the sample buffer information, prepares a package, and publishes that to the ``Payload`` channel. The Lora thread receives that because it is a ``Payload`` channel subscriber and sends the payload to the cloud. When it completes the transmission, the Lora thread publishes to the ``Transmission done`` channel. The VDED executes the blink callback again since it listens to the ``Transmission done`` channel. +For illustration purposes, suppose a usual sensor-based solution in the figure below. When the timer is triggered, it pushes an action to a work queue that publishes to the ``Start trigger`` channel. As the sensor thread subscribed to the ``Start trigger`` channel, it fetches the sensor data. Notice the VDED executes the blink callback because it also listens to the ``Start trigger`` channel. When the sensor data is ready, the sensor thread publishes it to the ``Sensor data`` channel. The core thread, as a ``Sensor data`` channel subscriber, processes the sensor data and stores it in an internal sample buffer. It repeats until the sample buffer is full; when it happens, the core thread aggregates the sample buffer information, prepares a package, and publishes that to the ``Payload`` channel. The Lora thread receives that because it is a ``Payload`` channel subscriber and sends the payload to the cloud. When it completes the transmission, the Lora thread publishes to the ``Transmission done`` channel. The VDED executes the blink callback again since it listens to the ``Transmission done`` channel. -.. _zbus operations: .. figure:: images/zbus_operations.svg :alt: Zbus sensor-based application :width: 80% @@ -73,9 +70,8 @@ The VDED execution always happens in the publishing's (thread) context. So it ca * At last, the publishing function unlocks the channel. -To illustrate the VDED execution, consider the example the :numref:`zbus vded scenario` shows. We have four threads in ascending priority T1, T2, T3, and T4 (the highest priority); two listeners, L1 and L2; and channel A. Suposing L1, L2, T2, T3, and T4 observer channel A. +To illustrate the VDED execution, consider the example iluustrated below. We have four threads in ascending priority T1, T2, T3, and T4 (the highest priority); two listeners, L1 and L2; and channel A. Suposing L1, L2, T2, T3, and T4 observer channel A. -.. _zbus vded scenario: .. figure:: images/zbus_publishing_process_example_scenario.svg :alt: Zbus example scenario :width: 55% @@ -97,10 +93,9 @@ The following code implements channel A. Note the ``struct a_msg`` is illustrati ); -In :numref:`zbus vded`, the letters indicate some action related to the VDED execution. The X-axis represents the time, and the Y-axis represents the priority of threads. Channel A's message, represented by a voice balloon, is only one memory portion (shared memory). It appears several times only as an illustration of the message at that point in time. +In the figure below, the letters indicate some action related to the VDED execution. The X-axis represents the time, and the Y-axis represents the priority of threads. Channel A's message, represented by a voice balloon, is only one memory portion (shared memory). It appears several times only as an illustration of the message at that point in time. -.. _zbus vded: .. figure:: images/zbus_publishing_process_example.svg :alt: Zbus publish processing detail :width: 85% @@ -109,10 +104,9 @@ In :numref:`zbus vded`, the letters indicate some action related to the VDED exe -The :numref:`zbus vded` illustrates the actions performed during the VDED execution when T1 publishes to channel A. Thus, :numref:`zbus vded table` describes the actions (represented by a letter) of the VDED execution. +The figure above illustrates the actions performed during the VDED execution when T1 publishes to channel A. Thus, the figure below describes the actions (represented by a letter) of the VDED execution. -.. _zbus vded table: .. list-table:: VDED execution steps in detail. :widths: 5 65 :header-rows: 1 @@ -279,7 +273,7 @@ Messages are read from a channel in zbus by calling :c:func:`zbus_chan_read`. So Do not use this function inside an ISR. .. warning:: - Choose the timeout of :c:func:`zbus_chan_read` after receiving a notification from :c:func:`zbus_sub_wait` carefully because the channel will always be unavailable during the VDED execution. Using ``K_NO_WAIT`` for reading is highly likely to return a timeout error if there are more than one subscriber. For example, consider the :numref:`zbus vded` again and notice how ``T3`` and ``T4's`` read attempts would definitely fail with K_NO_WAIT. For more details, check the `Virtual Distributed Event Dispatcher`_ section. + Choose the timeout of :c:func:`zbus_chan_read` after receiving a notification from :c:func:`zbus_sub_wait` carefully because the channel will always be unavailable during the VDED execution. Using ``K_NO_WAIT`` for reading is highly likely to return a timeout error if there are more than one subscriber. For example, consider the VDED illustration again and notice how ``T3`` and ``T4's`` read attempts would definitely fail with K_NO_WAIT. For more details, check the `Virtual Distributed Event Dispatcher`_ section. Forcing channel notification ============================