Exemplo n.º 1
0
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 );
	}
}
Exemplo n.º 2
0
/**
 * 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;
}
Exemplo n.º 3
0
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
  static xSemaphoreHandle xTxSemaphore = NULL;
  struct pbuf *q;
  u32_t l = 0;

  if( xTxSemaphore == NULL )
  {
      vSemaphoreCreateBinary( xTxSemaphore );
  }


#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE);			/* drop the padding word */
#endif


  /* Access to the EMAC is guarded using a semaphore. */
  if( xSemaphoreTake( xTxSemaphore, netifGUARD_BLOCK_TIME ) )
  {
      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. */
        memcpy(&TxBuff[l], (u8_t*)q->payload, q->len);
        l += q->len;
      }

      ENET_TxPkt(0, l);

      #if ETH_PAD_SIZE
        pbuf_header(p, ETH_PAD_SIZE);			/* reclaim the padding word */
      #endif

      #if LINK_STATS
        lwip_stats.link.xmit++;
      #endif /* LINK_STATS */

      xSemaphoreGive( xTxSemaphore );
  }

  return ERR_OK;
}