Ethernet - Transmitting and Receiving using Memory Copy
Reception using Memory Copy
On some devices, the MAC is not part of processor peripherals, and is connected through a serial or a parallel communication scheme. You will have to create specific data transfer functions for writing and reading the data structures of the MAC.
Processing reception buffers in the ISR
The following is a list of the actions that must be performed in NetDev_ISR_Handler()
to receive packets using Memory Copy.
- Read MAC Status Register
- Handle Receive ISR:
- Signal Net IF Receive task
- Clear Interrupt
- Handle any other reported interrupts by MAC controller.
The listing below shows a template for the NetDev_ISR_Handle()
function:
static void NetDev_ISR_Handler (NET_IF *pif, NET_DEV_ISR_TYPE type) { NET_DEV_CFG_ETHER *pdev_cfg; NET_DEV_DATA *pdev_data; NET_DEV *pdev; CPU_DATA reg_val; CPU_INT08U *p_data; NET_ERR err; (void)&type; (1) pdev_cfg = (NET_DEV_CFG_ETHER *)pif->Dev_Cfg; (2) pdev_data = (NET_DEV_DATA *)pif->Dev_Data; (3) pdev = (NET_DEV *)pdev_cfg->BaseAddr; (4) reg_val = pdev->ISR; (5) if ((reg_val & RX_ISR_EVENT_MSK) > 0) { (6) NetOS_IF_RxTaskSignal(pif->Nbr, &err); (7) switch (err) { case NET_IF_ERR_NONE: No error during signalling. break; case NET_IF_ERR_RX_Q_FULL: case NET_IF_ERR_RX_Q_SIGNAL_FAULT: default: An error occurred during signalling. break; } pdev->ISR |= RX_ISR_EVENT_MSK; (8) } (9) if ((reg_val & TX_ISR_EVENT_MSK) > 0) { (10) p_data = (CPU_INT08U *)pdev_data->TxBufCompPtr; NetOS_IF_TxDeallocTaskPost(p_data, &err); NetOS_Dev_TxRdySignal(pif->Nbr); (11) pdev->ISR |= TX_ISR_EVENT_MSK; (12) } pdev->ISR |= UNHANDLED_ISR_EVENT_MASK; (13) }
(1) Prevent “variable unused” compiler warning.
(2) Obtain pointer to the device configuration structure.
(3) Obtain pointer to device data area.
(4) Overlay device register structure on top of device base address.
(5) Determine interrupt type.
(6) Handle reception interrupts.
(7) Signal NetIF
reception queue task for each new ready descriptor.
(8) Clear device’s reception interrupt event flag.
(9) Handle transmission interrupts.
(10) Increment transmission packet counter.
(11) Signal NetIF
that transmission resources are now available.
(12) Clear device’s transmission interrupt event flag.
(13) Clear unhandled interrupt event flag.
The following a list of the actions that must be performed in NetDev_Rx()
to receive packets using Memory Copy.
- Disable interrupts
- Read the length of the received frame
- Obtain pointer to new data area
- Copy frame to new data area
- Set return values. Pointer to received data area and size
- Re-Enable interrupts
- Check for additional ready frames, and signal Net IF receive task
The listing below shows a template for the NetDev_Rx()
function:
static void NetDev_Rx (NET_IF *pif, CPU_INT08U **p_data, CPU_INT16U *size, NET_ERR *perr) { NET_DEV_CFG_ETHER *pdev_cfg; NET_DEV_DATA *pdev_data; NET_DEV *pdev; CPU_INT08U *pbuf_new; CPU_INT16S length; CPU_INT16U cnt; CPU_INT16U i; pdev_cfg = (NET_DEV_CFG_ETHER *)pif->Dev_Cfg; (1) pdev_data = (NET_DEV_DATA *)pif->Dev_Data; (2) pdev = (NET_DEV *)pdev_cfg->BaseAddr; (3) if ((pdev->RSTAT & RX_STATUS_ERR_MSK) > 0) { (4) *size = (CPU_INT16U )0; *p_data = (CPU_INT08U *)0; *perr = (NET_ERR )NET_DEV_ERR_RX; return; } length = (pdev->STATUS & RX_STATUS_SIZE_MSK) - NET_IF_ETHER_FRAME_CRC_SIZE; (5) if (length < NET_IF_ETHER_FRAME_MIN_SIZE) { *size = (CPU_INT16U )0; *p_data = (CPU_INT08U *)0; *perr = (NET_ERR )NET_DEV_ERR_INVALID_SIZE; return; } pbuf_new = NetBuf_GetDataPtr((NET_IF *)pif, (6) (NET_TRANSACTION)NET_TRANSACTION_RX, #if (NET_VERSION >= 21000u) (NET_BUF_SIZE )NET_IF_ETHER_FRAME_MAX_SIZE, (NET_BUF_SIZE )NET_IF_IX_RX, (NET_BUF_SIZE *)0, #else (NET_BUF_SIZE )pdev_cfg->RxBufLargeSize, (NET_BUF_SIZE )0u, #endif (NET_BUF_SIZE *)0, (NET_TYPE *)0, (NET_ERR *)perr); if (*perr != NET_BUF_ERR_NONE) { (7) *size = (CPU_INT16U )0; *p_data = (CPU_INT08U *)0; return; } *size = length; (8) cnt = length / pdev_cfg->DataBusSizeNbrBits; (9) for (i = 0; i < cnt; i++) { Read data from device using Memcopy. (10) } *p_data = pbuf_new; (11) *perr = NET_DEV_ERR_NONE; }
(1) Obtain pointer to the device configuration structure.
(2) Obtain pointer to device data area.
(3) Overlay device register structure on top of device base address.
(4) If the frame contains reception errors, discard the frame by setting *size
to 0, *p_data
to null. Set *perr
to NET_DEV_ERR_RX
to indicate a reception error.
(5) If frame is a runt, discard the frame.
(6) Request an empty buffer.
(7) If unable to get a buffer, discard the frame.
(8) Return the size of the received frame.
(9) Determine the number of device memory or FIFO reads that are required to complete the memory copy.
(10) Read data from device.
(11) Return a pointer to the received data.
Transmission using Memory Copy
The following a list of the actions that must be done in NetDev_Tx()
in order to implement transmission using Memory Copy:
- Disable interrupts.
- Prepare device to receive the transmit frame in memory.
- Copy frame to transmit to MAC buffer.
- If no frames are queued for transmission, issue a transmission request to the MAC.
- Update the device’s list of transmit pointers
- Re-enable interrupts
The listing below shows a template for the NetDev_Tx()
function:
static void NetDev_Tx (NET_IF *pif, CPU_INT08U *p_data, CPU_INT16U size, NET_ERR *perr) { NET_DEV_CFG_ETHER *pdev_cfg; NET_DEV_DATA *pdev_data; NET_DEV *pdev; CPU_INT16U cnt; CPU_INT16U i; pdev_cfg = (NET_DEV_CFG_ETHER *)pif->Dev_Cfg; (1) pdev_data = (NET_DEV_DATA *)pif->Dev_Data; (2) pdev = (NET_DEV *)pdev_cfg->BaseAddr; (3) if ((pdev->STATUS & TX_STATUS_BUSY) > 0) { (4) *perr = NET_DEV_ERR_TX_BUSY; return; } cnt = size / pdev_cfg->DataBusSizeNbrBits; (5) for (i = 0; i < cnt; i++) { Copy data to device using Memcopy (6) } pdev->CTRL = 1; (7) pdev_data->TxBufCompPtr = p_data; }
The following is a list of actions that must be performed in NetDev_ISR_Handler()
to transmit packets using Memory Copy.
(1) Obtain pointer to the device configuration structure.
(2) Obtain pointer to device data area.
(3) Overlay device register structure on top of the device base address.
(4) Check if the device is ready to transmit.
(5) Determine the number of device memory or FIFO writes that are required to complete the transfer.
(6) Copy data to device using memory copy.
(7) Initiate transmission of the packet.
Processing transmission buffer in the ISR
- Setup next frame to transmit if any
- Signal already transmitted frame for deallocation
- Signal that Transmit resources have become available
- Clear interrupt
For the template of NetDev_ISR_Handler()
refer to the template in the listing above.