Dawn Framework 1.0
Universal data acquisition framework for embedded systems
vecsplit.cxx
1// dawn/src/prog/vecsplit.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/prog/vecsplit.hxx"
7
8#include <cstring>
9#include <new>
10
11#include "dawn/debug.hxx"
12#include "dawn/io/common.hxx"
13
14using namespace dawn;
15
16CProgVecSplit::CProgVecSplit(CDescObject &desc)
17 : CProgCommon(desc)
18 , source(nullptr)
19 , sourceId(0)
20 , sourceData(nullptr)
21 , active(false)
22 , registered(false)
23{
24}
25
26CProgVecSplit::~CProgVecSplit()
27{
28 deinit();
29}
30
31int CProgVecSplit::allocOutput(SObjectId::ObjectId ioId)
32{
33 SVecOutput output;
34
35 output.io = nullptr;
36 output.ioId = ioId;
37 output.data = nullptr;
38 output.offset = 0;
39 outputs.push_back(output);
40 setObjectMapItem(ioId, nullptr);
41 return OK;
42}
43
44int CProgVecSplit::configureDesc(const CDescObject &desc)
45{
47 const SObjectId::UObjectId *ids;
48 size_t offset = 0;
49
50 for (size_t i = 0; i < desc.getSize(); i++)
51 {
52 item = desc.objectCfgItemNext(offset);
53
54 if (item->cfgid.s.cls != CProgCommon::PROG_CLASS_VECSPLIT)
55 {
56 DAWNERR("vecsplit: unsupported cfg class 0x%" PRIx32 "\n", item->cfgid.v);
57 return -EINVAL;
58 }
59
60 switch (item->cfgid.s.id)
61 {
62 case PROG_VECSPLIT_CFG_SOURCE:
63 {
64 if (item->cfgid.s.size != 1)
65 {
66 DAWNERR("vecsplit: SOURCE must have one item\n");
67 return -EINVAL;
68 }
69
70 ids = reinterpret_cast<const SObjectId::UObjectId *>(item->data);
71 sourceId = ids[0].v;
72 setObjectMapItem(sourceId, nullptr);
73 break;
74 }
75
76 case PROG_VECSPLIT_CFG_OUTPUTS:
77 {
78 if (item->cfgid.s.size == 0)
79 {
80 DAWNERR("vecsplit: OUTPUTS must not be empty\n");
81 return -EINVAL;
82 }
83
84 ids = reinterpret_cast<const SObjectId::UObjectId *>(item->data);
85 for (size_t j = 0; j < item->cfgid.s.size; j++)
86 {
87 int ret = allocOutput(ids[j].v);
88 if (ret != OK)
89 {
90 return ret;
91 }
92 }
93
94 break;
95 }
96
97 default:
98 {
99 DAWNERR("vecsplit: unsupported cfg id %u\n", item->cfgid.s.id);
100 return -EINVAL;
101 }
102 }
103 }
104
105 if (sourceId == 0 || outputs.empty())
106 {
107 DAWNERR("vecsplit: source and outputs are required\n");
108 return -EINVAL;
109 }
110
111 return OK;
112}
113
115{
116 return configureDesc(getDesc());
117}
118
120{
121 size_t dim = 0;
122 int ret;
123
124 source = getIO(sourceId);
125 if (source == nullptr || !source->isRead())
126 {
127 DAWNERR("vecsplit: source 0x%" PRIx32 " not readable\n", sourceId);
128 return -EIO;
129 }
130
131 for (auto &output : outputs)
132 {
133 output.io = getIO(output.ioId);
134 if (output.io == nullptr)
135 {
136 DAWNERR("vecsplit: output IO 0x%" PRIx32 " not found\n", output.ioId);
137 return -EIO;
138 }
139
140 if (output.io->getDataDim() == 0)
141 {
142 ret = prepareWritableTarget(output.io, 1, true);
143 if (ret != OK)
144 {
145 DAWNERR("vecsplit: output prepare failed %d\n", ret);
146 return ret;
147 }
148 }
149
150 if (output.io->getDtype() != source->getDtype())
151 {
152 DAWNERR("vecsplit: output 0x%" PRIx32 " dtype mismatch\n", output.ioId);
153 return -EINVAL;
154 }
155
156 output.offset = dim;
157 dim += output.io->getDataDim();
158 output.data = output.io->ddata_alloc(1);
159 if (output.data == nullptr)
160 {
161 return -ENOMEM;
162 }
163 }
164
165 if (dim > source->getDataDim())
166 {
167 DAWNERR("vecsplit: outputs need %zu elements, source has %zu\n", dim, source->getDataDim());
168 return -EINVAL;
169 }
170
171 sourceData = source->ddata_alloc(1);
172 if (sourceData == nullptr)
173 {
174 return -ENOMEM;
175 }
176
177 return OK;
178}
179
181{
182 doStop();
183
184 delete sourceData;
185 sourceData = nullptr;
186 for (auto &output : outputs)
187 {
188 delete output.data;
189 output.data = nullptr;
190 }
191
192 outputs.clear();
193 source = nullptr;
194 sourceId = 0;
195
196 return OK;
197}
198
199int CProgVecSplit::ioNotifierCb(void *priv, io_ddata_t *data)
200{
201 CProgVecSplit *self = static_cast<CProgVecSplit *>(priv);
202
203 if (self != nullptr && self->active)
204 {
205 self->updateOutputs(data);
206 }
207
208 return OK;
209}
210
212{
213 int ret;
214
215 if (!registered && source->isNotify())
216 {
217 ret = source->setNotifier(ioNotifierCb, 0, this);
218 if (ret != OK)
219 {
220 DAWNERR("vecsplit: setNotifier failed %d\n", ret);
221 return ret;
222 }
223
224 registered = true;
225 }
226
227 active = true;
228 updateOutputs(nullptr);
229 return OK;
230}
231
233{
234 if (registered && source != nullptr && source->isNotify())
235 {
236 source->setNotifier(nullptr, 0, nullptr);
237 registered = false;
238 }
239
240 active = false;
241 return OK;
242}
243
245{
246 return false;
247}
248
249void CProgVecSplit::updateOutputs(io_ddata_t *data)
250{
251 int ret;
252
253 if (source == nullptr || sourceData == nullptr)
254 {
255 return;
256 }
257
258 if (data != nullptr)
259 {
260 std::memcpy(sourceData->getDataPtr(), data->getDataPtr(), sourceData->getDataSize());
261 }
262 else if (source->getData(*sourceData, 1) != OK)
263 {
264 return;
265 }
266
267 for (auto &output : outputs)
268 {
269 std::memcpy(output.data->getDataPtr(),
270 static_cast<uint8_t *>(sourceData->getDataPtr()) +
271 output.offset * source->getDtypeSize(),
272 output.data->getDataSize());
273 ret = output.io->setData(*output.data);
274 if (ret != OK)
275 {
276 DAWNERR("vecsplit: output setData failed %d\n", ret);
277 }
278 }
279}
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.
int getData(IODataCmn &data, size_t len, size_t offset=0)
Get data from I/O (public interface with stats tracking).
Definition common.hxx:353
virtual bool isNotify() const =0
Check if IO supports notifications.
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 bool isRead() const =0
Check if IO supports read operations.
CDescObject & getDesc()
Get descriptor object for this object.
Definition object.cxx:190
size_t getDtypeSize() const
Get size of this object's data type.
Definition object.cxx:195
uint8_t getDtype() const
Get data type field.
Definition object.cxx:175
Base class for all PROG (processing) objects.
Definition common.hxx:27
Vector splitter: splits one vector IO into multiple outputs.
Definition vecsplit.hxx:26
int configure()
Configure object from descriptor data.
Definition vecsplit.cxx:114
int init()
One-time initialize object after bindings are resolved.
Definition vecsplit.cxx:119
int doStart()
Start implementation hook.
Definition vecsplit.cxx:211
int doStop()
Stop implementation hook.
Definition vecsplit.cxx:232
int deinit()
De-initialize object.
Definition vecsplit.cxx:180
bool hasThread() const
Check if a background thread is active.
Definition vecsplit.cxx:244
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).
uint32_t ObjectId
ObjectID type - single 32-bit value.
Definition objectid.hxx:44
Heap-allocated dynamic I/O data buffer.
Definition ddata.hxx:21
size_t getDataSize()
Get data size in bytes.
Definition ddata.hxx:153
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
Definition ddata.hxx:180
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).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
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