Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 510b93cc

History | View | Annotate | Download (34.1 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file    aos_main.cpp
21
 * @brief   Main function.
22
 *
23
 * @addtogroup aos_system
24
 * @{
25
 */
26

    
27
#include <amiroos.h>
28

    
29
/*
30
 * hook to add further includes
31
 */
32
#if defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER)
33
#include AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER
34
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER) */
35

    
36
/******************************************************************************/
37
/* LOCAL DEFINITIONS                                                          */
38
/******************************************************************************/
39

    
40
/**
41
 * @brief   Event mask to identify GPIO events.
42
 */
43
#define EVENTMASK_GPIO                          EVENT_MASK(0)
44

    
45
/**
46
 * @brief   Event mask to identify OS events.
47
 */
48
#define EVENTMASK_OS                            EVENT_MASK(1)
49

    
50
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
51

    
52
/**
53
 * @brief   Event mask to identify SSSP timer events.
54
 */
55
#define EVENTMASK_SSSPTIMER                     EVENT_MASK(2)
56

    
57
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
58

    
59
/******************************************************************************/
60
/* EXPORTED VARIABLES                                                         */
61
/******************************************************************************/
62

    
63
/******************************************************************************/
64
/* LOCAL TYPES                                                                */
65
/******************************************************************************/
66

    
67
/******************************************************************************/
68
/* LOCAL VARIABLES                                                            */
69
/******************************************************************************/
70

    
71
/**
72
 * @brief   Listener object for GPIO events.
73
 */
74
static event_listener_t _eventListenerGPIO;
75

    
76
/**
77
 * @brief   Listener object for OS events.
78
 */
79
static event_listener_t _eventListenerOS;
80

    
81
#if defined(MODULE_HAL_PROGIF) || defined(__DOXYGEN__)
82

    
83
/**
84
 * @brief   I/O channel for the programmer interface.
85
 */
86
static AosIOChannel _stdiochannel;
87

    
88
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
89

    
90
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
91

    
92
/**
93
 * @brief   I/O shell channel for the programmer interface.
94
 */
95
static AosShellChannel _stdshellchannel;
96

    
97
#endif /* defined(MODULE_HAL_PROGIF) */
98

    
99
/*
100
 * hook to add further static variables
101
 */
102
#if defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES)
103
AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES
104
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES) */
105

    
106
/******************************************************************************/
107
/* LOCAL FUNCTIONS                                                            */
108
/******************************************************************************/
109

    
110
/**
111
 * @brief   Prints an error message about an unexpected event.
112
 *
113
 * @param[in] mask    The event mask.
114
 * @param[in] flags   The event flags.
115
 */
116
static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
117
{
118
#if (AMIROOS_CFG_DBG == true)
119
  aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
120
#else /* (AMIROOS_CFG_DBG == true) */
121
  (void)(mask);
122
  (void)(flags);
123
#endif /* (AMIROOS_CFG_DBG == true) */
124
  return;
125
}
126

    
127
/**
128
 * @brief   Helper function to serialize data.
129
 *
130
 * @param[out]  dst   Pointer to the output buffer.
131
 * @param[in]   src   Data to be serialized.
132
 * @param[in]   n     Number of bytes to serialize.
133
 */
134
inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
135
{
136
  aosDbgCheck(dst != NULL);
137
  aosDbgCheck(n > 0 && n <= 8);
138

    
139
  for (uint8_t byte = 0; byte < n; ++byte) {
140
    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
141
  }
142

    
143
  return;
144
}
145

    
146
/**
147
 * @brief   Helper function to deserialize data.
148
 *
149
 * @param[in] src   Pointer to the buffer of data to be deserialzed.
150
 * @param[in] n     Number of bytes to deserialize.
151
 *
152
 * @return    The deserialized 32 bit data.
153
 */
154
inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
155
{
156
  aosDbgCheck(src != NULL);
157
  aosDbgCheck(n > 0 && n <= 8);
158

    
159
  uint64_t result = 0;
160
  for (uint8_t byte = 0; byte < n; ++byte) {
161
    result |= ((uint64_t)src[byte]) << (byte * 8);
162
  }
163

    
164
  return result;
165
}
166

    
167
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
168

    
169
/**
170
 * @brief   Converter function to encode a TM value to a single unsigned 64 bit integer.
171
 *
172
 * @details Contents of the TM struct are mapped as follows:
173
 *            bits  |63     62|61      53|52    50|49         26|25     22|21     17|16     12|11      6|5       0|
174
 *            #bits |       2 |        9 |      3 |          24 |       4 |       5 |       5 |       6 |       6 |
175
 *            value |   isdst |     yday |   wday |        year |     mon |    mday |    hour |     min |     sec |
176
 *            range | special | [0, 365] | [0, 6] | [1900, ...] | [0, 11] | [1, 31] | [0, 23] | [0, 59] | [0, 61] |
177
 *          The Daylight Saving Time Flag (isdsst) is encoded as follows:
178
 *            DST not in effect         -> 0
179
 *            DST in effect             -> 1
180
 *            no information available  -> 2
181
 *
182
 * @param[in] src   Pointer to the TM struct to encode.
183
 *
184
 * @return  An unsigned 64 bit integer, which holds the encoded time value.
185
 */
186
inline uint64_t _TM2U64(struct tm* src)
187
{
188
  aosDbgCheck(src != NULL);
189

    
190
  return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
191
          ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
192
          ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
193
          ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
194
          ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
195
          ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
196
          ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
197
          ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
198
          ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
199
}
200

    
201
/**
202
 * @brief   Converter functiomn to retrieve the encoded TM value from an unsigned 64 bit integer.
203
 *
204
 * @details For information on the encoding, please refer to @p _TM2U64 function.
205
 *
206
 * @param[out] dst  The TM struct to fill with the decoded values.
207
 * @param[in]  src  Unsigned 64 bit integer holding the encoded TM value.
208
 */
209
inline void _U642TM(struct tm* dst, const uint64_t src)
210
{
211
  aosDbgCheck(dst != NULL);
212

    
213
  dst->tm_sec  = (src >> 0)  & 0x0000003F;
214
  dst->tm_min  = (src >> 6)  & 0x0000003F;
215
  dst->tm_hour = (src >> 12) & 0x0000001F;
216
  dst->tm_mday = (src >> 17) & 0x0000001F;
217
  dst->tm_mon  = (src >> 22) & 0x0000000F;
218
  dst->tm_year = (src >> 26) & 0x00FFFFFF;
219
  dst->tm_wday = (src >> 50) & 0x00000007;
220
  dst->tm_yday = (src >> 53) & 0x000001FF;
221
  dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
222

    
223
  return;
224
}
225

    
226
#endif /* (HAL_USE_RTC == TRUE) */
227

    
228
/**
229
 * @brief   Application entry point.
230
 */
231
int main(void)
232
{
233
  // local variables
234
  eventmask_t eventmask = 0;
235
  eventflags_t eventflags = 0;
236
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
237
#if defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES)
238
  AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
239
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES) */
240

    
241
  /*
242
   * ##########################################################################
243
   * # system initialization                                                  #
244
   * ##########################################################################
245
   */
246

    
247
  /* hardware, kernel, and operating system initialization */
248
  // ChibiOS/HAL and custom hal additions (if any)
249
  halInit();
250
#if defined(MODULE_INIT_HAL_EXTRA)
251
  MODULE_INIT_HAL_EXTRA();
252
#endif /* defined(MODULE_INIT_HAL_EXTRA) */
253

    
254
  // ChibiOS/RT kernel and custom kernel additions (if any)
255
  chSysInit();
256
#if defined(MODULE_INIT_KERNEL_EXTRA)
257
  MODULE_INIT_KERNEL_EXTRA();
258
#endif /* defined(MODULE_INIT_KERNEL_EXTRA) */
259

    
260
  // AMiRo-OS, additional interrupts and custom OS additions (if any)
261
#if (AMIROOS_CFG_SHELL_ENABLE == true)
262
  aosSysInit(moduleShellPrompt);
263
#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
264
  aosSysInit();
265
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
266
#if defined(MODULE_INIT_INTERRUPTS)
267
  MODULE_INIT_INTERRUPTS();
268
#endif
269
#if defined(MODULE_INIT_OS_EXTRA)
270
  MODULE_INIT_OS_EXTRA();
271
#endif /* defined(MODULE_INIT_OS_EXTRA) */
272

    
273
  /* event associations */
274
#if (AMIROOS_CFG_SSSP_ENABLE == true)
275
  {
276
    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S;
277
#if (AMIROOS_CFG_SSSP_STACK_START != true)
278
    flagsmask |= MODULE_SSSP_EVENTFLAG_DN;
279
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
280
#if (AMIROOS_CFG_SSSP_STACK_END != true)
281
    flagsmask |= MODULE_SSSP_EVENTFLAG_UP;
282
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
283
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask);
284
  }
285
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
286
  if (AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK) {
287
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK);
288
  }
289
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
290
  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, EVENTMASK_OS);
291

    
292
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_STARTUP == true)
293

    
294
  /* perform SSSP basic initialization stage */
295

    
296
#if defined(MODULE_SSSP_BASICINIT_HOOK)
297
#if defined(MODULE_SSSP_BASICINIT_HOOK_ARGS)
298
  MODULE_SSSP_BASICINIT_HOOK(MODULE_SSSP_BASICINIT_HOOK_ARGS);
299
#else /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
300
  MODULE_SSSP_BASICINIT_HOOK();
301
#endif /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
302
#endif /* defined(MODULE_SSSP_BASICINIT_HOOK) */
303

    
304
  // proceed to startup stage 1.2
305
#if (AMIROOS_CFG_SSSP_MASTER == true)
306
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
307
    /*
308
     * This code is executed if the received event was not about the delay.
309
     * The received event could be casued by any listener.
310
     */
311
    // GPIO event
312
    if (eventmask & _eventListenerGPIO.events) {
313
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
314
      // PD event
315
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
316
        shutdown = AOS_SHUTDOWN_PASSIVE;
317
      } else {
318
#if defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK)
319
        MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK(eventmask, eventflags);
320
#else /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
321
        /* silently ignore any other GPIO events */
322
#endif /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
323
      }
324
    }
325
    // OS event
326
    else if (eventmask & _eventListenerOS.events) {
327
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
328
      _unexpectedEventError(eventmask, eventflags);
329
    }
330
    // unknown event
331
    else {
332
      _unexpectedEventError(eventmask, 0);
333
    }
334
  }
335
  if (shutdown == AOS_SHUTDOWN_NONE) {
336
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_2);
337
  }
338
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
339
  if (shutdown == AOS_SHUTDOWN_NONE) {
340
    aosSsspProceed(NULL, 0, 0, NULL);
341
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_2);
342
  }
343
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
344

    
345
  // proceed to startup stage 1.3
346
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
347
    /*
348
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
349
     * The received event could be caused by any listener.
350
     */
351
    // GPIO event
352
    if (eventmask & _eventListenerGPIO.events) {
353
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
354
      // PD event
355
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
356
        shutdown = AOS_SHUTDOWN_PASSIVE;
357
      } else {
358
#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
359
        MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK(eventmask, eventflags);
360
#else /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
361
        /* silently ignore any other GPIO events */
362
#endif /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
363
      }
364
    }
365
    // OS event
366
    else if (eventmask & _eventListenerOS.events) {
367
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
368
      _unexpectedEventError(eventmask, eventflags);
369
    }
370
    // unknown event
371
    else {
372
      _unexpectedEventError(eventmask, 0);
373
    }
374
  }
375
  if (shutdown == AOS_SHUTDOWN_NONE) {
376
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_3);
377
  }
378

    
379
  // proceed to startup stage 2.1
380
#if (AMIROOS_CFG_SSSP_MASTER == true)
381
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
382
    /*
383
     * This code is executed if the received event was not about the delay.
384
     * The received event could be caused by any listener.
385
     */
386
    // GPIO event
387
    if (eventmask & _eventListenerGPIO.events) {
388
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
389
      // PD event
390
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
391
        shutdown = AOS_SHUTDOWN_PASSIVE;
392
      } else {
393
#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
394
        MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
395
#else /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
396
        /* silently ignore any other GPIO events */
397
#endif /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
398
      }
399
    }
400
    // OS event
401
    else if (eventmask & _eventListenerOS.events) {
402
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
403
      _unexpectedEventError(eventmask, eventflags);
404
    }
405
    // unknown event
406
    else {
407
      _unexpectedEventError(eventmask, 0);
408
    }
409
  }
410
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
411
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
412
    /*
413
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
414
     * The received event could be caused by any listener.
415
     */
416
    // GPIO event
417
    if (eventmask & _eventListenerGPIO.events) {
418
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
419
      // PD event
420
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
421
        shutdown = AOS_SHUTDOWN_PASSIVE;
422
      } else {
423
#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
424
        MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK(eventmask, eventflags);
425
#else /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
426
        /* silently ignore any other GPIO events */
427
#endif /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
428
      }
429
    }
430
    // OS event
431
    else if (eventmask & _eventListenerOS.events) {
432
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
433
      _unexpectedEventError(eventmask, eventflags);
434
    }
435
    // unknown event
436
    else {
437
      _unexpectedEventError(eventmask, 0);
438
    }
439
  }
440
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
441
  if (shutdown == AOS_SHUTDOWN_NONE) {
442
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_1);
443
  }
444

    
445
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_STARTUP == true) */
446

    
447
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
448
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
449
  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
450
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
451
  AMIROOS_CFG_MAIN_INIT_HOOK_1();
452
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
453
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1) */
454

    
455
  /* periphery communication interfaces initialization */
456
#if defined(MODULE_INIT_PERIPHERY_IF)
457
  // module specific initialization
458
  MODULE_INIT_PERIPHERY_IF();
459
#endif /* defined(MODULE_INIT_PERIPHERY_IF) */
460
#if defined(MODULE_HAL_PROGIF)
461
  // user interface
462
  aosIOChannelInit(&_stdiochannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
463
  aosIOChannelOutputEnable(&_stdiochannel);
464
  aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
465
#if (AMIROOS_CFG_SHELL_ENABLE == true)
466
  aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
467
  aosShellChannelInputEnable(&_stdshellchannel);
468
  aosShellChannelOutputEnable(&_stdshellchannel);
469
  aosShellStreamAddChannel(&aos.shell.stream, &_stdshellchannel);
470
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
471
#endif /* defined(MODULE_HAL_PROGIF) */
472

    
473
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
474
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
475
  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
476
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
477
  AMIROOS_CFG_MAIN_INIT_HOOK_2();
478
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
479
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2) */
480

    
481
  /* module is ready -> print welcome prompt */
482
  aosprintf("\n");
483
  aosprintf("######################################################################\n");
484
  aosprintf("# AMiRo-OS is an operating system designed for the Autonomous Mini   #\n");
485
  aosprintf("# Robot (AMiRo) platform.                                            #\n");
486
  aosprintf("# Copyright (C) 2016..2019  Thomas Schöpping et al.                  #\n");
487
  aosprintf("#                                                                    #\n");
488
  aosprintf("# This is free software; see the source for copying conditions.      #\n");
489
  aosprintf("# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n");
490
  aosprintf("# A PARTICULAR PURPOSE.                                              #\n");
491
  aosprintf("# The development of this software was supported by the Excellence   #\n");
492
  aosprintf("# Cluster EXC 227 Cognitive Interaction Technology. The Excellence   #\n");
493
  aosprintf("# Cluster EXC 227 is a grant of the Deutsche Forschungsgemeinschaft  #\n");
494
  aosprintf("# (DFG) in the context of the German Excellence Initiative.          #\n");
495
  aosprintf("######################################################################\n");
496
  aosprintf("\n");
497

    
498
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
499
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
500
  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
501
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
502
  AMIROOS_CFG_MAIN_INIT_HOOK_3();
503
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
504
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3) */
505

    
506
#if (AMIROOS_CFG_TESTS_ENABLE == true)
507
#if defined(MODULE_INIT_TESTS)
508
  MODULE_INIT_TESTS();
509
#else /* defined(MODULE_INIT_TESTS) */
510
  #warning "AMIROOS_CFG_TESTS_ENABLE set to true, but MODULE_INIT_TESTS() not defined"
511
#endif /* defined(MODULE_INIT_TESTS) */
512
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
513

    
514
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
515
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
516
  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
517
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
518
  AMIROOS_CFG_MAIN_INIT_HOOK_4();
519
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
520
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4) */
521

    
522
#if (AMIROOS_CFG_SSSP_ENABLE == true)
523

    
524
  // proceed to startup stage 2.2
525
#if (AMIROOS_CFG_SSSP_MASTER == true)
526
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
527
    /*
528
     * This code is executed if the received event was not about the delay.
529
     * The received event could be caused by any listener.
530
     */
531
    // GPIO event
532
    if (eventmask & _eventListenerGPIO.events) {
533
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
534
      // PD event
535
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
536
        shutdown = AOS_SHUTDOWN_PASSIVE;
537
      } else {
538
#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
539
        MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
540
#else /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
541
        /* silently ignore any other GPIO events */
542
#endif /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
543
      }
544
    }
545
    // OS event
546
    else if (eventmask & _eventListenerOS.events) {
547
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
548
      _unexpectedEventError(eventmask, eventflags);
549
    }
550
    // unknown event
551
    else {
552
      _unexpectedEventError(eventmask, 0);
553
    }
554
  }
555
  if (shutdown == AOS_SHUTDOWN_NONE) {
556
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_2);
557
  }
558
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
559
  if (shutdown == AOS_SHUTDOWN_NONE) {
560
    aosSsspProceed(NULL, 0, 0, NULL);
561
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_2);
562
  }
563
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
564

    
565
  // proceed to startup stage 3 (MSI is enabled), or to operation phase (no MSI)
566
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
567
    /*
568
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
569
     * The received event could be caused by any listener.
570
     */
571
    // GPIO event
572
    if (eventmask & _eventListenerGPIO.events) {
573
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
574
      // PD event
575
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
576
        shutdown = AOS_SHUTDOWN_PASSIVE;
577
      } else {
578
#if defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK)
579
        MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK(eventmask, eventflags);
580
#else /* defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK) */
581
        /* silently ignore any other GPIO events */
582
#endif /* defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK) */
583
      }
584
    }
585
    // OS event
586
    else if (eventmask & _eventListenerOS.events) {
587
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
588
      _unexpectedEventError(eventmask, eventflags);
589
    }
590
    // unknown event
591
    else {
592
      _unexpectedEventError(eventmask, 0);
593
    }
594
  }
595
  if (shutdown == AOS_SHUTDOWN_NONE) {
596
#if (AMIROOS_CFG_SSSP_MSI == true)
597
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1);
598
#else /* (AMIROOS_CFG_SSSP_MSI == true) */
599
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_OPERATION);
600
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
601
  }
602

    
603
  // start the internal system uptime counter
604
  aosSysStartUptime();
605

    
606
  /*
607
   * There must be no delays at this point, thus no hook allowed.
608
   */
609

    
610
#if (AMIROOS_CFG_SSSP_MSI == true)
611

    
612
  //TODO
613

    
614
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
615

    
616
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
617

    
618
  /* completely start AMiRo-OS */
619
  if (shutdown == AOS_SHUTDOWN_NONE) {
620
    aosSysStart();
621
  }
622

    
623
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
624
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
625
  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
626
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
627
  AMIROOS_CFG_MAIN_INIT_HOOK_5();
628
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
629
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5) */
630

    
631
  /*
632
   * ##########################################################################
633
   * # infinite loop                                                          #
634
   * ##########################################################################
635
   */
636

    
637
  // sleep until a shutdown event is received
638
  while (shutdown == AOS_SHUTDOWN_NONE) {
639
    // wait for an event
640
#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0)
641
    eventmask = chEvtWaitOneTimeout(ALL_EVENTS, chTimeUS2I(AMIROOS_CFG_MAIN_LOOP_TIMEOUT));
642
#else /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0) */
643
    eventmask = chEvtWaitOne(ALL_EVENTS);
644
#endif /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0) */
645

    
646
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
647
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
648
    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
649
#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
650
    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
651
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
652
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1) */
653

    
654
    switch (eventmask) {
655
      // if this was an GPIO event
656
      case EVENTMASK_GPIO:
657
        // evaluate flags
658
        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
659
#if (AMIROOS_CFG_SSSP_ENABLE == true)
660
        // PD event
661
        if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
662
          aosSsspShutdownInit();
663
          shutdown = AOS_SHUTDOWN_PASSIVE;
664
        }
665
        // all other events
666
#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
667
        else {
668
          MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
669
        }
670
#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
671
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
672
#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
673
        MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
674
#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
675
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
676
        break;
677

    
678
      // if this was an OS event
679
      case EVENTMASK_OS:
680
        // evaluate flags
681
        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
682
        switch (eventflags) {
683
#if (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_NONE)
684
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_MASK:
685
            shutdown = AOS_SHUTDOWN_ACTIVE;
686
            break;
687
#elif (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_AMiRoBLT)
688
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_HIBERNATE:
689
            shutdown = AOS_SHUTDOWN_HIBERNATE;
690
            break;
691
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_DEEPSLEEP:
692
            shutdown = AOS_SHUTDOWN_DEEPSLEEP;
693
            break;
694
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_TRANSPORTATION:
695
            shutdown = AOS_SHUTDOWN_TRANSPORTATION;
696
            break;
697
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_RESTART:
698
            shutdown = AOS_SHUTDOWN_RESTART;
699
            break;
700
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_PASSIVE:
701
            _unexpectedEventError(eventmask, eventflags);
702
            break;
703
#endif /* (AMIROOS_CFG_BOOTLOADER == X) */
704
          default:
705
            _unexpectedEventError(eventmask, eventflags);
706
            break;
707
        }
708
        break;
709

    
710
      // if this was any other event (should be impossible to occur)
711
      default:
712
        eventflags = 0;
713
#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT == 0)
714
        _unexpectedEventError(eventmask, eventflags);
715
#endif /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT == 0) */
716
        break;
717
    }
718

    
719
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2)
720
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS)
721
    AMIROOS_CFG_MAIN_LOOP_HOOK_2(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS);
722
#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS) */
723
    AMIROOS_CFG_MAIN_LOOP_HOOK_2();
724
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS) */
725
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2) */
726
  }
727

    
728
  /*
729
   * ##########################################################################
730
   * # system shutdown                                                        #
731
   * ##########################################################################
732
   */
733

    
734
  aosDbgAssert(shutdown != AOS_SHUTDOWN_NONE);
735

    
736
  // initialize/acknowledge shutdown
737
  aosSysShutdownInit(shutdown);
738
#if (AMIROOS_CFG_SSSP_ENABLE == true)
739
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_1_2);
740
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
741

    
742
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1)
743
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS)
744
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS);
745
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
746
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1();
747
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
748
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1) */
749

    
750
  // wait for all threads to terminate
751
  aosSysStop();
752

    
753
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2)
754
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS)
755
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS);
756
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
757
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2();
758
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
759
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2) */
760

    
761
  // deinitialize system
762
  aosSysDeinit();
763

    
764
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3)
765
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS)
766
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS);
767
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
768
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3();
769
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
770
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3) */
771

    
772
  /* stop all periphery communication interfaces */
773
#if defined(MODULE_SHUTDOWN_PERIPHERY_IF)
774
  MODULE_SHUTDOWN_PERIPHERY_IF();
775
#endif /* defined(MODULE_SHUTDOWN_PERIPHERY_IF) */
776

    
777
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4)
778
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS)
779
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS);
780
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
781
  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4();
782
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
783
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4) */
784

    
785
#if (AMIROOS_CFG_SSSP_ENABLE == true)
786

    
787
  // proceed to SSSP shutdown stage 1.3
788
  aosSsspProceed(NULL, 0, 0, NULL);
789
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_1_3);
790

    
791
#if (AMIROOS_CFG_SSSP_SHUTDOWN == true)
792

    
793
  /* AMiRo-OS performs SSSP shutdown phase
794
   * NOTE:
795
   * The initiating module could deactivate PD at this point to indicate a restart rather than a shutdown request.
796
   * AMiRo-OS does not support restart though, thus the signal is not changed.
797
   */
798

    
799
  // proceed to SSSP shutdown stage 2.1
800
  while (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS) {
801
    /*
802
     * This code is executed if the received event was not about a deactivation of the synchronization signal.
803
     * The received event could be caused by any listener.
804
     */
805
    // GPIO event
806
    if (eventmask & _eventListenerGPIO.events) {
807
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
808
#if defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK)
809
        MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
810
#else /* defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK) */
811
        /* silently ignore any other GPIO events */
812
#endif /* defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK) */
813
    }
814
    // OS event
815
    else if (eventmask & _eventListenerOS.events) {
816
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
817
      _unexpectedEventError(eventmask, eventflags);
818
    }
819
    // unknown event
820
    else {
821
      _unexpectedEventError(eventmask, 0);
822
    }
823
  }
824
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_1);
825

    
826
  // proceed to SSSP shutdown stage 2.2
827
  aosSsspProceed(NULL, 0, 0, &eventmask);
828
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_2);
829
  if (shutdown == AOS_SHUTDOWN_PASSIVE) {
830
    aosDbgPrintf("%s request received\n", eventmask ? "shutdown" : "restart");
831
  }
832
  /* NOTE:
833
   * Actually the call of aosSsspProceed() returned an indicator, whether a shutdown or restart has been initiated.
834
   * Since AMiRo-OS does not support restart, this return value is ignored and shutdown is assumed.
835
   */
836

    
837
  // the initiating module broadcasts the shutdown identifier
838
  if (shutdown != AOS_SHUTDOWN_PASSIVE) {
839
    // since AMiRo-OS does not support multiple ways to shutdown or restart, the special identifier 0 is broadcasted.
840
    aosSsspShutdownBroadcastIdentifier(0);
841
  }
842
  // passive modules receive the broadcasted identifier
843
  else {
844
    unsigned int identifier = 0;
845

    
846
    // receive the identifier, which specifies the type of shutdown/restart
847
    while ((eventmask = aosSsspShutdownWaitForIdentifierPulse(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_SSSPTIMER, &identifier)) != EVENTMASK_SSSPTIMER) {
848
      // GPIO event
849
      if (eventmask & _eventListenerGPIO.events) {
850
        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
851
#if defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK)
852
        MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK(eventmask, eventflags);
853
#else /* defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK) */
854
        /* silently ignore any other GPIO events */
855
#endif /* defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK) */
856
        /* silently ignore any GPIO events */
857
      }
858
      // OS event
859
      else if (eventmask & _eventListenerOS.events) {
860
        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
861
        _unexpectedEventError(eventmask, eventflags);
862
      }
863
      // unknown event
864
      else {
865
        _unexpectedEventError(eventmask, 0);
866
      }
867
    }
868

    
869
    // Since AMiRo-OS does not support multiple ways to shutdown or restart, the identifier is ignored.
870
  }
871

    
872
  // proceed to SSSP shutdown stage 2.3
873
  aosSsspProceed(NULL, 0, 0, NULL);
874
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_3);
875

    
876
  /*
877
   * Since AMiRo-OS does only support one basic shutdown and no restart at all, the final shutdown is kept very simple.
878
   */
879

    
880
  // disable interrupts
881
  irqDeinit();
882
  chSysDisable();
883

    
884
  chThdExit(MSG_OK);
885
  return MSG_OK;
886

    
887
#else /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
888

    
889
  /* hand over to the bootloader to perform SSSP shutdown phase */
890
  aosSysShutdownToBootloader(shutdown);
891

    
892
  aosDbgAssertMsg(false, "AMiRo-OS must not proceed to this point!");
893
  chThdExit(MSG_RESET);
894
  return MSG_RESET;
895

    
896
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
897

    
898
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
899

    
900
  /*
901
   * Depending on the configured bootloader, trivial shutdown is either executed by AMiRo-OS or by that bootloader.
902
   */
903
#if (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_NONE)
904

    
905
  /* AMiRo-OS performs trivial shutdown */
906

    
907
  // disable interrupts
908
  irqDeinit();
909
  chSysDisable();
910

    
911
  chThdExit(MSG_OK);
912
  return MSG_OK;
913

    
914
#elif (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_AMiRoBLT)
915

    
916
  /* AMiRo-BLT performns shutdown */
917
  aosSysShutdownToBootloader(shutdown);
918

    
919
  aosDbgAssertMsg(false, "AMiRo-OS must not proceed to this point!");
920
  chThdExit(MSG_RESET);
921
  return MSG_RESET;
922

    
923
#endif /* (AMIROOS_CFG_BOOTLOADER == X) */
924
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
925
}
926

    
927
/******************************************************************************/
928
/* EXPORTED FUNCTIONS                                                         */
929
/******************************************************************************/
930

    
931
/** @} */