[posix] add microsecond timer support (#2086)

This commit is contained in:
Shu Chen
2017-08-10 10:08:17 -07:00
committed by Jonathan Hui
parent 592fbb27b1
commit 588613ba65
5 changed files with 152 additions and 28 deletions
+84 -28
View File
@@ -32,16 +32,27 @@
#include <stdio.h>
#include <string.h>
#include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
static bool s_is_running = false;
static uint32_t s_alarm = 0;
static struct timeval s_start;
#define MS_PER_S 1000
#define US_PER_MS 1000
#define US_PER_S 1000000
#define DEFAULT_TIMEOUT 10 // seconds
static bool sIsMsRunning = false;
static uint32_t sMsAlarm = 0;
static bool sIsUsRunning = false;
static uint32_t sUsAlarm = 0;
static struct timeval sStart;
void platformAlarmInit(void)
{
gettimeofday(&s_start, NULL);
gettimeofday(&sStart, NULL);
}
uint32_t otPlatAlarmMilliGetNow(void)
@@ -49,52 +60,81 @@ uint32_t otPlatAlarmMilliGetNow(void)
struct timeval tv;
gettimeofday(&tv, NULL);
timersub(&tv, &s_start, &tv);
timersub(&tv, &sStart, &tv);
return (uint32_t)((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
return (uint32_t)((tv.tv_sec * MS_PER_S) + (tv.tv_usec / US_PER_MS));
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
(void)aInstance;
s_alarm = t0 + dt;
s_is_running = true;
sMsAlarm = aT0 + aDt;
sIsMsRunning = true;
}
void otPlatAlarmMilliStop(otInstance *aInstance)
{
(void)aInstance;
s_is_running = false;
sIsMsRunning = false;
}
uint32_t otPlatAlarmMicroGetNow(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
timersub(&tv, &sStart, &tv);
return (uint32_t)(tv.tv_sec * US_PER_S + tv.tv_usec);
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
(void)aInstance;
sUsAlarm = aT0 + aDt;
sIsUsRunning = true;
}
void otPlatAlarmMicroStop(otInstance *aInstance)
{
(void)aInstance;
sIsUsRunning = false;
}
void platformAlarmUpdateTimeout(struct timeval *aTimeout)
{
int32_t remaining;
int32_t usRemaining = DEFAULT_TIMEOUT * US_PER_S;
int32_t msRemaining = DEFAULT_TIMEOUT * MS_PER_S;
if (aTimeout == NULL)
{
return;
}
if (s_is_running)
if (sIsUsRunning)
{
remaining = (int32_t)(s_alarm - otPlatAlarmMilliGetNow());
usRemaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
}
if (remaining > 0)
{
aTimeout->tv_sec = remaining / 1000;
aTimeout->tv_usec = (remaining % 1000) * 1000;
}
else
{
aTimeout->tv_sec = 0;
aTimeout->tv_usec = 0;
}
if (sIsMsRunning)
{
msRemaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
}
if (usRemaining <= 0 || msRemaining <= 0)
{
aTimeout->tv_sec = 0;
aTimeout->tv_usec = 0;
}
else if (msRemaining * US_PER_MS < usRemaining)
{
aTimeout->tv_sec = msRemaining / MS_PER_S;
aTimeout->tv_usec = (msRemaining % MS_PER_S) * US_PER_MS;
}
else
{
aTimeout->tv_sec = 10;
aTimeout->tv_usec = 0;
aTimeout->tv_sec = usRemaining / US_PER_S;
aTimeout->tv_usec = usRemaining % US_PER_S;
}
}
@@ -102,13 +142,13 @@ void platformAlarmProcess(otInstance *aInstance)
{
int32_t remaining;
if (s_is_running)
if (sIsMsRunning)
{
remaining = (int32_t)(s_alarm - otPlatAlarmMilliGetNow());
remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
if (remaining <= 0)
{
s_is_running = false;
sIsMsRunning = false;
#if OPENTHREAD_ENABLE_DIAG
@@ -123,4 +163,20 @@ void platformAlarmProcess(otInstance *aInstance)
}
}
}
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
if (sIsUsRunning)
{
remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
if (remaining <= 0)
{
sIsUsRunning = false;
otPlatAlarmMicroFired(aInstance);
}
}
#endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
}
@@ -51,4 +51,12 @@
*/
#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1
/**
* @def OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
*
* Define to 1 if you want to support microsecond timer in platform.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER 1
#endif // OPENTHREAD_CORE_POSIX_CONFIG_H_
+17
View File
@@ -54,6 +54,23 @@ void otPlatAlarmMilliStop(otInstance *aInstance)
(void)aInstance;
}
uint32_t otPlatAlarmMicroGetNow(void)
{
return 0;
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
(void)aInstance;
(void)aT0;
(void)aDt;
}
void otPlatAlarmMicroStop(otInstance *aInstance)
{
(void)aInstance;
}
void otPlatReset(otInstance *aInstance)
{
(void)aInstance;
+4
View File
@@ -57,6 +57,10 @@ extern "C" void otPlatAlarmMilliFired(otInstance *)
{
}
extern "C" void otPlatAlarmMicroFired(otInstance *)
{
}
extern "C" void otPlatRadioTxDone(otInstance *, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
{
(void)aFrame;
+39
View File
@@ -174,6 +174,45 @@ extern "C" {
}
}
void otPlatAlarmMicroStop(otInstance *aInstance)
{
if (g_testPlatAlarmStop)
{
g_testPlatAlarmStop(aInstance);
}
else
{
g_testPlatAlarmSet = false;
}
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
if (g_testPlatAlarmStartAt)
{
g_testPlatAlarmStartAt(aInstance, aT0, aDt);
}
else
{
g_testPlatAlarmSet = true;
g_testPlatAlarmNext = aT0 + aDt;
}
}
uint32_t otPlatAlarmMicroGetNow(void)
{
if (g_testPlatAlarmGetNow)
{
return g_testPlatAlarmGetNow();
}
else
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint32_t)((tv.tv_sec * 1000000) + tv.tv_usec + 123456);
}
}
//
// Radio
//