mirror of
https://github.com/espressif/openthread.git
synced 2026-08-19 08:59:52 +00:00
[posix-app] fix alarm issue when time changed (#3728)
Current posix app uses gettimeofday() to get time, which will be affected by system time changes, and results in alarm not fired. This commit uses clock_gettime() instead to avoid this issue.
This commit is contained in:
@@ -64,18 +64,9 @@ cd /tmp || die
|
||||
}
|
||||
|
||||
[ $BUILD_TARGET != posix-app-pty ] || {
|
||||
sudo apt-get install socat expect libdbus-1-dev autoconf-archive || die
|
||||
sudo apt-get install socat expect || die
|
||||
JOBS=$(getconf _NPROCESSORS_ONLN)
|
||||
(
|
||||
WPANTUND_TMPDIR=/tmp/wpantund
|
||||
git clone --depth 1 https://github.com/openthread/wpantund.git $WPANTUND_TMPDIR
|
||||
cd $WPANTUND_TMPDIR
|
||||
./bootstrap.sh
|
||||
./configure --prefix= --exec-prefix=/usr --disable-ncp-dummy --enable-static-link-ncp-plugin=spinel
|
||||
make -j $JOBS
|
||||
sudo make install
|
||||
) || die
|
||||
(
|
||||
LIBCOAP_TMPDIR=/tmp/libcoap
|
||||
mkdir $LIBCOAP_TMPDIR
|
||||
cd $LIBCOAP_TMPDIR
|
||||
|
||||
+21
-20
@@ -33,6 +33,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openthread/platform/alarm-micro.h>
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
@@ -40,10 +41,6 @@
|
||||
|
||||
#include "code_utils.h"
|
||||
|
||||
#define MS_PER_S 1000
|
||||
#define US_PER_MS 1000
|
||||
#define US_PER_S 1000000
|
||||
|
||||
static bool sIsMsRunning = false;
|
||||
static uint32_t sMsAlarm = 0;
|
||||
|
||||
@@ -52,28 +49,32 @@ static bool sIsUsRunning = false;
|
||||
static uint32_t sUsAlarm = 0;
|
||||
#endif
|
||||
|
||||
static uint32_t sSpeedUpFactor = 1;
|
||||
static struct timeval sStart;
|
||||
static uint32_t sSpeedUpFactor = 1;
|
||||
|
||||
#if !OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
uint64_t otSysGetTime(void)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
VerifyOrDie(clock_gettime(CLOCK_MONOTONIC, &now) == 0, OT_EXIT_FAILURE);
|
||||
|
||||
return (uint64_t)now.tv_sec * US_PER_S + (uint64_t)now.tv_nsec / NS_PER_US;
|
||||
}
|
||||
#endif // !OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
|
||||
static uint64_t platformAlarmGetNow(void)
|
||||
{
|
||||
return otSysGetTime() * sSpeedUpFactor;
|
||||
}
|
||||
|
||||
void platformAlarmInit(uint32_t aSpeedUpFactor)
|
||||
{
|
||||
sSpeedUpFactor = aSpeedUpFactor;
|
||||
otSysGetTime(&sStart);
|
||||
}
|
||||
|
||||
static uint64_t platformGetNow(void)
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
otSysGetTime(&now);
|
||||
timersub(&now, &sStart, &now);
|
||||
|
||||
return (uint64_t)now.tv_sec * US_PER_S * sSpeedUpFactor + (uint64_t)now.tv_usec * sSpeedUpFactor;
|
||||
}
|
||||
|
||||
uint32_t otPlatAlarmMilliGetNow(void)
|
||||
{
|
||||
return (uint32_t)(platformGetNow() / US_PER_MS);
|
||||
return (uint32_t)(platformAlarmGetNow() / US_PER_MS);
|
||||
}
|
||||
|
||||
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
|
||||
@@ -94,7 +95,7 @@ void otPlatAlarmMilliStop(otInstance *aInstance)
|
||||
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
|
||||
uint32_t otPlatAlarmMicroGetNow(void)
|
||||
{
|
||||
return (uint32_t)(platformGetNow());
|
||||
return (uint32_t)(otSysGetTime());
|
||||
}
|
||||
|
||||
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
|
||||
@@ -116,7 +117,7 @@ void otPlatAlarmMicroStop(otInstance *aInstance)
|
||||
void platformAlarmUpdateTimeout(struct timeval *aTimeout)
|
||||
{
|
||||
int64_t remaining = INT32_MAX;
|
||||
uint64_t now = platformGetNow();
|
||||
uint64_t now = platformAlarmGetNow();
|
||||
|
||||
assert(aTimeout != NULL);
|
||||
|
||||
|
||||
@@ -256,15 +256,12 @@ otError HdlcInterface::WaitForWritable(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
|
||||
struct timeval end;
|
||||
struct timeval now;
|
||||
uint64_t now = otSysGetTime();
|
||||
uint64_t end = now + kMaxWaitTime * US_PER_MS;
|
||||
fd_set writeFds;
|
||||
fd_set errorFds;
|
||||
int rval;
|
||||
|
||||
otSysGetTime(&now);
|
||||
timeradd(&now, &timeout, &end);
|
||||
|
||||
while (true)
|
||||
{
|
||||
FD_ZERO(&writeFds);
|
||||
@@ -297,11 +294,14 @@ otError HdlcInterface::WaitForWritable(void)
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
otSysGetTime(&now);
|
||||
now = otSysGetTime();
|
||||
|
||||
if (timercmp(&end, &now, >))
|
||||
if (end > now)
|
||||
{
|
||||
timersub(&end, &now, &timeout);
|
||||
uint64_t remain = end - now;
|
||||
|
||||
timeout.tv_sec = remain / US_PER_S;
|
||||
timeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -138,13 +138,10 @@ void platformAlarmProcess(otInstance *aInstance);
|
||||
*/
|
||||
int32_t platformAlarmGetNext(void);
|
||||
|
||||
/**
|
||||
* This function returns the current alarm time.
|
||||
*
|
||||
* @returns The current alarm time.
|
||||
*
|
||||
*/
|
||||
uint64_t platformAlarmGetNow(void);
|
||||
#define MS_PER_S 1000
|
||||
#define US_PER_MS 1000
|
||||
#define US_PER_S 1000000
|
||||
#define NS_PER_US 1000
|
||||
|
||||
/**
|
||||
* This function advances the alarm time by @p aDelta.
|
||||
@@ -275,14 +272,6 @@ void otSimInit(void);
|
||||
*/
|
||||
void otSimDeinit(void);
|
||||
|
||||
/**
|
||||
* This function gets simulation time.
|
||||
*
|
||||
* @param[in] aTime A pointer to a timeval receiving the current time.
|
||||
*
|
||||
*/
|
||||
void otSimGetTime(struct timeval *aTime);
|
||||
|
||||
/**
|
||||
* This function performs simulation processing.
|
||||
*
|
||||
@@ -354,11 +343,13 @@ void otSimRadioSpinelUpdate(struct timeval *atimeout);
|
||||
*/
|
||||
void otSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent);
|
||||
|
||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
#define otSysGetTime(aTime) otSimGetTime(aTime)
|
||||
#else
|
||||
#define otSysGetTime(aTime) gettimeofday(aTime, NULL)
|
||||
#endif
|
||||
/**
|
||||
* This function gets system time in microseconds without applying speed up factor.
|
||||
*
|
||||
* @returns System time in microseconds.
|
||||
*
|
||||
*/
|
||||
uint64_t otSysGetTime(void);
|
||||
|
||||
/**
|
||||
* This function initializes platform UDP driver.
|
||||
|
||||
@@ -923,13 +923,10 @@ otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...)
|
||||
|
||||
otError RadioSpinel::WaitResponse(void)
|
||||
{
|
||||
struct timeval end;
|
||||
struct timeval now;
|
||||
uint64_t now = otSysGetTime();
|
||||
uint64_t end = now + kMaxWaitTime * US_PER_MS;
|
||||
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
|
||||
|
||||
otSysGetTime(&now);
|
||||
timeradd(&now, &timeout, &end);
|
||||
|
||||
do
|
||||
{
|
||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
@@ -997,10 +994,14 @@ otError RadioSpinel::WaitResponse(void)
|
||||
}
|
||||
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
|
||||
otSysGetTime(&now);
|
||||
if (timercmp(&end, &now, >))
|
||||
now = otSysGetTime();
|
||||
|
||||
if (end > now)
|
||||
{
|
||||
timersub(&end, &now, &timeout);
|
||||
uint64_t remain = end - now;
|
||||
|
||||
timeout.tv_sec = remain / US_PER_S;
|
||||
timeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -198,10 +198,9 @@ void otSimProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set
|
||||
otSimRadioSpinelProcess(aInstance, &event);
|
||||
}
|
||||
|
||||
void otSimGetTime(struct timeval *aTime)
|
||||
uint64_t otSysGetTime(void)
|
||||
{
|
||||
aTime->tv_sec = (time_t)sNow / kUsPerSecond;
|
||||
aTime->tv_usec = sNow % kUsPerSecond;
|
||||
return sNow;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
|
||||
Reference in New Issue
Block a user