Dawn Framework 1.0
Universal data acquisition framework for embedded systems
sensor_producer.cxx
1// dawn/src/io/sensor_producer.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/io/sensor_producer.hxx"
7
8#include <cstdio>
9#include <cstring>
10
11#include <nuttx/sensors/sensor.h>
12
13using namespace dawn;
14
15int CIOSensorProducer::configureDesc(const CDescObject &desc)
16{
18 size_t offset = 0;
19
20 for (size_t i = 0; i < desc.getSize(); i++)
21 {
22 item = desc.objectCfgItemAtOffset(offset);
23
24 switch (item->cfgid.s.cls)
25 {
27 {
28 switch (item->cfgid.s.id)
29 {
30 case CIOSensorProducer::IO_SENSOR_PRODUCER_CFG_QUEUE_SIZE:
31 {
32 const uint32_t *tmp = reinterpret_cast<const uint32_t *>(&item->data);
33 queueSize = *tmp;
34 offset += 2;
35 break;
36 }
37
38 case CIOSensorProducer::IO_SENSOR_PRODUCER_CFG_PERSIST:
39 {
40 const uint32_t *tmp = reinterpret_cast<const uint32_t *>(&item->data);
41 persist = (*tmp != 0);
42 offset += 2;
43 break;
44 }
45
46 default:
47 {
48 DAWNERR("Unsupported sensor producer config 0x%08" PRIx32 "\n",
49 item->cfgid.v);
50 return -EINVAL;
51 }
52 }
53 break;
54 }
55
57 {
58 offset += cfgCmnOffset(item);
59 break;
60 }
61
62 default:
63 {
64 DAWNERR("Unsupported sensor producer config 0x%08" PRIx32 "\n", item->cfgid.v);
65 return -EINVAL;
66 }
67 }
68 }
69
70 return OK;
71}
72
73CIOSensorProducer::~CIOSensorProducer()
74{
75 deinit();
76}
77
79{
80 int dtypeSize;
81 int ret;
82
83 if (info == nullptr)
84 {
85 DAWNERR("Unsupported sensor producer class %d\n", getCls());
86 return -EINVAL;
87 }
88
89#ifdef CONFIG_SENSORS_USE_B16
91 {
92 DAWNERR("Sensor producer requires DTYPE_B16 when CONFIG_SENSORS_USE_B16 is enabled\n");
93 return -EINVAL;
94 }
95#else
97 {
98 DAWNERR("Sensor producer requires DTYPE_FLOAT when CONFIG_SENSORS_USE_FLOAT is enabled\n");
99 return -EINVAL;
100 }
101#endif
102
104 if (dtypeSize != sizeof(sensor_data_t))
105 {
106 DAWNERR("Sensor producer dtype size %d does not match NuttX sensor data size %zu\n",
107 dtypeSize,
108 sizeof(sensor_data_t));
109 return -EINVAL;
110 }
111
112 if (info->path == nullptr || info->rsize == 0 || info->dsize == 0 ||
113 info->payloadOffset + getDataSize() > info->rsize)
114 {
115 DAWNERR("Unsupported sensor producer class %d\n", getCls());
116 return -EINVAL;
117 }
118
119 if (DATA_BUFFER_SIZE < info->rsize)
120 {
121 DAWNERR(
122 "Sensor producer event size %zu exceeds buffer size %zu\n", info->rsize, DATA_BUFFER_SIZE);
123 return -EINVAL;
124 }
125
126 ret = configureDesc(getDesc());
127 if (ret != OK)
128 {
129 DAWNERR("Sensor producer configure failed (error %d)\n", ret);
130 return ret;
131 }
132
133 if (getCmnDevno() == -1)
134 {
135 DAWNERR("SENSOR producer device number not configured\n");
136 return -EINVAL;
137 }
138
139 snprintf(path, sizeof(path), SENSOR_PATH_FMT, info->path, "", getCmnDevno());
140
141 ret = sensor_user_register(path, info->rsize, queueSize, persist);
142 if (ret == OK)
143 {
144 registered = true;
145 }
146 else if (ret != -EEXIST)
147 {
148 DAWNERR("failed to register sensor producer %s %d\n", path, ret);
149 return ret;
150 }
151
152 fd = sensor_open_write(path);
153 if (fd < 0)
154 {
155 if (registered)
156 {
157 sensor_user_unregister(path);
158 registered = false;
159 }
160 return fd;
161 }
162
163 return OK;
164}
165
167{
168 if (fd >= 0)
169 {
170 sensor_close(fd);
171 fd = -1;
172 }
173
174 if (registered)
175 {
176 sensor_user_unregister(path);
177 registered = false;
178 }
179
180 return OK;
181}
182
184{
185 uint8_t buf[DATA_BUFFER_SIZE];
186 io_ts_t *eventTs;
187 int ret;
188
189 if (fd < 0)
190 {
191 return -ENODEV;
192 }
193
194 if (data.getDataSize() != getDataSize())
195 {
196 return -EINVAL;
197 }
198
199 std::memset(buf, 0, info->rsize);
200 eventTs = reinterpret_cast<io_ts_t *>(buf);
201 *eventTs = sensor_get_timestamp();
202 std::memcpy(buf + info->payloadOffset, data.getDataPtr(), data.getDataSize());
203
204 ret = sensor_write(fd, buf, info->rsize);
205 if (ret < 0)
206 {
207 DAWNERR("sensor producer write failed %d\n", ret);
208 return ret;
209 }
210
211 if (static_cast<size_t>(ret) != info->rsize)
212 {
213 return -EIO;
214 }
215
216#ifdef CONFIG_DAWN_IO_TIMESTAMP
217 if (isTimestamp())
218 {
219 eventTs = reinterpret_cast<io_ts_t *>(buf);
220 this->ts = *eventTs;
221 }
222#endif
223
224 return OK;
225}
226
228{
229 return info != nullptr ? info->dsize * sizeof(sensor_data_t) : 0;
230}
231
233{
234 return getDataSize() / sizeof(sensor_data_t);
235}
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemAtOffset(size_t offset) const
Get configuration item at specified offset.
bool isTimestamp() const
Check if I/O supports timestamp.
Definition common.cxx:189
int getCmnDevno() const
Get device number for this I/O.
Definition common.hxx:798
size_t cfgCmnOffset(const SObjectCfg::SObjectCfgItem *cfg)
Get offset of configuration item in descriptor.
Definition common.cxx:144
@ IO_CLASS_SENSOR_PRODUCER_CONFIG
Sensor producer configuration IDs.
Definition common.hxx:142
@ IO_CLASS_ANY
Any I/O class.
Definition common.hxx:86
size_t getDataDim() const
Get data vector dimension.
int configure()
Configure object from descriptor data.
int setDataImpl(IODataCmn &data)
Set data implementation (override in derived classes).
size_t getDataSize() const
Get data size in bytes.
int deinit()
De-initialize object.
uint16_t getCls() const
Get object class field.
Definition object.cxx:170
CDescObject & getDesc()
Get descriptor object for this object.
Definition object.cxx:190
uint8_t getDtype() const
Get data type field.
Definition object.cxx:175
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
uint64_t io_ts_t
Timestamp data type (uint64_t, typically microseconds since boot).
Definition idata.hxx:16
Base interface for I/O data buffers (static and dynamic).
Definition idata.hxx:21
virtual void * getDataPtr(size_t batch=0)=0
Get pointer to data only (skips timestamp if present).
virtual size_t getDataSize()=0
Get data size in bytes.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
EObjectDataType
Data types supported by Dawn framework.
Definition objectid.hxx:61
@ DTYPE_FLOAT
IEEE 754 single-precision floating point (32-bit).
Definition objectid.hxx:112
@ DTYPE_B16
Signed 16.16 fixed-point (32-bit).
Definition objectid.hxx:128
static int getDtypeSize_(const EObjectDataType dtype)
Get byte size for a specific data type.
Definition objectid.cxx:12
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
Definition objectcfg.hxx:82
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
Definition objectcfg.hxx:94
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.