static void prvENET_Send(void) { portBASE_TYPE i; static unsigned portCHAR *pcTxData; /* Get a DMA buffer into which we can write the data to send. */ for( i = 0; i < uipBUFFER_WAIT_ATTEMPTS; i++ ) { pcTxData = pcGetNextBuffer(); if( pcTxData ) { break; } else { vTaskDelay( uipBUFFER_WAIT_DELAY ); } } if( pcTxData ) { /* Copy the header into the Tx buffer. */ memcpy( ( void * ) pcTxData, ( void * ) uip_buf, uipTOTAL_FRAME_HEADER_SIZE ); if( uip_len > uipTOTAL_FRAME_HEADER_SIZE ) { memcpy( ( void * ) &( pcTxData[ uipTOTAL_FRAME_HEADER_SIZE ] ), ( void * ) uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) ); } ENET_TxPkt( &pcTxData, uip_len ); } }
/** * This function should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf * might be chained. * * @param netif the lwip network interface structure for this ethernetif * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) * @return ERR_OK if the packet could be sent * an err_t value if the packet couldn't be sent * * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to * strange results. You might consider waiting for space in the DMA queue * to become availale since the stack doesn't retry to send a packet * dropped because of memory failure (except for the TCP timers). */ static err_t low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; u32_t l = 0; unsigned char *pcTxData; #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif /* Get a DMA buffer into which we can write the data to send. */ for( int i = 0; i < netifBUFFER_WAIT_ATTEMPTS; i++ ) { pcTxData = pcGetNextBuffer(); if( pcTxData ) { break; } else { vTaskDelay( netifBUFFER_WAIT_DELAY ); } } if (pcTxData == NULL) { portNOP(); return ERR_BUF; } else { for(q = p; q != NULL; q = q->next) { /* Send the data from the pbuf to the interface, one pbuf at a time. The size of the data in each pbuf is kept in the ->len variable. */ vTaskSuspendAll(); memcpy(&pcTxData[l], (u8_t*)q->payload, q->len); xTaskResumeAll(); l += q->len; } } ENET_TxPkt( &pcTxData, l ); #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif LINK_STATS_INC(link.xmit); return ERR_OK; }