doc: fix usage of :c:type
Fixing issues with recent versions of breathe 4.19.2: WARNING: Unparseable C cross-reference: 'struct device' Invalid C declaration: Expected identifier in nested name, got keyword: struct [error at 6] struct device ------^ Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
06052927be
commit
0ff33d1ae7
24 changed files with 65 additions and 66 deletions
|
@ -62,7 +62,7 @@ Implementation
|
||||||
Defining a FIFO
|
Defining a FIFO
|
||||||
===============
|
===============
|
||||||
|
|
||||||
A FIFO is defined using a variable of type :c:type:`struct k_fifo`.
|
A FIFO is defined using a variable of type :c:type:`k_fifo`.
|
||||||
It must then be initialized by calling :cpp:func:`k_fifo_init()`.
|
It must then be initialized by calling :cpp:func:`k_fifo_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty FIFO.
|
The following code defines and initializes an empty FIFO.
|
||||||
|
|
|
@ -53,7 +53,7 @@ Implementation
|
||||||
Defining a LIFO
|
Defining a LIFO
|
||||||
===============
|
===============
|
||||||
|
|
||||||
A LIFO is defined using a variable of type :c:type:`struct k_lifo`.
|
A LIFO is defined using a variable of type :c:type:`k_lifo`.
|
||||||
It must then be initialized by calling :cpp:func:`k_lifo_init()`.
|
It must then be initialized by calling :cpp:func:`k_lifo_init()`.
|
||||||
|
|
||||||
The following defines and initializes an empty LIFO.
|
The following defines and initializes an empty LIFO.
|
||||||
|
|
|
@ -118,7 +118,7 @@ Implementation
|
||||||
Defining a Mailbox
|
Defining a Mailbox
|
||||||
==================
|
==================
|
||||||
|
|
||||||
A mailbox is defined using a variable of type :c:type:`struct k_mbox`.
|
A mailbox is defined using a variable of type :c:type:`k_mbox`.
|
||||||
It must then be initialized by calling :cpp:func:`k_mbox_init()`.
|
It must then be initialized by calling :cpp:func:`k_mbox_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty mailbox.
|
The following code defines and initializes an empty mailbox.
|
||||||
|
@ -141,7 +141,7 @@ The following code has the same effect as the code segment above.
|
||||||
Message Descriptors
|
Message Descriptors
|
||||||
===================
|
===================
|
||||||
|
|
||||||
A message descriptor is a structure of type :c:type:`struct k_mbox_msg`.
|
A message descriptor is a structure of type :c:type:`k_mbox_msg`.
|
||||||
Only the fields listed below should be used; any other fields are for
|
Only the fields listed below should be used; any other fields are for
|
||||||
internal mailbox use only.
|
internal mailbox use only.
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ Implementation
|
||||||
Defining a Message Queue
|
Defining a Message Queue
|
||||||
========================
|
========================
|
||||||
|
|
||||||
A message queue is defined using a variable of type :c:type:`struct k_msgq`.
|
A message queue is defined using a variable of type :c:type:`k_msgq`.
|
||||||
It must then be initialized by calling :cpp:func:`k_msgq_init()`.
|
It must then be initialized by calling :cpp:func:`k_msgq_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty message queue
|
The following code defines and initializes an empty message queue
|
||||||
|
|
|
@ -52,8 +52,8 @@ waiting sender(s).
|
||||||
Implementation
|
Implementation
|
||||||
**************
|
**************
|
||||||
|
|
||||||
A pipe is defined using a variable of type :c:type:`struct k_pipe` and an
|
A pipe is defined using a variable of type :c:type:`k_pipe` and an
|
||||||
optional character buffer of type :c:type:`unsigned char`. It must then be
|
optional character buffer of type ``unsigned char``. It must then be
|
||||||
initialized by calling :cpp:func:`k_pipe_init()`.
|
initialized by calling :cpp:func:`k_pipe_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty pipe that has a ring
|
The following code defines and initializes an empty pipe that has a ring
|
||||||
|
|
|
@ -55,7 +55,7 @@ Implementation
|
||||||
Defining a Stack
|
Defining a Stack
|
||||||
================
|
================
|
||||||
|
|
||||||
A stack is defined using a variable of type :c:type:`struct k_stack`.
|
A stack is defined using a variable of type :c:type:`k_stack`.
|
||||||
It must then be initialized by calling :cpp:func:`k_stack_init()` or
|
It must then be initialized by calling :cpp:func:`k_stack_init()` or
|
||||||
:cpp:func:`k_stack_alloc_init()`. In the latter case, a buffer is not
|
:cpp:func:`k_stack_alloc_init()`. In the latter case, a buffer is not
|
||||||
provided and it is instead allocated from the calling thread's resource
|
provided and it is instead allocated from the calling thread's resource
|
||||||
|
|
|
@ -13,8 +13,8 @@ Creating a Heap
|
||||||
===============
|
===============
|
||||||
|
|
||||||
The simplest way to define a heap is statically, with the
|
The simplest way to define a heap is statically, with the
|
||||||
:c:macro:`K_HEAP_DEFINE` macro. This creates a static :c:type:`struct
|
:c:macro:`K_HEAP_DEFINE` macro. This creates a static :c:type:`k_heap` variable
|
||||||
k_heap` variable with a given name that manages a memory region of the
|
with a given name that manages a memory region of the
|
||||||
specified size.
|
specified size.
|
||||||
|
|
||||||
Heaps can also be created to manage arbitrary regions of
|
Heaps can also be created to manage arbitrary regions of
|
||||||
|
@ -46,9 +46,9 @@ returned by :cpp:func:`k_heap_alloc()` for the same heap. Freeing a
|
||||||
Low Level Heap Allocator
|
Low Level Heap Allocator
|
||||||
************************
|
************************
|
||||||
|
|
||||||
The underlying implementation of the :c:type:`struct k_heap`
|
The underlying implementation of the :c:type:`k_heap`
|
||||||
abstraction is provided a data structure named :c:type:`struct
|
abstraction is provided a data structure named :c:type:`sys_heap`. This
|
||||||
sys_heap`. This implements exactly the same allocation semantics, but
|
implements exactly the same allocation semantics, but
|
||||||
provides no kernel synchronization tools. It is available for
|
provides no kernel synchronization tools. It is available for
|
||||||
applications that want to manage their own blocks of memory in
|
applications that want to manage their own blocks of memory in
|
||||||
contexts (for example, userspace) where synchronization is unavailable
|
contexts (for example, userspace) where synchronization is unavailable
|
||||||
|
@ -79,7 +79,7 @@ combined with adjacent free blocks to prevent fragmentation.
|
||||||
All metadata is stored at the beginning of the contiguous block of
|
All metadata is stored at the beginning of the contiguous block of
|
||||||
heap memory, including the variable-length list of bucket list heads
|
heap memory, including the variable-length list of bucket list heads
|
||||||
(which depend on heap size). The only external memory required is the
|
(which depend on heap size). The only external memory required is the
|
||||||
:c:type:`struct sys_heap` structure itself.
|
:c:type:`sys_heap` structure itself.
|
||||||
|
|
||||||
The ``sys_heap`` functions are unsynchronized. Care must be taken by
|
The ``sys_heap`` functions are unsynchronized. Care must be taken by
|
||||||
any users to prevent concurrent access. Only one context may be
|
any users to prevent concurrent access. Only one context may be
|
||||||
|
|
|
@ -5,12 +5,12 @@ Memory Pools
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The ``k_mem_pool`` data structure defined here has been deprecated
|
The :c:type:`k_mem_pool` data structure defined here has been deprecated
|
||||||
in current Zephyr code. It still exists for applications which
|
in current Zephyr code. It still exists for applications which
|
||||||
require the specific memory allocation and alignment patterns
|
require the specific memory allocation and alignment patterns
|
||||||
detailed below, but the default heap implementation (including the
|
detailed below, but the default heap implementation (including the
|
||||||
default backend to the k_mem_pool APIs) is now a :c:type:`struct
|
default backend to the k_mem_pool APIs) is now a :c:type:` k_heap`
|
||||||
k_heap` allocator, which is a better choice for general purpose
|
allocator, which is a better choice for general purpose
|
||||||
code.
|
code.
|
||||||
|
|
||||||
A :dfn:`memory pool` is a kernel object that allows memory blocks
|
A :dfn:`memory pool` is a kernel object that allows memory blocks
|
||||||
|
@ -119,7 +119,7 @@ Implementation
|
||||||
Defining a Memory Pool
|
Defining a Memory Pool
|
||||||
======================
|
======================
|
||||||
|
|
||||||
A memory pool is defined using a variable of type :c:type:`struct k_mem_pool`.
|
A memory pool is defined using a variable of type :c:type:`k_mem_pool`.
|
||||||
However, since a memory pool also requires a number of variable-size data
|
However, since a memory pool also requires a number of variable-size data
|
||||||
structures to represent its block sets and the status of its quad-blocks,
|
structures to represent its block sets and the status of its quad-blocks,
|
||||||
the kernel does not support the runtime definition of a memory pool.
|
the kernel does not support the runtime definition of a memory pool.
|
||||||
|
|
|
@ -67,7 +67,7 @@ Implementation
|
||||||
Defining a Memory Slab
|
Defining a Memory Slab
|
||||||
======================
|
======================
|
||||||
|
|
||||||
A memory slab is defined using a variable of type :c:type:`struct k_mem_slab`.
|
A memory slab is defined using a variable of type :c:type:`k_mem_slab`.
|
||||||
It must then be initialized by calling :cpp:func:`k_mem_slab_init()`.
|
It must then be initialized by calling :cpp:func:`k_mem_slab_init()`.
|
||||||
|
|
||||||
The following code defines and initializes a memory slab that has 6 blocks
|
The following code defines and initializes a memory slab that has 6 blocks
|
||||||
|
|
|
@ -68,7 +68,7 @@ Using k_poll()
|
||||||
==============
|
==============
|
||||||
|
|
||||||
The main API is :cpp:func:`k_poll()`, which operates on an array of poll events
|
The main API is :cpp:func:`k_poll()`, which operates on an array of poll events
|
||||||
of type :c:type:`struct k_poll_event`. Each entry in the array represents one
|
of type :c:type:`k_poll_event`. Each entry in the array represents one
|
||||||
event a call to :cpp:func:`k_poll()` will wait for its condition to be
|
event a call to :cpp:func:`k_poll()` will wait for its condition to be
|
||||||
fulfilled.
|
fulfilled.
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ this). The user **tag** is optional and completely opaque to the API: it is
|
||||||
there to help a user to group similar events together. Being optional, it is
|
there to help a user to group similar events together. Being optional, it is
|
||||||
passed to the static initializer, but not the runtime ones for performance
|
passed to the static initializer, but not the runtime ones for performance
|
||||||
reasons. If using runtime initializers, the user must set it separately in the
|
reasons. If using runtime initializers, the user must set it separately in the
|
||||||
:c:type:`struct k_poll_event` data structure. If an event in the array is to be
|
:c:type:`k_poll_event` data structure. If an event in the array is to be
|
||||||
ignored, most likely temporarily, its type can be set to K_POLL_TYPE_IGNORE.
|
ignored, most likely temporarily, its type can be set to K_POLL_TYPE_IGNORE.
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
@ -125,12 +125,12 @@ satisfied and not sooner.
|
||||||
|
|
||||||
Only one thread can poll on a semaphore or a FIFO at a time. If a second thread
|
Only one thread can poll on a semaphore or a FIFO at a time. If a second thread
|
||||||
tries to poll on the same semaphore or FIFO, :cpp:func:`k_poll()` immediately
|
tries to poll on the same semaphore or FIFO, :cpp:func:`k_poll()` immediately
|
||||||
returns with the return value :c:macro:`-EADDRINUSE`. In that case, if other
|
returns with the return value -:c:macro:`EADDRINUSE`. In that case, if other
|
||||||
conditions passed to :cpp:func:`k_poll` were met, their state will be set in
|
conditions passed to :cpp:func:`k_poll` were met, their state will be set in
|
||||||
the corresponding poll event.
|
the corresponding poll event.
|
||||||
|
|
||||||
In case of success, :cpp:func:`k_poll()` returns 0. If it times out, it returns
|
In case of success, :cpp:func:`k_poll()` returns 0. If it times out, it returns
|
||||||
:c:macro:`-EAGAIN`.
|
-:c:macro:`EAGAIN`.
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ One of the types of events is :c:macro:`K_POLL_TYPE_SIGNAL`: this is a "direct"
|
||||||
signal to a poll event. This can be seen as a lightweight binary semaphore only
|
signal to a poll event. This can be seen as a lightweight binary semaphore only
|
||||||
one thread can wait for.
|
one thread can wait for.
|
||||||
|
|
||||||
A poll signal is a separate object of type :c:type:`struct k_poll_signal` that
|
A poll signal is a separate object of type :c:type:`k_poll_signal` that
|
||||||
must be attached to a k_poll_event, similar to a semaphore or FIFO. It must
|
must be attached to a k_poll_event, similar to a semaphore or FIFO. It must
|
||||||
first be initialized either via :c:macro:`K_POLL_SIGNAL_INITIALIZER()` or
|
first be initialized either via :c:macro:`K_POLL_SIGNAL_INITIALIZER()` or
|
||||||
:cpp:func:`k_poll_signal_init()`.
|
:cpp:func:`k_poll_signal_init()`.
|
||||||
|
|
|
@ -117,7 +117,7 @@ Implementation
|
||||||
Defining a Ring Buffer
|
Defining a Ring Buffer
|
||||||
======================
|
======================
|
||||||
|
|
||||||
A ring buffer is defined using a variable of type :c:type:`struct ring_buf`.
|
A ring buffer is defined using a variable of type :c:type:`ring_buf`.
|
||||||
It must then be initialized by calling :cpp:func:`ring_buf_init()`.
|
It must then be initialized by calling :cpp:func:`ring_buf_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty **data item mode** ring
|
The following code defines and initializes an empty **data item mode** ring
|
||||||
|
|
|
@ -93,7 +93,7 @@ Implementation
|
||||||
Defining a Mutex
|
Defining a Mutex
|
||||||
================
|
================
|
||||||
|
|
||||||
A mutex is defined using a variable of type :c:type:`struct k_mutex`.
|
A mutex is defined using a variable of type :c:type:`k_mutex`.
|
||||||
It must then be initialized by calling :cpp:func:`k_mutex_init()`.
|
It must then be initialized by calling :cpp:func:`k_mutex_init()`.
|
||||||
|
|
||||||
The following code defines and initializes a mutex.
|
The following code defines and initializes a mutex.
|
||||||
|
|
|
@ -47,7 +47,7 @@ Implementation
|
||||||
Defining a Semaphore
|
Defining a Semaphore
|
||||||
====================
|
====================
|
||||||
|
|
||||||
A semaphore is defined using a variable of type :c:type:`struct k_sem`.
|
A semaphore is defined using a variable of type :c:type:`k_sem`.
|
||||||
It must then be initialized by calling :cpp:func:`k_sem_init()`.
|
It must then be initialized by calling :cpp:func:`k_sem_init()`.
|
||||||
|
|
||||||
The following code defines a semaphore, then configures it as a binary
|
The following code defines a semaphore, then configures it as a binary
|
||||||
|
|
|
@ -24,7 +24,7 @@ A thread has the following key properties:
|
||||||
stack memory regions.
|
stack memory regions.
|
||||||
|
|
||||||
* A **thread control block** for private kernel bookkeeping of the thread's
|
* A **thread control block** for private kernel bookkeeping of the thread's
|
||||||
metadata. This is an instance of type :c:type:`struct k_thread`.
|
metadata. This is an instance of type :c:type:`k_thread`.
|
||||||
|
|
||||||
* An **entry point function**, which is invoked when the thread is started.
|
* An **entry point function**, which is invoked when the thread is started.
|
||||||
Up to 3 **argument values** can be passed to this function.
|
Up to 3 **argument values** can be passed to this function.
|
||||||
|
|
|
@ -179,7 +179,7 @@ Implementation
|
||||||
Defining a Workqueue
|
Defining a Workqueue
|
||||||
====================
|
====================
|
||||||
|
|
||||||
A workqueue is defined using a variable of type :c:type:`struct k_work_q`.
|
A workqueue is defined using a variable of type :c:type:`k_work_q`.
|
||||||
The workqueue is initialized by defining the stack area used by its thread
|
The workqueue is initialized by defining the stack area used by its thread
|
||||||
and then calling :cpp:func:`k_work_q_start()`. The stack area must be defined
|
and then calling :cpp:func:`k_work_q_start()`. The stack area must be defined
|
||||||
using :c:macro:`K_THREAD_STACK_DEFINE` to ensure it is properly set up in
|
using :c:macro:`K_THREAD_STACK_DEFINE` to ensure it is properly set up in
|
||||||
|
@ -202,7 +202,7 @@ The following code defines and initializes a workqueue.
|
||||||
Submitting a Work Item
|
Submitting a Work Item
|
||||||
======================
|
======================
|
||||||
|
|
||||||
A work item is defined using a variable of type :c:type:`struct k_work`.
|
A work item is defined using a variable of type :c:type:`k_work`.
|
||||||
It must then be initialized by calling :cpp:func:`k_work_init()`.
|
It must then be initialized by calling :cpp:func:`k_work_init()`.
|
||||||
|
|
||||||
An initialized work item can be submitted to the system workqueue by
|
An initialized work item can be submitted to the system workqueue by
|
||||||
|
@ -250,7 +250,7 @@ Submitting a Delayed Work Item
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
A delayed work item is defined using a variable of type
|
A delayed work item is defined using a variable of type
|
||||||
:c:type:`struct k_delayed_work`. It must then be initialized by calling
|
:c:type:`k_delayed_work`. It must then be initialized by calling
|
||||||
:cpp:func:`k_delayed_work_init()`.
|
:cpp:func:`k_delayed_work_init()`.
|
||||||
|
|
||||||
An initialized delayed work item can be submitted to the system workqueue by
|
An initialized delayed work item can be submitted to the system workqueue by
|
||||||
|
|
|
@ -103,7 +103,7 @@ Implementation
|
||||||
Defining a Timer
|
Defining a Timer
|
||||||
================
|
================
|
||||||
|
|
||||||
A timer is defined using a variable of type :c:type:`struct k_timer`.
|
A timer is defined using a variable of type :c:type:`k_timer`.
|
||||||
It must then be initialized by calling :cpp:func:`k_timer_init()`.
|
It must then be initialized by calling :cpp:func:`k_timer_init()`.
|
||||||
|
|
||||||
The following code defines and initializes a timer.
|
The following code defines and initializes a timer.
|
||||||
|
|
|
@ -21,7 +21,7 @@ API.
|
||||||
A limitation is that this API is not suitable for :ref:`syscalls`
|
A limitation is that this API is not suitable for :ref:`syscalls`
|
||||||
because:
|
because:
|
||||||
|
|
||||||
* :c:type:`struct sys_notify` is not a kernel object;
|
* :c:type:`sys_notify` is not a kernel object;
|
||||||
* copying the notification content from userspace will break use of
|
* copying the notification content from userspace will break use of
|
||||||
:c:macro:`CONTAINER_OF` in the implementing function;
|
:c:macro:`CONTAINER_OF` in the implementing function;
|
||||||
* neither the spin-wait nor callback notification methods can be
|
* neither the spin-wait nor callback notification methods can be
|
||||||
|
@ -29,7 +29,7 @@ because:
|
||||||
|
|
||||||
Where a notification is required for an asynchronous operation invoked
|
Where a notification is required for an asynchronous operation invoked
|
||||||
from a user mode thread the subsystem or driver should provide a syscall
|
from a user mode thread the subsystem or driver should provide a syscall
|
||||||
API that uses :c:type:`struct k_poll_signal` for notification.
|
API that uses :c:type:`k_poll_signal` for notification.
|
||||||
|
|
||||||
API Reference
|
API Reference
|
||||||
*************
|
*************
|
||||||
|
|
|
@ -247,7 +247,7 @@ Sample usage
|
||||||
************
|
************
|
||||||
|
|
||||||
To use the LwM2M library, start by creating an LwM2M client context
|
To use the LwM2M library, start by creating an LwM2M client context
|
||||||
:c:type:`struct lwm2m_ctx` structure:
|
:c:type:`lwm2m_ctx` structure:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,12 @@ Overview
|
||||||
|
|
||||||
The L2 stack is designed to hide the whole networking link-layer part
|
The L2 stack is designed to hide the whole networking link-layer part
|
||||||
and the related device drivers from the upper network stack. This is made
|
and the related device drivers from the upper network stack. This is made
|
||||||
through a :c:type:`struct net_if` declared in
|
through a :c:type:`net_if` declared in
|
||||||
:zephyr_file:`include/net/net_if.h`.
|
:zephyr_file:`include/net/net_if.h`.
|
||||||
|
|
||||||
The upper layers are unaware of implementation details beyond the net_if
|
The upper layers are unaware of implementation details beyond the net_if
|
||||||
object and the generic API provided by the L2 layer in
|
object and the generic API provided by the L2 layer in
|
||||||
:zephyr_file:`include/net/net_l2.h` as :c:type:`struct net_l2`.
|
:zephyr_file:`include/net/net_l2.h` as :c:type:`net_l2`.
|
||||||
|
|
||||||
Only the L2 layer can talk to the device driver, linked to the net_if
|
Only the L2 layer can talk to the device driver, linked to the net_if
|
||||||
object. The L2 layer dictates the API provided by the device driver,
|
object. The L2 layer dictates the API provided by the device driver,
|
||||||
|
@ -39,7 +39,7 @@ See also :ref:`network stack architecture <network_stack_architecture>` for
|
||||||
more details. The generic L2 API has these functions:
|
more details. The generic L2 API has these functions:
|
||||||
|
|
||||||
- ``recv()``: All device drivers, once they receive a packet which they put
|
- ``recv()``: All device drivers, once they receive a packet which they put
|
||||||
into a :c:type:`struct net_pkt`, will push this buffer to the network
|
into a :c:type:`net_pkt`, will push this buffer to the network
|
||||||
stack via :c:func:`net_recv_data()`. At this point, the network
|
stack via :c:func:`net_recv_data()`. At this point, the network
|
||||||
stack does not know what to do with it. Instead, it passes the
|
stack does not know what to do with it. Instead, it passes the
|
||||||
buffer along to the L2 stack's ``recv()`` function for handling.
|
buffer along to the L2 stack's ``recv()`` function for handling.
|
||||||
|
@ -69,13 +69,13 @@ basis. Please refer to :ref:`device_model_api`.
|
||||||
|
|
||||||
There are, however, two differences:
|
There are, however, two differences:
|
||||||
|
|
||||||
- The driver_api pointer must point to a valid :c:type:`struct net_if_api`
|
- The driver_api pointer must point to a valid :c:type:`net_if_api`
|
||||||
pointer.
|
pointer.
|
||||||
|
|
||||||
- The network device driver must use ``NET_DEVICE_INIT_INSTANCE()``
|
- The network device driver must use ``NET_DEVICE_INIT_INSTANCE()``
|
||||||
or ``ETH_NET_DEVICE_INIT()`` for Ethernet devices. These
|
or ``ETH_NET_DEVICE_INIT()`` for Ethernet devices. These
|
||||||
macros will call the ``DEVICE_AND_API_INIT()`` macro, and also
|
macros will call the ``DEVICE_AND_API_INIT()`` macro, and also
|
||||||
instantiate a unique :c:type:`struct net_if` related to the created
|
instantiate a unique :c:type:`net_if` related to the created
|
||||||
device driver instance.
|
device driver instance.
|
||||||
|
|
||||||
Implementing a network device driver depends on the L2 stack it
|
Implementing a network device driver depends on the L2 stack it
|
||||||
|
@ -90,7 +90,7 @@ Ethernet device driver
|
||||||
|
|
||||||
On reception, it is up to the device driver to fill-in the network packet with
|
On reception, it is up to the device driver to fill-in the network packet with
|
||||||
as many data buffers as required. The network packet itself is a
|
as many data buffers as required. The network packet itself is a
|
||||||
:c:type:`struct net_pkt` and should be allocated through
|
:c:type:`net_pkt` and should be allocated through
|
||||||
:c:func:`net_pkt_rx_alloc_with_buffer()`. Then all data buffers will be
|
:c:func:`net_pkt_rx_alloc_with_buffer()`. Then all data buffers will be
|
||||||
automatically allocated and filled by :c:func:`net_pkt_write()`.
|
automatically allocated and filled by :c:func:`net_pkt_write()`.
|
||||||
|
|
||||||
|
@ -116,9 +116,8 @@ Device drivers for IEEE 802.15.4 L2 work basically the same as for
|
||||||
Ethernet. What has been described above, especially for ``recv()``, applies
|
Ethernet. What has been described above, especially for ``recv()``, applies
|
||||||
here as well. There are two specific differences however:
|
here as well. There are two specific differences however:
|
||||||
|
|
||||||
- It requires a dedicated device driver API: :c:type:`struct
|
- It requires a dedicated device driver API: :c:type:`ieee802154_radio_api`,
|
||||||
ieee802154_radio_api`, which overloads :c:type:`struct
|
which overloads :c:type:`net_if_api`. This is because 802.15.4 L2 needs more from the device
|
||||||
net_if_api`. This is because 802.15.4 L2 needs more from the device
|
|
||||||
driver than just ``send()`` and ``recv()`` functions. This dedicated API is
|
driver than just ``send()`` and ``recv()`` functions. This dedicated API is
|
||||||
declared in :zephyr_file:`include/net/ieee802154_radio.h`. Each and every
|
declared in :zephyr_file:`include/net/ieee802154_radio.h`. Each and every
|
||||||
IEEE 802.15.4 device driver must provide a valid pointer on such
|
IEEE 802.15.4 device driver must provide a valid pointer on such
|
||||||
|
@ -129,15 +128,15 @@ here as well. There are two specific differences however:
|
||||||
payload and frame checksum. Buffers are meant to fit such
|
payload and frame checksum. Buffers are meant to fit such
|
||||||
frame size limitation. But a buffer containing an IPv6/UDP packet
|
frame size limitation. But a buffer containing an IPv6/UDP packet
|
||||||
might have more than one fragment. IEEE 802.15.4 drivers
|
might have more than one fragment. IEEE 802.15.4 drivers
|
||||||
handle only one buffer at a time. This is why the :c:type:`struct
|
handle only one buffer at a time. This is why the
|
||||||
ieee802154_radio_api` requires a tx function pointer which differs
|
:c:type:`ieee802154_radio_api` requires a tx function pointer which differs
|
||||||
from the :c:type:`struct net_if_api` send function pointer.
|
from the :c:type:`net_if_api` send function pointer.
|
||||||
Instead, the IEEE 802.15.4 L2, provides a generic
|
Instead, the IEEE 802.15.4 L2, provides a generic
|
||||||
:c:func:`ieee802154_radio_send()` meant to be given as
|
:c:func:`ieee802154_radio_send()` meant to be given as
|
||||||
:c:type:`struct net_if` send function. It turn, the implementation
|
:c:type:`net_if` send function. It turn, the implementation
|
||||||
of :c:func:`ieee802154_radio_send()` will ensure the same behavior:
|
of :c:func:`ieee802154_radio_send()` will ensure the same behavior:
|
||||||
sending one buffer at a time through :c:type:`struct
|
sending one buffer at a time through :c:type:`ieee802154_radio_api` tx
|
||||||
ieee802154_radio_api` tx function, and unreferencing the network packet
|
function, and unreferencing the network packet
|
||||||
only when all the transmission were successful.
|
only when all the transmission were successful.
|
||||||
|
|
||||||
Each IEEE 802.15.4 device driver, in the end, will need to call
|
Each IEEE 802.15.4 device driver, in the end, will need to call
|
||||||
|
|
|
@ -74,7 +74,7 @@ Buffer allocation
|
||||||
=================
|
=================
|
||||||
|
|
||||||
The net_pkt object does not define its own buffer, but instead uses an
|
The net_pkt object does not define its own buffer, but instead uses an
|
||||||
existing object for this: :c:type:`struct net_buf`. (See
|
existing object for this: :c:type:`net_buf`. (See
|
||||||
:ref:`net_buf_interface` for more information). However, it mostly
|
:ref:`net_buf_interface` for more information). However, it mostly
|
||||||
hides the usage of such a buffer because net_pkt brings network
|
hides the usage of such a buffer because net_pkt brings network
|
||||||
awareness to buffer allocation and, as we will see later, its
|
awareness to buffer allocation and, as we will see later, its
|
||||||
|
|
|
@ -29,7 +29,7 @@ description and units of measurement:
|
||||||
Values
|
Values
|
||||||
======
|
======
|
||||||
|
|
||||||
Sensor devices return results as :c:type:`struct sensor_value`. This
|
Sensor devices return results as :c:type:`sensor_value`. This
|
||||||
representation avoids use of floating point values as they may not be
|
representation avoids use of floating point values as they may not be
|
||||||
supported on certain setups.
|
supported on certain setups.
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ application instructs the driver to fetch a sample of all its channels.
|
||||||
Then, individual channels may be read. In the case of channels with
|
Then, individual channels may be read. In the case of channels with
|
||||||
multiple axes, they can be read in a single operation by supplying
|
multiple axes, they can be read in a single operation by supplying
|
||||||
the corresponding :literal:`_XYZ` channel type and a buffer of 3
|
the corresponding :literal:`_XYZ` channel type and a buffer of 3
|
||||||
:c:type:`struct sensor_value` objects. This approach ensures consistency
|
:c:type:`sensor_value` objects. This approach ensures consistency
|
||||||
of channels between reads and efficiency of communication by issuing a
|
of channels between reads and efficiency of communication by issuing a
|
||||||
single transaction on the underlying bus.
|
single transaction on the underlying bus.
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ compensates data for both channels.
|
||||||
:lines: 12-
|
:lines: 12-
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
The example assumes that the returned values have type :c:type:`struct
|
The example assumes that the returned values have type :c:type:`sensor_value`,
|
||||||
sensor_value`, which is the case for BME280. A real application
|
which is the case for BME280. A real application
|
||||||
supporting multiple sensors should inspect the :c:data:`type` field of
|
supporting multiple sensors should inspect the :c:data:`type` field of
|
||||||
the :c:data:`temp` and :c:data:`press` values and use the other fields
|
the :c:data:`temp` and :c:data:`press` values and use the other fields
|
||||||
of the structure accordingly.
|
of the structure accordingly.
|
||||||
|
@ -89,9 +89,9 @@ 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
|
include: new data is ready for reading, a channel value has crossed a
|
||||||
threshold, or the device has sensed motion.
|
threshold, or the device has sensed motion.
|
||||||
|
|
||||||
To configure a trigger, an application needs to supply a :c:type:`struct
|
To configure a trigger, an application needs to supply a
|
||||||
sensor_trigger` and a handler function. The structure contains the trigger
|
:c:type:`sensor_trigger` and a handler function. The structure contains the
|
||||||
type and the channel on which the trigger must be configured.
|
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
|
Because most sensors are connected via SPI or I2C busses, it is not possible
|
||||||
to communicate with them from the interrupt execution context. The
|
to communicate with them from the interrupt execution context. The
|
||||||
|
|
|
@ -6,7 +6,7 @@ Kernel Objects
|
||||||
A kernel object can be one of three classes of data:
|
A kernel object can be one of three classes of data:
|
||||||
|
|
||||||
* A core kernel object, such as a semaphore, thread, pipe, etc.
|
* A core kernel object, such as a semaphore, thread, pipe, etc.
|
||||||
* A thread stack, which is an array of :c:type:`struct z_thread_stack_element`
|
* A thread stack, which is an array of :c:type:`z_thread_stack_element`
|
||||||
and declared with :c:macro:`K_THREAD_STACK_DEFINE()`
|
and declared with :c:macro:`K_THREAD_STACK_DEFINE()`
|
||||||
* A device driver instance (struct device) that belongs to one of a defined
|
* A device driver instance (struct device) that belongs to one of a defined
|
||||||
set of subsystems
|
set of subsystems
|
||||||
|
@ -109,14 +109,14 @@ When a system call is made and the kernel is presented with a memory address
|
||||||
of what may or may not be a valid kernel object, the address can be validated
|
of what may or may not be a valid kernel object, the address can be validated
|
||||||
with a constant-time lookup in this table.
|
with a constant-time lookup in this table.
|
||||||
|
|
||||||
Drivers are a special case. All drivers are instances of :c:type:`struct
|
Drivers are a special case. All drivers are instances of :c:type:`device`, but
|
||||||
device`, but it is important to know what subsystem a driver belongs to so that
|
it is important to know what subsystem a driver belongs to so that
|
||||||
incorrect operations, such as calling a UART API on a sensor driver object, can
|
incorrect operations, such as calling a UART API on a sensor driver object, can
|
||||||
be prevented. When a device struct is found, its API pointer is examined to
|
be prevented. When a device struct is found, its API pointer is examined to
|
||||||
determine what subsystem the driver belongs to.
|
determine what subsystem the driver belongs to.
|
||||||
|
|
||||||
The table itself maps kernel object memory addresses to instances of
|
The table itself maps kernel object memory addresses to instances of
|
||||||
:c:type:`struct z_object`, which has all the metadata for that object. This
|
:c:type:`z_object`, which has all the metadata for that object. This
|
||||||
includes:
|
includes:
|
||||||
|
|
||||||
* A bitfield indicating permissions on that object. All threads have a
|
* A bitfield indicating permissions on that object. All threads have a
|
||||||
|
@ -129,7 +129,7 @@ includes:
|
||||||
* A set of flags for that object. This is currently used to track
|
* A set of flags for that object. This is currently used to track
|
||||||
initialization state and whether an object is public or not.
|
initialization state and whether an object is public or not.
|
||||||
* An extra data field. The semantics of this field vary by object type, see
|
* An extra data field. The semantics of this field vary by object type, see
|
||||||
the definition of :c:type:`union z_object_data`.
|
the definition of :c:type:`z_object_data`.
|
||||||
|
|
||||||
Dynamic objects allocated at runtime are tracked in a runtime red/black tree
|
Dynamic objects allocated at runtime are tracked in a runtime red/black tree
|
||||||
which is used in parallel to the gperf table when validating object pointers.
|
which is used in parallel to the gperf table when validating object pointers.
|
||||||
|
@ -250,7 +250,7 @@ Instances of the new struct should now be tracked.
|
||||||
Creating New Driver Subsystem Kernel Objects
|
Creating New Driver Subsystem Kernel Objects
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
All driver instances are :c:type:`struct device`. They are differentiated by
|
All driver instances are :c:type:`device`. They are differentiated by
|
||||||
what API struct they are set to.
|
what API struct they are set to.
|
||||||
|
|
||||||
* In ``scripts/gen_kobject_list.py``, add the name of the API struct for the
|
* In ``scripts/gen_kobject_list.py``, add the name of the API struct for the
|
||||||
|
|
|
@ -324,7 +324,7 @@ Create a Memory Domain
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
A memory domain is defined using a variable of type
|
A memory domain is defined using a variable of type
|
||||||
:c:type:`struct k_mem_domain`. It must then be initialized by calling
|
:c:type:`k_mem_domain`. It must then be initialized by calling
|
||||||
:cpp:func:`k_mem_domain_init()`.
|
:cpp:func:`k_mem_domain_init()`.
|
||||||
|
|
||||||
The following code defines and initializes an empty memory domain.
|
The following code defines and initializes an empty memory domain.
|
||||||
|
|
|
@ -4299,7 +4299,7 @@ struct k_pipe {
|
||||||
struct {
|
struct {
|
||||||
_wait_q_t readers; /**< Reader wait queue */
|
_wait_q_t readers; /**< Reader wait queue */
|
||||||
_wait_q_t writers; /**< Writer wait queue */
|
_wait_q_t writers; /**< Writer wait queue */
|
||||||
} wait_q;
|
} wait_q; /** Wait queue */
|
||||||
|
|
||||||
_OBJECT_TRACING_NEXT_PTR(k_pipe)
|
_OBJECT_TRACING_NEXT_PTR(k_pipe)
|
||||||
_OBJECT_TRACING_LINKED_FLAG
|
_OBJECT_TRACING_LINKED_FLAG
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue