amiro-os / core / src / aos_sssp.c @ 8ba3c06b
History | View | Annotate | Download (47.633 KB)
| 1 | cda14729 | Thomas Schöpping | /*
|
|---|---|---|---|
| 2 | AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
|
||
| 3 | 96621a83 | Thomas Schöpping | Copyright (C) 2016..2020 Thomas Schöpping et al.
|
| 4 | cda14729 | Thomas Schöpping | |
| 5 | This program is free software: you can redistribute it and/or modify
|
||
| 6 | it under the terms of the GNU General Public License as published by
|
||
| 7 | the Free Software Foundation, either version 3 of the License, or
|
||
| 8 | (at your option) any later version.
|
||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful,
|
||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 13 | GNU General Public License for more details.
|
||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License
|
||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
| 17 | */
|
||
| 18 | |||
| 19 | /**
|
||
| 20 | * @file aos_sssp.c
|
||
| 21 | * @brief SSSP related code.
|
||
| 22 | *
|
||
| 23 | * @addtogroup aos_sssp
|
||
| 24 | * @{
|
||
| 25 | */
|
||
| 26 | |||
| 27 | #include <amiroos.h> |
||
| 28 | |||
| 29 | #if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__) |
||
| 30 | |||
| 31 | /******************************************************************************/
|
||
| 32 | /* LOCAL DEFINITIONS */
|
||
| 33 | /******************************************************************************/
|
||
| 34 | |||
| 35 | c218345a | Thomas Schöpping | #if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__) |
| 36 | |||
| 37 | /**
|
||
| 38 | * @brief Weighting factor for smoothing the @p _syncskew value.
|
||
| 39 | */
|
||
| 40 | #define SYNCSKEW_SMOOTHFACTOR (0.1f / AOS_SYSTEM_TIME_RESOLUTION) |
||
| 41 | |||
| 42 | #endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */ |
||
| 43 | |||
| 44 | cda14729 | Thomas Schöpping | /******************************************************************************/
|
| 45 | /* EXPORTED VARIABLES */
|
||
| 46 | /******************************************************************************/
|
||
| 47 | |||
| 48 | /******************************************************************************/
|
||
| 49 | /* LOCAL TYPES */
|
||
| 50 | /******************************************************************************/
|
||
| 51 | |||
| 52 | /******************************************************************************/
|
||
| 53 | /* LOCAL VARIABLES */
|
||
| 54 | /******************************************************************************/
|
||
| 55 | |||
| 56 | /**
|
||
| 57 | c218345a | Thomas Schöpping | * @brief Pointer to the system uptime.
|
| 58 | */
|
||
| 59 | static aos_timestamp_t* _uptime;
|
||
| 60 | |||
| 61 | #if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__) |
||
| 62 | |||
| 63 | /**
|
||
| 64 | * @brief Timer to drive the S signal for system wide time synchronization during operation phase.
|
||
| 65 | */
|
||
| 66 | static virtual_timer_t _synctimer;
|
||
| 67 | |||
| 68 | /**
|
||
| 69 | * @brief Last uptime of system wide time synchronization.
|
||
| 70 | */
|
||
| 71 | static aos_timestamp_t _synctime;
|
||
| 72 | |||
| 73 | #endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
||
| 74 | |||
| 75 | #if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__) |
||
| 76 | |||
| 77 | /**
|
||
| 78 | * @brief Offset between local clock and system wide synchronization signal.
|
||
| 79 | */
|
||
| 80 | static float _syncskew; |
||
| 81 | |||
| 82 | #endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */ |
||
| 83 | |||
| 84 | /**
|
||
| 85 | cda14729 | Thomas Schöpping | * @brief A timer event based delays.
|
| 86 | c53ef0b1 | Thomas Schöpping | * @details This timer must not be an AMiRo-OS timer, since delays occurr before system is initialized.
|
| 87 | cda14729 | Thomas Schöpping | */
|
| 88 | static virtual_timer_t _delayTimer;
|
||
| 89 | |||
| 90 | /**
|
||
| 91 | * @brief Event source for the delay timer.
|
||
| 92 | */
|
||
| 93 | c53ef0b1 | Thomas Schöpping | static event_source_t _delayEventSource;
|
| 94 | cda14729 | Thomas Schöpping | |
| 95 | /**
|
||
| 96 | * @brief Event listener for the delay event.
|
||
| 97 | */
|
||
| 98 | c53ef0b1 | Thomas Schöpping | static event_listener_t _delayEventListener;
|
| 99 | cda14729 | Thomas Schöpping | |
| 100 | /******************************************************************************/
|
||
| 101 | /* LOCAL FUNCTIONS */
|
||
| 102 | /******************************************************************************/
|
||
| 103 | |||
| 104 | c218345a | Thomas Schöpping | #if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__) |
| 105 | |||
| 106 | /**
|
||
| 107 | c53ef0b1 | Thomas Schöpping | * @brief Callback function for the S signal interrupt.
|
| 108 | c218345a | Thomas Schöpping | *
|
| 109 | * @param[in] args Pointer to the GPIO line identifier.
|
||
| 110 | */
|
||
| 111 | static void _gpioCallbackSSignal(void *args) |
||
| 112 | {
|
||
| 113 | aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8)); |
||
| 114 | |||
| 115 | apalControlGpioState_t s; |
||
| 116 | aos_timestamp_t t; |
||
| 117 | |||
| 118 | chSysLockFromISR(); |
||
| 119 | |||
| 120 | // if the system is in operation phase
|
||
| 121 | if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
|
||
| 122 | // read signal S
|
||
| 123 | c53ef0b1 | Thomas Schöpping | apalControlGpioGet(moduleSsspSignalS(), &s); |
| 124 | c218345a | Thomas Schöpping | // if S was toggled from on to off
|
| 125 | if (s == APAL_GPIO_OFF) {
|
||
| 126 | // get current uptime
|
||
| 127 | aosSysGetUptimeX(&t); |
||
| 128 | // align the uptime with the synchronization period
|
||
| 129 | t %= AMIROOS_CFG_SSSP_SYSSYNCPERIOD; |
||
| 130 | if (t < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) { |
||
| 131 | *_uptime -= t; |
||
| 132 | #if (AMIROOS_CFG_PROFILE == true) |
||
| 133 | _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) + (SYNCSKEW_SMOOTHFACTOR * t); |
||
| 134 | #endif /* (AMIROOS_CFG_PROFILE == true) */ |
||
| 135 | } else {
|
||
| 136 | t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - t; |
||
| 137 | *_uptime += t; |
||
| 138 | #if (AMIROOS_CFG_PROFILE == true) |
||
| 139 | _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) - (SYNCSKEW_SMOOTHFACTOR * t); |
||
| 140 | #endif /* (AMIROOS_CFG_PROFILE == true) */ |
||
| 141 | } |
||
| 142 | } |
||
| 143 | } |
||
| 144 | |||
| 145 | // broadcast event
|
||
| 146 | chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args)))); |
||
| 147 | chSysUnlockFromISR(); |
||
| 148 | |||
| 149 | return;
|
||
| 150 | } |
||
| 151 | |||
| 152 | #endif /* (AMIROOS_CFG_SSSP_MASTER != true) */ |
||
| 153 | |||
| 154 | #if (AMIROOS_CFG_SSSP_MASTER == true) || defined (__DOXYGEN__) |
||
| 155 | |||
| 156 | /**
|
||
| 157 | * @brief Periodic system synchronization callback function.
|
||
| 158 | c53ef0b1 | Thomas Schöpping | * @details Toggles the S signal and reconfigures the system synchronization timer.
|
| 159 | c218345a | Thomas Schöpping | *
|
| 160 | * @param[in] par Unused parameters.
|
||
| 161 | */
|
||
| 162 | static void _syncTimerCallback(void* par) |
||
| 163 | {
|
||
| 164 | (void)par;
|
||
| 165 | |||
| 166 | c53ef0b1 | Thomas Schöpping | // local variables
|
| 167 | c218345a | Thomas Schöpping | apalControlGpioState_t state; |
| 168 | aos_timestamp_t uptime; |
||
| 169 | |||
| 170 | chSysLockFromISR(); |
||
| 171 | // toggle and read signal S
|
||
| 172 | c53ef0b1 | Thomas Schöpping | apalGpioToggle(moduleSsspSignalS()->gpio); |
| 173 | apalControlGpioGet(moduleSsspSignalS(), &state); |
||
| 174 | c218345a | Thomas Schöpping | // if S was toggled from off to on
|
| 175 | if (state == APAL_GPIO_ON) {
|
||
| 176 | // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
|
||
| 177 | _synctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD; |
||
| 178 | aosSysGetUptimeX(&uptime); |
||
| 179 | c53ef0b1 | Thomas Schöpping | chVTSetI(&_synctimer, chTimeUS2I((time_usecs_t)(_synctime - uptime)), _syncTimerCallback, NULL);
|
| 180 | c218345a | Thomas Schöpping | } |
| 181 | // if S was toggled from on to off
|
||
| 182 | else /* if (state == APAL_GPIO_OFF) */ { |
||
| 183 | // reconfigure the timer (lazy)
|
||
| 184 | chVTSetI(&_synctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _syncTimerCallback, NULL); |
||
| 185 | } |
||
| 186 | chSysUnlockFromISR(); |
||
| 187 | |||
| 188 | return;
|
||
| 189 | } |
||
| 190 | |||
| 191 | /**
|
||
| 192 | * @brief Start the timer that toggles S for synchronization of the system.
|
||
| 193 | * @note Must be called from a locked context.
|
||
| 194 | */
|
||
| 195 | static inline void _syncTimerStartS(void) |
||
| 196 | {
|
||
| 197 | chDbgCheckClassS(); |
||
| 198 | |||
| 199 | // start synchronization timer
|
||
| 200 | // The first iteration of the timer is set to the next 'center' of a 'slice'.
|
||
| 201 | aos_timestamp_t t; |
||
| 202 | aosSysGetUptimeX(&t); |
||
| 203 | t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD); |
||
| 204 | c53ef0b1 | Thomas Schöpping | chVTSetI(&_synctimer, chTimeUS2I((time_usecs_t)((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)))), _syncTimerCallback, NULL); |
| 205 | c218345a | Thomas Schöpping | |
| 206 | return;
|
||
| 207 | } |
||
| 208 | |||
| 209 | #endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
||
| 210 | |||
| 211 | cda14729 | Thomas Schöpping | /**
|
| 212 | * @brief General callback function to be used for any local timers.
|
||
| 213 | *
|
||
| 214 | * @param[in] par A pointer to an @p event_source_t to be fired.
|
||
| 215 | */
|
||
| 216 | static void _timerCallback(void* par) |
||
| 217 | {
|
||
| 218 | aosDbgCheck(par != NULL);
|
||
| 219 | |||
| 220 | chSysLockFromISR(); |
||
| 221 | chEvtBroadcastI((event_source_t*)par); |
||
| 222 | chSysUnlockFromISR(); |
||
| 223 | |||
| 224 | return;
|
||
| 225 | } |
||
| 226 | |||
| 227 | /**
|
||
| 228 | * @brief Waits for the S signal to switch to the desired state.
|
||
| 229 | *
|
||
| 230 | * @param[in] listener Pointer to the GPIO event listener to be used.
|
||
| 231 | * @param[in] signalstate Desired state of the S signal ti be waited for.
|
||
| 232 | * @param[out] received Output variable to store the received event mask to.
|
||
| 233 | *
|
||
| 234 | * @return Status, indicating whether the expected event was received.
|
||
| 235 | */
|
||
| 236 | c5 |