Revision 933df08e

View differences:

modules/DiWheelDrive_1-1/aosconf.h
99 99
#endif
100 100

  
101 101
/**
102
 * @brief   Flag to set the module to be the first in the stack.
103
 * @details There must be only one module with this flag set to true in a system.
104
 */
105
#if !defined(OS_CFG_SSSP_STACK_START)
106
  #define AMIROOS_CFG_SSSP_STACK_START          true
107
#else
108
  #define AMIROOS_CFG_SSSP_STACK_START          OS_CFG_SSSP_STACK_START
109
#endif
110

  
111
/**
112
 * @brief   Flag to set the module to be the last in the stack.
113
 * @details There must be only one module with this flag set to true in a system.
114
 */
115
#if !defined(OS_CFG_SSSP_STACK_END)
116
  #define AMIROOS_CFG_SSSP_STACK_END            false
117
#else
118
  #define AMIROOS_CFG_SSSP_STACK_END            OS_CFG_SSSP_STACK_END
119
#endif
120

  
121
/**
122
 * @brief   Delay time (in microseconds) how long a SSSP signal must be active.
123
 */
124
#if !defined(OS_CFG_SSSP_SIGNALDELAY)
125
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          1000
126
#else
127
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          OS_CFG_SSSP_SIGNALDELAY
128
#endif
129

  
130
/**
102 131
 * @brief   Time boundary for robot wide clock synchronization in microseconds.
103 132
 * @details Whenever the SSSP S (snychronization) signal gets logically deactivated,
104 133
 *          All modules need to align their local uptime to the nearest multiple of this value.
......
121 150
/**
122 151
 * @brief   Shell enable flag.
123 152
 */
124
#if (AMIROOS_CFG_TESTS_ENABLE == false) && !defined(OS_CFG_SHELL_ENABLE)
153
#if (AMIROOS_CFG_TESTS_ENABLE != true) && !defined(OS_CFG_SHELL_ENABLE)
125 154
  #define AMIROOS_CFG_SHELL_ENABLE              true
126 155
#elif (AMIROOS_CFG_TESTS_ENABLE == true)
127 156
  #define AMIROOS_CFG_SHELL_ENABLE              true
modules/DiWheelDrive_1-1/board.h
260 260
 * PA9  - PROG_RX                   (alternate pushpull 50MHz)
261 261
 * PA10 - PROG_TX                   (input pullup)
262 262
 * PA11 - CAN_RX                    (input pullup)
263
 * PA12 - CAN_TX                    (input floating)
263
 * PA12 - CAN_TX                    (alternate pushpull 50MHz)
264 264
 * PA13 - SWDIO                     (input pullup)
265 265
 * PA14 - SWCLK                     (input pullup)
266 266
 * PA15 - DRIVE_PWM2B               (alternate pushpull 50MHz)
......
277 277
                                     PIN_CR(GPIOA_PROG_RX, PIN_MODE_OUTPUT_50M, PIN_CNF_ALTERNATE_PUSHPULL) |      \
278 278
                                     PIN_CR(GPIOA_PROG_TX, PIN_MODE_INPUT, PIN_CNF_INPUT_PULLX) |                  \
279 279
                                     PIN_CR(GPIOA_CAN_RX, PIN_MODE_INPUT, PIN_CNF_INPUT_PULLX) |                   \
280
                                     PIN_CR(GPIOA_CAN_TX, PIN_MODE_INPUT, PIN_CNF_INPUT_FLOATING) |                \
280
                                     PIN_CR(GPIOA_CAN_TX, PIN_MODE_OUTPUT_50M, PIN_CNF_ALTERNATE_PUSHPULL) |       \
281 281
                                     PIN_CR(GPIOA_SWDIO, PIN_MODE_INPUT, PIN_CNF_INPUT_PULLX) |                    \
282 282
                                     PIN_CR(GPIOA_SWCLK, PIN_MODE_INPUT, PIN_CNF_INPUT_PULLX) |                    \
283 283
                                     PIN_CR(GPIOA_DRIVE_PWM2B, PIN_MODE_OUTPUT_50M, PIN_CNF_ALTERNATE_PUSHPULL))
modules/DiWheelDrive_1-1/module.c
310 310
 */
311 311
/*===========================================================================*/
312 312

  
313

  
314 313
apalControlGpio_t moduleSsspGpioPd = {
315 314
  /* GPIO */ &moduleGpioSysPd,
316 315
  /* meta */ {
......
329 328
  },
330 329
};
331 330

  
331
apalControlGpio_t moduleSsspGpioUp = {
332
  /* GPIO */ &moduleGpioSysUartUp,
333
  /* meta */ {
334
    /* active state */ APAL_GPIO_ACTIVE_LOW,
335
    /* edge         */ APAL_GPIO_EDGE_FALLING,
336
    /* direction    */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
337
  },
338
};
339

  
332 340
/** @} */
333 341

  
334 342
/*===========================================================================*/
modules/DiWheelDrive_1-1/module.h
437 437
extern apalControlGpio_t moduleSsspGpioSync;
438 438

  
439 439
/**
440
 * @brief   UP signal GPIO.
441
 */
442
extern apalControlGpio_t moduleSsspGpioUp;
443

  
444
/**
440 445
 * @brief   Event flags for PD signal events.
441 446
 */
442 447
#define MODULE_SSSP_EVENTFLAGS_PD               MODULE_OS_IOEVENTFLAGS_SYSPD
443 448

  
444 449
/**
445
 * @brief   Event flags for Sync signal events.
450
 * @brief   Event flags for SYNC signal events.
446 451
 */
447 452
#define MODULE_SSSP_EVENTFLAGS_SYNC             MODULE_OS_IOEVENTFLAGS_SYSSYNC
448 453

  
449 454
/**
455
 * @brief   Event flags for UP signal events.
456
 */
457
#define MODULE_SSSP_EVENTFLAGS_UP               MODULE_OS_IOEVENTFLAGS_SYSUARTUP
458

  
459
/**
450 460
 * @brief   Hook to handle IO events during SSSP startup synchronization.
451 461
 */
452
#define MODULE_SSSP_STARTUP_OSINIT_OUTRO_IOEVENT_HOOK(mask, flags) {          \
462
#define MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(mask, flags) {                   \
453 463
  /* ignore all events */                                                     \
454 464
  (void)mask;                                                                 \
455 465
  (void)flags;                                                                \
modules/LightRing_1-0/aosconf.h
99 99
#endif
100 100

  
101 101
/**
102
 * @brief   Flag to set the module to be the first in the stack.
103
 * @details There must be only one module with this flag set to true in a system.
104
 */
105
#if !defined(OS_CFG_SSSP_STACK_START)
106
  #define AMIROOS_CFG_SSSP_STACK_START          false
107
#else
108
  #define AMIROOS_CFG_SSSP_STACK_START          OS_CFG_SSSP_STACK_START
109
#endif
110

  
111
/**
112
 * @brief   Flag to set the module to be the last in the stack.
113
 * @details There must be only one module with this flag set to true in a system.
114
 */
115
#if !defined(OS_CFG_SSSP_STACK_END)
116
  #define AMIROOS_CFG_SSSP_STACK_END            true
117
#else
118
  #define AMIROOS_CFG_SSSP_STACK_END            OS_CFG_SSSP_STACK_END
119
#endif
120

  
121
/**
122
 * @brief   Delay time (in microseconds) how long a SSSP signal must be active.
123
 */
124
#if !defined(OS_CFG_SSSP_SIGNALDELAY)
125
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          1000
126
#else
127
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          OS_CFG_SSSP_SIGNALDELAY
128
#endif
129

  
130
/**
102 131
 * @brief   Time boundary for robot wide clock synchronization in microseconds.
103 132
 * @details Whenever the SSSP S (snychronization) signal gets logically deactivated,
104 133
 *          All modules need to align their local uptime to the nearest multiple of this value.
......
121 150
/**
122 151
 * @brief   Shell enable flag.
123 152
 */
124
#if (AMIROOS_CFG_TESTS_ENABLE == false) && !defined(OS_CFG_SHELL_ENABLE)
153
#if (AMIROOS_CFG_TESTS_ENABLE != true) && !defined(OS_CFG_SHELL_ENABLE)
125 154
  #define AMIROOS_CFG_SHELL_ENABLE              true
126 155
#elif (AMIROOS_CFG_TESTS_ENABLE == true)
127 156
  #define AMIROOS_CFG_SHELL_ENABLE              true
modules/LightRing_1-0/module.c
250 250
  },
251 251
};
252 252

  
253
apalControlGpio_t moduleSsspGpioDn = {
254
  /* GPIO */ &moduleGpioSysUartDn,
255
  /* meta */ {
256
    /* active state */ APAL_GPIO_ACTIVE_LOW,
257
    /* edge         */ APAL_GPIO_EDGE_FALLING,
258
    /* direction    */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
259
  },
260
};
261

  
253 262
/** @} */
254 263

  
255 264
/*===========================================================================*/
modules/LightRing_1-0/module.h
277 277
extern apalControlGpio_t moduleSsspGpioSync;
278 278

  
279 279
/**
280
 * @brief   DN signal GPIO.
281
 */
282
extern apalControlGpio_t moduleSsspGpioDn;
283

  
284
/**
280 285
 * @brief   Event flags for PD signal events.
281 286
 */
282 287
#define MODULE_SSSP_EVENTFLAGS_PD               MODULE_OS_IOEVENTFLAGS_SYSPD
283 288

  
284 289
/**
285
 * @brief   Event flags for Sync signal events.
290
 * @brief   Event flags for SYNC signal events.
286 291
 */
287 292
#define MODULE_SSSP_EVENTFLAGS_SYNC             MODULE_OS_IOEVENTFLAGS_SYSSYNC
288 293

  
289 294
/**
295
 * @brief   Event flags for DN signal events.
296
 */
297
#define MODULE_SSSP_EVENTFLAGS_DN               MODULE_OS_IOEVENTFLAGS_SYSUARTDN
298

  
299
/**
290 300
 * @brief   Hook to handle IO events during SSSP startup synchronization.
291 301
 */
292
#define MODULE_SSSP_STARTUP_OSINIT_OUTRO_IOEVENT_HOOK(mask, flags) {          \
302
#define MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(mask, flags) {                   \
293 303
  /* ignore all events */                                                     \
294 304
  (void)mask;                                                                 \
295 305
  (void)flags;                                                                \
modules/PowerManagement_1-1/aosconf.h
99 99
#endif
100 100

  
101 101
/**
102
 * @brief   Flag to set the module to be the first in the stack.
103
 * @details There must be only one module with this flag set to true in a system.
104
 */
105
#if !defined(OS_CFG_SSSP_STACK_START)
106
  #define AMIROOS_CFG_SSSP_STACK_START          false
107
#else
108
  #define AMIROOS_CFG_SSSP_STACK_START          OS_CFG_SSSP_STACK_START
109
#endif
110

  
111
/**
112
 * @brief   Flag to set the module to be the last in the stack.
113
 * @details There must be only one module with this flag set to true in a system.
114
 */
115
#if !defined(OS_CFG_SSSP_STACK_END)
116
  #define AMIROOS_CFG_SSSP_STACK_END            false
117
#else
118
  #define AMIROOS_CFG_SSSP_STACK_END            OS_CFG_SSSP_STACK_END
119
#endif
120

  
121
/**
122
 * @brief   Delay time (in microseconds) how long a SSSP signal must be active.
123
 */
124
#if !defined(OS_CFG_SSSP_SIGNALDELAY)
125
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          1000
126
#else
127
  #define AMIROOS_CFG_SSSP_SIGNALDELAY          OS_CFG_SSSP_SIGNALDELAY
128
#endif
129

  
130
/**
102 131
 * @brief   Time boundary for robot wide clock synchronization in microseconds.
103 132
 * @details Whenever the SSSP S (snychronization) signal gets logically deactivated,
104 133
 *          All modules need to align their local uptime to the nearest multiple of this value.
......
121 150
/**
122 151
 * @brief   Shell enable flag.
123 152
 */
124
#if (AMIROOS_CFG_TESTS_ENABLE == false) && !defined(OS_CFG_SHELL_ENABLE)
153
#if (AMIROOS_CFG_TESTS_ENABLE != true) && !defined(OS_CFG_SHELL_ENABLE)
125 154
  #define AMIROOS_CFG_SHELL_ENABLE              true
126 155
#elif (AMIROOS_CFG_TESTS_ENABLE == true)
127 156
  #define AMIROOS_CFG_SHELL_ENABLE              true
modules/PowerManagement_1-1/board.h
323 323
 * PA9  - PROG_RX                       (alternate 7 pushpull floating)
324 324
 * PA10 - PROG_TX                       (alternate 7 pushpull pullup)
325 325
 * PA11 - CAN_RX                        (alternate 9 pushpull floating)
326
 * PA12 - CAN_TX                        (input floating)
326
 * PA12 - CAN_TX                        (alternate 9 pushpull floating)
327 327
 * PA13 - SWDIO                         (alternate 0 pushpull floating)
328 328
 * PA14 - SWCLK                         (alternate 0 pushpull floating)
329 329
 * PA15 - SYS_SPI_SS1_N                 (input floating)
......
340 340
                                         PIN_MODE_ALTERNATE(GPIOA_PROG_RX) |                          \
341 341
                                         PIN_MODE_ALTERNATE(GPIOA_PROG_TX) |                          \
342 342
                                         PIN_MODE_ALTERNATE(GPIOA_CAN_RX) |                           \
343
                                         PIN_MODE_INPUT(GPIOA_CAN_TX) |                               \
343
                                         PIN_MODE_ALTERNATE(GPIOA_CAN_TX) |                           \
344 344
                                         PIN_MODE_ALTERNATE(GPIOA_SWDIO) |                            \
345 345
                                         PIN_MODE_ALTERNATE(GPIOA_SWCLK) |                            \
346 346
                                         PIN_MODE_INPUT(GPIOA_SYS_SPI_SS1_N))
modules/PowerManagement_1-1/module.c
69 69

  
70 70
CANConfig moduleHalCanConfig = {
71 71
  /* mcr  */ CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
72
  /* btr  */ CAN_BTR_SJW(1) | CAN_BTR_TS2(2) | CAN_BTR_TS1(13) | CAN_BTR_BRP(1),
72
  /* btr  */ CAN_BTR_SJW(1) | CAN_BTR_TS2(3) | CAN_BTR_TS1(15) | CAN_BTR_BRP(1),
73 73
};
74 74

  
75 75
EXTConfig moduleHalExtConfig = {
......
386 386
  },
387 387
};
388 388

  
389
apalControlGpio_t moduleSsspGpioDn = {
390
  /* GPIO */ &moduleGpioSysUartDn,
391
  /* meta */ {
392
    /* active state */ APAL_GPIO_ACTIVE_LOW,
393
    /* edge         */ APAL_GPIO_EDGE_FALLING,
394
    /* direction    */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
395
  },
396
};
397

  
398
apalControlGpio_t moduleSsspGpioUp = {
399
  /* GPIO */ &moduleGpioSysUartUp,
400
  /* meta */ {
401
    /* active state */ APAL_GPIO_ACTIVE_LOW,
402
    /* edge         */ APAL_GPIO_EDGE_FALLING,
403
    /* direction    */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
404
  },
405
};
406

  
389 407
/** @} */
390 408

  
391 409
/*===========================================================================*/
modules/PowerManagement_1-1/module.h
514 514
extern apalControlGpio_t moduleSsspGpioSync;
515 515

  
516 516
/**
517
 * @brief   DN signal GPIO.
518
 */
519
extern apalControlGpio_t moduleSsspGpioDn;
520

  
521
/**
522
 * @brief   UP signal GPIO.
523
 */
524
extern apalControlGpio_t moduleSsspGpioUp;
525

  
526
/**
517 527
 * @brief   Event flags for PD signal events.
518 528
 */
