Statistics
| Branch: | Tag: | Revision:

amiro-os / os / core / src / main.c @ e545e620

History | View | Annotate | Download (12.703 KB)

1 e545e620 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  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
#include <hal.h>
20
#include <ch.h>
21
#include <amiroos.h>
22
23
/**
24
 * @brief   Event mask to identify I/O events.
25
 */
26
#define IOEVENT_MASK                            EVENT_MASK(0)
27
28
/**
29
 * @brief   Event mask to identify OS events.
30
 */
31
#define OSEVENT_MASK                            EVENT_MASK(1)
32
33
/**
34
 * @brief   Listener object for I/O events.
35
 */
36
static event_listener_t _eventListenerIO;
37
38
/**
39
 * @brief   Listener object for OS events.
40
 */
41
static event_listener_t _eventListenerOS;
42
43
#if defined(MODULE_HAL_PROGIF) || defined(__DOXYGEN__)
44
/**
45
 * @brief   SSM output for the programmer interface.
46
 */
47
static ssm_output_t _ssmProgIfOutput;
48
#endif
49
50
/**
51
 * @brief   Prints an error message about an unexpected event.
52
 *
53
 * @param[in] mask    The event mask.
54
 * @param[in] flags   The event flags.
55
 */
56
static inline void _unexpectedEventError(eventmask_t mask, eventflags_t flags)
57
{
58
  aosprintf("unexpected/unknown event recieved. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
59
  return;
60
}
61
62
/**
63
 * @brief   Application entry point.
64
 */
65
int main(void)
66
{
67
  // local variables
68
  eventmask_t eventmask = 0;
69
  eventflags_t eventflags = 0;
70
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
71
#if defined(AMIROOS_CFG_MAIN_EXTRA_VARIABLES)
72
  AMIROOS_CFG_MAIN_EXTRA_VARIABLES
73
#endif
74
75
  /*
76
   * ##########################################################################
77
   * # system initialization                                                  #
78
   * ##########################################################################
79
   */
80
81
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0)
82
  AMIROOS_CFG_MAIN_INIT_HOOK_0();
83
#endif
84
85
  /* hardware, kernel, and operating system initialization */
86
  // ChibiOS/HAL and custom hal additions (if any)
87
  halInit();
88
#ifdef MODULE_INIT_HAL_EXTRA
89
  MODULE_INIT_HAL_EXTRA();
90
#endif
91
92
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
93
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
94
  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
95
#else
96
  AMIROOS_CFG_MAIN_INIT_HOOK_1();
97
#endif
98
#endif
99
100
  // ChibiOS/RT kernel and custom kernel additions (if any)
101
  chSysInit();
102
#ifdef MODULE_INIT_KERNEL_EXTRA
103
  MODULE_INIT_KERNEL_EXTRA();
104
#endif
105
106
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
107
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
108
  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
109
#else
110
  AMIROOS_CFG_MAIN_INIT_HOOK_2();
111
#endif
112
#endif
113
114
  // AMiRo-OS and custom OS additions (if any)
115
  aosSysInit(&MODULE_HAL_EXT,
116
             &moduleHalExtConfig,
117
             &moduleSsspPd,
118
             &moduleSsspSync,
119
             MODULE_OS_IOEVENTFLAGS_SYSPD,
120
             MODULE_OS_IOEVENTFLAGS_SYSSYNC,
121
             moduleShellPrompt);
122
#ifdef MODULE_INIT_OS_EXTRA
123
  MODULE_INIT_OS_EXTRA();
124
#endif
125
126
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
127
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
128
  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
129
#else
130
  AMIROOS_CFG_MAIN_INIT_HOOK_3();
131
#endif
132
#endif
133
134
#if (AMIROOS_CFG_TESTS_ENABLE == true)
135
#if defined(MODULE_INIT_TESTS)
136
  MODULE_INIT_TESTS();
137
#else
138
  #warning "MODULE_INIT_TESTS no defined"
139
#endif
140
#endif
141
142
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
143
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
144
  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
145
#else
146
  AMIROOS_CFG_MAIN_INIT_HOOK_4();
147
#endif
148
#endif
149
150
  /* event associations */
151
  chEvtRegisterMask(&aos.events.io.source, &_eventListenerIO, IOEVENT_MASK);
152
  chEvtRegisterMask(&aos.events.os.source, &_eventListenerOS, OSEVENT_MASK);
153
154
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
155
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
156
  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
157
#else
158
  AMIROOS_CFG_MAIN_INIT_HOOK_5();
159
#endif
160
#endif
161
162
  /* periphery communication initialization */
163
  // CAN (mandatory)
164
  canStart(&MODULE_HAL_CAN, &moduleHalCanConfig);
165
  // module specific initialization (if any)
166
#ifdef MODULE_INIT_PERIPHERY_COMM
167
  MODULE_INIT_PERIPHERY_COMM();
168
#endif
169
  // user interface (if any)
170
#ifdef MODULE_HAL_PROGIF
171
  ssmOutputInit(&_ssmProgIfOutput, (BaseSequentialStream*)&MODULE_HAL_PROGIF);
172
  ssmAddOutput(aos.ssm, &_ssmProgIfOutput);
173
  ssmEnableOutput(aos.ssm, _ssmProgIfOutput.stream);
174
  ssmSetInput(aos.ssm, (BaseSequentialStream*)&MODULE_HAL_PROGIF);
175
#endif
176
177
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6)
178
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS)
179
  AMIROOS_CFG_MAIN_INIT_HOOK_6(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS);
180
#else
181
  AMIROOS_CFG_MAIN_INIT_HOOK_6();
182
#endif
183
#endif
184
185
  /* module is ready -> print welcome prompt */
186
  aosprintf("\n");
187
  aosprintf("######################################################################\n");
188
  aosprintf("# AMiRo-OS is an operating system designed for the Autonomous Mini   #\n");
189
  aosprintf("# Robot (AMiRo) platform.                                            #\n");
190
  aosprintf("# Copyright (C) 2016..2018  Thomas Schöpping et al.                  #\n");
191
  aosprintf("#                                                                    #\n");
192
  aosprintf("# This is free software; see the source for copying conditions.      #\n");
193
  aosprintf("# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n");
194
  aosprintf("# A PARTICULAR PURPOSE.                                              #\n");
195
  aosprintf("# The development of this software was supported by the Excellence   #\n");
196
  aosprintf("# Cluster EXC 227 Cognitive Interaction Technology. The Excellence   #\n");
197
  aosprintf("# Cluster EXC 227 is a grant of the Deutsche Forschungsgemeinschaft  #\n");
198
  aosprintf("# (DFG) in the context of the German Excellence Initiative.          #\n");
199
  aosprintf("######################################################################\n");
200
  aosprintf("\n");
201
202
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7)
203
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS)
204
  AMIROOS_CFG_MAIN_INIT_HOOK_7(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS);
205
#else
206
  AMIROOS_CFG_MAIN_INIT_HOOK_7();
207
#endif
208
#endif
209
210
  /* SSSP startup outro (end of startup stage 2) synchronization */
211
  while ((eventmask = aosSysSsspStartupOsInitSyncCheck(&_eventListenerIO)) != 0) {
212
    /*
213
     * This code is executed if the received event was not about the SYS_SYNC control signal.
214
     * The returned event could be caused by any listener (not only the argument).
215
     */
216
    // unexpected IO events
217
    if (eventmask & _eventListenerIO.events) {
218
      eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
219
#ifdef MODULE_SSP_STARTUP_OUTRO_IO_EVENT
220
      MODULE_SSP_STARTUP_OUTRO_IO_EVENT(eventmask, eventflags);
221
#else
222
      _unexpectedEventError(eventmask, eventflags);
223
#endif
224
    }
225
    // unexpected OS event
226
    else if (eventmask & _eventListenerOS.events) {
227
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
228
      _unexpectedEventError(eventmask, eventflags);
229
    }
230
#if (AMIROOS_CFG_DBG == true)
231
    // unknown event (must never occur, thus disabled for release builds)
232
    else {
233
      eventflags = 0;
234
      _unexpectedEventError(eventmask, eventflags);
235
    }
236
#endif
237
  }
238
239
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
240
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS)
241
  AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
242
#else
243
  AMIROOS_CFG_MAIN_INIT_HOOK_8();
244
#endif
245
#endif
246
247
  /* completely start AMiRo-OS */
248
  aosSysStart();
249
250
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9)
251
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS)
252
  AMIROOS_CFG_MAIN_INIT_HOOK_9(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS);
253
#else
254
  AMIROOS_CFG_MAIN_INIT_HOOK_9();
255
#endif
256
#endif
257
258
  /*
259
   * ##########################################################################
260
   * # infinite loop                                                          #
261
   * ##########################################################################
262
   */
263
264
  // sleep until a shutdown event is received
265
  while (shutdown == AOS_SHUTDOWN_NONE) {
266
    // wait for an event
267
#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0)
268
    eventmask = chEvtWaitOneTimeout(ALL_EVENTS, US2ST_LLD(AMIROOS_CFG_MAIN_LOOP_TIMEOUT));
269
#else
270
    eventmask = chEvtWaitOne(ALL_EVENTS);
271
#endif
272
273
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0)
274
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS)
275
    AMIROOS_CFG_MAIN_LOOP_HOOK_0(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS);
276
#else
277
    AMIROOS_CFG_MAIN_LOOP_HOOK_0();
278
#endif
279
#endif
280
281
    switch (eventmask) {
282
      // if this was an I/O event
283
      case IOEVENT_MASK:
284
        // evaluate flags
285
        eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
286
        // PD event
287
        if (eventflags & MODULE_OS_IOEVENTFLAGS_SYSPD) {
288
          shutdown = AOS_SHUTDOWN_PASSIVE;
289
        }
290
        // all other events
291
#ifdef MODULE_MAIN_LOOP_IO_EVENT
292
        else {
293
          MODULE_MAIN_LOOP_IO_EVENT(eventmask, eventflags);
294
        }
295
#endif
296
        break;
297
298
      // if this was an OS event
299
      case OSEVENT_MASK:
300
        // evaluate flags
301
        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
302
        switch (eventflags) {
303
          case AOS_SYSTEM_EVENTFLAGS_HIBERNATE:
304
            shutdown = AOS_SHUTDOWN_HIBERNATE;
305
            break;
306
          case AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP:
307
            shutdown = AOS_SHUTDOWN_DEEPSLEEP;
308
            break;
309
          case AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION:
310
            shutdown = AOS_SHUTDOWN_TRANSPORTATION;
311
            break;
312
          case AOS_SYSTEM_EVENTFLAGS_RESTART:
313
            shutdown = AOS_SHUTDOWN_RESTART;
314
            break;
315
          default:
316
            _unexpectedEventError(eventmask, eventflags);
317
            break;
318
        }
319
        break;
320
321
      // if this was any other event (should be impossible to occur)
322
      default:
323
        eventflags = 0;
324
        _unexpectedEventError(eventmask, eventflags);
325
        break;
326
    }
327
328
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
329
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
330
    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
331
#else
332
    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
333
#endif
334
#endif
335
  }
336
337
  /*
338
   * ##########################################################################
339
   * # system shutdown                                                        #
340
   * ##########################################################################
341
   */
342
343
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0)
344
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS)
345
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS);
346
#else
347
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0();
348
#endif
349
#endif
350
351
  // initialize/acknowledge shutdown
352
  aosSysShutdownInit(shutdown);
353
354
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1)
355
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS)
356
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS);
357
#else
358
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1();
359
#endif
360
#endif
361
362
  // stop system threads
363
  aosSysStop();
364
365
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2)
366
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS)
367
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS);
368
#else
369
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2();
370
#endif
371
#endif
372
373
  // deinitialize system
374
  aosSysDeinit();
375
376
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3)
377
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS)
378
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS);
379
#else
380
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3();
381
#endif
382
#endif
383
384
  /* stop all periphery communication */
385
  // CAN (mandatory)
386
  canStop(&MODULE_HAL_CAN);
387
#ifdef MODULE_SHUTDOWN_PERIPHERY_COMM
388
  MODULE_SHUTDOWN_PERIPHERY_COMM();
389
#endif
390
391
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4)
392
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS)
393
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS);
394
#else
395
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4();
396
#endif
397
#endif
398
399
  // finally hand over to bootloader
400
  aosSysShutdownFinal(&MODULE_HAL_EXT, shutdown);
401
402
  /*
403
   * ##########################################################################
404
   * # after shutdown/restart                                                 #
405
   * ##########################################################################
406
   *
407
   * NOTE: This code will not be executed, since the bootloader callbacks will stop/restart the MCU.
408
   *       It is included nevertheless for the sake of completeness and to explicitely indicate,
409
   *       which subsystems should NOT be shut down.
410
   */
411
412
  // return an error, since this code should not be executed
413
  return -1;
414
}