Device Driver Interface

Device Model

const int _INIT_LEVEL_PRIMARY = 1
const int _INIT_LEVEL_SECONDARY = 1
const int _INIT_LEVEL_NANOKERNEL = 1
const int _INIT_LEVEL_MICROKERNEL = 1
const int _INIT_LEVEL_PRE_KERNEL_1 = 1
const int _INIT_LEVEL_PRE_KERNEL_2 = 1
const int _INIT_LEVEL_POST_KERNEL = 1
const int _INIT_LEVEL_APPLICATION = 1
struct device_pm_ops device_pm_ops_nop
void _sys_device_do_config_level(int level)
struct device *device_get_binding(const char *name)

Retrieve the device structure for a driver by name.

Device objects are created via the DEVICE_INIT() macro and placed in memory by the linker. If a driver needs to bind to another driver it can use this function to retrieve the device structure of the lower level driver by the name the driver exposes to the system.

Return
pointer to device structure; NULL if not found or cannot be used.
Parameters
  • name: device name to search for.

static void device_sync_call_init(device_sync_call_t *sync)

Initialize the context-dependent synchronization data.

Parameters

static void device_sync_call_wait(device_sync_call_t *sync)

Wait for the isr to complete the synchronous call Note: It will simply wait on the internal semaphore.

Parameters

static void device_sync_call_complete(device_sync_call_t *sync)

Signal the waiter about synchronization completion Note: It will simply release the internal semaphore.

Parameters

_DEPRECATION_CHECK(dev_name, level) static inline void _CONCAT(_deprecation_check_, dev_name)() \ { \ int foo = _CONCAT(_INIT_LEVEL_, level); \ (void)foo; \ }
DEVICE_INIT(dev_name, drv_name, init_fn, data, cfg_info, level, prio) DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \ level, prio, NULL)

Create device object and set it up for boot time initialization.

This macro defines a device object that is automatically configured by the kernel during system initialization.

Parameters
  • dev_name: Device name.
  • drv_name: The name this instance of the driver exposes to the system.
  • init_fn: Address to the init function of the driver.
  • data: Pointer to the device’s configuration data.
  • cfg_info: The address to the structure containing the configuration information for this instance of the driver.
  • level: The initialization level at which configuration occurs. Must be one of the following symbols, which are listed in the order they are performed by the kernel:
    • PRE_KERNEL_1: Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot use any kernel services during configuration, since they are not yet available.
    • PRE_KERNEL_2: Used for devices that rely on the initialization of devices initialized as part of the PRIMARY level. These devices cannot use any kernel services during configuration, since they are not yet available.
    • POST_KERNEL: Used for devices that require kernel services during configuration.
    • APPLICATION: Used for application components (i.e. non-kernel components) that need automatic configuration. These devices can use all services provided by the kernel during configuration.
  • prio: The initialization priority of the device, relative to other devices of the same initialization level. Specified as an integer value in the range 0 to 99; lower values indicate earlier initialization. Must be a decimal integer literal without leading zeroes or sign (e.g. 32), or an equivalent symbolic name (e.g. #define MY_INIT_PRIO 32); symbolic expressions are not permitted (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).

DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, level, prio, api) DEVICE_DEFINE(dev_name, drv_name, init_fn, \ device_pm_control_nop, data, cfg_info, level, \ prio, api)

Create device object and set it up for boot time initialization, with the option to set driver_api.

This macro defines a device object that is automatically configured by the kernel during system initialization.

The driver api is also set here, eliminating the need to do that during initialization.

Parameters
  • dev_name: Device name.
  • drv_name: The name this instance of the driver exposes to the system.
  • init_fn: Address to the init function of the driver.
  • data: Pointer to the device’s configuration data.
  • cfg_info: The address to the structure containing the configuration information for this instance of the driver.
  • level: The initialization level at which configuration occurs. Must be one of the following symbols, which are listed in the order they are performed by the kernel:
    • PRE_KERNEL_1: Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot use any kernel services during configuration, since they are not yet available.
    • PRE_KERNEL_2: Used for devices that rely on the initialization of devices initialized as part of the PRIMARY level. These devices cannot use any kernel services during configuration, since they are not yet available.
    • POST_KERNEL: Used for devices that require kernel services during configuration.
    • APPLICATION: Used for application components (i.e. non-kernel components) that need automatic configuration. These devices can use all services provided by the kernel during configuration.
  • prio: The initialization priority of the device, relative to other devices of the same initialization level. Specified as an integer value in the range 0 to 99; lower values indicate earlier initialization. Must be a decimal integer literal without leading zeroes or sign (e.g. 32), or an equivalent symbolic name (e.g. #define MY_INIT_PRIO 32); symbolic expressions are not permitted (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).
  • api: Provides an initial pointer to the API function struct used by the driver. Can be NULL.

DEVICE_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, data, cfg_info, level, prio) DEVICE_AND_API_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, \ data, cfg_info, level, prio, NULL)

