LwIP v2 support

This commit is contained in:
Our Air Quality 2017-06-06 12:47:21 +10:00
parent 1cfded6389
commit cd23acaa4a
39 changed files with 1357 additions and 664 deletions

View file

@ -49,17 +49,147 @@
#include "lwip/mem.h"
#include "lwip/stats.h"
extern bool esp_in_isr;
/* Based on the default xInsideISR mechanism to determine
if an ISR is running.
Doesn't support the possibility that LWIP functions are called from the NMI
handler (none are called from NMI when using current/SDK implementation.)
*/
static inline bool is_inside_isr()
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t ucCount)
{
return esp_in_isr;
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary(*pxSemaphore);
if (*pxSemaphore != NULL) {
if (ucCount == 0U) {
xSemaphoreTake(*pxSemaphore, 1UL);
}
xReturn = ERR_OK;
SYS_STATS_INC_USED(sem);
} else {
SYS_STATS_INC(sem.err);
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free(sys_sem_t *pxSemaphore)
{
SYS_STATS_DEC(sem.used);
vQueueDelete(*pxSemaphore);
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal(sys_sem_t *pxSemaphore)
{
xSemaphoreGive(*pxSemaphore);
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* Blocks the thread while waiting for the semaphore to be signaled. If the
* "timeout" argument is non-zero, the thread should only be blocked for
* the specified time (measured in milliseconds). If the "timeout" argument
* is zero, the thread should be blocked until the semaphore is signalled.
*
* The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled
* within the specified time or any other value if it was signaled (with or
* without waiting).
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value on success
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t ulTimeout)
{
u32_t ulReturn;
if (ulTimeout != 0UL) {
if (xSemaphoreTake(*pxSemaphore, ulTimeout / portTICK_PERIOD_MS) == pdTRUE) {
ulReturn = 0;
} else {
ulReturn = SYS_ARCH_TIMEOUT;
}
} else {
while (xSemaphoreTake(*pxSemaphore, portMAX_DELAY) != pdTRUE);
ulReturn = 0;
}
return ulReturn;
}
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new(sys_mutex_t *pxMutex)
{
err_t xReturn;
*pxMutex = xSemaphoreCreateMutex();
if (*pxMutex != NULL) {
xReturn = ERR_OK;
SYS_STATS_INC_USED(mutex);
} else {
xReturn = ERR_MEM;
SYS_STATS_INC(mutex.err);
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock(sys_mutex_t *pxMutex)
{
while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex)
{
xSemaphoreGive(*pxMutex);
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free(sys_mutex_t *pxMutex)
{
SYS_STATS_DEC(mutex.used);
vQueueDelete(*pxMutex);
}
/*---------------------------------------------------------------------------*
@ -72,16 +202,15 @@ static inline bool is_inside_isr()
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
err_t sys_mbox_new(sys_mbox_t *pxMailBox, int iSize)
{
err_t xReturn = ERR_MEM;
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
*pxMailBox = xQueueCreate(iSize, sizeof(void *));
if( *pxMailBox != NULL )
{
if (*pxMailBox != NULL) {
xReturn = ERR_OK;
SYS_STATS_INC_USED( mbox );
SYS_STATS_INC_USED(mbox);
}
return xReturn;
@ -100,25 +229,24 @@ err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free( sys_mbox_t *pxMailBox )
void sys_mbox_free(sys_mbox_t *pxMailBox)
{
unsigned long ulMessagesWaiting;
unsigned long ulMessagesWaiting;
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
configASSERT( ( ulMessagesWaiting == 0 ) );
ulMessagesWaiting = uxQueueMessagesWaiting(*pxMailBox);
configASSERT(ulMessagesWaiting == 0);
#if SYS_STATS
{
if( ulMessagesWaiting != 0UL )
{
SYS_STATS_INC( mbox.err );
if (ulMessagesWaiting != 0UL) {
SYS_STATS_INC(mbox.err);
}
SYS_STATS_DEC( mbox.used );
SYS_STATS_DEC(mbox.used);
}
#endif /* SYS_STATS */
vQueueDelete( *pxMailBox );
vQueueDelete(*pxMailBox);
}
/*---------------------------------------------------------------------------*
@ -130,9 +258,9 @@ unsigned long ulMessagesWaiting;
* sys_mbox_t mbox -- Handle of mailbox
* void *data -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
void sys_mbox_post(sys_mbox_t *pxMailBox, void *pxMessageToPost)
{
while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
while (xQueueSendToBack(*pxMailBox, &pxMessageToPost, portMAX_DELAY) != pdTRUE);
}
/*---------------------------------------------------------------------------*
@ -148,26 +276,13 @@ void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
* err_t -- ERR_OK if message posted, else ERR_MEM
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
err_t sys_mbox_trypost(sys_mbox_t *pxMailBox, void *pxMessageToPost)
{
err_t xReturn;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
err_t xReturn;
if( is_inside_isr() != pdFALSE )
{
xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
}
else
{
xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( TickType_t ) 0 );
}
if( xReturn == pdPASS )
{
if (xQueueSend(*pxMailBox, &pxMessageToPost, 0)) {
xReturn = ERR_OK;
}
else
{
} else {
/* The queue was already full. */
xReturn = ERR_MEM;
SYS_STATS_INC( mbox.err );
@ -188,8 +303,8 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
* should be dropped.
*
* The return values are the same as for the sys_arch_sem_wait() function:
* Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
* timeout.
* SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages
* is received.
*
* Note that a function with a similar name, sys_mbox_fetch(), is
* implemented by lwIP.
@ -198,52 +313,28 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
* void **msg -- Pointer to pointer to msg received
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
* of milliseconds until received.
* u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
u32_t sys_arch_mbox_fetch(sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut)
{
void *pvDummy;
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
void *pvDummy;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( NULL == ppvBuffer )
{
if (ppvBuffer == NULL) {
ppvBuffer = &pvDummy;
}
if( ulTimeOut != 0UL )
{
configASSERT( is_inside_isr() == ( portBASE_TYPE ) 0 );
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_PERIOD_MS ) )
{
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
if (ulTimeOut != 0UL) {
if (xQueueReceive(*pxMailBox, &(*ppvBuffer), ulTimeOut / portTICK_PERIOD_MS) == pdTRUE) {
ulReturn = 0;
} else {
/* Timed out. */
*ppvBuffer = NULL;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( pdTRUE != xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
} else {
while (xQueueReceive(*pxMailBox, &(*ppvBuffer), portMAX_DELAY) != pdTRUE);
ulReturn = 0;
}
return ulReturn;
@ -263,218 +354,24 @@ unsigned long ulReturn;
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *pxMailBox, void **ppvBuffer)
{
void *pvDummy;
unsigned long ulReturn;
long lResult;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
void *pvDummy;
unsigned long ulReturn;
if( ppvBuffer== NULL )
{
if (ppvBuffer== NULL) {
ppvBuffer = &pvDummy;
}
if( is_inside_isr() != pdFALSE )
{
lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
}
else
{
lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL );
}
if( lResult == pdPASS )
{
if (xQueueReceive(*pxMailBox, &(*ppvBuffer), 0UL) == pdPASS) {
ulReturn = ERR_OK;
}
else
{
} else {
ulReturn = SYS_MBOX_EMPTY;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary( ( *pxSemaphore ) );
if( *pxSemaphore != NULL )
{
if( ucCount == 0U )
{
xSemaphoreTake( *pxSemaphore, 1UL );
}
xReturn = ERR_OK;
SYS_STATS_INC_USED( sem );
}
else
{
SYS_STATS_INC( sem.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* Blocks the thread while waiting for the semaphore to be
* signaled. If the "timeout" argument is non-zero, the thread should
* only be blocked for the specified time (measured in
* milliseconds).
*
* If the timeout argument is non-zero, the return value is the number of
* milliseconds spent waiting for the semaphore to be signaled. If the
* semaphore wasn't signaled within the specified time, the return value is
* SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
* (i.e., it was already signaled), the function may return zero.
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
{
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( ulTimeout != 0UL )
{
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_PERIOD_MS ) == pdTRUE )
{
xEndTime = xTaskGetTickCount();
xElapsed = (xEndTime - xStartTime) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( xSemaphoreTake( *pxSemaphore, portMAX_DELAY ) != pdTRUE );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new( sys_mutex_t *pxMutex )
{
err_t xReturn = ERR_MEM;
*pxMutex = xSemaphoreCreateMutex();
if( *pxMutex != NULL )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mutex );
}
else
{
SYS_STATS_INC( mutex.err );
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex )
{
xSemaphoreGive( *pxMutex );
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free( sys_mutex_t *pxMutex )
{
SYS_STATS_DEC( mutex.used );
vQueueDelete( *pxMutex );
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( is_inside_isr() != pdFALSE )
{
xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
}
else
{
xSemaphoreGive( *pxSemaphore );
}
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free( sys_sem_t *pxSemaphore )
{
SYS_STATS_DEC(sem.used);
vQueueDelete( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
* Routine: sys_init
*---------------------------------------------------------------------------*
@ -508,20 +405,17 @@ u32_t sys_now(void)
* Outputs:
* sys_thread_t -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int iStackSize, int iPriority)
{
TaskHandle_t xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
TaskHandle_t xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
xResult = xTaskCreate( pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
xResult = xTaskCreate(pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask);
if( xResult == pdPASS )
{
if (xResult == pdPASS) {
xReturn = xCreatedTask;
}
else
{
} else {
xReturn = NULL;
}
@ -547,13 +441,14 @@ sys_thread_t xReturn;
* Outputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect( void )
static uint32_t my_nesting = 0;
sys_prot_t sys_arch_protect(void)
{
if( is_inside_isr() == pdFALSE )
{
taskENTER_CRITICAL();
}
return ( sys_prot_t ) 1;
taskENTER_CRITICAL();
uint32_t prev = my_nesting;
my_nesting++;
return prev;
//return (sys_prot_t)1;
}
/*---------------------------------------------------------------------------*
@ -567,26 +462,16 @@ sys_prot_t sys_arch_protect( void )
* Inputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
void sys_arch_unprotect( sys_prot_t xValue )
void sys_arch_unprotect(sys_prot_t xValue)
{
(void) xValue;
if( is_inside_isr() == pdFALSE )
{
taskEXIT_CRITICAL();
//(void) xValue;
my_nesting--;
if (xValue != my_nesting) {
printf("lwip nesting %d\n", my_nesting);
}
taskEXIT_CRITICAL();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *pcMessage )
{
(void) pcMessage;
for (;;)
{
}
}
/*-------------------------------------------------------------------------*
* End of File: sys_arch.c
*-------------------------------------------------------------------------*/