519 529
#define MODULE_SSSP_EVENTFLAGS_PD               MODULE_OS_IOEVENTFLAGS_SYSPD
520 530

  
521 531
/**
522
 * @brief   Event flags for Sync signal events.
532
 * @brief   Event flags for SYNC signal events.
523 533
 */
524 534
#define MODULE_SSSP_EVENTFLAGS_SYNC             MODULE_OS_IOEVENTFLAGS_SYSSYNC
525 535

  
526 536
/**
537
 * @brief   Event flags for UP signal events.
538
 */
539
#define MODULE_SSSP_EVENTFLAGS_UP               MODULE_OS_IOEVENTFLAGS_SYSUARTUP
540

  
541
/**
542
 * @brief   Event flags for DN signal events.
543
 */
544
#define MODULE_SSSP_EVENTFLAGS_DN               MODULE_OS_IOEVENTFLAGS_SYSUARTDN
545

  
546
/**
527 547
 * @brief   Hook to handle IO events during SSSP startup synchronization.
528 548
 */
529
#define MODULE_SSSP_STARTUP_OSINIT_OUTRO_IOEVENT_HOOK(mask, flags) {          \
549
#define MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(mask, flags) {                   \
530 550
  /* ignore all events */                                                     \
531 551
  (void)mask;                                                                 \
532 552
  (void)flags;                                                                \
os/core/inc/aos_confcheck.h
49 49
  #error "AMIROOS_CFG_SSSP_MASTER not defined in aosconf.h"
50 50
#endif
51 51

  
52
#ifndef AMIROOS_CFG_SSSP_STACK_START
53
  #error "AMIROOS_CFG_SSSP_STACK_START not defined in aosconf.h"
54
#endif
55

  
56
#ifndef AMIROOS_CFG_SSSP_STACK_END
57
  #error "AMIROOS_CFG_SSSP_STACK_END not defined in aosconf.h"
58
#endif
59

  
60
#if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
61
  #warning "AMIROOS_CFG_SSSP_STACK_START and AMIROOS_CFG_SSSP_STACK_END both enabled in aosconf.h"
62
  #if (AMIROOS_CFG_SSSP_MASTER != true)
63
    #error "AMIROOS_CFG_SSSP_MASTER must be enabled in this case"
64
  #endif
65
#endif
66

  
67
#ifndef AMIROOS_CFG_SSSP_SIGNALDELAY
68
  #error "AMIROOS_CFG_SSSP_SIGNALDELAY not defined in aosconf.h"
69
#endif
70

  
52 71
#ifndef AMIROOS_CFG_SSSP_SYSSYNCPERIOD
53 72
  #error "AMIROOS_CFG_SSSP_SYSSYNCPERIOD not defined in aosconf.h"
54 73
#endif
os/core/inc/aos_debug.h
54 54
  chDbgAssert(c, r);                                      \
55 55
}
56 56

  
57
/**
58
 * @brief   Printf function for messages only printed in debug builds.
59
 *
60
 * @param[in] fmt   Formatted string to print.
61
 */
62
#define aosDbgPrintf(fmt, ...)           chprintf((BaseSequentialStream*)&aos.iostream, fmt, ##__VA_ARGS__)
63

  
57 64
#else
58 65

  
59 66
#define aosDbgCheck(c) {                                  \
......
69 76
  (void)(r);                                              \
70 77
}
71 78

  
79
#define aosDbgPrintf(fmt, ...) {                          \
80
  (void)(fmt);                                            \
81
}
82

  
72 83
#endif
73 84

  
74 85
#ifdef __cplusplus
os/core/inc/aos_system.h
58 58
/**
59 59
 * @brief   Major version of the implemented SSSP.
60 60
 */
61
#define AOS_SYSTEM_SSSP_MAJOR                   1
61
#define AOS_SYSTEM_SSSP_VERSION_MAJOR           1
62 62

  
63 63
/**
64 64
 * @brief   Minor version of the implemented SSSP.
65 65
 */
66
#define AOS_SYSTEM_SSSP_MINOR                   3
66
#define AOS_SYSTEM_SSSP_VERSION_MINOR           4
67

  
68
/**
69
 * @brief   Timeout delay according to SSSP.
70
 * @details SSSP defines timeouts to be ten times longer than the signal delay time.
71
 */
72
#define AOS_SYSTEM_SSSP_TIMEOUT                 (10 * AMIROOS_CFG_SSSP_SIGNALDELAY)
67 73

  
68 74
/**
69 75
 * @brief   Enumerator to identify shutdown types.
......
78 84
} aos_shutdown_t;
79 85

  
80 86
/**
81
 * @brief   Enumerator of the several stages of SSSP
87
 * @brief   Enumerator of the several stages of SSSP.
82 88
 */
83 89
typedef enum aos_ssspstage {
84
  AOS_SSSP_STARTUP_1_1  = 0x0000, /**< Identifier of SSSP startup phase stage 1-1. */
85
  AOS_SSSP_STARTUP_1_2  = 0x0001, /**< Identifier of SSSP startup phase stage 1-2. */
86
  AOS_SSSP_STARTUP_1_3  = 0x0002, /**< Identifier of SSSP startup phase stage 1-3. */
87
  AOS_SSSP_STARTUP_2_1  = 0x0004, /**< Identifier of SSSP startup phase stage 2-1. */
88
  AOS_SSSP_STARTUP_2_2  = 0x0005, /**< Identifier of SSSP startup phase stage 2-2. */
89
  AOS_SSSP_STARTUP_3_1  = 0x0008, /**< Identifier of SSSP startup phase stage 3-1. */
90
  AOS_SSSP_STARTUP_3_2  = 0x0009, /**< Identifier of SSSP startup phase stage 3-2. */
91
  AOS_SSSP_STARTUP_3_3  = 0x000A, /**< Identifier of SSSP startup phase stage 3-3. */
92
  AOS_SSSP_STARTUP_3_4  = 0x000B, /**< Identifier of SSSP startup phase stage 3-4. */
93
  AOS_SSSP_OPERATION    = 0x0100, /**< Identifier of SSSP operation pahse. */
94
  AOS_SSSP_SHUTDOWN_1_1 = 0x0200, /**< Identifier of SSSP shutdown phase stage 1-1. */
95
  AOS_SSSP_SHUTDOWN_1_2 = 0x0201, /**< Identifier of SSSP shutdown phase stage 1-2. */
96
  AOS_SSSP_SHUTDOWN_1_3 = 0x0202, /**< Identifier of SSSP shutdown phase stage 1-3. */
97
  AOS_SSSP_SHUTDOWN_2_1 = 0x0204, /**< Identifier of SSSP shutdown phase stage 2-1. */
98
  AOS_SSSP_SHUTDOWN_2_2 = 0x0205, /**< Identifier of SSSP shutdown phase stage 2-2. */
99
  AOS_SSSP_SHUTDOWN_3   = 0x0208, /**< Identifier of SSSP shutdown phase stage 3. */
90
  AOS_SSSP_STARTUP_1_1  = 0x10, /**< Identifier of SSSP startup phase stage 1-1. */
91
  AOS_SSSP_STARTUP_1_2  = 0x11, /**< Identifier of SSSP startup phase stage 1-2. */
92
  AOS_SSSP_STARTUP_1_3  = 0x12, /**< Identifier of SSSP startup phase stage 1-3. */
93
  AOS_SSSP_STARTUP_2_1  = 0x14, /**< Identifier of SSSP startup phase stage 2-1. */
94
  AOS_SSSP_STARTUP_2_2  = 0x15, /**< Identifier of SSSP startup phase stage 2-2. */
95
  AOS_SSSP_STARTUP_3_1  = 0x18, /**< Identifier of SSSP startup phase stage 3-1. */
96
  AOS_SSSP_STARTUP_3_2  = 0x19, /**< Identifier of SSSP startup phase stage 3-2. */
97
  AOS_SSSP_STARTUP_3_3  = 0x1A, /**< Identifier of SSSP startup phase stage 3-3. */
98
  AOS_SSSP_STARTUP_3_4  = 0x1B, /**< Identifier of SSSP startup phase stage 3-4. */
99
  AOS_SSSP_OPERATION    = 0x20, /**< Identifier of SSSP operation pahse. */
100
  AOS_SSSP_SHUTDOWN_1_1 = 0x30, /**< Identifier of SSSP shutdown phase stage 1-1. */
101
  AOS_SSSP_SHUTDOWN_1_2 = 0x31, /**< Identifier of SSSP shutdown phase stage 1-2. */
102
  AOS_SSSP_SHUTDOWN_1_3 = 0x32, /**< Identifier of SSSP shutdown phase stage 1-3. */
103
  AOS_SSSP_SHUTDOWN_2_1 = 0x34, /**< Identifier of SSSP shutdown phase stage 2-1. */
104
  AOS_SSSP_SHUTDOWN_2_2 = 0x35, /**< Identifier of SSSP shutdown phase stage 2-2. */
105
  AOS_SSSP_SHUTDOWN_3   = 0x38, /**< Identifier of SSSP shutdown phase stage 3. */
100 106
} aos_ssspstage_t;
101 107

  
102 108
/**
109
 * @brief   Type to represent module IDs.
110
 */
111
typedef uint16_t aos_ssspmoduleid_t;
112

  
113
/**
103 114
 * @brief   AMiRo-OS base system structure.
104 115
 */
105 116
typedef struct aos_system {
......
112 123
     * @brief   Current SSSP stage of the system.
113 124
     */
114 125
    aos_ssspstage_t stage;
126

  
127
    /**
128
     * @brief   Module identifier.
129
     * @details A value of 0 indicates an uninitialized ID.
130
     *          The vlaues 0 and ~0 are reserved und must not be set.
131
     */
132
    aos_ssspmoduleid_t moduleId;
115 133
  } sssp;
116 134

  
117 135
  /**
......
151 169

  
152 170
/**
153 171
 * @brief   Printf function that uses the default system I/O stream.
172
 *
173
 * @param[in] fmt   Formatted string to print.
154 174
 */
155 175
#define aosprintf(fmt, ...)                     chprintf((BaseSequentialStream*)&aos.iostream, fmt, ##__VA_ARGS__)
156 176

  
os/core/src/aos_main.cpp
37 37
#define OSEVENT_MASK                            EVENT_MASK(1)
38 38

  
39 39
/**
40
 * @brief   Event mask to idetify CAN events.
41
 */
42
#define CANEVENT_MASK                           EVENT_MASK(2)
43

  
44
/**
45
 * @brief   Event mask to idetify timeout events.
46
 */
47
#define TIMEOUTEVENT_MASK                       EVENT_MASK(3)
48

  
49
/**
50
 * @brief   Event mask to idetify signal delay events.
51
 */
52
#define DELAYEVENT_MASK                         EVENT_MASK(4)
53

  
54
/**
55
 * @brief   CAN message identifier for initialization of the SSSP stack initialization sequence.
56
 */
57
#define SSSP_STACKINIT_CANMSGID_INIT            0x003
58

  
59
/**
60
 * @brief   CAN message identifier for transmitting module IDs during the SSSP stack initialization sequence.
61
 */
62
#define SSSP_STACKINIT_CANMSGID_MODULEID        0x002
63

  
64
/**
65
 * @brief   CAN message identifier for abortion of the SSSP stack initialization sequence.
66
 */
67
#define SSSP_STACKINIT_CANMSGID_ABORT           0x001
68

  
69
/**
40 70
 * @brief   Listener object for I/O events.
41 71
 */
42 72
static event_listener_t _eventListenerIO;
......
73 103
 * @param[in] mask    The event mask.
74 104
 * @param[in] flags   The event flags.
75 105
 */
76
static inline void _unexpectedEventError(eventmask_t mask, eventflags_t flags)
106
static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
77 107
{
78 108
#if (AMIROOS_CFG_DBG == true)
79 109
  aosprintf("unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
80 110
#else
81
  (void)mask;
82
  (void)flags;
111
  (void)(mask);
112
  (void)(flags);
83 113
#endif
114
}
115

  
116
/**
117
 * @brief   Callback function to be used during SSSP stack initialization sequence.
118
 *
119
 * @param[in] par   A pointer to an @p event_source_t to be fired.
120
 */
121
static void _ssspTimerCallback(void* par)
122
{
123
  aosDbgCheck(par != NULL);
124

  
125
  chSysLockFromISR();
126
  chEvtBroadcastI((event_source_t*)par);
127
  chSysUnlockFromISR();
128

  
84 129
  return;
85 130
}
86 131

  
87 132
/**
133
 * @brief   Helper function to serialize 32 bit data.
134
 *
135
 * @param[out]  dst   Pointer to the output buffer.
136
 * @param[in]   src   32 bit data to be serielized.
137
 */
138
inline void _canSerialize32(uint8_t* dst, const uint32_t src)
139
{
140
  aosDbgCheck(dst != NULL);
141

  
142
  for (uint8_t byte = 0; byte < 4; ++byte) {
143
    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
144
  }
145

  
146
  return;
147
}
148

  
149
/**
150
 * @brief   Helper function to deserialize 32 bit data.
151
 *
152
 * @param[in] src   Pointer to the buffer of data to be deserialzed.
153
 *
154
 * @return    The deserialized 32 bit data.
155
 */
156
inline uint32_t _canDeserialize32(uint8_t* src)
157
{
158
  aosDbgCheck(src != NULL);
159

  
160
  return ((uint32_t)src[0]) | (((uint32_t)src[1]) << 8) | (((uint32_t)src[2]) << 16) | (((uint32_t)src[3]) << 24);
161
}
162

  
163
/**
164
 * @brief   Implementation of the SSSP module stack initialization sequence (startup phase 3).
165
 *
166
 * @return Shutdown value.
167
 * @retval AOS_SHUTDOWN_NONE      No shutdown signal received
168
 * @retval AOS_SHUTDOWN_PASSIVE   Shutdown signal received.
169
 */
170
aos_shutdown_t _ssspModuleStackInitialization(void)
171
{
172
  // local types
173
  /**
174
   * @brief   States for the internal state machine to implement SSSP startup stage 3.
175
   */
176
  typedef enum {
177
    STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
178
    STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
179
    STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
180
    STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
181
    STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
182
    STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
183
    STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
184
    STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
185
  } sssp_modulestackinitstage_t;
186

  
187
  typedef struct {
188
    bool loop     : 1;
189
    bool wfe      : 1;
190
    bool wfe_next : 1;
191
  } flags_t;
192

  
193
  // local variables
194
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
195
  sssp_modulestackinitstage_t stage = STAGE_3_1;
196
  eventmask_t eventmask = 0;
197
  eventflags_t ioflags;
198
  event_source_t eventSourceTimeout;
199
  event_source_t eventSourceDelay;
200
  event_listener_t eventListenerTimeout;
201
  event_listener_t eventListenerDelay;
202
  event_listener_t eventListenerCan;
203
  virtual_timer_t timerTimeout;
204
  virtual_timer_t timerDelay;
205
  CANTxFrame canTxFrame;
206
  CANRxFrame canRxFrame;
207
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
208
  aos_ssspmoduleid_t lastid = 0;
209
#endif
210
  flags_t flags;
211

  
212
  // initialize local varibles
213
  chEvtObjectInit(&eventSourceTimeout);
214
  chEvtObjectInit(&eventSourceDelay);
215
  chVTObjectInit(&timerTimeout);
216
  chVTObjectInit(&timerDelay);
217
  canTxFrame.RTR = CAN_RTR_DATA;
218
  canTxFrame.IDE = CAN_IDE_STD;
219
  flags.loop = true;
220
  flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
221
  flags.wfe_next = true;
222

  
223
  // initialize system variables
224
  aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
225
  aos.sssp.moduleId = 0;
226

  
227
  // listen to events (timout, delay, CAN receive)
228
  chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
229
  chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
230
  chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
231

  
232
  /*
233
   * FSM in a loop.
234
   *
235
   * This is a fully event-based FSM for the module stack initialization
236
   * sequence, defined by SSSP as startup stage 3. There are five different
237
   * events that can occur at this point:
238
   *  I/O events: The input level of an input pin has changed. Such events must
239
   *              be handled differently depending on the current state. Most
240
   *              of the time, however, such events can be ignored.
241
   *  OS events:  Such events are only available after this stage completed and
242
   *              thus should never occur. However, there is an optional hook
243
   *              to handle such events, nevertheless.
244
   *  CAN events: At least one CAN message was received. Note that this event
245
   *              will only fire again if all input buffers have been cleared.
246
   *  timeouts:   If some module does not support the sequence of there is any
247
   *              issue, such a case is detected via timeouts and must be
248
   *              handled accordingly (see abort state). In some cases, it is
249
   *              possible that a timeout event occurres 'simultaneously' with
250
   *              some other event. This can be caused by several timing issues
251
   *              and is a valid situation. As a result, any other events
252
   *              should be handled before the timeout event. If the other
253
   *              events are expected and valid, this implementation requires
254
   *              the timeout event flag to be cleared explicitely. Otherwise
255
   *              it is evaluated at the end of each iteration of the loop.
256
   *  delays:     Depending on the current state, delays are required by SSSP
257
   *              for timing of the sequential activation of signals.
258
   */
259
  aosDbgPrintf("SSSP stack initialization sequence:\n");
260
  while (flags.loop) {
261
#if (AMIROOS_CFG_DBG == true)
262
    switch (stage) {
263
      case STAGE_3_1:
264
        aosDbgPrintf(">>> 3-1\n");
265
        break;
266
      case STAGE_3_2:
267
        aosDbgPrintf(">>> 3-2\n");
268
        break;
269
      case STAGE_3_3_WAITFORFIRSTID:
270
        aosDbgPrintf(">>> 3-3 (1st ID)\n");
271
        break;
272
      case STAGE_3_3_WAITFORIDORSIG:
273
        aosDbgPrintf(">>> 3-3 (ID/sig)\n");
274
        break;
275
      case STAGE_3_3_WAITFORID:
276
        aosDbgPrintf(">>> 3-3 (ID)\n");
277
        break;
278
      case STAGE_3_4_FINISH:
279
        aosDbgPrintf(">>> 3-4 (finish)\n");
280
        break;
281
      case STAGE_3_4_ABORT_ACTIVE:
282
        aosDbgPrintf(">>> 3-4 (avtive abort)\n");
283
        break;
284
      case STAGE_3_4_ABORT:
285
        aosDbgPrintf(">>> 3-4 (abort)\n");
286
        break;
287
    }
288
#endif
289

  
290
    // reset wfe flag for the next iteration
291
    flags.wfe_next = true;
292

  
293
    // waiting for events may be skipped
294
    if (flags.wfe) {
295
      // wait for any event to occur
296
      aosDbgPrintf("WFE...");
297
      eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT));
298
      aosDbgPrintf("\t0x%08X", eventmask);
299
    } else {
300
      aosDbgPrintf("WFE skipped");
301
    }
302
    aos_timestamp_t uptime;
303
    aosSysGetUptime(&uptime);
304
    aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / 1000));
305

  
306
    /*
307
     * execute some general tasks and high priority events
308
     */
309
    // no event occurred at all
310
    if ((flags.wfe) && (eventmask == 0)) {
311
      aosDbgPrintf("ERR: no evt\n");
312
      // enforce timeout event
313
      chEvtBroadcast(&eventSourceTimeout);
314
      continue;
315
    }
316
    // if an IO event occurred
317
    if (eventmask & IOEVENT_MASK) {
318
      ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
319
      aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
320
      // a power-down event occurred
321
      if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
322
        aosDbgPrintf("PD evt\n");
323
        // deactivate S and UP
324
        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
325
  #if (AMIROOS_CFG_SSSP_STACK_END != true)
326
        apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
327
  #endif
328
        // set shutdown flag and exit the loop
329
        shutdown = AOS_SHUTDOWN_PASSIVE;
330
        break;
331
      }
332
      // the S signal was deactivated
333
      if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
334
        apalControlGpioState_t sstate;
335
        apalControlGpioGet(&moduleSsspGpioSync, &sstate);
336
        if (sstate == APAL_GPIO_OFF) {
337
          aosDbgPrintf("-S evt\n");
338
          // either finish or abort
339
          if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
340
            stage = STAGE_3_4_FINISH;
341
          } else if (stage != STAGE_3_4_ABORT) {
342
            stage = STAGE_3_4_ABORT_ACTIVE;
343
          }
344
        }
345
      }
346
    }
347
    // an OS event occurred
348
    if (eventmask & OSEVENT_MASK) {
349
      aosDbgPrintf("WARN: OS evt\n");
350
      // get the flags
351
      eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
352
      // there should be no OS events at this point
353
#ifdef MODULE_SSSP_STARTUP_3_OSEVENT_HOOK
354
      MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
355
#else
356
      _unexpectedEventError(eventmask, oseventflags);
357
#endif
358
    }
359
    // if a CAN event occurred
360
    if ((eventmask & CANEVENT_MASK)) {
361
      // fetch message
362
      if (flags.wfe) {
363
        canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
364
        aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
365
      }
366
      // identify and handle abort messgaes
367
      if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
368
        stage = STAGE_3_4_ABORT;
369
      }
370
      // warn if a unexpected message was received
371
      else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
372
               (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
373
        aosDbgPrintf("WARN: unknown msg\n");
374
      }
375
      // any further pending messages are fetched at the end of the loop
376
    }
377
    // if a timeout event occurred
378
    if (eventmask & TIMEOUTEVENT_MASK) {
379
      // is handled at the end of the loop (or must be cleared by FSM)
380
    }
381
    // if a delay event occurred
382
    if (eventmask & DELAYEVENT_MASK) {
383
      // is handled by FSM
384
    }
385

  
386
    /*
387
     * this is the actual FSM
388
     */
389
    switch (stage) {
390
      case STAGE_3_1:
391
      {
392
        aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
393

  
394
        // there was no event at all (skipped wfe)
395
        if (eventmask == 0 && flags.wfe == false) {
396
#if (AMIROOS_CFG_SSSP_MASTER == true)
397
          // initialize the stage by transmitting an according CAN message
398
          aosDbgPrintf("CAN -> init\n");
399
          canTxFrame.DLC = 0;
400
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_INIT;
401
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
402
            chEvtBroadcast(&eventSourceTimeout);
403
            break;
404
          }
405
          // activate S
406
          aosDbgPrintf("S+\n");
407
          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
408
#if (AMIROOS_CFG_SSSP_STACK_START == true)
409
          // proceed immediately
410
          stage = STAGE_3_2;
411
          flags.wfe_next = false;
412
#else
413
          // set the timeout timer
414
          chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
415
          // proceed
416
          stage = STAGE_3_3_WAITFORFIRSTID;
417
#endif
418
#else
419
          // set the timeout timer
420
          chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
421
#endif
422
        }
423

  
424
#if (AMIROOS_CFG_SSSP_MASTER != true)
425
        // a CAN message was received
426
        else if (eventmask & CANEVENT_MASK) {
427
          // if an initiation message was received
428
          if (canRxFrame.DLC == 0 &&
429
              canRxFrame.RTR == CAN_RTR_DATA &&
430
              canRxFrame.IDE == CAN_IDE_STD &&
431
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_INIT) {
432
            aosDbgPrintf("init msg\n");
433
            // reset the timeout timer and clear pending flags
434
            chVTReset(&timerTimeout);
435
            chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
436
            eventmask &= ~TIMEOUTEVENT_MASK;
437
            // activate S
438
            aosDbgPrintf("S+\n");
439
            apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
440
#if (AMIROOS_CFG_SSSP_STACK_START == true)
441
            // proceed
442
            stage = STAGE_3_2;
443
            flags.wfe_next = false;
444
#else
445
            // set the timeout timer
446
            chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
447
            // proceed
448
            stage = STAGE_3_3_WAITFORFIRSTID;
449
#endif
450
          }
451
        }
452
#endif
453

  
454
        break;
455
      } /* end of STAGE_3_1 */
