Dawn Framework 1.0
Universal data acquisition framework for embedded systems
process.cxx
1// dawn/src/prog/process.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/prog/process.hxx"
7
8#include "dawn/debug.hxx"
9#include "dawn/io/common.hxx"
10#include "dawn/io/ddata.hxx"
11
12using namespace dawn;
13
14int CProgProcess::ioNotifierCb(void *priv, io_ddata_t *data)
15{
16 SProcessBind *bind = static_cast<SProcessBind *>(priv);
17
18 if (!bind->active)
19 {
20 return OK;
21 }
22
23 // Get data and handle
24
25 bind->owner->handleCmn(bind, data);
26 return OK;
27}
28
29int CProgProcess::configureDesc(const CDescObject &desc)
30{
31 SObjectCfg::SObjectCfgItem *item = nullptr;
32 size_t offset = 0;
33
34 for (size_t i = 0; i < desc.getSize(); i++)
35 {
36 item = desc.objectCfgItemNext(offset);
37
38 switch (item->cfgid.s.id)
39 {
41 {
42 const size_t wpe = sizeof(SProgStatsIOBind) / 4;
43 size_t nbinds;
44 size_t b;
45
46 if (item->cfgid.s.size == 0 || item->cfgid.s.size % wpe != 0)
47 {
48 DAWNERR(
49 "Invalid config size %d, expected multiple of %zu\n", item->cfgid.s.size, wpe);
50 return -EINVAL;
51 }
52
53 nbinds = item->cfgid.s.size / wpe;
54 for (b = 0; b < nbinds; b++)
55 {
56 SProgStatsIOBind *tmp =
57 reinterpret_cast<SProgStatsIOBind *>(item->data + b * wpe);
58
59 int ret = allocObject(tmp);
60 if (ret != OK)
61 {
62 return ret;
63 }
64 }
65
66 break;
67 }
68
69 default:
70 {
71 int ret = configureExtraCfgItem(desc, item, offset);
72 if (ret != OK)
73 {
74 DAWNERR("Unsupported stats config 0x%08" PRIx32 "\n", item->cfgid.v);
75 return -EINVAL;
76 }
77 break;
78 }
79 }
80 }
81
82 return OK;
83}
84
87 size_t &offset)
88{
89 (void)desc;
90 (void)item;
91 (void)offset;
92 return -ENOTSUP;
93}
94
96 CIOCommon *output,
97 io_ddata_t *ioData,
98 io_ddata_t *outputData,
99 SBindState **state)
100{
101 (void)src;
102 (void)output;
103 (void)ioData;
104 (void)outputData;
105
106 *state = nullptr;
107 return OK;
108}
109
111 io_ddata_t *data,
112 io_ddata_t *ioData,
113 io_ddata_t *outputData,
114 bool &initsample,
115 void *state)
116{
117 (void)state;
118 handle(output, data, ioData, outputData, initsample);
119}
120
121int CProgProcess::allocObject(const SProgStatsIOBind *alloc)
122{
123 DAWNINFO("allocate prog 0x%" PRIx32 " -> 0x%" PRIx32 "\n", alloc->objid.v, alloc->output.v);
124
125 // Allocate source and output in map
126
127 setObjectMapItem(alloc->objid.v, nullptr);
128 setObjectMapItem(alloc->output.v, nullptr);
129 binds.push_back({this, *alloc});
130
131 return OK;
132};
133
134int CProgProcess::bindPrepare(SProcessBind *bind)
135{
136 int ret;
137 size_t dim;
138
139 // Check IO property
140
141 if (!bind->src->isNotify())
142 {
143 DAWNERR("Notifications not supported by IO 0x%" PRIx32 "\n", bind->src->getIdV());
144 return -EINVAL;
145 }
146
147 if (!bind->src->isRead())
148 {
149 DAWNERR("Source IO 0x%" PRIx32 " is not readable\n", bind->src->getIdV());
150 return -EINVAL;
151 }
152
153 // Register callback
154
155 ret = bind->src->setNotifier(ioNotifierCb, 0, bind);
156 if (ret < 0)
157 {
158 DAWNERR("Set notifier failed for objId = 0x%" PRIx32 "\n", bind->src->getIdV());
159 return ret;
160 }
161
162 // Get dimension
163
164 dim = bind->src->getDataDim();
165
166 // Initialize deferred virtual outputs and validate configured targets.
167
168 ret = prepareWritableTarget(bind->output, dim, true);
169 if (ret != OK)
170 {
171 DAWNERR("Failed to initialize output IO (error %d)\n", ret);
172 return ret;
173 }
174
175 if (bind->output->getDataDim() != dim)
176 {
177 DAWNERR("Process output 0x%" PRIx32 " shape mismatch\n", bind->output->getIdV());
178 return -EINVAL;
179 }
180
181 return OK;
182}
183
188
190{
191 int ret;
192
193 // Configure object
194
195 ret = configureDesc(getDesc());
196 if (ret != OK)
197 {
198 DAWNERR("Stats configure failed (error %d)\n", ret);
199 return ret;
200 }
201
202 // One-time initialization that depends on bindings is done in init()
203
204 return OK;
205}
206
208{
209 int ret;
210
211 for (auto &bind : binds)
212 {
213 bind.src = getIO(bind.cfg.objid.v);
214 if (!bind.src)
215 {
216 return -EIO;
217 }
218
219 bind.output = getIO(bind.cfg.output.v);
220 if (!bind.output)
221 {
222 return -EIO;
223 }
224
225 ret = bindPrepare(&bind);
226 if (ret != OK)
227 {
228 return ret;
229 }
230
231 bind.ioData = bind.src->ddata_alloc(1);
232 if (!bind.ioData)
233 {
234 return -ENOMEM;
235 }
236
237 bind.outputData = bind.output->ddata_alloc(1);
238 if (!bind.outputData)
239 {
240 delete bind.ioData;
241 bind.ioData = nullptr;
242 return -ENOMEM;
243 }
244
245 ret = bindStateAlloc(bind.src, bind.output, bind.ioData, bind.outputData, &bind.state);
246 if (ret != OK)
247 {
248 delete bind.ioData;
249 bind.ioData = nullptr;
250 delete bind.outputData;
251 bind.outputData = nullptr;
252 return ret;
253 }
254 }
255
256 return OK;
257}
258
260{
261 for (auto &bind : binds)
262 {
263 delete bind.state;
264 bind.state = nullptr;
265
266 delete bind.ioData;
267
268 bind.ioData = nullptr;
269
270 delete bind.outputData;
271
272 bind.outputData = nullptr;
273 bind.src = nullptr;
274 bind.output = nullptr;
275 }
276
277 binds.clear();
278
279 return OK;
280}
281
283{
284 // Mark first sample as init sample
285
286 for (auto &bind : binds)
287 {
288 bind.initsample = true;
289 bind.active = true;
290 }
291
292 return OK;
293};
294
296{
297 for (auto &bind : binds)
298 {
299 bind.active = false;
300 }
301
302 return OK;
303};
304
306{
307 return false;
308}
309
310int CProgProcess::trigger(uint8_t cmd)
311{
312 if (cmd == CMD_RESET)
313 {
314 for (auto &bind : binds)
315 {
316 bind.initsample = true;
317 if (bind.state != nullptr)
318 {
319 bind.state->reset();
320 }
321 }
322
323 return OK;
324 }
325
326 return -ENOTSUP;
327}
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
Definition bindable.cxx:41
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Definition bindable.cxx:23
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
Base class for all I/O objects.
Definition common.hxx:27
CDescObject & getDesc()
Get descriptor object for this object.
Definition object.cxx:190
@ CMD_RESET
Reset object internal state.
Definition object.hxx:42
int trigger(uint8_t cmd)
Execute a trigger command.
Definition process.cxx:310
bool hasThread() const
Check if a background thread is active.
Definition process.cxx:305
int init()
One-time initialize Program after bindings are resolved.
Definition process.cxx:207
virtual void handle(CIOCommon *output, io_ddata_t *data, io_ddata_t *ioData, io_ddata_t *outputData, bool &initsample)=0
Process incoming sample.
int configure()
Configure Program from descriptor.
Definition process.cxx:189
int deinit()
Deinitialize Program.
Definition process.cxx:259
virtual void handleWithState(CIOCommon *output, io_ddata_t *data, io_ddata_t *ioData, io_ddata_t *outputData, bool &initsample, void *state)
Process incoming sample with optional per-binding state.
Definition process.cxx:110
virtual int configureExtraCfgItem(const CDescObject &desc, const SObjectCfg::SObjectCfgItem *item, size_t &offset)
Parse program-specific config item (optional extension hook).
Definition process.cxx:85
~CProgProcess()
Destruct the a Program.
Definition process.cxx:184
virtual int bindStateAlloc(CIOCommon *src, CIOCommon *output, io_ddata_t *ioData, io_ddata_t *outputData, SBindState **state)
Allocate optional per-binding derived state.
Definition process.cxx:95
int doStart()
Start the Program.
Definition process.cxx:282
int doStop()
Stop the Program.
Definition process.cxx:295
@ PROG_STATS_CFG_IOBIND
I/O binding configuration.
Definition process.hxx:35
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
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).
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 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).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.