diff options
author | Tom Rini <trini@konsulko.com> | 2024-10-16 08:10:14 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-10-16 08:10:14 -0600 |
commit | f3f86fd1fe0fb288356bff78f8a6fa2edf89e3fc (patch) | |
tree | f0a99ea87d92f63895a6d053e3185838ebecf2d0 /contrib/ports/unix/port/netif/fifo.c |
Squashed 'lib/lwip/lwip/' content from commit 0a0452b2c39b
git-subtree-dir: lib/lwip/lwip
git-subtree-split: 0a0452b2c39bdd91e252aef045c115f88f6ca773
Diffstat (limited to 'contrib/ports/unix/port/netif/fifo.c')
-rw-r--r-- | contrib/ports/unix/port/netif/fifo.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/contrib/ports/unix/port/netif/fifo.c b/contrib/ports/unix/port/netif/fifo.c new file mode 100644 index 00000000000..350d3eaedeb --- /dev/null +++ b/contrib/ports/unix/port/netif/fifo.c @@ -0,0 +1,139 @@ +/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */ + +/* ---------------------------------------------- */ +/* --- fifo 4 unix ------------------------------ */ +/* ---------------------------------------------- */ +#include "lwip/err.h" +#include "netif/fifo.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/arch.h" +#include <unistd.h> + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef SIO_FIFO_DEBUG +#define SIO_FIFO_DEBUG LWIP_DBG_OFF +#endif + +u8_t fifoGet(fifo_t * fifo) +{ + u8_t c; + + sys_sem_wait(&fifo->sem); /* enter critical section */ + + if (fifo->dataslot == fifo->emptyslot) + { + fifo->getWaiting = TRUE; /* tell putFifo to signal us when data is available */ + sys_sem_signal(&fifo->sem); /* leave critical section (allow input from serial port..) */ + sys_sem_wait(&fifo->getSem); /* wait 4 data */ + sys_sem_wait(&fifo->sem); /* reenter critical section */ + } + + c = fifo->data[fifo->dataslot++]; + fifo->len--; + + if (fifo->dataslot == FIFOSIZE) + { + fifo->dataslot = 0; + } + sys_sem_signal(&fifo->sem); /* leave critical section */ + return c; +} + + +s16_t fifoGetNonBlock(fifo_t * fifo) +{ + u16_t c; + + sys_sem_wait(&fifo->sem); /* enter critical section */ + + if (fifo->dataslot == fifo->emptyslot) + { + /* empty fifo */ + c = -1; + } + else + { + c = fifo->data[fifo->dataslot++]; + fifo->len--; + + if (fifo->dataslot == FIFOSIZE) + { + fifo->dataslot = 0; + } + } + sys_sem_signal(&fifo->sem); /* leave critical section */ + return c; +} + + +void fifoPut(fifo_t * fifo, int fd) +{ + /* FIXME: mutex around struct data.. */ + int cnt=0; + + sys_sem_wait(&fifo->sem ); /* enter critical */ + + LWIP_DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) ); + + if ( fifo->emptyslot < fifo->dataslot ) + { + cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot ); + } + else + { + cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot ); + } + fifo->emptyslot += cnt; + fifo->len += cnt; + + LWIP_DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) ); + + if ( fifo->len > FIFOSIZE ) + { + printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len ); + fifo->dataslot = 0; + fifo->emptyslot = 0; + fifo->len = 0; + } + + if ( fifo->emptyslot == FIFOSIZE ) + { + fifo->emptyslot = 0; + LWIP_DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") ); + + sys_sem_signal(&fifo->sem ); /* leave critical */ + fifoPut( fifo, fd ); + return; + } + if ( fifo->getWaiting ) + { + fifo->getWaiting = FALSE; + sys_sem_signal(&fifo->getSem ); + } + + sys_sem_signal(&fifo->sem ); /* leave critical */ + return; +} + + +void fifoInit(fifo_t * fifo) +{ + fifo->dataslot = 0; + fifo->emptyslot = 0; + fifo->len = 0; + if(sys_sem_new(&fifo->sem, 1) != ERR_OK) { /* critical section 1=free to enter */ + LWIP_ASSERT("Failed to create semaphore", 0); + } + if(sys_sem_new(&fifo->getSem, 0) != ERR_OK) { /* 0 = no one waiting */ + LWIP_ASSERT("Failed to create semaphore", 0); + } + fifo->getWaiting = FALSE; +} |