456

  
457
      case STAGE_3_2:
458
      {
459
#if (AMIROOS_CFG_SSSP_STACK_START == true)
460
        aos.sssp.stage = AOS_SSSP_STARTUP_3_2;
461

  
462
        // if this stage was just entered
463
        if (flags.wfe == false) {
464
          // set the module ID
465
          aos.sssp.moduleId = 1;
466
          // broadcast module ID
467
          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
468
          canTxFrame.DLC = 4;
469
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
470
          _canSerialize32(canTxFrame.data8, aos.sssp.moduleId);
471
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
472
            chEvtBroadcast(&eventSourceTimeout);
473
            break;
474
          }
475
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
476
          lastid = aos.sssp.moduleId;
477
#endif
478
#if (AMIROOS_CFG_SSSP_STACK_END == true)
479
          // sequence is already over
480
          // deactivate S
481
          aosDbgPrintf("S-\n");
482
          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
483
          // proceed
484
          stage = STAGE_3_3_WAITFORID;
485
#else
486
          // set the delay timer so the UP signal is activated later
487
          chVTSet(&timerDelay, LL_US2ST(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
488
#endif
489
        }
490

  
491
        // if a delay event occurred
492
        if (eventmask & DELAYEVENT_MASK) {
493
          // activate UP
494
          aosDbgPrintf("UP+\n");
495
          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
496
          // deactivate S
497
          aosDbgPrintf("S-\n");
498
          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
499
          // explicitely clear timeout event flag
500
          chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
501
          eventmask &= ~TIMEOUTEVENT_MASK;
502
          // proceed
503
          stage = STAGE_3_3_WAITFORID;
504
        }
505
#endif
506

  
507
        break;
508
      } /* end of STAGE_3_2 */
509

  
510
      case STAGE_3_3_WAITFORFIRSTID:
511
      {
512
#if (AMIROOS_CFG_SSSP_STACK_START != true)
513
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
514

  
515
        // a CAN message was received
516
        if (eventmask & CANEVENT_MASK) {
517
          // if an ID message was received
518
          if (canRxFrame.DLC == 4 &&
519
              canRxFrame.RTR == CAN_RTR_DATA &&
520
              canRxFrame.IDE == CAN_IDE_STD &&
521
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
522
            aosDbgPrintf("ID (%u)\n", _canDeserialize32(canRxFrame.data8));
523
            // validate received ID
524
            if (lastid < _canDeserialize32(canRxFrame.data8)) {
525
              // store received ID
526
              lastid = _canDeserialize32(canRxFrame.data8);
527
              // restart timeout timer
528
              chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
529
              // proceed
530
              stage = STAGE_3_3_WAITFORIDORSIG;
531
            } else {
532
              aosDbgPrintf("ERR: invalid ID\n");
533
              // abort
534
              stage = STAGE_3_4_ABORT_ACTIVE;
535
              flags.wfe_next = false;
536
            }
537
            // explicitely clear timeout event flag
538
            chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
539
            eventmask &= ~TIMEOUTEVENT_MASK;
540
          }
541
        }
542
#endif
543
        break;
544
      } /* end of STAGE_3_3_WAITFORFIRSTID */
545

  
546
      case STAGE_3_3_WAITFORIDORSIG:
547
      {
548
#if (AMIROOS_CFG_SSSP_STACK_START != true)
549
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
550

  
551
        // a CAN message was received
552
        if (eventmask & CANEVENT_MASK) {
553
          // if an ID message was received
554
          if (canRxFrame.DLC == 4 &&
555
              canRxFrame.RTR == CAN_RTR_DATA &&
556
              canRxFrame.IDE == CAN_IDE_STD &&
557
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
558
            aosDbgPrintf("ID (%u)\n", _canDeserialize32(canRxFrame.data8));
559
            // validate received ID
560
            if (lastid < _canDeserialize32(canRxFrame.data8)) {
561
              // store received ID
562
              lastid = _canDeserialize32(canRxFrame.data8);
563
              // restart timeout timer
564
              chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
565
            } else {
566
              aosDbgPrintf("ERR: invalid ID\n");
567
              // abort
568
              stage = STAGE_3_4_ABORT_ACTIVE;
569
              flags.wfe_next = false;
570
            }
571
            // explicitely clear timeout event flag
572
            chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
573
            eventmask &= ~TIMEOUTEVENT_MASK;
574
          }
575
        }
576

  
577
        // if an IO event was received (DN signal)
578
        if ((eventmask & IOEVENT_MASK) && (ioflags & MODULE_SSSP_EVENTFLAGS_DN)) {
579
          aosDbgPrintf("DN <-\n");
580
          // reset timeout timer
581
          chVTReset(&timerTimeout);
582
          chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
583
          eventmask &= ~TIMEOUTEVENT_MASK;
584
          // increment and broadcast ID
585
          aos.sssp.moduleId = lastid + 1;
586
          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
587
          canTxFrame.DLC = 4;
588
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
589
          _canSerialize32(canTxFrame.data8, aos.sssp.moduleId);
590
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
591
            chEvtBroadcast(&eventSourceTimeout);
592
            break;
593
          }
594
          // set delay timer
595
          chVTSet(&timerDelay, LL_US2ST(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
596
        }
597

  
598
        // if a delay event occurred
599
        if (eventmask & DELAYEVENT_MASK) {
600
#if (AMIROOS_CFG_SSSP_STACK_END != true)
601
          // activate UP
602
          aosDbgPrintf("UP+\n");
603
          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
604
#endif
605
          // deactivate S
606
          aosDbgPrintf("S-\n");
607
          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
608
          // reset the timeout timer
609
          chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
610
          chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
611
          eventmask &= ~TIMEOUTEVENT_MASK;
612
          // proceed
613
          stage = STAGE_3_3_WAITFORID;
614
        }
615
#endif
616

  
617
        break;
618
      } /* end of STAGE_3_3_WAITFORIDORSIG */
619

  
620
      case STAGE_3_3_WAITFORID:
621
      {
622
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
623

  
624
#if (AMIROOS_CFG_SSSP_STACK_END != true)
625
        // a CAN message was received
626
        if (eventmask & CANEVENT_MASK) {
627
          // if an ID message was received
628
          if (canRxFrame.DLC == 4 &&
629
              canRxFrame.RTR == CAN_RTR_DATA &&
630
              canRxFrame.IDE == CAN_IDE_STD &&
631
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
632
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
633
            // Plausibility of the received ID is not checked at this point but is done by other modules still in a previous stage.
634
            lastid = _canDeserialize32(canRxFrame.data8);
635
            aosDbgPrintf("ID (%u)\n", lastid);
636
#endif
637
            // restart timeout timer
638
            chVTSet(&timerTimeout, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
639
            chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
640
            eventmask &= ~TIMEOUTEVENT_MASK;
641
          }
642
        }
643
#endif
644

  
645
        break;
646
      } /* end of STAGE_3_3_WAITFORID */
647

  
648
      case STAGE_3_4_FINISH:
649
      {
650
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
651

  
652
        // if an IO event was received (S signal)
653
        if ((eventmask & IOEVENT_MASK) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
654
          // reset the timeout timer
655
          chVTReset(&timerTimeout);
656
          chEvtWaitAnyTimeout(TIMEOUTEVENT_MASK, TIME_IMMEDIATE);
657
          eventmask &= ~TIMEOUTEVENT_MASK;
658
          //set the delay timer
659
          chVTSet(&timerDelay, LL_US2ST(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceDelay);
660
        }
661

  
662
        // if a CAN event was received
663
        if (eventmask & CANEVENT_MASK) {
664
          // if an abort message was received
665
          if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
666
            aosDbgPrintf("abort msg\n");
667
            // reset the delay timer
668
            chVTReset(&timerDelay);
669
            chEvtWaitAnyTimeout(DELAYEVENT_MASK, TIME_IMMEDIATE);
670
            eventmask &= ~DELAYEVENT_MASK;
671
            // proceed
672
            stage = STAGE_3_4_ABORT;
673
          }
674
        }
675

  
676
        // if a delay timer event occurred
677
        if (eventmask & DELAYEVENT_MASK) {
678
          aosDbgPrintf("sequence sucessful\n");
679
          // sequence finished sucessfully
680
          flags.loop = false;
681
        }
682

  
683
        break;
684
      } /* end of STAGE_3_4_FINISH */
685

  
686
      case STAGE_3_4_ABORT_ACTIVE:
687
      {
688
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
689

  
690
        // emit abort message
691
        canTxFrame.DLC = 0;
692
        canTxFrame.SID = SSSP_STACKINIT_CANMSGID_ABORT;
693
        canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_INFINITE);
694
        aosDbgPrintf("CAN -> abort\n");
695
        // clear timeout flag
696
        eventmask &= ~TIMEOUTEVENT_MASK;
697
        // proceed immediately
698
        stage = STAGE_3_4_ABORT;
699
        flags.wfe_next = false;
700
        break;
701
      } /* end of STAGE_3_4_ABORT_ACTIVE */
702

  
703
      case STAGE_3_4_ABORT:
704
      {
705
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
706

  
707
        // deactivate S
708
        aosDbgPrintf("S-\n");
709
        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
710
        // invalidate module ID
711
        aos.sssp.moduleId = 0;
712

  
713
        // if an IO event was received (S signal)
714
        if ((eventmask & IOEVENT_MASK) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
715
          aosDbgPrintf("sequence aborted\n");
716
          // exit the sequence
717
          flags.loop = false;
718
        }
719

  
720
        break;
721
      } /* end of STAGE_3_4_ABORT */
722
    }
723

  
724
    // fetch pending CAN message (if any)
725
    if ((eventmask & CANEVENT_MASK) && (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE) == MSG_OK)) {
726
      aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
727
      flags.wfe_next = false;
728
    }
729

  
730
    // handle unhandled timeout events
731
    if (eventmask & TIMEOUTEVENT_MASK) {
732
      aosDbgPrintf("ERR: timeout evt\n");
733
      // abort
734
      flags.wfe_next = false;
735
      stage = STAGE_3_4_ABORT_ACTIVE;
736
    }
737

  
738
    // apply wfe value for next iteration
739
    flags.wfe = flags.wfe_next;
740
  }
741
  aosDbgPrintf("\n");
742

  
743
  // unregister all events (timeout, delay, CAN receive)
744
  chEvtUnregister(&eventSourceTimeout, &eventListenerTimeout);
745
  chEvtUnregister(&eventSourceDelay, &eventListenerDelay);
746
  chEvtUnregister(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan);
747
  // clear any pending events (timeout, delay, CAN receive)
748
  chEvtWaitAllTimeout(TIMEOUTEVENT_MASK | DELAYEVENT_MASK | CANEVENT_MASK, TIME_IMMEDIATE);
749

  
750
  // reset all control signals
751
#if (AMIROOS_CFG_SSSP_STACK_END != true)
752
  apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
753
#endif
754
  apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
755

  
756
  return shutdown;
757
}
758

  
759
/**
88 760
 * @brief   Application entry point.
89 761
 */
90 762
int main(void)
......
159 831
#endif
160 832

  
161 833
#if (AMIROOS_CFG_TESTS_ENABLE == true)
162
#if defined(MODULE_INIT_TESTS)
163 834
  MODULE_INIT_TESTS();
164
#else
165
  #warning "MODULE_INIT_TESTS not defined"
166
#endif
167 835
#endif
168 836

  
169 837
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
......
248 916
    // unexpected IO events
249 917
    if (eventmask & _eventListenerIO.events) {
250 918
      eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
251
#ifdef MODULE_SSSP_STARTUP_OSINIT_OUTRO_IOEVENT_HOOK
252
      MODULE_SSSP_STARTUP_OSINIT_OUTRO_IOEVENT_HOOK(eventmask, eventflags);
919
#ifdef MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK
920
      MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(eventmask, eventflags);
253 921
#else
254 922
      _unexpectedEventError(eventmask, eventflags);
255 923
#endif
......
259 927
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
260 928
      _unexpectedEventError(eventmask, eventflags);
261 929
    }
930
#if (AMIROOS_CFG_DBG == true)
262 931
    // unknown event (must never occur, thus disabled for release builds)
263 932
    else {
264
      _unexpectedEventError(eventmask, eventflags);
933
      _unexpectedEventError(eventmask, 0);
265 934
    }
935
#endif
266 936
  }
267 937

  
938
  /*
939
   * There must be no delays at this point, thus no hook is allowed.
940
   */
941

  
942
  /* SSSP startup stage 3 (module stack initialization) */
943
  shutdown = _ssspModuleStackInitialization();
944

  
268 945
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
269 946
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS)
270 947
  AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
......
274 951
#endif
275 952

  
276 953
  /* completely start AMiRo-OS */
277
  aosSysStart();
954
  if (shutdown == AOS_SHUTDOWN_NONE) {
955
    aosSysStart();
956
  }
278 957

  
279 958
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9)
280 959
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS)
os/core/src/aos_system.c
193 193
  n += chvprintf(stream, fmt, ap);
194 194
  va_end(ap);
195 195

  
196
  streamPut(stream, '\n');
197
  ++n;
198

  
196 199
  return n;
