Dawn Framework 1.0
Universal data acquisition framework for embedded systems
handler.cxx
1// dawn/src/io/handler.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/io/handler.hxx"
7
8#include <fixedmath.h>
9
10#include <algorithm>
11#include <cerrno>
12#include <cstdlib>
13#include <functional>
14
15#include <errno.h>
16
17#include "dawn/debug.hxx"
18#include "dawn/io/common.hxx"
19
20#ifdef CONFIG_DAWN_IO_CONFIG
21# include "dawn/io/config.hxx"
22#endif
23
24#ifdef CONFIG_DAWN_IO_CONTROL
25# include "dawn/io/control.hxx"
26#endif
27
28#ifdef CONFIG_DAWN_IO_TRIGGER
29# include "dawn/io/trigger.hxx"
30#endif
31
32#ifdef CONFIG_DAWN_IO_DESCRIPTOR
33# include "dawn/io/descriptor.hxx"
34#endif
35
36#ifdef CONFIG_DAWN_INSPECT
37# include "dawn/dev/inspector.hxx"
38#endif
39
40using namespace dawn;
41
42void CIOHandler::objallocPriv(CHandler &obj, CDescObject &desc)
43{
44 // Allocate object
45
47 {
48 CIOHandler &t = static_cast<CIOHandler &>(obj);
49 CIOCommon *tmp = nullptr;
50
51 tmp = t.create(desc);
52 if (tmp == nullptr)
53 {
54 DAWNERR("Failed to create IO object 0x%" PRIx32 "\n", desc.getObjectIdV());
55 t.allocError = -ENOMEM;
56 return;
57 }
58
59 DAWNINFO("created IO: 0x%" PRIx32 " %p\n", desc.getObjectIdV(), tmp);
60
61 if (t.registerObject(tmp) < 0)
62 {
63 return;
64 }
65 }
66}
67
68CIOCommon *CIOHandler::create(CDescObject &desc)
69{
70 CIOCommon *ret = nullptr;
71
72 // User factory has priority
73
74 if (userFactory != nullptr)
75 {
76 ret = userFactory->create(desc);
77 if (ret != nullptr)
78 {
79 return ret;
80 }
81 }
82
83 return factory.create(desc);
84}
85
86int CIOHandler::objalloc(CDescriptor &desc)
87{
88 return CGenericHandler<CIOCommon>::objalloc(desc, objallocPriv);
89}
90
92{
93 int ret;
94
95 // Set user factory
96
97 userFactory = f;
98
99 // Allocate objects from descriptor
100
101 ret = objalloc(desc);
102 if (ret < 0)
103 {
104 return ret;
105 }
106
107#ifdef CONFIG_DAWN_INSPECT
108 // Register with global inspector for debugging
109
111 inspector->registerIOHandler(this);
112#endif
113
114 return OK;
115}
116
118{
119#ifdef CONFIG_DAWN_IO_NOTIFY
120 notifyMgr.regIO(io);
121#endif
122}
123
125{
126#ifdef CONFIG_DAWN_IO_NOTIFY
127 // Start all notifier instances
128 notifyMgr.start();
129#endif
130
131 // Call base class to start all IOs
133}
134
136{
137 int ret;
138
139 // Configure IO objects (descriptor parsing / validation)
141 if (ret != OK)
142 {
143 return ret;
144 }
145
146 // One-time IO init (allocations / fd open)
148 if (ret != OK)
149 {
150 return ret;
151 }
152
153 return OK;
154}
155
157{
158 // Call base class to stop all IOs
160
161#ifdef CONFIG_DAWN_IO_NOTIFY
162 // Stop all notifier instances
163 notifyMgr.stop();
164#endif
165
166 return ret;
167}
168
170{
171 return SObjectId::objectIsIO(obj);
172}
173
175{
177 uid.v = id;
178 return static_cast<CObject *>(getIO(uid));
179}
180
185
186#if defined(CONFIG_DAWN_IO_CONFIG) || defined(CONFIG_DAWN_IO_CONTROL) || \
187 defined(CONFIG_DAWN_IO_TRIGGER)
188static int resolveObjectById(SObjectId::ObjectId id,
189 IHandler &io,
190 IHandler &prog,
191 IHandler &prot,
192 CObject **out)
193{
194 CObject *obj;
195
196 switch (SObjectId::objectIdGetType(id))
197 {
199 {
200 obj = io.getObject(id);
201 break;
202 }
203
205 {
206 obj = prot.getObject(id);
207 break;
208 }
209
211 {
212 obj = prog.getObject(id);
213 break;
214 }
215
216 default:
217 {
218 DAWNERR("invalid object type for ID 0x%" PRIx32 "\n", id);
219 return -EINVAL;
220 }
221 }
222
223 if (obj == nullptr)
224 {
225 DAWNERR("object not found for ID 0x%" PRIx32 "\n", id);
226 return -ENOENT;
227 }
228
229 *out = obj;
230 return OK;
231}
232#endif
233
234#if defined(CONFIG_DAWN_IO_CONFIG) || defined(CONFIG_DAWN_IO_CONTROL) || \
235 defined(CONFIG_DAWN_IO_TRIGGER)
236static int bindGeneric(IHandler &io,
237 IHandler &prog,
238 IHandler &prot,
239 const std::vector<SObjectId::ObjectId> &ids,
240 const std::function<int(CObject *, SObjectId::ObjectId)> &bind)
241{
242 for (auto const &id : ids)
243 {
244 CObject *obj;
245 int ret;
246
247 ret = resolveObjectById(id, io, prog, prot, &obj);
248 if (ret < 0)
249 {
250 return ret;
251 }
252
253 ret = bind(obj, id);
254 if (ret < 0)
255 {
256 DAWNERR("bind failed for ID 0x%" PRIx32 " (error %d)\n", id, ret);
257 return ret;
258 }
259 }
260
261 return OK;
262}
263#endif
264
266{
267 UNUSED(io);
268 UNUSED(prog);
269 UNUSED(prot);
270
271#if defined(CONFIG_DAWN_IO_CONFIG) || defined(CONFIG_DAWN_IO_CONTROL) || \
272 defined(CONFIG_DAWN_IO_TRIGGER)
273 for (CIOCommon *tmp : objects)
274 {
275# ifdef CONFIG_DAWN_IO_CONFIG
277 {
278 CIOConfig *cfg = static_cast<CIOConfig *>(tmp);
279 std::vector<SObjectId::ObjectId> ids;
280
281 ids.reserve(cfg->map.size());
282 for (auto const &[id, _] : cfg->map)
283 {
284 ids.push_back(id);
285 }
286
287 int ret =
288 bindGeneric(io,
289 prog,
290 prot,
291 ids,
292 [cfg](CObject *o, SObjectId::ObjectId id) { return cfg->bind(o, id); });
293 if (ret < 0)
294 {
295 return ret;
296 }
297 }
298# endif // CONFIG_DAWN_IO_CONFIG
299
300# ifdef CONFIG_DAWN_IO_CONTROL
302 {
303 CIOControl *ctrl = static_cast<CIOControl *>(tmp);
304
305 int ret = bindGeneric(io,
306 prog,
307 prot,
308 ctrl->ids,
309 [ctrl](CObject *o, SObjectId::ObjectId) { return ctrl->bind(o); });
310 if (ret < 0)
311 {
312 return ret;
313 }
314 }
315# endif // CONFIG_DAWN_IO_CONTROL
316
317# ifdef CONFIG_DAWN_IO_TRIGGER
319 {
320 CIOTrigger *trig = static_cast<CIOTrigger *>(tmp);
321
322 int ret = bindGeneric(io,
323 prog,
324 prot,
325 trig->ids,
326 [trig](CObject *o, SObjectId::ObjectId) { return trig->bind(o); });
327 if (ret < 0)
328 {
329 return ret;
330 }
331 }
332# endif // CONFIG_DAWN_IO_TRIGGER
333 }
334#endif
335
336 return OK;
337}
Descriptor wrapper for individual object configuration.
SObjectId::ObjectId getObjectIdV() const
Get object identifier as raw 32-bit value.
SObjectId::UObjectId & getObjectId() const
Get object identifier as union structure.
Binary device descriptor manager.
Global registry for object inspection.
Definition inspector.hxx:38
static CDevInspector * getInst()
Get singleton instance.
Definition inspector.hxx:59
void registerIOHandler(const CIOHandler *handler)
Register IO handler.
Definition inspector.cxx:30
int initAll()
Run one-time init() for all configured objects.
int registerObject(T *obj)
Register object.
int stopAll()
Stop all objects managed by this handler.
T * getObjectById(const SObjectId::UObjectId &id) const
Get object by ObjectID.
int configureAll()
Configure all objects managed by this handler.
std::vector< CIOCommon * > objects
Vector of registered objects.
int objalloc(CDescriptor &desc, CDescriptor::allocobj_func_t func)
Allocate objects from descriptor.
int startAll()
Start all objects managed by this handler.
Base implementation of IHandler interface.
Definition handler.hxx:110
Base class for all I/O objects.
Definition common.hxx:27
@ IO_CLASS_TRIGGER
Trigger I/O.
Definition common.hxx:91
@ IO_CLASS_CONTROL
Control I/O.
Definition common.hxx:93
@ IO_CLASS_CONFIG
Configuration I/O.
Definition common.hxx:90
Configuration I/O for runtime object management.
Definition config.hxx:24
std::map< uint32_t, CObject * > map
Map of object ID to bound CObject pointers.
Definition config.hxx:125
Control I/O for lifecycle management of bound objects.
Definition control.hxx:19
std::vector< SObjectId::ObjectId > ids
Object IDs to resolve; populated during configure().
Definition control.hxx:79
CIOCommon * create(CDescObject &desc)
Create I/O object from descriptor.
Definition factory.cxx:105
Manages I/O object lifecycle and dispatch.
Definition handler.hxx:37
void onInitObject(CIOCommon *io)
Hook called for each I/O object during initAll().
Definition handler.cxx:117
int startAll()
Start all I/O objects.
Definition handler.cxx:124
CObject * getObject(const SObjectId::ObjectId id)
Get object by ObjectID as CObject*.
Definition handler.cxx:174
int stopAll()
Stop all I/O objects.
Definition handler.cxx:156
int initAll()
Configure and initialize all I/O objects.
Definition handler.cxx:135
int init(CDescriptor &desc, IIOFactory *f)
Initialize virtual I/O.
Definition handler.cxx:91
CIOCommon * getIO(SObjectId::UObjectId &id) const
Get I/O object by ObjectID as CIOCommon*.
Definition handler.cxx:181
bool isObjectValid(SObjectId::UObjectId &obj) const
Validate object ID.
Definition handler.cxx:169
int bindObjects(IHandler &io, IHandler &prog, IHandler &prot)
Bind special I/O objects (Config, Control, Trigger) to targets.
Definition handler.cxx:265
Trigger I/O for dispatching commands to bound objects.
Definition trigger.hxx:19
std::vector< SObjectId::ObjectId > ids
Object IDs to resolve; populated during configure().
Definition trigger.hxx:81
Base class for all Dawn objects (IOs, Programs, Protocols).
Definition object.hxx:28
uint16_t getCls() const
Get object class field.
Definition object.cxx:170
Common interface for all handler implementations.
Definition handler.hxx:21
virtual CObject * getObject(const SObjectId::ObjectId id)=0
Get object from this handler by ID.
Abstract factory interface for extensible I/O object creation.
Definition factory.hxx:20
virtual CIOCommon * create(CDescObject &desc)=0
Create I/O object from descriptor.
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
@ OBJTYPE_PROTO
Protocol object type.
Definition objectid.hxx:193
@ OBJTYPE_IO
Input/Output object type.
Definition objectid.hxx:184
@ OBJTYPE_PROG
Program/algorithm object type.
Definition objectid.hxx:202
static bool objectIsIO(const UObjectId &objid)
Check if object is I/O type (union structure version).
Definition objectid.hxx:387
static uint8_t objectIdGetType(const ObjectId objid)
Extract object type from ObjectID.
Definition objectid.hxx:361
uint32_t ObjectId
ObjectID type - single 32-bit value.
Definition objectid.hxx:44
32-bit encoded object identifier (union with bit field).
Definition objectid.hxx:218
ObjectId v
Raw 32-bit ObjectID value (for comparison, hashing, storage).
Definition objectid.hxx:221