doc: Edited synchronous_call.rst for typos, ReST syntax
API notes needed a bit of clarification, fixed typo of file name. Change-Id: I57438165fb2fc3da796fcde19d58a46862ffbbd9 Signed-off-by: L.S. Cook <leonax.cook@intel.com>
This commit is contained in:
parent
f3f8eeed66
commit
13d064c58c
1 changed files with 40 additions and 40 deletions
|
@ -1,57 +1,57 @@
|
|||
.. _synchrounous_call:
|
||||
.. _synchronous_call:
|
||||
|
||||
Synchronous call within interrupt based device drivers
|
||||
######################################################
|
||||
Synchronous Call
|
||||
################
|
||||
|
||||
Zephyr provides a set of device drivers for various platforms. As a preemptive
|
||||
OS, those are meant to be implemented through an interrupt based mode and not
|
||||
a polling mode unless the driven hardware does not provide any interrupt
|
||||
enabled mechanism.
|
||||
Zephyr provides a set of device drivers for multiple platforms. Each driver
|
||||
should support an interrupt-based implementation, rather than polling, unless
|
||||
the specific hardware does not provide any interrupt.
|
||||
|
||||
The higher level calls accessed through devices's specific API, such as i2c.h
|
||||
or spi.h, are meant to be, most of the time, synchronous. Thus these calls
|
||||
should be blocking.
|
||||
High-level calls accessed through devices's specific API, such as i2c.h
|
||||
or spi.h, are usually intended as synchronous. Thus, these calls should be
|
||||
blocking.
|
||||
|
||||
However, and due to the fact Zephyr provides 2 types of executions context on
|
||||
a microkernel, drivers need to act accordingly. A nanokernel semaphore cannot
|
||||
be used if the context is a task for instance. Thus, include/device.h exposes
|
||||
an helper API to handle this case transparently, and no other means should be
|
||||
used instead.
|
||||
Due to the fact that Zephyr provides two types of execution contexts (task
|
||||
and fiber) on a microkernel, drivers need to act accordingly. For example, a
|
||||
nanokernel semaphore cannot be used when the context is a task, so the
|
||||
:file:`include/device.h` exposes a helper API to handle this case transparently;
|
||||
no other means ought to be used instead.
|
||||
|
||||
Usage of device_sync_call_* API
|
||||
*******************************
|
||||
Usage of the device_sync_call_* API
|
||||
***********************************
|
||||
|
||||
1 type and 3 inline functions are exposed to solve this issue.
|
||||
Zephyr API exposes 1 type and 3 inline functions to solve this issue.
|
||||
|
||||
The device_sync_call_t type
|
||||
===========================
|
||||
``device_sync_call_t``
|
||||
======================
|
||||
|
||||
It provides a nanokernel semaphore, always present in both built types:
|
||||
nanokernel and microkernel. It is meant to be used within a fiber context.
|
||||
This type provides a nanokernel semaphore, always present in both nanokernel
|
||||
and microkernel use cases. It is meant to be used within a fiber context.
|
||||
Then, and only on a microkernel type, it will provide a kernel semaphore
|
||||
meant to be used within a task context. A boolean marker is used to remember
|
||||
the caller's context when running a microkernel.
|
||||
|
||||
device_sync_call_init()
|
||||
=======================
|
||||
:cpp:func:`device_sync_call_init()`
|
||||
===================================
|
||||
|
||||
It initializes the device_sync_call_t type: its semaphores and the marker.
|
||||
Such function should be used only once in the device driver's instance life
|
||||
time. Thus the driver's initialization function is the best place for calling
|
||||
it.
|
||||
This function initializes the ``device_sync_call_t`` type semaphores and the
|
||||
marker. Such function should be used only once in the device driver's instance
|
||||
lifetime. Thus, the driver's initialization function is the best place for
|
||||
calling it.
|
||||
|
||||
device_sync_call_wait()
|
||||
=======================
|
||||
:cpp:func:`device_sync_call_wait()`
|
||||
===================================
|
||||
|
||||
This functions will block - i.e. will perform a "take wait" - on the relevant
|
||||
semaphore. This will make the exposed driver's API function using it a blocking
|
||||
function, until the relevant semaphore is released by a give. This is therefore
|
||||
used to start a synchronous call, until being signaled for synchronization.
|
||||
This function will block - that is, it will perform a "take wait" - on the
|
||||
relevant semaphore. The exposed driver's API function can then be used as a
|
||||
blocking function until the relevant semaphore is released by a ``give``.
|
||||
This is therefore used to start a synchronous call, and waits until being
|
||||
signaled for synchronization.
|
||||
|
||||
device_sync_call_complete()
|
||||
===========================
|
||||
:cpp:func:`device_sync_call_complete()`
|
||||
=======================================
|
||||
|
||||
This function is used to release the relevant semaphore and thus will unlock
|
||||
the blocking function. This is thus being called in the driver's ISR handler
|
||||
mostly. This is used to signal the completion of the synchronous call, whatever
|
||||
fate would be (error or success).
|
||||
This function releases the relevant semaphore and thus will unlock the blocking
|
||||
function. Most frequently will it be called in the driver's ISR handler. It is
|
||||
used to signal the completion of the synchronous call, whatever fate would be
|
||||
(error or success).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue