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 // Initialize SYSTEM handler
95
96 ret = system.init(desc, nullptr);
97 if (ret < 0)
98 {
99 DAWNERR("failed to initialize SYSTEM handler\n");
100 return ret;
101 }
102
103 // Initialize SYSTEM objects
104
105 ret = system.initAll();
106 if (ret < 0)
107 {
108 DAWNERR("failed to initialize SYSTEM objects\n");
109 return ret;
110 }
111
112 // Bind special IO objects (Config, Control, Trigger) to their targets
113
114 ret = io.bindObjects(io, prog, proto, system);
115 if (ret < 0)
116 {
117 DAWNERR("failed to bind special IO objects\n");
118 return ret;
119 }
120
121 return OK;
122}
123
124#ifdef CONFIG_DAWN_DESC_SWITCH
125int CDawn::load_descriptor_from_slot(uint8_t slot)
126{
128 int ret;
129
130 ret = CDevDescriptor::getInst()->getDescriptor(slot, reg);
131 if (ret < 0)
132 {
133 return ret;
134 }
135
136 if (reg.ptr == nullptr || reg.len == 0)
137 {
138 return -ENODATA;
139 }
140
141 return load_descriptor(static_cast<uint32_t *>(reg.ptr), reg.len);
142}
143#endif
144
145int CDawn::start(bool no_loop)
146{
147 int ret = OK;
148#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
149 int tmp;
150#endif
151#ifdef CONFIG_DAWN_DESC_SWITCH
152 uint8_t newSlot;
153
156#endif
157
158 for (;;)
159 {
160#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
162#endif
163 // Start IO
164
165 ret = io.startAll();
166 if (ret < 0)
167 {
168#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
169 goto deinit_all;
170#else
171 return ret;
172#endif
173 }
174
175 // Start SYSTEM objects (e.g. bring up LTE before protocols need the network)
176
177 ret = system.startAll();
178 if (ret < 0)
179 {
180#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
181 goto stop_io;
182#else
183 return ret;
184#endif
185 }
186
187 // Start programs
188
189 ret = prog.startAll();
190 if (ret < 0)
191 {
192#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
193 goto stop_sys;
194#else
195 return ret;
196#endif
197 }
198
199 // Start protocols
200
201 ret = proto.startAll();
202 if (ret < 0)
203 {
204#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
205 goto stop_prog;
206#else
207 return ret;
208#endif
209 }
210
211 DAWNINFO("DAWN: START SUCCESS!\n");
212
213 while (!no_loop)
214 {
215#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
217 {
218 DAWNINFO("shutdown requested - quit\n");
219 break;
220 }
221#endif
222
223#ifdef CONFIG_DAWN_DESC_SWITCH
225 {
226 DAWNINFO("descriptor switch requested\n");
227 break;
228 }
229#endif
230
231 if (!desc.getNoIdleQuit() && !(proto.hasThread() || prog.hasThread()))
232 {
233 DAWNINFO("no active protocols - quit\n");
234 break;
235 }
236
237 // Idle: protocols and progs run their own threads; the main loop
238 // hands the wait to the user idle hook (default is sleep(1)).
239 // The hook owns cadence and must return promptly so the
240 // shutdown / descriptor-switch / no-thread checks above run
241 // each iteration.
242
243 dawn::oot::user_on_idle(this);
244 }
245
246#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
247 // User-supplied pre-shutdown hook (weak default is a no-op).
248 // A negative return is logged but does not abort teardown.
249
250 tmp = dawn::oot::user_pre_shutdown(this);
251 if (tmp < 0)
252 {
253 DAWNWARN("user_pre_shutdown returned %d\n", tmp);
254 }
255
256 tmp = proto.stopAll();
257 if (tmp < 0)
258 {
259 DAWNERR("failed to stop protos %d\n", tmp);
260 if (ret == OK)
261 {
262 ret = tmp;
263 }
264 }
265
266 stop_prog:
267 tmp = prog.stopAll();
268 if (tmp < 0)
269 {
270 DAWNERR("failed to stop programs %d\n", tmp);
271 if (ret == OK)
272 {
273 ret = tmp;
274 }
275 }
276
277 stop_sys:
278 tmp = system.stopAll();
279 if (tmp < 0)
280 {
281 DAWNERR("failed to stop SYSTEM objects %d\n", tmp);
282 if (ret == OK)
283 {
284 ret = tmp;
285 }
286 }
287
288 stop_io:
289 tmp = io.stopAll();
290 if (tmp < 0)
291 {
292 DAWNERR("failed to stop IO %d\n", tmp);
293 if (ret == OK)
294 {
295 ret = tmp;
296 }
297 }
298
299 deinit_all:
300 tmp = proto.deinitAll();
301 if (tmp < 0)
302 {
303 DAWNERR("failed to deinit protos %d\n", tmp);
304 if (ret == OK)
305 {
306 ret = tmp;
307 }
308 }
309
310 tmp = prog.deinitAll();
311 if (tmp < 0)
312 {
313 DAWNERR("failed to deinit programs %d\n", tmp);
314 if (ret == OK)
315 {
316 ret = tmp;
317 }
318 }
319
320 tmp = system.deinitAll();
321 if (tmp < 0)
322 {
323 DAWNERR("failed to deinit SYSTEM objects %d\n", tmp);
324 if (ret == OK)
325 {
326 ret = tmp;
327 }
328 }
329
330 tmp = io.deinitAll();
331 if (tmp < 0)
332 {
333 DAWNERR("failed to deinit IO %d\n", tmp);
334 if (ret == OK)
335 {
336 ret = tmp;
337 }
338 }
339#else
340 return ret;
341#endif
342
343#ifdef CONFIG_DAWN_DESC_SWITCH
345 {
346 newSlot = CDescSwitch::getSwitchSlot();
349
350 ret = load_descriptor_from_slot(newSlot);
351 if (ret < 0)
352 {
353 DAWNERR("descriptor switch failed for slot %d\n", newSlot);
354 return ret;
355 }
356
357 continue;
358 }
359#endif
360
361 return ret;
362 }
363}
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:145
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, IHandler &dev)
Bind special I/O objects (Config, Control, Trigger) to targets.
Definition handler.cxx:276
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
int startAll()
Start all objects managed by this handler.
Definition handler.hxx:42
int deinitAll()
De-initialize all objects managed by this handler.
Definition handler.hxx:37
int stopAll()
Stop all objects managed by this handler.
Definition handler.hxx:47
int initAll()
Run one-time init() for all configured objects.
Definition handler.hxx:26
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.