Revision c218345a core/src/aos_system.c

View differences:

core/src/aos_system.c
55 55
 */
56 56
#define SYSTEM_INFO_NAMEWIDTH         14
57 57

  
58
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
59

  
60
/**
61
 * @brief   Weighting factor for the low-pass filter used for calculating the @p _syssyncskew value.
62
 */
63
#define SYSTEM_SYSSYNCSKEW_LPFACTOR   (0.1f / AOS_SYSTEM_TIME_RESOLUTION)
64

  
65
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
66

  
67 58
/******************************************************************************/
68 59
/* EXPORTED VARIABLES                                                         */
69 60
/******************************************************************************/
......
108 99
 */
109 100
static systime_t _synctime;
110 101

  
111
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
112
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
113

  
114
/**
115
 * @brief   Timer to drive the SYS_SYNC signal for system wide time synchronization according to SSSP.
116
 */
117
static virtual_timer_t _syssynctimer;
118

  
119
/**
120
 * @brief   Last uptime of system wide time synchronization.
121
 */
122
static aos_timestamp_t _syssynctime;
123

  
124
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
125

  
126
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
127

  
128
/**
129
 * @brief   Offset between local clock and system wide synchronization signal.
130
 */
131
static float _syssyncskew;
132

  
133
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
134
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
135

  
136 102
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
137 103

  
138 104
/**
......
536 502
  chprintf(stream, "%10u milliseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_SECOND / MICROSECONDS_PER_MILLISECOND));
537 503
  chprintf(stream, "%10u microseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_MILLISECOND / MICROSECONDS_PER_MICROSECOND));
538 504
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
539
  chprintf(stream, "SSSP synchronization offset: %.3fus per %uus\n", (double)_syssyncskew, AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
505
  chprintf(stream, "SSSP synchronization offset: %.3fus per %uus\n", (double)aosSsspGetSyncSkew(), AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
540 506
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
541 507
  _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
542 508

  
......
694 660
}
695 661
#pragma GCC diagnostic pop
696 662

  
697
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true)) || defined(__DOXYGEN__)
698

  
699
/**
700
 * @brief   Callback function for the Sync signal interrupt.
701
 *
702
 * @param[in] args   Pointer to the GPIO line identifier.
703
 */
704
static void _signalSyncCallback(void *args)
705
{
706
  aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8));
707

  
708
  apalControlGpioState_t state;
709
  aos_timestamp_t uptime;
710

  
711
  chSysLockFromISR();
712

  
713
  // if the system is in operation phase
714
  if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
715
    // read signal S
716
    apalControlGpioGet(&moduleSsspGpioS, &state);
717
    // if S was toggled from on to off
718
    if (state == APAL_GPIO_OFF) {
719
      // get current uptime
720
      aosSysGetUptimeX(&uptime);
721
      // align the uptime with the synchronization period
722
      if (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) {
723
        _uptime -= uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
724
#if (AMIROOS_CFG_PROFILE == true)
725
        _syssyncskew = ((1.0f - SYSTEM_SYSSYNCSKEW_LPFACTOR) * _syssyncskew) + (SYSTEM_SYSSYNCSKEW_LPFACTOR * (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD));
726
#endif /* (AMIROOS_CFG_PROFILE == true) */
727
      } else {
728
        _uptime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
729
#if (AMIROOS_CFG_PROFILE == true)
730
        _syssyncskew = ((1.0f - SYSTEM_SYSSYNCSKEW_LPFACTOR) * _syssyncskew) - (SYSTEM_SYSSYNCSKEW_LPFACTOR * (AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD)));
731
#endif /* (AMIROOS_CFG_PROFILE == true) */
732
      }
733
    }
734
  }
735

  
736
  // broadcast event
737
  chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args))));
738
  chSysUnlockFromISR();
739

  
740
  return;
741
}
742

  
743
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) */
744

  
745 663
/**
746 664
 * @brief   Callback function for the uptime accumulation timer.
747 665
 *
......
764 682
  return;
765 683
}
766 684

  
767
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true)) || defined (__DOXYGEN__)
768

  
769
/**
770
 * @brief   Periodic system synchronization callback function.
771
 * @details Toggles the SYS_SYNC signal and reconfigures the system synchronization timer.
772
 *
773
 * @param[in] par   Unused parameters.
774
 */
775
static void _sysSyncTimerCallback(void* par)
776
{
777
  (void)par;
778

  
779
  apalControlGpioState_t state;
780
  aos_timestamp_t uptime;
781

  
782
  chSysLockFromISR();
783
  // toggle and read signal S
784
  apalGpioToggle(moduleSsspGpioS.gpio);
785
  apalControlGpioGet(&moduleSsspGpioS, &state);
786
  // if S was toggled from off to on
787
  if (state == APAL_GPIO_ON) {
788
    // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
789
    _syssynctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
790
    aosSysGetUptimeX(&uptime);
791
    chVTSetI(&_syssynctimer, chTimeUS2I(_syssynctime - uptime), _sysSyncTimerCallback, NULL);
792
  }
793
  // if S was toggled from on to off
794
  else /* if (state == APAL_GPIO_OFF) */ {
795
    // reconfigure the timer (lazy)
796
    chVTSetI(&_syssynctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _sysSyncTimerCallback, NULL);
797
  }
798
  chSysUnlockFromISR();
799

  
800
  return;
801
}
802

  
803
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true) */
804

  
805 685
/**
806 686
 * @brief   Retreive the number of active threads.
807 687
 *
......
835 715
  chThdSetPriority(AOS_THD_CTRLPRIO);
836 716

  
837 717
#if (AMIROOS_CFG_SSSP_ENABLE == true)
838
  aosSsspInit();
718
  aosSsspInit(&_uptime);
839 719
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
840 720

  
841 721
  /* set local variables */
842 722
  chVTObjectInit(&_systimer);
843 723
#if (AMIROOS_CFG_SSSP_ENABLE == true)
724
  // uptime counter is started when SSSP proceeds to operation phase
844 725
  _synctime = 0;
845 726
  _uptime = 0;
846
#if (AMIROOS_CFG_SSSP_MASTER == true)
847
  chVTObjectInit(&_syssynctimer);
848
  _syssynctime = 0;
849
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
850
#if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
851
  _syssyncskew = 0.0f;
852
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
853 727
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
854 728
  // start the uptime counter
855 729
  chSysLock();
856
  _synctime = chVTGetSystemTimeX();
857
  _uptime = 0;
858
  chVTSetI(&_systimer, SYSTIMER_PERIOD, &_uptimeCallback, NULL);
730
  aosSysStartUptimeS();
859 731
  chSysUnlock();
860 732
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
861 733

  
......
864 736
  chEvtObjectInit(&aos.events.gpio);
865 737
  chEvtObjectInit(&aos.events.os);
866 738

  
867
#if (AMIROOS_CFG_SSSP_ENABLE == true)
868

  
869
  /* SSSP signal interrupt setup */
870
  // PD signal
871
  palSetLineCallback(moduleSsspGpioPD.gpio->line, _gpioCallback, &moduleSsspGpioPD.gpio->line);
872
  palEnableLineEvent(moduleSsspGpioPD.gpio->line, APAL2CH_EDGE(moduleSsspGpioPD.meta.edge));
873
  // S signal
874
#if (AMIROOS_CFG_SSSP_MASTER == true)
875
  palSetLineCallback(moduleSsspGpioS.gpio->line, _gpioCallback, &moduleSsspGpioS.gpio->line);
876
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
877
  palSetLineCallback(moduleSsspGpioS.gpio->line, _signalSyncCallback, &moduleSsspGpioS.gpio->line);
878
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
879
  palEnableLineEvent(moduleSsspGpioS.gpio->line, APAL2CH_EDGE(moduleSsspGpioS.meta.edge));
880
#if (AMIROOS_CFG_SSSP_STACK_START != true)
881
  // DN signal
882
  palSetLineCallback(moduleSsspGpioDN.gpio->line, _gpioCallback, &moduleSsspGpioDN.gpio->line);
883
  palEnableLineEvent(moduleSsspGpioDN.gpio->line, APAL2CH_EDGE(moduleSsspGpioDN.meta.edge));
884
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
885
#if (AMIROOS_CFG_SSSP_STACK_END != true)
886
  // UP signal
887
  palSetLineCallback(moduleSsspGpioUP.gpio->line, _gpioCallback, &moduleSsspGpioUP.gpio->line);
888
  palEnableLineEvent(moduleSsspGpioUP.gpio->line, APAL2CH_EDGE(moduleSsspGpioUP.meta.edge));
889
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
890

  
891
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
892

  
893 739
#if (AMIROOS_CFG_SHELL_ENABLE == true)
894 740

  
895 741
  /* init shell */
......
908 754
  aosShellAddCommand(&aos.shell, &_shellcmd_kerneltest);
909 755
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
910 756

  
757
#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
758

  
759
  // suppress unused variable warnings
760
  (void)shellPrompt;
761

  
911 762
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
912 763

  
913 764
  return;
......
918 769
 */
919 770
void aosSysStart(void)
920 771
{
921
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true)
922
  {
923
    chSysLock();
924
    // start the system synchronization counter
925
    // The first iteration of the timer is set to the next 'center' of a 'slice'.
926
    aos_timestamp_t t;
927
    aosSysGetUptimeX(&t);
928
    t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
929
    chVTSetI(&_syssynctimer, chTimeUS2I((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2))), _sysSyncTimerCallback, NULL);
930
    chSysUnlock();
931
  }
932
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) && (AMIROOS_CFG_SSSP_ENABLE == true) */
933

  
934 772
  // print system information;
935 773
  _printSystemInfo((BaseSequentialStream*)&aos.iostream);
936 774
  aosprintf("\n");
......
947 785
  return;
948 786
}
949 787

  
950
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
951

  
952 788
/**
953 789
 * @brief   Start the system uptime measurement.
790
 * @note    Must be called from a locked context.
954 791
 */
955
void aosSysStartUptime(void)
792
void aosSysStartUptimeS(void)
956 793
{
957
  chSysLock();
794
  chDbgCheckClassS();
958 795

  
959
  // start the uptime counter
796
  // start the uptime aggregation counter
960 797
  _synctime = chVTGetSystemTimeX();
961 798
  _uptime = 0;
962 799
  chVTSetI(&_systimer, SYSTIMER_PERIOD, &_uptimeCallback, NULL);
963 800

  
964
  chSysUnlock();
965

  
966 801
  return;
967 802
}
968 803

  
969
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
970

  
971 804
/**
972 805
 * @brief   Retrieves the system uptime.
973 806
 *
......
1031 864

  
1032 865
#if (AMIROOS_CFG_SSSP_ENABLE == true)
1033 866

  
1034
#if (AMIROOS_CFG_SSSP_MASTER == true)
1035
  // deactivate the system synchronization timer
1036
  chVTReset(&_syssynctimer);
1037
  // activate SSSP S signal in case the synchronization timer had it deactivated.
1038
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
1039
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
1040

  
1041 867
  // activate the PD signal only if this module initiated the shutdown
1042 868
  if (shutdown != AOS_SHUTDOWN_PASSIVE) {
1043
    apalControlGpioSet(&moduleSsspGpioPD, APAL_GPIO_ON);
1044
    aosSsspShutdownInit();
869
    aosSsspShutdownInit(true);
1045 870
  }
1046 871

  
1047 872
  switch (shutdown) {

Also available in: Unified diff