Skip to content

Commit 8cf3e65

Browse files
committed
Don't use semaphore from ENET_IRQHandler to packet_rx
I now use a signal to communicate when a packet has been received by the ethernet hardware and should be processed by the packet_rx thread. Previously the change to make the lwIP stack thread safe introduced enough delay in packet_rx that the semaphore count could lag behind the processed packets and overflow its maximum token count. Now the ISR uses the signal to indicate that >= 1 packet has been received since the last time packet_rx() was awaken. Previously the ethernet driver used generic sys_arch* APIs exposed from lwIP to manipulate the semaphores. I now call CMSIS RTOS APIs directly when using the signals. I think this is acceptable since that same driver source file already contains similar os* calls that talk directly to the RTOS.
1 parent 2bed996 commit 8cf3e65

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

libraries/net/eth/lwip-eth/arch/lpc17_emac.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@
8888
*/
8989
#define TXINTGROUP (EMAC_INT_TX_UNDERRUN | EMAC_INT_TX_ERR | EMAC_INT_TX_DONE)
9090

91+
/** \brief Signal used for ethernet ISR to signal packet_rx() thread.
92+
*/
93+
#define RX_SIGNAL 1
94+
9195
#else
9296
#define RXINTGROUP 0
9397
#define TXINTGROUP 0
@@ -123,7 +127,7 @@ struct lpc_enetdata {
123127
struct pbuf *txb[LPC_NUM_BUFF_TXDESCS]; /**< TX pbuf pointer list, zero-copy mode */
124128
u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
125129
#if NO_SYS == 0
126-
sys_sem_t RxSem; /**< RX receive thread wakeup semaphore */
130+
sys_thread_t RxThread; /**< RX receive thread data object pointer */
127131
sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
128132
sys_mutex_t TXLockMutex; /**< TX critical section mutex */
129133
sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
@@ -783,8 +787,8 @@ void ENET_IRQHandler(void)
783787
ints = LPC_EMAC->IntStatus;
784788

785789
if (ints & RXINTGROUP) {
786-
/* RX group interrupt(s): Give semaphore to wakeup RX receive task.*/
787-
sys_sem_signal(&lpc_enetdata.RxSem);
790+
/* RX group interrupt(s): Give signal to wakeup RX receive task.*/
791+
osSignalSet(lpc_enetdata.RxThread->id, RX_SIGNAL);
788792
}
789793

790794
if (ints & TXINTGROUP) {
@@ -810,7 +814,7 @@ static void packet_rx(void* pvParameters) {
810814

811815
while (1) {
812816
/* Wait for receive task to wakeup */
813-
sys_arch_sem_wait(&lpc_enetif->RxSem, 0);
817+
osSignalWait(RX_SIGNAL, osWaitForever);
814818

815819
/* Process packets until all empty */
816820
while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex)
@@ -1096,9 +1100,8 @@ err_t lpc_enetif_init(struct netif *netif)
10961100
LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
10971101

10981102
/* Packet receive task */
1099-
err = sys_sem_new(&lpc_enetdata.RxSem, 0);
1100-
LWIP_ASSERT("RxSem creation error", (err == ERR_OK));
1101-
sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
1103+
lpc_enetdata.RxThread = sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
1104+
LWIP_ASSERT("RxThread creation error", (lpc_enetdata.RxThread));
11021105

11031106
/* Transmit cleanup task */
11041107
err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);

0 commit comments

Comments
 (0)