Dawn Framework 1.0
Universal data acquisition framework for embedded systems
common.cxx
1// dawn/src/io/common.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/io/common.hxx"
7
8#include <climits>
9#include <new>
10
11using namespace dawn;
12
13int CIOCommon::configureDesc(const CDescObject &desc)
14{
15 SObjectCfg::SObjectCfgItem *item = nullptr;
16 size_t offset = 0;
17
18 for (size_t i = 0; i < desc.getSize(); i++)
19 {
20 item = desc.objectCfgItemAtOffset(offset);
21
23 {
24 offset += item->cfgid.s.size + 1;
25 continue;
26 }
27
28 switch (item->cfgid.s.id)
29 {
31 {
32 if (item->data[0] > INT_MAX)
33 {
34 return -ERANGE;
35 }
36
37 devno = static_cast<int>(item->data[0]);
38 offset += 2;
39 break;
40 }
41
43 {
45 item->cfgid.s.dtype,
46 item->cfgid.s.size,
47 reinterpret_cast<const uint32_t *>(&item->data[0])) < 0)
48 {
49 return -EINVAL;
50 }
51
52 offset += item->cfgid.s.size + 1;
53 break;
54 }
55
57 {
59 item->cfgid.s.dtype,
60 item->cfgid.s.size,
61 reinterpret_cast<const uint32_t *>(&item->data[0])) < 0)
62 {
63 return -EINVAL;
64 }
65
66 offset += item->cfgid.s.size + 1;
67 break;
68 }
69
71 {
73 item->cfgid.s.dtype,
74 item->cfgid.s.size,
75 reinterpret_cast<const uint32_t *>(&item->data[0])) < 0)
76 {
77 return -EINVAL;
78 }
79
80 offset += item->cfgid.s.size + 1;
81 break;
82 }
83
85 {
86#ifdef CONFIG_DAWN_IO_NOTIFY
87 notifyType = static_cast<uint8_t>(item->data[0]);
88 notifyPrio = static_cast<int>(item->data[1]);
89 notifyBatch = static_cast<size_t>(item->data[2]);
90 if (notifyBatch == 0)
91 {
92 notifyBatch = 1;
93 }
94#endif
95 offset += 4;
96 break;
97 }
98
99 default:
100 {
101 DAWNERR("Unsupported common config 0x%08" PRIx32 "\n", item->cfgid.v);
102 return -EINVAL;
103 }
104 }
105 }
106
107 return OK;
108}
109
111 : CObject(desc)
112{
113 DAWNASSERT(desc.getObjectId().s.cls > IO_CLASS_ANY && desc.getObjectId().s.cls < IO_CLASS_LAST,
114 "invalid class");
115
116 // Reset state
117
118#ifdef CONFIG_DAWN_IO_NOTIFY
119 notifier = nullptr;
120 notifyType = IO_NOTIFY_POLL;
121 notifyPrio = 0;
122 notifyBatch = 1;
123#endif
124
125 limits.reset();
126
127#ifdef CONFIG_DAWN_IO_HAS_STATS
128 // Initialize statistics
129
130 stats.read_count = 0;
131 stats.write_count = 0;
132 stats.error_count = 0;
133#endif
134
135 // By default devno is equal to instance number.
136
137 devno = getPriv();
138
139 // Configure common IO data
140
141 configureDesc(desc);
142}
143
145{
146 switch (cfg->cfgid.s.cls)
147 {
149 {
150 switch (cfg->cfgid.s.id)
151 {
153 {
154 return 2;
155 }
156
160 {
161 return cfg->cfgid.s.size + 1;
162 }
163
165 {
166 return 4;
167 }
168
169 default:
170 {
171 DAWNERR("unsupported common cfg 0x08%" PRIx32 "\n", cfg->cfgid.v);
172 return -1;
173 }
174 }
175
176 break;
177 }
178
179 default:
180 {
181 DAWNERR("unsupported common cfg 0x08%" PRIx32 "\n", cfg->cfgid.v);
182 return -1;
183 }
184 }
185
186 return 0;
187}
188
190{
191 return getFlags() & IO_FLAGS_TS;
192}
193
195{
196#if defined(CONFIG_DAWN_IO_TIMESTAMP) || defined(CONFIG_DAWN_IO_TIMESTAMPIO)
197 struct timespec ts;
198
199 clock_systime_timespec(&ts);
200 return 1000000ull * ts.tv_sec + ts.tv_nsec / 1000;
201#else
202 return 0;
203#endif
204}
205
206#ifdef CONFIG_DAWN_IO_NOTIFY
207void CIOCommon::bindNotifier(IIONotifier *n)
208{
209 DAWNASSERT(n, "notifier is nullptr");
210
211 notifier = n;
212}
213
214int CIOCommon::setNotifier(IIONotifier::notifier_cb_t cb, int prio, void *priv)
215{
217
218 // Notifier not supported
219
220 if (!notifier)
221 {
222 DAWNERR("notifier=NULL!\n");
223 return -EPERM;
224 }
225
226 // Fill notifier data
227
228 n.priv = priv;
229 n.io = this;
230 n.cb = cb;
231 n.prio = prio;
232
233 return notifier->regNotifier(n);
234}
235
236int CIOCommon::notifyData(io_ddata_t *data)
237{
238 if (!notifier)
239 {
240 return OK;
241 }
242
243 return notifier->notifyData(this, data);
244}
245#endif
246
247io_ddata_t *CIOCommon::ddata_alloc(size_t batch, size_t chunk_size)
248{
249 size_t dim = getDataDim();
250 size_t dsize = getDataSize();
251 size_t tsize;
252#ifdef CONFIG_DAWN_IO_SEEKABLE
253 size_t chunk;
254
255 // Seekable IOs use a chunk buffer (T=1, UINT8) capped to chunk_size.
256
257 if (isSeekable())
258 {
259 if (chunk_size == 0)
260 {
261 DAWNERR("ddata_alloc: seekable IO requires chunk_size > 0\n");
262 return nullptr;
263 }
264
265 chunk = dsize > 0 && chunk_size < dsize ? chunk_size : dsize;
266 if (chunk == 0)
267 {
268 chunk = chunk_size;
269 }
270
271 io_ddata_t *data = new (std::nothrow) io_ddata_t(1, chunk, batch, SObjectId::DTYPE_UINT8);
272 if (data == nullptr || !data->isAllocated())
273 {
274 delete data;
275 return nullptr;
276 }
277
278 return data;
279 }
280#endif
281
282 if (dim == 0)
283 {
284 DAWNERR("dim == 0");
285 return nullptr;
286 }
287
288 // check input
289
290 tsize = dsize / dim;
291 if (tsize == 0)
292 {
293 DAWNERR("tsize == 0");
294 return nullptr;
295 }
296
297 io_ddata_t *data = new (std::nothrow) io_ddata_t(tsize, dim, batch, getDtype(), isTimestamp());
298 if (data == nullptr || !data->isAllocated())
299 {
300 delete data;
301 return nullptr;
302 }
303
304 return data;
305}
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.
SObjectId::UObjectId & getObjectId() const
Get object identifier as union structure.
CIOCommon(CDescObject &desc)
Construct CIOCommon from descriptor.
Definition common.cxx:110
@ IO_CFG_LIMIT_STEP
Step limit words.
Definition common.hxx:214
@ IO_CFG_NOTIFY
Notifier configuration (type + priority)
Definition common.hxx:215
@ IO_CFG_LIMIT_MIN
Minimum limit words.
Definition common.hxx:212
@ IO_CFG_LIMIT_MAX
Maximum limit words.
Definition common.hxx:213
@ IO_CFG_DEVNO
Device number configuration.
Definition common.hxx:211
uint64_t getTimestamp()
Get current timestamp.
Definition common.cxx:194
virtual bool isSeekable() const
Check if IO supports partial (seekable) access.
Definition common.hxx:502
bool isTimestamp() const
Check if I/O supports timestamp.
Definition common.cxx:189
@ IO_NOTIFY_POLL
Poll-based notifier (default)
Definition common.hxx:223
virtual size_t getDataDim() const =0
Get data vector dimension.
io_ddata_t * ddata_alloc(size_t batch, size_t chunk_size=0)
Allocate data buffer for this I/O.
Definition common.cxx:247
virtual size_t getDataSize() const =0
Get data size in bytes.
@ IO_FLAGS_TS
Timestamp support flag.
Definition common.hxx:76
size_t cfgCmnOffset(const SObjectCfg::SObjectCfgItem *cfg)
Get offset of configuration item in descriptor.
Definition common.cxx:144
@ IO_CLASS_ANY
Any I/O class.
Definition common.hxx:86
@ IO_CLASS_LAST
Last I/O class marker.
Definition common.hxx:195
@ CFG_LIMIT_STEP
Step limit words.
Definition limits.hxx:34
@ CFG_LIMIT_MIN
Minimum limit words.
Definition limits.hxx:32
@ CFG_LIMIT_MAX
Maximum limit words.
Definition limits.hxx:33
int bind(uint8_t id, uint8_t dtype, size_t words, const uint32_t *data)
Bind one limit config item.
Definition limits.hxx:164
void reset()
Reset all configured limits.
Definition limits.hxx:50
Base class for all Dawn objects (IOs, Programs, Protocols).
Definition object.hxx:28
uint16_t getPriv() const
Get instance/private data field.
Definition object.cxx:185
uint8_t getFlags() const
Get type-specific flags field.
Definition object.cxx:180
uint8_t getDtype() const
Get data type field.
Definition object.cxx:175
Abstract interface for registering asynchronous I/O notification.
Definition inotifier.hxx:25
int(* notifier_cb_t)(void *priv, io_ddata_t *data)
Notifier callback function type.
Definition inotifier.hxx:37
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
Notifier registration structure.
Definition inotifier.hxx:46
CIOCommon * io
I/O object pointer.
Definition inotifier.hxx:62
int(* cb)(void *priv, io_ddata_t *data)
Notifier callback function type.
Definition inotifier.hxx:70
void * priv
Private context pointer.
Definition inotifier.hxx:53
int prio
Notification callback priority.
Definition inotifier.hxx:78
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).
@ DTYPE_UINT8
Unsigned 8-bit integer (0 to 255).
Definition objectid.hxx:80
Heap-allocated dynamic I/O data buffer.
Definition ddata.hxx:21
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
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
uint32_t dtype
Configuration data type (bits 16-19).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
uint32_t cls
Object class field (bits 21-29, max 511).
Definition objectid.hxx:265
struct dawn::SObjectId::UObjectId::@14 s
Bit-field structure for named member access.