Create device object and set it up for boot time initialization, with the option to device_pm_ops.

This macro defines a device object that is automatically configured by the kernel during system initialization.

Warning
This macro is deprecated and will be removed in a future version, superseded by DEVICE_DEFINE.

Parameters
  • dev_name: Device name.
  • drv_name: The name this instance of the driver exposes to the system.
  • init_fn: Address to the init function of the driver.
  • data: Pointer to the device’s configuration data.
  • cfg_info: The address to the structure containing the configuration information for this instance of the driver.
  • level: The initialization level at which configuration occurs. Must be one of the following symbols, which are listed in the order they are performed by the kernel:
    • PRE_KERNEL_1: Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot use any kernel services during configuration, since they are not yet available.
    • PRE_KERNEL_2: Used for devices that rely on the initialization of devices initialized as part of the PRIMARY level. These devices cannot use any kernel services during configuration, since they are not yet available.
    • POST_KERNEL: Used for devices that require kernel services during configuration.
    • APPLICATION: Used for application components (i.e. non-kernel components) that need automatic configuration. These devices can use all services provided by the kernel during configuration.
  • prio: The initialization priority of the device, relative to other devices of the same initialization level. Specified as an integer value in the range 0 to 99; lower values indicate earlier initialization. Must be a decimal integer literal without leading zeroes or sign (e.g. 32), or an equivalent symbolic name (e.g. #define MY_INIT_PRIO 32); symbolic expressions are not permitted (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).
  • device_pm_ops: Address to the device_pm_ops structure of the driver.

DEVICE_AND_API_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, data, cfg_info, level, prio, api) \ static struct device_config _CONCAT(__config_, dev_name) __used \ __attribute__((__section__(".devconfig.init"))) = { \ .name = drv_name, .init = (init_fn), \ .dev_pm_ops = (device_pm_ops), \ .config_info = (cfg_info) \ }; \ _DEPRECATION_CHECK(dev_name, level) \ static struct device _CONCAT(__device_, dev_name) __used \ __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ .config = &_CONCAT(__config_, dev_name), \ .driver_api = api, \ .driver_data = data \ }

Create device object and set it up for boot time initialization, with the options to set driver_api and device_pm_ops.

This macro defines a device object that is automatically configured by the kernel during system initialization.

Warning
This macro is deprecated and will be removed in a future version, superseded by DEVICE_DEFINE.
Warning
This macro is deprecated and will be removed in a future version, superseded by DEVICE_DEFINE.

The driver api is also set here, eliminating the need to do that during initialization.

Parameters
  • dev_name: Device name.
  • drv_name: The name this instance of the driver exposes to the system.
  • init_fn: Address to the init function of the driver.
  • data: Pointer to the device’s configuration data.
  • cfg_info: The address to the structure containing the configuration information for this instance of the driver.
  • level: The initialization level at which configuration occurs. Must be one of the following symbols, which are listed in the order they are performed by the kernel:
    • PRE_KERNEL_1: Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot use any kernel services during configuration, since they are not yet available.
    • PRE_KERNEL_2: Used for devices that rely on the initialization of devices initialized as part of the PRIMARY level. These devices cannot use any kernel services during configuration, since they are not yet available.
    • POST_KERNEL: Used for devices that require kernel services during configuration.
    • APPLICATION: Used for application components (i.e. non-kernel components) that need automatic configuration. These devices can use all services provided by the kernel during configuration.
  • prio: The initialization priority of the device, relative to other devices of the same initialization level. Specified as an integer value in the range 0 to 99; lower values indicate earlier initialization. Must be a decimal integer literal without leading zeroes or sign (e.g. 32), or an equivalent symbolic name (e.g. #define MY_INIT_PRIO 32); symbolic expressions are not permitted (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).
  • device_pm_ops: Address to the device_pm_ops structure of the driver.
  • api: Provides an initial pointer to the API function struct used by the driver. Can be NULL.

DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, cfg_info, level, prio, api) \ static struct device_config _CONCAT(__config_, dev_name) __used \ __attribute__((__section__(".devconfig.init"))) = { \ .name = drv_name, .init = (init_fn), \ .device_pm_control = (pm_control_fn), \ .dev_pm_ops = (&device_pm_ops_nop), \ .config_info = (cfg_info) \ }; \ _DEPRECATION_CHECK(dev_name, level) \ static struct device _CONCAT(__device_, dev_name) __used \ __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ .config = &_CONCAT(__config_, dev_name), \ .driver_api = api, \ .driver_data = data \ }

