sensor.c: Added new interface for obtaining and setting sensor device information.

When there is an actual physical sensor, the driver must implement the get info interface. The upper layer can obtain the actual physical sensor information through SNIOC_GET_INFO.
SNIOC_SET_INFO can only set the information of the local virtual sensor, which means it is bound to the local advertisement. Remote subscribers cannot set the information.

Usage:
  struct sensor_device_info dev_info;
  orb_ioctl(fd, SNIOC_GET_INFO, (unsigned long)(uintptr_t)&dev_info);

  or:
  ret = orb_set_info(fd, &dev_info);
  ret = orb_get_info(fd, &dev_info);

Signed-off-by: likun17 <likun17@xiaomi.com>
This commit is contained in:
likun17 2024-03-11 18:31:30 +08:00 committed by Xiang Xiao
parent c0674b34d6
commit 703bb7e7b3
6 changed files with 196 additions and 9 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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
****************************************************************************/

View File

@ -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 */

View File

@ -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
*

View File

@ -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 */