Dawn Framework 1.0
Universal data acquisition framework for embedded systems
dawn.cxx
1// dawn/src/dawn.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/dawn.hxx"
7#include "dawn/oot.hxx"
8#ifdef CONFIG_DAWN_DESC_SWITCH
9# include "dawn/dev/descriptor.hxx"
10# include "dawn/dev/descswitch.hxx"
11#endif
12#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
13# include "dawn/dev/shutdown.hxx"
14#endif
15
16using namespace dawn;
17
18CDawn::CDawn(IIOFactory *iofactory, IProgFactory *progfactory, IProtoFactory *protofactory)
19 : userIOFactory(iofactory)
20 , userProgFactory(progfactory)
21 , userProtoFactory(protofactory)
22{
23}
24
25int CDawn::load_descriptor(uint32_t *bin, size_t len)
26{
27 int ret = OK;
28
29 DAWNASSERT(bin != nullptr && len > 0, "invalid input");
30
31 // Load binary data
32
33 ret = desc.loadBin(bin, len, false);
34 if (ret < 0)
35 {
36 DAWNERR("ERROR: _desc.loadBin failed %d\n", ret);
37 return ret;
38 }
39
40 // Initialize IO handler
41
42 ret = io.init(desc, userIOFactory);
43 if (ret < 0)
44 {
45 DAWNERR("failed to initialize IO handler\n");
46 return ret;
47 }
48
49 // Initialize IOs
50
51 ret = io.initAll();
52 if (ret < 0)
53 {
54 DAWNERR("failed to initialize IOs\n");
55 return ret;
56 }
57
58 // Initialize PROG handler
59
60 ret = prog.init(desc, &io, userProgFactory);
61 if (ret < 0)
62 {
63 DAWNERR("failed to initialize PROG handler\n");
64 return ret;
65 }
66
67 // Initialize PROGs
68
69 ret = prog.initAll();
70 if (ret < 0)
71 {
72 DAWNERR("failed to initialize PROGs\n");
73 return ret;
74 }
75
76 // Initialize PROTO handler
77
78 ret = proto.init(desc, &io, userProtoFactory);
79 if (ret < 0)
80 {
81 DAWNERR("failed to initialize PROTO handler\n");
82 return ret;
83 }
84
85 // Initialize PROTOs
86
87 ret = proto.initAll();
88 if (ret < 0)
89 {
90 DAWNERR("failed to initialize PROTOs\n");
91 return ret;
92 }
93
94 // Bind special IO objects (Config, Control, Trigger) to their targets
95
96 ret = io.bindObjects(io, prog, proto);
97 if (ret < 0)
98 {
99 DAWNERR("failed to bind special IO objects\n");
100 return ret;
101 }
102
103 return OK;
104}
105
106#ifdef CONFIG_DAWN_DESC_SWITCH
107int CDawn::load_descriptor_from_slot(uint8_t slot)
108{
110 int ret;
111
112 ret = CDevDescriptor::getInst()->getDescriptor(slot, reg);
113 if (ret < 0)
114 {
115 return ret;
116 }
117
118 if (reg.ptr == nullptr || reg.len == 0)
119 {
120 return -ENODATA;
121 }
122
123 return load_descriptor(static_cast<uint32_t *>(reg.ptr), reg.len);
124}
125#endif
126
127int CDawn::start(bool no_loop)
128{
129 int ret = OK;
130#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
131 int tmp;
132#endif
133#ifdef CONFIG_DAWN_DESC_SWITCH
134 uint8_t newSlot;
135
138#endif
139
140 for (;;)
141 {
142#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
144#endif
145 // Start IO
146
147 ret = io.startAll();
148 if (ret < 0)
149 {
150#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
151 goto deinit_all;
152#else
153 return ret;
154#endif
155 }
156
157 // Start programs
158
159 ret = prog.startAll();
160 if (ret < 0)
161 {
162#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
163 goto stop_io;
164#else
165 return ret;
166#endif
167 }
168
169 // Start protocols
170
171 ret = proto.startAll();
172 if (ret < 0)
173 {
174#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
175 goto stop_prog;
176#else
177 return ret;
178#endif
179 }
180
181 DAWNINFO("DAWN: START SUCCESS!\n");
182
183 while (!no_loop)
184 {
185#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
187 {
188 DAWNINFO("shutdown requested - quit\n");
189 break;
190 }
191#endif
192
193#ifdef CONFIG_DAWN_DESC_SWITCH
195 {
196 DAWNINFO("descriptor switch requested\n");
197 break;
198 }
199#endif
200
201 if (!desc.getNoIdleQuit() && !(proto.hasThread() || prog.hasThread()))
202 {
203 DAWNINFO("no active protocols - quit\n");
204 break;
205 }
206
207 // Idle: protocols and progs run their own threads; the main loop
208 // hands the wait to the user idle hook (default is sleep(1)).
209 // The hook owns cadence and must return promptly so the
210 // shutdown / descriptor-switch / no-thread checks above run
211 // each iteration.
212
213 dawn::oot::user_on_idle(this);
214 }
215
216#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
217 // User-supplied pre-shutdown hook (weak default is a no-op).
218 // A negative return is logged but does not abort teardown.
219
220 tmp = dawn::oot::user_pre_shutdown(this);
221 if (tmp < 0)
222 {
223 DAWNWARN("user_pre_shutdown returned %d\n", tmp);
224 }
225
226 tmp = proto.stopAll();
227 if (tmp < 0)
228 {
229 DAWNERR("failed to stop protos %d\n", tmp);
230 if (ret == OK)
231 {
232 ret = tmp;
233 }
234 }
235
236 stop_prog:
237 tmp = prog.stopAll();
238 if (tmp < 0)
239 {
240 DAWNERR("failed to stop programs %d\n", tmp);
241 if (ret == OK)
242 {
243 ret = tmp;
244 }
245 }
246
247 stop_io:
248 tmp = io.stopAll();
249 if (tmp < 0)
250 {
251 DAWNERR("failed to stop IO %d\n", tmp);
252 if (ret == OK)
253 {
254 ret = tmp;
255 }
256 }
257
258 deinit_all:
259 tmp = proto.deinitAll();
260 if (tmp < 0)
261 {
262 DAWNERR("failed to deinit protos %d\n", tmp);
263 if (ret == OK)
264 {
265 ret = tmp;
266 }
267 }
268
269 tmp = prog.deinitAll();
270 if (tmp < 0)
271 {
272 DAWNERR("failed to deinit programs %d\n", tmp);
273 if (ret == OK)
274 {
275 ret = tmp;
276 }
277 }
278
279 tmp = io.deinitAll();
280 if (tmp < 0)
281 {
282 DAWNERR("failed to deinit IO %d\n", tmp);
283 if (ret == OK)
284 {
285 ret = tmp;
286 }
287 }
288#else
289 return ret;
290#endif
291
292#ifdef CONFIG_DAWN_DESC_SWITCH
294 {
295 newSlot = CDescSwitch::getSwitchSlot();
298
299 ret = load_descriptor_from_slot(newSlot);
300 if (ret < 0)
301 {
302 DAWNERR("descriptor switch failed for slot %d\n", newSlot);
303 return ret;
304 }
305
306 continue;
307 }
308#endif
309
310 return ret;
311 }
312}
int load_descriptor(uint32_t *bin, size_t len)
Load and initialize descriptor.
Definition dawn.cxx:25
int start(bool no_loop=false)
Start Dawn framework.
Definition dawn.cxx:127
CDawn(IIOFactory *iofactory=nullptr, IProgFactory *progfactory=nullptr, IProtoFactory *protofactory=nullptr)
Construct CDawn framework.
Definition dawn.cxx:18
static void setActiveSlot(uint8_t slot)
Set currently active descriptor slot.
static void clear()
Clear pending switch request.
static uint8_t getSwitchSlot()
Get pending switch target slot.
static bool isSwitchRequested()
Check if descriptor switch is pending.
bool getNoIdleQuit() const
Return true if the descriptor requests no idle quit.
int loadBin(uint32_t *bin, size_t len, bool force_valid=false, bool dump=false)
Load binary descriptor from memory.
int getDescriptor(int inst, SDescriptorReg &reg)
Get registered descriptor data for an instance.
static CDevDescriptor * getInst()
Get singleton instance.
int deinitAll()
De-initialize all I/O objects.
Definition handler.hxx:88
int startAll()
Start all I/O objects.
Definition handler.cxx:124
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
int bindObjects(IHandler &io, IHandler &prog, IHandler &prot)
Bind special I/O objects (Config, Control, Trigger) to targets.
Definition handler.cxx:265
int stopAll()
Stop all Programs objects.
Definition handler.hxx:110
int startAll()
Start all Programs objects.
Definition handler.hxx:96
int initAll()
Configure, bind, and initialize all Program objects.
Definition handler.cxx:99
bool hasThread() const
Check if any Programs are running.
Definition handler.hxx:123
int init(CDescriptor &desc, CIOHandler *io, IProgFactory *f)
Initialize the Programs handler.
Definition handler.cxx:72
int deinitAll()
Deinitialize all Programs objects.
Definition handler.hxx:82
int startAll()
Start all protocol objects.
Definition handler.hxx:95
int init(CDescriptor &desc, CIOHandler *io, IProtoFactory *f)
Initialize protocol handler and instances.
Definition handler.cxx:73
int initAll()
Configure, bind, and initialize all protocol objects.
Definition handler.cxx:100
bool hasThread() const
Check if any protocol is running.
Definition handler.hxx:119
int stopAll()
Stop all protocol objects.
Definition handler.hxx:108
int deinitAll()
Deinitialize all protocol objects.
Definition handler.hxx:82
static void clear()
Clear pending shutdown request.
Definition shutdown.cxx:22
static bool isRequested()
Check if shutdown has been requested.
Definition shutdown.cxx:27
Abstract factory interface for extensible I/O object creation.
Definition factory.hxx:20
Abstract factory interface for PROG object creation.
Definition factory.hxx:20
Abstract factory interface for protocol creation.
Definition factory.hxx:17
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
Registered descriptor information.
size_t len
Descriptor length in bytes.
void * ptr
Pointer to descriptor data.