/**************************************************************************** * include/nuttx/sensors/cluster_driver.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ #ifndef __INCLUDE_NUTTX_SENSORS_CLUSTER_DRIVER_H #define __INCLUDE_NUTTX_SENSORS_CLUSTER_DRIVER_H /* Definitions for the cluster driver interface: * * The sensor cluster driver interface is created to permit high performance * collection and processing of sensor data. Normally when high performance * sensor data collection is required, data is needed from multiple sensors * and the collection/processing task needs to run as a "higher than user * priority" priority level. This mechanism is commonly supported by writing * the collection/processing task as a kernel driver worker thread that can * access multiple sensors. * * A clean way to implement this is to implement this collection/processing * mechanism is as a driver that has efficient kernel-to-kernel access to * other sensor leaf-drivers that support the cluster driver interface. * (This documentation describes the "cluster driver interface" from the * perspective of a "cluster driver interface" enabled leaf driver.) * * The file_operations interface typically deals with the caller's parameters * and buffers being in user space, while the driver's code, variables, and * buffers are in kernel space. There is also a layer of kernel code between * the caller and driver that deals with security and assists helps with the * driver's access of user space memory. So the file_operations interface * is not appropriate for driver-to-driver communication. * * Since the driver registration function is not part of the file_operations * interface and is permitted to be called from a kernel task, this function * is reused. But rather than being called by the board initialization * function, the cluster drivers registration function is called from the * board initialization function; and the cluster drivers registration * function calls the leaf driver's registration function. * * To be "cluster driver interface" enabled the leaf driver's registration * function must communicate the leaf driver's instance back to the cluster * driver's registration function. This is done by storing the leaf * driver's instance handle into the caller provided config structure. * This handle is provided as a parameter in cluster driver interface calls. * * dvr_open(): Reserve this sensor. * * dvr_close(): Places the sensor into low power standby mode, frees driver * resources associated with the sensor, and release the reservation * . of the sensor. * * To perform I/O to a sensor, the cluster driver needs... * * > A pointer to the spi instance (struct spi_dev_s *). The cluster driver * has this pointer, because it provides it to the leaf driver as an input * parameter to the leaf driver's registration function. * > The chip select gpio pin identifier for the sensor device. The cluster * driver knows this identifier,because it provides it to the leaf driver * as an input parameter to the leaf driver's registration function. * > A pointer to the leaf driver instance. The leaf driver communicates this * pointer to the cluster driver by storing it into the config struct * leaf_handle (struct spi_dev_s *) field that is also passed as an in/out * parameter in the leaf driver's registration function. * * With the above information, the sensor cluster driver may efficiently * access multiple sensors and aggregate their data. * ****************************************************************************/ /**************************************************************************** * Public Types ****************************************************************************/ /* Cluster driver operations interface */ struct sensor_cluster_operations_s { CODE int (*driver_open)(FAR void *instance_handle, int32_t arg); CODE int (*driver_close)(FAR void *instance_handle, int32_t arg); CODE ssize_t (*driver_read)(FAR void *instance_handle, FAR char *buffer, size_t buflen); CODE ssize_t (*driver_write)(FAR void *instance_handle, FAR const char *buffer, size_t buflen); CODE off_t (*driver_seek)(FAR void *instance_handle, off_t offset, int whence); CODE int (*driver_ioctl)(FAR void *instance_handle, int cmd, unsigned long arg); CODE int (*driver_suspend)(FAR void *instance_handle, int32_t arg); CODE int (*driver_resume)(FAR void *instance_handle, int32_t arg); }; /**************************************************************************** * Public Function Prototypes ****************************************************************************/ #ifdef __cplusplus #define EXTERN extern "C" extern "C" { #else #define EXTERN extern #endif /**************************************************************************** * Name: xxxxxx_register <-- for a leaf driver. * * Description: * Example of a driver register function for a "sensor leaf driver" that * can be controlled by a "sensor cluster driver". The specific format of * the registration function will vary based on the characteristics of the * driver. The below is an example, which describes common aspects of the * function and and its parameters. * * Normally, sensor driver register functions are called by the board * initialization code. In the case of a "sensor cluster driver", the board * initialization code calls the register function of the "sensor cluster * driver"; and the "sensor cluster driver" calls the register function of * each of the sensor (leaf) drivers that it will be controlling. * * Input Parameters: * devpath - The full path to the leaf driver to register. E.g., * "/dev/acl0" * spi - An instance of the SPI interface to use to communicate with * the leaf driver. Or, it could be the I2C driver instance if * the sensor is on an I2C bus. * config - configuration struct for the sensor leaf driver. * This struct is defined in the leaf driver's xxxxxx.h file. * * For a SPI sensor, this structure must contain: * * int spi_devid; The spi device id, which is used by NuttX to * select/deselect the device. This is usually some * type of reference to the chip_select gpio pin. * FAR void *leaf_handle; The handle to the leaf driver instance. * This is an opaque handle that provided by the * leaf driver's register function. * It is passed as a parameter to the leaf driver's * driver_open() and driver_close() functions. * * For an I2C sensor, this struct must contain: * * int i2c_devid; The i2c device id, which is used by NuttX to * address the sensor device on an I2C bus.. * FAR void *leaf_handle; The handle to the leaf driver instance. * This is an opaque handle that provided by the * leaf driver's register function. * It is passed as a parameter to the leaf driver's * driver_open() and driver_close() functions. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. * * int xxxxxx_register(FAR const char *devpath, * FAR struct spi_dev_s *spi, * FAR struct xxxxxx_config_s *config); * ****************************************************************************/ #undef EXTERN #ifdef __cplusplus } #endif #endif /* __INCLUDE_NUTTX_SENSORS_CLUSTER_DRIVER_H */