[posix-app] expose mainloop APIs (#3490)

This commit is contained in:
Yakun Xu
2019-01-23 08:46:33 -08:00
committed by Jonathan Hui
parent dde12296e5
commit d8c17ceef2
5 changed files with 102 additions and 49 deletions
+26 -2
View File
@@ -28,9 +28,13 @@
#include <assert.h>
#include <openthread-core-config.h>
#include "openthread-core-config.h"
#include "platform-posix.h"
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#ifdef __linux__
#include <sys/prctl.h>
@@ -97,8 +101,28 @@ int main(int argc, char *argv[])
while (true)
{
otSysMainloopContext mainloop;
otTaskletsProcess(instance);
otSysProcessDrivers(instance);
FD_ZERO(&mainloop.mReadFdSet);
FD_ZERO(&mainloop.mWriteFdSet);
FD_ZERO(&mainloop.mErrorFdSet);
mainloop.mMaxFd = -1;
mainloop.mTimeout.tv_sec = 10;
mainloop.mTimeout.tv_usec = 0;
otSysMainloopUpdate(instance, &mainloop);
if (otSysMainloopPoll(&mainloop) >= 0)
{
otSysMainloopProcess(instance, &mainloop);
}
else if (errno != EINTR)
{
perror("select");
exit(OT_EXIT_FAILURE);
}
}
otInstanceFinalize(instance);
+35 -2
View File
@@ -72,16 +72,49 @@ void otSysInitNetif(otInstance *aInstance);
*/
void otSysDeinit(void);
/**
* This structure represents a context for a select() based mainloop.
*
*/
typedef struct otSysMainloopContext
{
fd_set mReadFdSet; ///< The read file descriptors.
fd_set mWriteFdSet; ///< The write file descriptors.
fd_set mErrorFdSet; ///< The error file descriptors.
int mMaxFd; ///< The max file descriptor.
struct timeval mTimeout; ///< The timeout.
} otSysMainloopContext;
/**
* This function updates the file descriptor sets with file descriptors used by OpenThread drivers.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[inout] aMainloop A pointer to the mainloop context.
*
*/
void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop);
/**
* This function polls OpenThread's mainloop.
*
* @param[inout] aMainloop A pointer to the mainloop context.
*
* @returns value returned from select().
*
*/
int otSysMainloopPoll(otSysMainloopContext *aMainloop);
/**
* This function performs all platform-specific processing for OpenThread's example applications.
*
* @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
* in the main loop when processing OpenThread's drivers is most appropriate.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aMainloop A pointer to the mainloop context.
*
*/
void otSysProcessDrivers(otInstance *aInstance);
void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
/**
* This function is called whenever platform drivers needs processing.
+1 -1
View File
@@ -200,7 +200,7 @@ void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMax
* @param[in] aWriteFdSet A pointer to the write file descriptors.
*
*/
void platformRadioProcess(otInstance *aInstance, fd_set *aReadFdSet, fd_set *aWriteFdSet);
void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet);
/**
* This function initializes the random number service used by OpenThread.
+1 -1
View File
@@ -1455,7 +1455,7 @@ void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMax
sRadioSpinel.UpdateFdSet(*aReadFdSet, *aWriteFdSet, *aMaxFd, *aTimeout);
}
void platformRadioProcess(otInstance *aInstance, fd_set *aReadFdSet, fd_set *aWriteFdSet)
void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
{
sRadioSpinel.Process(*aReadFdSet, *aWriteFdSet);
OT_UNUSED_VARIABLE(aInstance);
+39 -43
View File
@@ -35,7 +35,6 @@
#include "platform-posix.h"
#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <stddef.h>
@@ -49,6 +48,8 @@
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
#include "openthread-system.h"
uint64_t gNodeId = 0;
static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
@@ -213,53 +214,50 @@ static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSe
}
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
void otSysProcessDrivers(otInstance *aInstance)
void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
{
fd_set readFdSet;
fd_set writeFdSet;
fd_set errorFdSet;
struct timeval timeout;
int maxFd = -1;
int rval;
FD_ZERO(&readFdSet);
FD_ZERO(&writeFdSet);
FD_ZERO(&errorFdSet);
platformAlarmUpdateTimeout(&timeout);
platformUartUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd);
platformAlarmUpdateTimeout(&aMainloop->mTimeout);
platformUartUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
&aMainloop->mMaxFd);
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpUpdateFdSet(aInstance, &readFdSet, &maxFd);
platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd);
#endif
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
platformNetifUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd);
platformNetifUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
&aMainloop->mMaxFd);
#endif
#if OPENTHREAD_POSIX_VIRTUAL_TIME
otSimUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd, &timeout);
otSimUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, &aMainloop->mMaxFd,
&aMainloop->mTimeout);
#else
platformRadioUpdateFdSet(&readFdSet, &writeFdSet, &maxFd, &timeout);
platformRadioUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mMaxFd, &aMainloop->mTimeout);
#endif
if (otTaskletsArePending(aInstance))
{
timeout.tv_sec = 0;
timeout.tv_usec = 0;
aMainloop->mTimeout.tv_sec = 0;
aMainloop->mTimeout.tv_usec = 0;
}
}
int otSysMainloopPoll(otSysMainloopContext *aMainloop)
{
int rval;
#if OPENTHREAD_POSIX_VIRTUAL_TIME
if (timerisset(&timeout))
if (timerisset(&aMainloop->mTimeout))
{
// Make sure there are no data ready in UART
rval = trySelect(&readFdSet, &writeFdSet, &errorFdSet, maxFd);
rval = trySelect(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, aMainloop->mMaxFd);
if (rval == 0)
{
bool noWrite = true;
// If there are write requests, the device is supposed to wake soon
for (int i = 0; i < maxFd + 1; ++i)
for (int i = 0; i < aMainloop->mMaxFd + 1; ++i)
{
if (FD_ISSET(i, &writeFdSet))
if (FD_ISSET(i, &aMainloop->mWriteFdSet))
{
noWrite = false;
break;
@@ -268,38 +266,36 @@ void otSysProcessDrivers(otInstance *aInstance)
if (noWrite)
{
otSimSendSleepEvent(&timeout);
otSimSendSleepEvent(&aMainloop->mTimeout);
}
rval = select(maxFd + 1, &readFdSet, &writeFdSet, &errorFdSet, NULL);
assert(rval > 0);
rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet,
&aMainloop->mErrorFdSet, NULL);
}
}
else
#endif
{
rval = select(maxFd + 1, &readFdSet, &writeFdSet, &errorFdSet, &timeout);
rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
&aMainloop->mTimeout);
}
if ((rval < 0) && (errno != EINTR))
{
perror("select");
exit(OT_EXIT_FAILURE);
}
else if (rval >= 0)
{
return rval;
}
void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop)
{
#if OPENTHREAD_POSIX_VIRTUAL_TIME
otSimProcess(aInstance, &readFdSet, &writeFdSet, &errorFdSet);
otSimProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
#else
platformRadioProcess(aInstance, &readFdSet, &writeFdSet);
platformRadioProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet);
#endif
platformUartProcess(&readFdSet, &writeFdSet, &errorFdSet);
platformAlarmProcess(aInstance);
platformUartProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
platformAlarmProcess(aInstance);
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
platformNetifProcess(&readFdSet, &writeFdSet, &errorFdSet);
platformNetifProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
#endif
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpProcess(aInstance, &readFdSet);
platformUdpProcess(aInstance, &aMainloop->mReadFdSet);
#endif
}
}