doc/reference/drivers: document device-specific API extensions
This PR updates the documentation to cover a technical solution to providing a driver instance that extends the functionality of a subsystem API. The solution described was mooted in Zephyr PR #17072 and approved by the Technical Steering Committee during its 2019-08-07 meeting. Relates-to: #11993 Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
469accfbe2
commit
24b67ef119
1 changed files with 54 additions and 0 deletions
|
@ -180,6 +180,60 @@ in the driver init function.
|
||||||
most cases requires that the optional feature be controlled by a
|
most cases requires that the optional feature be controlled by a
|
||||||
Kconfig option.
|
Kconfig option.
|
||||||
|
|
||||||
|
Device-Specific API Extensions
|
||||||
|
******************************
|
||||||
|
|
||||||
|
Some devices can be cast as an instance of a driver subsystem such as GPIO,
|
||||||
|
but provide additional functionality that cannot be exposed through the
|
||||||
|
standard API. These devices combine subsystem operations with
|
||||||
|
device-specific APIs, described in a device-specific header.
|
||||||
|
|
||||||
|
A device-specific API definition typically looks like this:
|
||||||
|
|
||||||
|
.. code-block:: C
|
||||||
|
|
||||||
|
#include <drivers/subsystem.h>
|
||||||
|
|
||||||
|
typedef int (*specific_do_this_t)(struct device *device, int foo);
|
||||||
|
|
||||||
|
struct specific_api {
|
||||||
|
subsystem_driver_api subsystem_api; /* this must be first */
|
||||||
|
specific_do_this_t do_this;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int specific_do_this(struct device *device, int foo)
|
||||||
|
{
|
||||||
|
struct specific_api *api = (struct specific_api*)device->driver_api;
|
||||||
|
|
||||||
|
return api->do_this(device, foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
A driver implementing extensions to the subsystem will define the real
|
||||||
|
implementation of both the subsystem API and the specific APIs:
|
||||||
|
|
||||||
|
.. code-block:: C
|
||||||
|
|
||||||
|
static int generic_do_whatever(struct device *device, void *arg)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
static int specific_do_this(struct device *device, int foo)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct specific_api driver_api = {
|
||||||
|
.subsystem_api = {
|
||||||
|
.do_whatever = generic_do_whatever,
|
||||||
|
},
|
||||||
|
.do_this = specific_do_this,
|
||||||
|
};
|
||||||
|
|
||||||
|
Applications use the device through both the subsystem and specific
|
||||||
|
APIs. The subsystem APIs will directly access the subsystem part of the
|
||||||
|
specific API structure.
|
||||||
|
|
||||||
Single Driver, Multiple Instances
|
Single Driver, Multiple Instances
|
||||||
*********************************
|
*********************************
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue