Revision 933df08e os/core/src/aos_main.cpp

View differences:

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)

Also available in: Unified diff