Create device object and set it up for boot time initialization, with the option to device_pm_control.

This macro defines a device object that is automatically configured by the kernel during system initialization.

The driver api is also set here, eliminating the need to do that during initialization.

Parameters
  • dev_name: Device name.
  • drv_name: The name this instance of the driver exposes to the system.
  • init_fn: Address to the init function of the driver.
  • data: Pointer to the device’s configuration data.
  • cfg_info: The address to the structure containing the configuration information for this instance of the driver.
  • level: The initialization level at which configuration occurs. Must be one of the following symbols, which are listed in the order they are performed by the kernel:
    • PRE_KERNEL_1: Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot use any kernel services during configuration, since they are not yet available.
    • PRE_KERNEL_2: Used for devices that rely on the initialization of devices initialized as part of the PRIMARY level. These devices cannot use any kernel services during configuration, since they are not yet available.
    • POST_KERNEL: Used for devices that require kernel services during configuration.
    • APPLICATION: Used for application components (i.e. non-kernel components) that need automatic configuration. These devices can use all services provided by the kernel during configuration.
  • prio: The initialization priority of the device, relative to other devices of the same initialization level. Specified as an integer value in the range 0 to 99; lower values indicate earlier initialization. Must be a decimal integer literal without leading zeroes or sign (e.g. 32), or an equivalent symbolic name (e.g. #define MY_INIT_PRIO 32); symbolic expressions are not permitted (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).
  • api: Provides an initial pointer to the API function struct used by the driver. Can be NULL.
Parameters
  • pm_control_fn: Pointer to device_pm_control function. Can be empty function (device_pm_control_nop) if not implemented.

DEVICE_NAME_GET(name) (_CONCAT(__device_, name))

Expands to the full name of a global device object.

Return the full name of a device object symbol created by DEVICE_INIT(), using the dev_name provided to DEVICE_INIT().

It is meant to be used for declaring extern symbols pointing on device objects before using the DEVICE_GET macro to get the device object.

Return
The exanded name of the device object created by DEVICE_INIT()
Parameters
  • name: The same as dev_name provided to DEVICE_INIT()

DEVICE_GET(name) (&DEVICE_NAME_GET(name))

Obtain a pointer to a device object by name.

Return the address of a device object created by DEVICE_INIT(), using the dev_name provided to DEVICE_INIT().

Return
A pointer to the device object created by DEVICE_INIT()
Parameters
  • name: The same as dev_name provided to DEVICE_INIT()

DEVICE_DECLARE(name) extern struct device DEVICE_NAME_GET(name)

Declare a device object.

This macro can be used at the top-level to declare a device, such that DEVICE_GET() may be used before the full declaration in DEVICE_INIT(), or reference the device in another C file.

This is often useful when configuring interrupts statically in a device’s init or per-instance config function, as the init function itself is required by DEVICE_INIT() and use of DEVICE_GET() inside it creates a circular dependeny.

Parameters
  • name: Device name

DEVICE_PM_ACTIVE_STATE 1

device is in ACTIVE power state

Normal operation of the device. All device context is retained.

DEVICE_PM_LOW_POWER_STATE 2

device is in LOW power state

Device context is preserved by the HW and need not be restored by the driver.

DEVICE_PM_SUSPEND_STATE 3

device is in SUSPEND power state

Most device context is lost by the hardware. Device drivers must save and restore or reinitialize any context lost by the hardware

DEVICE_PM_OFF_STATE 4

device is in OFF power state

  • Power has been fully removed from the device. The device context is lost when this state is entered, so the OS software will reinitialize the device when powering it back on

DEVICE_PM_SET_POWER_STATE 1
DEVICE_PM_GET_POWER_STATE 2
struct device_config
#include <device.h>

Static device information (In ROM) Per driver instance.

Note
This struct contains deprecated struct (device_pm_ops) that will be removed in a future version.
Parameters
  • name: name of the device
  • init: init function for the driver
  • config_info: address of driver instance config information

struct device
#include <device.h>

Runtime device structure (In memory) Per driver instance.

Parameters
  • device_config: Build time config information
  • driver_api: pointer to structure containing the API functions for the device type. This pointer is filled in by the driver at init time.
  • driver_data: driver instance data. For driver use only

struct device_sync_call_t
#include <device.h>

Synchronous calls API Specific type for synchronizing calls among the 2 possible contexts