diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index b387fb6e7fb..cdb02dd55db 100644 --- a/drivers/sensors/sensor.c +++ b/drivers/sensors/sensor.c @@ -66,9 +66,9 @@ struct sensor_axis_map_s int8_t sign_z; }; -/* This structure describes sensor info */ +/* This structure describes sensor meta */ -struct sensor_info_s +struct sensor_meta_s { unsigned long esize; FAR char *name; @@ -145,7 +145,7 @@ static const struct sensor_axis_map_s g_remap_tbl[] = { 1, 0, 2, 1, 1, -1 }, /* P7 */ }; -static const struct sensor_info_s g_sensor_info[] = +static const struct sensor_meta_s g_sensor_meta[] = { {0, NULL}, {sizeof(struct sensor_accel), "accel"}, @@ -866,6 +866,19 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + case SNIOC_GET_INFO: + { + if (lower->ops->get_info == NULL) + { + ret = -ENOTSUP; + break; + } + + ret = lower->ops->get_info(lower, filep, + (FAR struct sensor_device_info_s *)(uintptr_t)arg); + } + break; + default: /* Lowerhalf driver process other cmd. */ @@ -1095,11 +1108,11 @@ int sensor_register(FAR struct sensor_lowerhalf_s *lower, int devno) DEBUGASSERT(lower != NULL); snprintf(path, PATH_MAX, DEVNAME_FMT, - g_sensor_info[lower->type].name, + g_sensor_meta[lower->type].name, lower->uncalibrated ? DEVNAME_UNCAL : "", devno); return sensor_custom_register(lower, path, - g_sensor_info[lower->type].esize); + g_sensor_meta[lower->type].esize); } /**************************************************************************** @@ -1229,7 +1242,7 @@ void sensor_unregister(FAR struct sensor_lowerhalf_s *lower, int devno) char path[PATH_MAX]; snprintf(path, PATH_MAX, DEVNAME_FMT, - g_sensor_info[lower->type].name, + g_sensor_meta[lower->type].name, lower->uncalibrated ? DEVNAME_UNCAL : "", devno); sensor_custom_unregister(lower, path); diff --git a/drivers/sensors/sensor_rpmsg.c b/drivers/sensors/sensor_rpmsg.c index eb8a9977409..2dc4715a4d7 100644 --- a/drivers/sensors/sensor_rpmsg.c +++ b/drivers/sensors/sensor_rpmsg.c @@ -215,6 +215,9 @@ static int sensor_rpmsg_set_calibvalue(FAR struct sensor_lowerhalf_s *lower, static int sensor_rpmsg_calibrate(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, unsigned long arg); +static int sensor_rpmsg_get_info(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + FAR struct sensor_device_info_s *info); static int sensor_rpmsg_control(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg); @@ -262,6 +265,7 @@ static const struct sensor_ops_s g_sensor_rpmsg_ops = .selftest = sensor_rpmsg_selftest, .set_calibvalue = sensor_rpmsg_set_calibvalue, .calibrate = sensor_rpmsg_calibrate, + .get_info = sensor_rpmsg_get_info, .control = sensor_rpmsg_control }; @@ -692,6 +696,28 @@ SENSOR_RPMSG_FUNCTION(set_calibvalue, SNIOC_SET_CALIBVALUE, arg, arg, 256, true) SENSOR_RPMSG_FUNCTION(calibrate, SNIOC_CALIBRATE, arg, arg, 256, true) +static int sensor_rpmsg_get_info(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + FAR struct sensor_device_info_s *info) +{ + FAR struct sensor_rpmsg_dev_s *dev = lower->priv; + FAR struct sensor_lowerhalf_s *drv = dev->drv; + int ret = -ENOTTY; + + if (drv->ops->get_info) + { + ret = drv->ops->get_info(drv, filep, info); + } + else if (!(filep->f_oflags & SENSOR_REMOTE)) + { + ret = sensor_rpmsg_ioctl(dev, SNIOC_GET_INFO, + (unsigned long)(uintptr_t)info, + sizeof(struct sensor_device_info_s), true); + } + + return ret; +} + static int sensor_rpmsg_control(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg) diff --git a/drivers/sensors/usensor.c b/drivers/sensors/usensor.c index 8fdd18a49d0..84b3b73d75f 100644 --- a/drivers/sensors/usensor.c +++ b/drivers/sensors/usensor.c @@ -47,6 +47,12 @@ static ssize_t usensor_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static int usensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int usensor_get_info(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + FAR struct sensor_device_info_s *info); +static int usensor_control(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + int cmd, unsigned long arg); /**************************************************************************** * Private Types @@ -64,9 +70,10 @@ struct usensor_context_s struct usensor_lowerhalf_s { - struct list_node node; /* node in all usensor list */ - struct sensor_lowerhalf_s driver; /* The lowerhalf driver of user sensor */ - char path[1]; /* The path of usensor character device */ + struct list_node node; /* node in all usensor list */ + struct sensor_lowerhalf_s driver; /* The lowerhalf driver of user sensor */ + struct sensor_device_info_s info; /* Virtual sensor information */ + char path[1]; /* The path of usensor character device */ }; /**************************************************************************** @@ -88,6 +95,8 @@ static const struct file_operations g_usensor_fops = static const struct sensor_ops_s g_usensor_ops = { + .get_info = usensor_get_info, + .control = usensor_control }; /**************************************************************************** @@ -212,6 +221,35 @@ static int usensor_ioctl(FAR struct file *filep, int cmd, return ret; } +static int usensor_get_info(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + FAR struct sensor_device_info_s *info) +{ + FAR struct usensor_lowerhalf_s *ulower = container_of(lower, + struct usensor_lowerhalf_s, + node); + + *info = ulower->info; + return 0; +} + +static int usensor_control(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + int cmd, unsigned long arg) +{ + FAR struct usensor_lowerhalf_s *ulower = container_of(lower, + struct usensor_lowerhalf_s, + node); + + if (cmd == SNIOC_SET_INFO) + { + ulower->info = *(FAR struct sensor_device_info_s *)(uintptr_t)arg; + return 0; + } + + return -ENOTTY; +} + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h index cd1b926c250..0dc98b5358c 100644 --- a/include/nuttx/sensors/ioctl.h +++ b/include/nuttx/sensors/ioctl.h @@ -435,4 +435,20 @@ #define SNIOC_HEAT _SNIOC(0x009B) +/* Command: SNIOC_GET_INFO + * Description: Get device information. + * Argument: This is the device info pointer. + */ + +#define SNIOC_GET_INFO _SNIOC(0x009B) + +#ifdef CONFIG_USENSOR +/* Command: SNIOC_SET_INFO + * Description: Set device information. Only used by user space. + * Argument: This is the device info pointer. + */ + +# define SNIOC_SET_INFO _SNIOC(0x009C) +#endif + #endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */ diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h index 62afd14f7cd..1075cd29eb5 100644 --- a/include/nuttx/sensors/sensor.h +++ b/include/nuttx/sensors/sensor.h @@ -424,6 +424,28 @@ struct sensor_ops_s FAR struct file *filep, unsigned long arg); + /************************************************************************** + * Name: get_info + * + * With this method, the user can obtain information about the current + * device. The name and vendor information cannot exceed + * SENSOR_INFO_NAME_SIZE. + * + * Input Parameters: + * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. + * info - Device information structure pointer. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * -ENOTTY - The cmd don't support. + * + **************************************************************************/ + + CODE int (*get_info)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + FAR struct sensor_device_info_s *info); + /************************************************************************** * Name: control * diff --git a/include/nuttx/uorb.h b/include/nuttx/uorb.h index c58d79d31db..71ed8397312 100644 --- a/include/nuttx/uorb.h +++ b/include/nuttx/uorb.h @@ -317,6 +317,10 @@ #define SENSOR_GPS_SAT_INFO_MAX 4 +/* Maximum length of sensor device information name and path name. */ + +#define SENSOR_INFO_NAME_SIZE 32 + /**************************************************************************** * Public Types ****************************************************************************/ @@ -658,4 +662,72 @@ struct sensor_ioctl_s char data[1]; /* The argument buf of ioctl */ }; +/* This structure describes the information of the sensor device and + * requires the manufacturer to implement the device info function. + */ + +struct sensor_device_info_s +{ + /* Version of the hardware part + driver. */ + + uint32_t version; + + /* Rough estimate of this sensor's power consumption in mA. + * Divide the current data by 1000 to get the real data. + */ + + uint32_t power; + + /* Maximum range of this sensor's value in SI units. */ + + float max_range; + + /* Smallest difference between two values reported by this sensor. */ + + float resolution; + + /* This value depends on the reporting mode: + * + * continuous: minimum sample period allowed in microseconds + * on-change : 0 + * one-shot :-1 + * special : 0, unless otherwise noted + */ + + long min_delay; + + /* This value is defined only for continuous mode and on-change sensors. + * it is the delay between two sensor events corresponding to the lowest + * frequency that this sensor supports. when lower frequencies are + * requested through batch()/set_interval() the events will be generated + * at this frequency instead. it can be used by the framework or + * applications to estimate when the batch FIFO may be full. + */ + + unsigned long max_delay; + + /* Number of events reserved for this sensor in the batch mode FIFO. + * if there is a dedicated FIFO for this sensor, then this is the + * size of this FIFO. If the FIFO is shared with other sensors, + * this is the size reserved for that sensor and it can be zero. + */ + + uint32_t fifo_reserved_event_count; + + /* Maximum number of events of this sensor that could be batched. + * this is especially relevant when the FIFO is shared between + * several sensors; this value is then set to the size of that FIFO. + */ + + uint32_t fifo_max_event_count; + + /* Name of this sensor. */ + + char name[SENSOR_INFO_NAME_SIZE]; + + /* Vendor of the hardware part. */ + + char vendor[SENSOR_INFO_NAME_SIZE]; +}; + #endif /* __INCLUDE_NUTTX_SENSORS_SENSOR_H */