Dawn Framework 1.0
Universal data acquisition framework for embedded systems
redirect.cxx
1// dawn/src/prog/redirect.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/prog/redirect.hxx"
7
8#include <new>
9
10#include "dawn/debug.hxx"
11#include "dawn/io/common.hxx"
12#include "dawn/io/ddata.hxx"
13
14using namespace dawn;
15
16int CProgRedirect::ioNotifierCb(void *priv, io_ddata_t *data)
17{
18 SRedirectBind *bind = static_cast<SRedirectBind *>(priv);
19 int ret;
20
21 if (bind == nullptr || !bind->active)
22 {
23 return OK;
24 }
25
26 ret = bind->dst->setData(*data);
27 if (ret != OK)
28 {
29 DAWNERR("redirect: dst 0x%" PRIx32 " setData failed: %d\n", bind->dst->getIdV(), ret);
30 return ret;
31 }
32
33 return OK;
34}
35
36int CProgRedirect::configureDesc(const CDescObject &desc)
37{
38 const SObjectCfg::SObjectCfgItem *item = nullptr;
39 size_t offset = 0;
40
41 while (offset < desc.getSize())
42 {
43 item = desc.objectCfgItemNext(offset);
44
46 {
47 DAWNERR("redirect: unsupported cfg 0x%08" PRIx32 "\n", item->cfgid.v);
48 return -EINVAL;
49 }
50
51 switch (item->cfgid.s.id)
52 {
53 case PROG_REDIRECT_CFG_IOBIND:
54 {
55 const size_t wpe = sizeof(SProgRedirectIOBind) / 4;
56 const SProgRedirectIOBind *tmp;
57 size_t nbinds;
58 size_t i;
59 int ret;
60
61 if (item->cfgid.s.size == 0 || item->cfgid.s.size % wpe != 0)
62 {
63 DAWNERR("redirect: invalid IOBIND size %d\n", item->cfgid.s.size);
64 return -EINVAL;
65 }
66
67 nbinds = item->cfgid.s.size / wpe;
68 tmp = reinterpret_cast<const SProgRedirectIOBind *>(item->data);
69
70 for (i = 0; i < nbinds; i++)
71 {
72 ret = allocObject(&tmp[i]);
73 if (ret != OK)
74 {
75 return ret;
76 }
77 }
78
79 break;
80 }
81
82 default:
83 {
84 DAWNERR("redirect: unsupported cfg 0x%08" PRIx32 "\n", item->cfgid.v);
85 return -EINVAL;
86 }
87 }
88 }
89
90 return OK;
91}
92
93int CProgRedirect::allocObject(const SProgRedirectIOBind *cfg)
94{
95 SRedirectBind *b;
96
97 DAWNINFO("allocate redirect 0x%" PRIx32 " -> 0x%" PRIx32 "\n", cfg->src.v, cfg->dst.v);
98
99 b = new (std::nothrow) SRedirectBind();
100 if (!b)
101 {
102 return -ENOMEM;
103 }
104
105 b->cfg = *cfg;
106 b->src = nullptr;
107 b->dst = nullptr;
108 b->active = false;
109
110 setObjectMapItem(b->cfg.src.v, nullptr);
111 setObjectMapItem(b->cfg.dst.v, nullptr);
112 binds.push_back(b);
113
114 return OK;
115}
116
117CProgRedirect::~CProgRedirect()
118{
119 deinit();
120}
121
123{
124 int ret = configureDesc(getDesc());
125 if (ret != OK)
126 {
127 DAWNERR("redirect configure failed: %d\n", ret);
128 return ret;
129 }
130
131 if (binds.empty())
132 {
133 DAWNERR("redirect: no bindings configured\n");
134 return -EINVAL;
135 }
136
137 return OK;
138}
139
141{
142 for (auto bind : binds)
143 {
144 int ret;
145
146 bind->src = getIO(bind->cfg.src.v);
147 if (!bind->src)
148 {
149 DAWNERR("redirect: src 0x%" PRIx32 " not found\n", bind->cfg.src.v);
150 return -EIO;
151 }
152
153 bind->dst = getIO(bind->cfg.dst.v);
154 if (!bind->dst)
155 {
156 DAWNERR("redirect: dst 0x%" PRIx32 " not found\n", bind->cfg.dst.v);
157 return -EIO;
158 }
159
160 if (!bind->src->isNotify())
161 {
162 DAWNERR("redirect: src 0x%" PRIx32 " has no notify support\n", bind->src->getIdV());
163 return -EINVAL;
164 }
165
166 if (bind->src->getDtype() != bind->dst->getDtype() ||
167 bind->src->getDataDim() != bind->dst->getDataDim() ||
168 bind->src->isTimestamp() != bind->dst->isTimestamp() ||
169 bind->src->getDataSize() != bind->dst->getDataSize())
170 {
171 DAWNERR("redirect: incompatible src/dst IO types 0x%" PRIx32 " -> 0x%" PRIx32 "\n",
172 bind->src->getIdV(),
173 bind->dst->getIdV());
174 return -EINVAL;
175 }
176
177 ret = prepareWritableTarget(bind->dst, bind->src->getDataDim(), true);
178 if (ret != OK)
179 {
180 DAWNERR(
181 "redirect: target prepare failed for 0x%" PRIx32 ": %d\n", bind->dst->getIdV(), ret);
182 return ret;
183 }
184 }
185
186 return OK;
187}
188
190{
191 doStop();
192
193 for (auto bind : binds)
194 {
195 bind->src = nullptr;
196 bind->dst = nullptr;
197 delete bind;
198 }
199
200 binds.clear();
201 return OK;
202}
203
205{
206 for (auto bind : binds)
207 {
208 int ret;
209
210 bind->active = true;
211 ret = bind->src->setNotifier(ioNotifierCb, 0, bind);
212 if (ret != OK)
213 {
214 DAWNERR("redirect: setNotifier failed for 0x%" PRIx32 ": %d\n", bind->src->getIdV(), ret);
215 return ret;
216 }
217 }
218
219 return OK;
220}
221
223{
224 for (auto bind : binds)
225 {
226 if (bind->src != nullptr)
227 {
228 bind->src->setNotifier(nullptr, 0, nullptr);
229 }
230
231 bind->active = false;
232 }
233
234 return OK;
235}
236
238{
239 return false;
240}
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.
CDescObject & getDesc()
Get descriptor object for this object.
Definition object.cxx:190
@ PROG_CLASS_REDIRECT
Generic input-to-output routing bridge.
Definition common.hxx:83
bool hasThread() const
Check if a background thread is active.
Definition redirect.cxx:237
int deinit()
De-initialize object.
Definition redirect.cxx:189
int init()
One-time initialize object after bindings are resolved.
Definition redirect.cxx:140
int doStop()
Stop implementation hook.
Definition redirect.cxx:222
int configure()
Configure object from descriptor data.
Definition redirect.cxx:122
int doStart()
Start implementation hook.
Definition redirect.cxx:204
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 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.