197 200
}
198 201

  
......
205 208
{
206 209
  aosDbgCheck(stream != NULL);
207 210

  
211
  // local variables
212
  struct tm dt;
213
  aosSysGetDateTime(&dt);
214

  
215
  // print static information about module and operating system
208 216
  _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
209
  _printSystemInfoLine(stream, "Module", SYSTEM_INFO_NAMEWIDTH, "%s (v%s)\n", BOARD_NAME, BOARD_VERSION);
217
  _printSystemInfoLine(stream, "Module", SYSTEM_INFO_NAMEWIDTH, "%s (v%s)", BOARD_NAME, BOARD_VERSION);
210 218
#ifdef PLATFORM_NAME
211
  _printSystemInfoLine(stream, "Platform", SYSTEM_INFO_NAMEWIDTH, "%s\n", PLATFORM_NAME);
219
  _printSystemInfoLine(stream, "Platform", SYSTEM_INFO_NAMEWIDTH, "%s", PLATFORM_NAME);
212 220
#endif
213 221
#ifdef PORT_CORE_VARIANT_NAME
214
  _printSystemInfoLine(stream, "Core Variant", SYSTEM_INFO_NAMEWIDTH, "%s\n", PORT_CORE_VARIANT_NAME);
222
  _printSystemInfoLine(stream, "Core Variant", SYSTEM_INFO_NAMEWIDTH, "%s", PORT_CORE_VARIANT_NAME);
215 223
#endif
216
  _printSystemInfoLine(stream, "Architecture", SYSTEM_INFO_NAMEWIDTH, "%s\n", PORT_ARCHITECTURE_NAME);
224
  _printSystemInfoLine(stream, "Architecture", SYSTEM_INFO_NAMEWIDTH, "%s", PORT_ARCHITECTURE_NAME);
217 225
  _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
218
  _printSystemInfoLine(stream, "AMiRo-OS" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)\n", AMIROOS_VERSION_MAJOR, AMIROOS_VERSION_MINOR, AMIROOS_VERSION_PATCH, AMIROOS_RELEASE_TYPE, AOS_SYSTEM_SSSP_MAJOR, AOS_SYSTEM_SSSP_MINOR);
219
  _printSystemInfoLine(stream, "AMiRo-LLD" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (periphAL %u.%u)\n", AMIRO_LLD_VERSION_MAJOR, AMIRO_LLD_VERSION_MINOR, AMIRO_LLD_VERSION_PATCH, AMIRO_LLD_RELEASE_TYPE, PERIPHAL_VERSION_MAJOR, PERIPHAL_VERSION_MINOR);
220
  _printSystemInfoLine(stream, "ChibiOS/RT" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s\n", CH_KERNEL_MAJOR, CH_KERNEL_MINOR, CH_KERNEL_PATCH, (CH_KERNEL_STABLE == 1) ? "stable" : "non-stable");
221
  _printSystemInfoLine(stream, "ChibiOS/HAL", SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s\n", CH_HAL_MAJOR, CH_HAL_MINOR, CH_HAL_PATCH, (CH_HAL_STABLE == 1) ? "stable" : "non-stable");
222
  _printSystemInfoLine(stream, "build type", SYSTEM_INFO_NAMEWIDTH,"%s\n", (AMIROOS_CFG_DBG == true) ? "debug" : "release");
223
  _printSystemInfoLine(stream, "Compiler" , SYSTEM_INFO_NAMEWIDTH, "%s %u.%u.%u\n", "GCC", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); // TODO: support other compilers than GCC
224
  _printSystemInfoLine(stream, "Compiled" , SYSTEM_INFO_NAMEWIDTH, "%s - %s\n", __DATE__, __TIME__);
226
  _printSystemInfoLine(stream, "AMiRo-OS" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)", AMIROOS_VERSION_MAJOR, AMIROOS_VERSION_MINOR, AMIROOS_VERSION_PATCH, AMIROOS_RELEASE_TYPE, AOS_SYSTEM_SSSP_VERSION_MAJOR, AOS_SYSTEM_SSSP_VERSION_MINOR);
227
  _printSystemInfoLine(stream, "AMiRo-LLD" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (periphAL %u.%u)", AMIRO_LLD_VERSION_MAJOR, AMIRO_LLD_VERSION_MINOR, AMIRO_LLD_VERSION_PATCH, AMIRO_LLD_RELEASE_TYPE, PERIPHAL_VERSION_MAJOR, PERIPHAL_VERSION_MINOR);
228
  _printSystemInfoLine(stream, "ChibiOS/RT" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s", CH_KERNEL_MAJOR, CH_KERNEL_MINOR, CH_KERNEL_PATCH, (CH_KERNEL_STABLE == 1) ? "stable" : "non-stable");
229
  _printSystemInfoLine(stream, "ChibiOS/HAL", SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s", CH_HAL_MAJOR, CH_HAL_MINOR, CH_HAL_PATCH, (CH_HAL_STABLE == 1) ? "stable" : "non-stable");
230
  _printSystemInfoLine(stream, "build type", SYSTEM_INFO_NAMEWIDTH,"%s", (AMIROOS_CFG_DBG == true) ? "debug" : "release");
231
  _printSystemInfoLine(stream, "Compiler" , SYSTEM_INFO_NAMEWIDTH, "%s %u.%u.%u", "GCC", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); // TODO: support other compilers than GCC
232
  _printSystemInfoLine(stream, "Compiled" , SYSTEM_INFO_NAMEWIDTH, "%s - %s", __DATE__, __TIME__);
233

  
234
  // print static information about the bootloader
225 235
  _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
226 236
  if (BL_CALLBACK_TABLE_ADDRESS->magicNumber == BL_MAGIC_NUMBER) {
227
    _printSystemInfoLine(stream, "AMiRo-BLT", SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)\n", BL_CALLBACK_TABLE_ADDRESS->vBootloader.major, BL_CALLBACK_TABLE_ADDRESS->vBootloader.minor, BL_CALLBACK_TABLE_ADDRESS->vBootloader.patch,
237
    _printSystemInfoLine(stream, "AMiRo-BLT", SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)", BL_CALLBACK_TABLE_ADDRESS->vBootloader.major, BL_CALLBACK_TABLE_ADDRESS->vBootloader.minor, BL_CALLBACK_TABLE_ADDRESS->vBootloader.patch,
228 238
                         (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_Release) ? "stable" :
229 239
                         (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_ReleaseCandidate) ? "release candidate" :
230 240
                         (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_Beta) ? "beta" :
......
232 242
                         (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_PreAlpha) ? "pre-alpha" :
233 243
                         "<release type unknown>",
234 244
                         BL_CALLBACK_TABLE_ADDRESS->vSSSP.major, BL_CALLBACK_TABLE_ADDRESS->vSSSP.minor);
235
    if (BL_CALLBACK_TABLE_ADDRESS->vSSSP.major != AOS_SYSTEM_SSSP_MAJOR) {
245
    if (BL_CALLBACK_TABLE_ADDRESS->vSSSP.major != AOS_SYSTEM_SSSP_VERSION_MAJOR) {
236 246
      if (stream) {
237 247
        chprintf(stream, "WARNING: Bootloader and AMiRo-OS implement incompatible SSSP versions!\n");
238 248
      } else {
239 249
        aosprintf("WARNING: Bootloader and AMiRo-OS implement incompatible SSSP versions!\n");
240 250
      }
241 251
    }
242
    _printSystemInfoLine(stream, "Compiler", SYSTEM_INFO_NAMEWIDTH, "%s %u.%u.%u\n", (BL_CALLBACK_TABLE_ADDRESS->vCompiler.identifier == BL_VERSION_ID_GCC) ? "GCC" : "<compiler unknown>", BL_CALLBACK_TABLE_ADDRESS->vCompiler.major, BL_CALLBACK_TABLE_ADDRESS->vCompiler.minor, BL_CALLBACK_TABLE_ADDRESS->vCompiler.patch); // TODO: support other compilers than GCC
252
    _printSystemInfoLine(stream, "Compiler", SYSTEM_INFO_NAMEWIDTH, "%s %u.%u.%u", (BL_CALLBACK_TABLE_ADDRESS->vCompiler.identifier == BL_VERSION_ID_GCC) ? "GCC" : "<compiler unknown>", BL_CALLBACK_TABLE_ADDRESS->vCompiler.major, BL_CALLBACK_TABLE_ADDRESS->vCompiler.minor, BL_CALLBACK_TABLE_ADDRESS->vCompiler.patch); // TODO: support other compilers than GCC
243 253
  } else {
244 254
    if (stream) {
245 255
      chprintf(stream, "Bootloader incompatible or not available.\n");
......
247 257
      aosprintf("Bootloader incompatible or not available.\n");
248 258
    }
249 259
  }
260

  
261
  // print dynamic information about the module
250 262
  _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
251
  struct tm dt;
252
  aosSysGetDateTime(&dt);
253
  _printSystemInfoLine(stream, "Date", SYSTEM_INFO_NAMEWIDTH, "%s %02u-%02u-%04u\n", (dt.tm_wday == 0) ? "Sunday" : (dt.tm_wday == 1) ? "Monday" : (dt.tm_wday == 2) ? "Tuesday" : (dt.tm_wday == 3) ? "Wednesday" : (dt.tm_wday == 4) ? "Thursday" : (dt.tm_wday == 5) ? "Friday" : "Saturday",
263
  if (aos.sssp.moduleId != 0) {
264
    _printSystemInfoLine(stream, "Module ID", SYSTEM_INFO_NAMEWIDTH, "%u", aos.sssp.moduleId);
265
  } else {
266
    _printSystemInfoLine(stream, "Module ID", SYSTEM_INFO_NAMEWIDTH, "not available");
267
  }
268
  _printSystemInfoLine(stream, "Date", SYSTEM_INFO_NAMEWIDTH, "%s %02u-%02u-%04u", (dt.tm_wday == 0) ? "Sunday" : (dt.tm_wday == 1) ? "Monday" : (dt.tm_wday == 2) ? "Tuesday" : (dt.tm_wday == 3) ? "Wednesday" : (dt.tm_wday == 4) ? "Thursday" : (dt.tm_wday == 5) ? "Friday" : "Saturday",
254 269
                       dt.tm_mday,
255 270
                       dt.tm_mon + 1,
256 271
                       dt.tm_year + 1900);
257
  _printSystemInfoLine(stream, "Time", SYSTEM_INFO_NAMEWIDTH, "%02u:%02u:%02u\n", dt.tm_hour, dt.tm_min, dt.tm_sec);
272
  _printSystemInfoLine(stream, "Time", SYSTEM_INFO_NAMEWIDTH, "%02u:%02u:%02u", dt.tm_hour, dt.tm_min, dt.tm_sec);
273

  
258 274
  _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
259 275

  
260 276
  return;

Also available in: Unified diff