Revision c218345a
core/inc/aos_sssp.h | ||
---|---|---|
101 | 101 |
AOS_SSSP_STAGE_STARTUP_3_2 = 0x1320, /**< Identifier of SSSP startup phase stage 3-2. */ |
102 | 102 |
AOS_SSSP_STAGE_STARTUP_3_3 = 0x1330, /**< Identifier of SSSP startup phase stage 3-3. */ |
103 | 103 |
AOS_SSSP_STAGE_STARTUP_3_4 = 0x1340, /**< Identifier of SSSP startup phase stage 3-4. */ |
104 |
AOS_SSSP_STAGE_OPERATION = 0x2000, /**< Identifier of SSSP operation pahse. */
|
|
104 |
AOS_SSSP_STAGE_OPERATION = 0x2000, /**< Identifier of SSSP operation phase. */
|
|
105 | 105 |
AOS_SSSP_STAGE_SHUTDOWN = 0x3000, /**< Identifier of SSSP shutdown phase. */ |
106 | 106 |
AOS_SSSP_STAGE_SHUTDOWN_1 = 0x3100, /**< Identifier of SSSP shutdown phase stage 1. */ |
107 | 107 |
AOS_SSSP_STAGE_SHUTDOWN_1_1 = 0x3110, /**< Identifier of SSSP shutdown phase stage 1-1. */ |
... | ... | |
159 | 159 |
#if defined(__cplusplus) |
160 | 160 |
extern "C" { |
161 | 161 |
#endif /* defined(__cplusplus) */ |
162 |
void aosSsspInit(void);
|
|
162 |
void aosSsspInit(aos_timestamp_t* system_uptime);
|
|
163 | 163 |
aos_status_t aosSsspProceed(event_listener_t* listener, eventflags_t flags, eventmask_t mask, eventmask_t* received); |
164 |
void aosSsspShutdownInit(void);
|
|
164 |
void aosSsspShutdownInit(bool active);
|
|
165 | 165 |
#if (AMIROOS_CFG_SSSP_SHUTDOWN == true) || defined(__DOXYGEN__) |
166 | 166 |
void aosSsspShutdownBroadcastIdentifier(unsigned int identifier); |
167 | 167 |
eventmask_t aosSsspShutdownWaitForIdentifierPulse(event_listener_t* gpiolistener, eventflags_t sflags, eventmask_t timermask, unsigned int* identifier); |
168 | 168 |
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */ |
169 |
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__) |
|
170 |
float aosSsspGetSyncSkew(void); |
|
171 |
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */ |
|
169 | 172 |
#if defined(__cplusplus) |
170 | 173 |
} |
171 | 174 |
#endif /* defined(__cplusplus) */ |
core/inc/aos_system.h | ||
---|---|---|
171 | 171 |
#endif /* defined(__cplusplus) */ |
172 | 172 |
void aosSysInit(const char* shellPrompt); |
173 | 173 |
void aosSysStart(void); |
174 |
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined (__DOXYGEN__) |
|
175 |
void aosSysStartUptime(void); |
|
176 |
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
|
174 |
void aosSysStartUptimeS(void); |
|
177 | 175 |
void aosSysGetUptimeX(aos_timestamp_t* ut); |
178 | 176 |
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__) |
179 | 177 |
void aosSysGetDateTime(struct tm* dt); |
core/src/aos_main.cpp | ||
---|---|---|
274 | 274 |
#if (AMIROOS_CFG_SSSP_ENABLE == true) |
275 | 275 |
{ |
276 | 276 |
eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S; |
277 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
|
277 | 278 |
#if (AMIROOS_CFG_SSSP_STACK_START != true) |
278 | 279 |
flagsmask |= MODULE_SSSP_EVENTFLAG_DN; |
279 | 280 |
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */ |
280 | 281 |
#if (AMIROOS_CFG_SSSP_STACK_END != true) |
281 | 282 |
flagsmask |= MODULE_SSSP_EVENTFLAG_UP; |
282 | 283 |
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */ |
284 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
|
283 | 285 |
chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask); |
284 | 286 |
} |
285 | 287 |
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
... | ... | |
600 | 602 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
601 | 603 |
} |
602 | 604 |
|
603 |
// start the internal system uptime counter |
|
604 |
aosSysStartUptime(); |
|
605 |
|
|
606 | 605 |
/* |
607 |
* There must be no delays at this point, thus no hook allowed.
|
|
606 |
* There must be no delay at this point, thus no hook allowed. |
|
608 | 607 |
*/ |
609 | 608 |
|
610 | 609 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
611 | 610 |
|
612 |
//TODO |
|
611 |
//TODO: MSI
|
|
613 | 612 |
|
613 |
#if (HAL_USE_RTC == TRUE) |
|
614 |
|
|
615 |
//TODO: Calendar synchronization |
|
616 |
|
|
617 |
#endif /* (HAL_USE_RTC == TRUE) */ |
|
614 | 618 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
615 | 619 |
|
616 | 620 |
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
... | ... | |
634 | 638 |
* ########################################################################## |
635 | 639 |
*/ |
636 | 640 |
|
641 |
#if (AMIROOS_CFG_SSSP_ENABLE == true) |
|
642 |
/* ignore all SSSP signal events, except for PD and configured events */ |
|
643 |
eventflags = MODULE_SSSP_EVENTFLAG_S; |
|
644 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
|
645 |
#if (AMIROOS_CFG_SSSP_STACK_START != true) |
|
646 |
eventflags |= MODULE_SSSP_EVENTFLAG_DN; |
|
647 |
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */ |
|
648 |
#if (AMIROOS_CFG_SSSP_STACK_END != true) |
|
649 |
eventflags |= MODULE_SSSP_EVENTFLAG_UP; |
|
650 |
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */ |
|
651 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
|
652 |
eventflags &= ~((eventflags_t)AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK); |
|
653 |
_eventListenerGPIO.wflags &= ~eventflags; |
|
654 |
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
|
655 |
|
|
637 | 656 |
// sleep until a shutdown event is received |
638 | 657 |
while (shutdown == AOS_SHUTDOWN_NONE) { |
639 | 658 |
// wait for an event |
... | ... | |
659 | 678 |
#if (AMIROOS_CFG_SSSP_ENABLE == true) |
660 | 679 |
// PD event |
661 | 680 |
if (eventflags & MODULE_SSSP_EVENTFLAG_PD) { |
662 |
aosSsspShutdownInit(); |
|
681 |
aosSsspShutdownInit(false);
|
|
663 | 682 |
shutdown = AOS_SHUTDOWN_PASSIVE; |
664 | 683 |
} |
665 | 684 |
// all other events |
... | ... | |
716 | 735 |
break; |
717 | 736 |
} |
718 | 737 |
|
738 |
#if (AMIROOS_CFG_SSSP_ENABLE == true) |
|
739 |
|
|
740 |
/* |
|
741 |
* Re-anable the S signal GPIO event. |
|
742 |
* Note that events for the optional signals UP and DN are not enabled as they are not utilized during SSSP shutdown phase. |
|
743 |
*/ |
|
744 |
chSysLock(); |
|
745 |
_eventListenerGPIO.wflags |= MODULE_SSSP_EVENTFLAG_S; |
|
746 |
chSysUnlock(); |
|
747 |
|
|
748 |
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
|
749 |
|
|
719 | 750 |
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2) |
720 | 751 |
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS) |
721 | 752 |
AMIROOS_CFG_MAIN_LOOP_HOOK_2(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS); |
core/src/aos_sssp.c | ||
---|---|---|
32 | 32 |
/* LOCAL DEFINITIONS */ |
33 | 33 |
/******************************************************************************/ |
34 | 34 |
|
35 |
#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 |
|
|
35 | 44 |
/******************************************************************************/ |
36 | 45 |
/* EXPORTED VARIABLES */ |
37 | 46 |
/******************************************************************************/ |
... | ... | |
45 | 54 |
/******************************************************************************/ |
46 | 55 |
|
47 | 56 |
/** |
57 |
* @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 |
/** |
|
48 | 85 |
* @brief A timer event based delays. |
49 | 86 |
*/ |
50 | 87 |
static virtual_timer_t _delayTimer; |
... | ... | |
63 | 100 |
/* LOCAL FUNCTIONS */ |
64 | 101 |
/******************************************************************************/ |
65 | 102 |
|
103 |
#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__) |
|
104 |
|
|
105 |
/** |
|
106 |
* @brief Callback function for the Sync signal interrupt. |
|
107 |
* |
|
108 |
* @param[in] args Pointer to the GPIO line identifier. |
|
109 |
*/ |
|
110 |
static void _gpioCallbackSSignal(void *args) |
|
111 |
{ |
|
112 |
aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8)); |
|
113 |
|
|
114 |
apalControlGpioState_t s; |
|
115 |
aos_timestamp_t t; |
|
116 |
|
|
117 |
chSysLockFromISR(); |
|
118 |
|
|
119 |
// if the system is in operation phase |
|
120 |
if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) { |
|
121 |
// read signal S |
|
122 |
apalControlGpioGet(&moduleSsspGpioS, &s); |
|
123 |
// if S was toggled from on to off |
|
124 |
if (s == APAL_GPIO_OFF) { |
|
125 |
// get current uptime |
|
126 |
aosSysGetUptimeX(&t); |
|
127 |
// align the uptime with the synchronization period |
|
128 |
t %= AMIROOS_CFG_SSSP_SYSSYNCPERIOD; |
|
129 |
if (t < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) { |
|
130 |
*_uptime -= t; |
|
131 |
#if (AMIROOS_CFG_PROFILE == true) |
|
132 |
_syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) + (SYNCSKEW_SMOOTHFACTOR * t); |
|
133 |
#endif /* (AMIROOS_CFG_PROFILE == true) */ |
|
134 |
} else { |
|
135 |
t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - t; |
|
136 |
*_uptime += t; |
|
137 |
#if (AMIROOS_CFG_PROFILE == true) |
|
138 |
_syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) - (SYNCSKEW_SMOOTHFACTOR * t); |
|
139 |
#endif /* (AMIROOS_CFG_PROFILE == true) */ |
|
140 |
} |
|
141 |
} |
|
142 |
} |
|
143 |
|
|
144 |
// broadcast event |
|
145 |
chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args)))); |
|
146 |
chSysUnlockFromISR(); |
|
147 |
|
|
148 |
return; |
|
149 |
} |
|
150 |
|
|
151 |
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */ |
|
152 |
|
|
153 |
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined (__DOXYGEN__) |
|
154 |
|
|
155 |
/** |
|
156 |
* @brief Periodic system synchronization callback function. |
|
157 |
* @details Toggles the SYS_SYNC signal and reconfigures the system synchronization timer. |
|
158 |
* |
|
159 |
* @param[in] par Unused parameters. |
|
160 |
*/ |
|
161 |
static void _syncTimerCallback(void* par) |
|
162 |
{ |
|
163 |
(void)par; |
|
164 |
|
|
165 |
apalControlGpioState_t state; |
|
166 |
aos_timestamp_t uptime; |
|
167 |
|
|
168 |
chSysLockFromISR(); |
|
169 |
// toggle and read signal S |
|
170 |
apalGpioToggle(moduleSsspGpioS.gpio); |
|
171 |
apalControlGpioGet(&moduleSsspGpioS, &state); |
|
172 |
// if S was toggled from off to on |
|
173 |
if (state == APAL_GPIO_ON) { |
|
174 |
// reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time |
|
175 |
_synctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD; |
|
176 |
aosSysGetUptimeX(&uptime); |
|
177 |
chVTSetI(&_synctimer, chTimeUS2I(_synctime - uptime), _syncTimerCallback, NULL); |
|
178 |
} |
|
179 |
// if S was toggled from on to off |
|
180 |
else /* if (state == APAL_GPIO_OFF) */ { |
|
181 |
// reconfigure the timer (lazy) |
|
182 |
chVTSetI(&_synctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _syncTimerCallback, NULL); |
|
183 |
} |
|
184 |
chSysUnlockFromISR(); |
|
185 |
|
|
186 |
return; |
|
187 |
} |
|
188 |
|
|
189 |
/** |
|
190 |
* @brief Start the timer that toggles S for synchronization of the system. |
|
191 |
* @note Must be called from a locked context. |
|
192 |
*/ |
|
193 |
static inline void _syncTimerStartS(void) |
|
194 |
{ |
|
195 |
chDbgCheckClassS(); |
|
196 |
|
|
197 |
// start synchronization timer |
|
198 |
// The first iteration of the timer is set to the next 'center' of a 'slice'. |
|
199 |
aos_timestamp_t t; |
|
200 |
aosSysGetUptimeX(&t); |
|
201 |
t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD); |
|
202 |
chVTSetI(&_synctimer, chTimeUS2I((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2))), _syncTimerCallback, NULL); |
|
203 |
|
|
204 |
return; |
|
205 |
} |
|
206 |
|
|
207 |
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
208 |
|
|
66 | 209 |
/** |
67 | 210 |
* @brief General callback function to be used for any local timers. |
68 | 211 |
* |
... | ... | |
153 | 296 |
/** |
154 | 297 |
* @brief Initialize all SSSP related data. |
155 | 298 |
*/ |
156 |
void aosSsspInit(void)
|
|
299 |
void aosSsspInit(aos_timestamp_t* system_uptime)
|
|
157 | 300 |
{ |
301 |
aosDbgCheck(system_uptime != NULL); |
|
302 |
|
|
158 | 303 |
// local variables |
159 | 304 |
apalControlGpioState_t state; |
160 | 305 |
|
... | ... | |
171 | 316 |
aosDbgAssert(state == APAL_GPIO_ON); |
172 | 317 |
apalControlGpioGet(&moduleSsspGpioPD, &state); |
173 | 318 |
aosDbgAssert(state == APAL_GPIO_OFF); |
319 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
|
174 | 320 |
#if (AMIROOS_CFG_SSSP_STACK_END != true) |
175 | 321 |
apalControlGpioGet(&moduleSsspGpioUP, &state); |
176 | 322 |
aosDbgAssert(state == APAL_GPIO_OFF); |
... | ... | |
179 | 325 |
apalControlGpioGet(&moduleSsspGpioDN, &state); |
180 | 326 |
aosDbgAssert(state == APAL_GPIO_OFF); |
181 | 327 |
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */ |
328 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
|
182 | 329 |
|
183 | 330 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
184 | 331 |
// module ID is initialized as 'invalid' |
... | ... | |
186 | 333 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
187 | 334 |
|
188 | 335 |
// initialize static variables |
336 |
_uptime = system_uptime; |
|
337 |
#if (AMIROOS_CFG_SSSP_MASTER == true) |
|
338 |
chVTObjectInit(&_synctimer); |
|
339 |
_synctime = 0; |
|
340 |
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
341 |
#if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) |
|
342 |
_syncskew = 0.0f; |
|
343 |
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */ |
|
189 | 344 |
chVTObjectInit(&_delayTimer); |
190 | 345 |
chEvtObjectInit(&_eventSourceDelay); |
191 | 346 |
|
347 |
// signal interrupt setup |
|
348 |
palSetLineCallback(moduleSsspGpioPD.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioPD.gpio->line); |
|
349 |
palEnableLineEvent(moduleSsspGpioPD.gpio->line, APAL2CH_EDGE(moduleSsspGpioPD.meta.edge)); |
|
350 |
#if (AMIROOS_CFG_SSSP_MASTER == true) |
|
351 |
palSetLineCallback(moduleSsspGpioS.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioS.gpio->line); |
|
352 |
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
353 |
palSetLineCallback(moduleSsspGpioS.gpio->line, _gpioCallbackSSignal, &moduleSsspGpioS.gpio->line); |
|
354 |
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
355 |
palEnableLineEvent(moduleSsspGpioS.gpio->line, APAL2CH_EDGE(moduleSsspGpioS.meta.edge)); |
|
356 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
|
357 |
#if (AMIROOS_CFG_SSSP_STACK_START != true) |
|
358 |
palSetLineCallback(moduleSsspGpioDN.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioDN.gpio->line); |
|
359 |
palEnableLineEvent(moduleSsspGpioDN.gpio->line, APAL2CH_EDGE(moduleSsspGpioDN.meta.edge)); |
|
360 |
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */ |
|
361 |
#if (AMIROOS_CFG_SSSP_STACK_END != true) |
|
362 |
palSetLineCallback(moduleSsspGpioUP.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioUP.gpio->line); |
|
363 |
palEnableLineEvent(moduleSsspGpioUP.gpio->line, APAL2CH_EDGE(moduleSsspGpioUP.meta.edge)); |
|
364 |
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */ |
|
365 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
|
366 |
|
|
192 | 367 |
return; |
193 | 368 |
} |
194 | 369 |
|
195 | 370 |
/** |
196 | 371 |
* @brief Proceed to the next SSSP stage. |
372 |
* @note Calling this function when in operation phase is invalid. |
|
373 |
* The function aosSsspShutdownInit() must be used instead. |
|
197 | 374 |
* |
198 | 375 |
* @param[in] listener An optional listener, in case the system has to wait for a specific event. |
199 | 376 |
* @param[in] flags The relevant flags to wait for (mandatory if a listener is given). |
... | ... | |
331 | 508 |
|
332 | 509 |
/* |
333 | 510 |
* Wait for the S signal to become inactive. |
511 |
* When proceeding to operation phase, the master starts toggling S for synchronization |
|
334 | 512 |
*/ |
335 | 513 |
case AOS_SSSP_STAGE_STARTUP_2_2: |
336 | 514 |
{ |
... | ... | |
344 | 522 |
#if (AMIROOS_CFG_SSSP_MSI == true) |
345 | 523 |
nextstage = AOS_SSSP_STAGE_STARTUP_3; |
346 | 524 |
#else /* (AMIROOS_CFG_SSSP_MSI == true) */ |
525 |
chSysLock(); |
|
526 |
// start the internal uptime aggregation |
|
527 |
aosSysStartUptimeS(); |
|
528 |
#if (AMIROOS_CFG_SSSP_MASTER == true) |
|
529 |
// start toggling S for system synchronization |
|
530 |
_syncTimerStartS(); |
|
531 |
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
532 |
chSysUnlock(); |
|
347 | 533 |
nextstage = AOS_SSSP_STAGE_OPERATION; |
348 | 534 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
349 | 535 |
} |
... | ... | |
357 | 543 |
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */ |
358 | 544 |
|
359 | 545 |
/* |
546 |
* Invalid operation. |
|
547 |
* Shutdon must be initiatid via the aosSsspShutdownInit() function. |
|
548 |
*/ |
|
549 |
case AOS_SSSP_STAGE_OPERATION: |
|
550 |
{ |
|
551 |
aosDbgAssertMsg(false, "in order to exit operation phase, aosSsspShutdownInit() function must be used"); |
|
552 |
break; |
|
553 |
} |
|
554 |
|
|
555 |
/* |
|
360 | 556 |
* Delay execution by one perion AOS_SSSP_DELAY, deactivate the SYNC signal and proceed. |
361 | 557 |
* NOTE: Actually only the module that initiated the shutdown has to delay execution here. |
362 | 558 |
* For the sake of simlicity though, each module delays execution. |
... | ... | |
446 | 642 |
return status; |
447 | 643 |
} |
448 | 644 |
|
449 |
void aosSsspShutdownInit(void) |
|
645 |
/** |
|
646 |
* @brief Leave the operation pahse and initiate or acknowledge shutdown. |
|
647 |
* |
|
648 |
* @param[in] active Flag, indicating whether the shutdon shall be activeliy initiated (true) or a passive request was received (false). |
|
649 |
*/ |
|
650 |
void aosSsspShutdownInit(bool active) |
|
450 | 651 |
{ |
451 |
// activate S signal
|
|
452 |
apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON); |
|
652 |
aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_OPERATION);
|
|
653 |
|
|
453 | 654 |
// proceed to shutdown phase |
655 |
aos.sssp.stage = AOS_SSSP_STAGE_SHUTDOWN_1_1; |
|
656 |
|
|
657 |
// activate PD if this was an active shutdown initiation |
|
658 |
if (active) { |
|
659 |
apalControlGpioSet(&moduleSsspGpioPD, APAL_GPIO_ON); |
|
660 |
} |
|
661 |
|
|
662 |
#if (AMIROOS_CFG_SSSP_MASTER == true) |
|
663 |
// stop toggling S |
|
664 |
chVTReset(&_synctimer); |
|
665 |
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */ |
|
666 |
|
|
667 |
// activate S |
|
668 |
apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON); |
|
669 |
|
|
670 |
// proceed in the shutdown phase |
|
454 | 671 |
aos.sssp.stage = AOS_SSSP_STAGE_SHUTDOWN_1_2; |
455 | 672 |
|
456 | 673 |
return; |
... | ... | |
547 | 764 |
|
548 | 765 |
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */ |
549 | 766 |
|
767 |
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__) |
|
768 |
|
|
769 |
/** |
|
770 |
* @brief Retreive the offset between local clock and system synchronization signal. |
|
771 |
* |
|
772 |
* @return |
|
773 |
*/ |
|
774 |
float aosSsspGetSyncSkew(void) |
|
775 |
{ |
|
776 |
return _syncskew; |
|
777 |
} |
|
778 |
|
|
779 |
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */ |
|
780 |
|
|
550 | 781 |
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */ |
551 | 782 |
|
552 | 783 |
/** @} */ |
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