1、从官网下载lwip2.0.2压缩包
2、将解压后的lwip中的代码依次添加到工程中去
3、修改lwip_v2.0.2\src\netif 里面的ethernetif.c源代码文件:
ethernetif.c是做初始化网卡、发送数据包、接收数据包等最底层的操作。
移植的主要工作就是将ethernetif.c中的low_level_init,low_level_output,low_level_input这三个函数(橙色标记为修改部分)进行修改,以及定义相关的数据结构和宏。
static void low_level_init(struct netif *netif)
{
#ifdef CHECKSUM_BY_HARDWARE
int i;
#endif#if 1 //在MylwIP_Init()中已经设置了MAC地址
uint8_t macaddress[6]={IMT407G_MAC_ADDR};/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;//根据硬件mac地址,初始化netif结构体的硬件地址信息。该模块mac地址可以由用户定义。
/* set MAC hardware address */
netif->hwaddr[0] = macaddress[0];
netif->hwaddr[1] = macaddress[1];
netif->hwaddr[2] = macaddress[2];
netif->hwaddr[3] = macaddress[3];
netif->hwaddr[4] = macaddress[4];
netif->hwaddr[5] = macaddress[5];
/* initialize MAC address in ethernet MAC */
ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
#endif
/* maximum transfer unit */
netif->mtu = 1500;/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;/* Initialize Tx Descriptors list: Chain Mode */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
#ifdef CHECKSUM_BY_HARDWARE
/* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */
for(i=0; i<ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
#endif/* Note: TCP, UDP, ICMP checksum checking for received frame are enabled in DMA config */
/* Enable MAC and DMA transmission and reception */
ETH_Start();}
定义接收发送缓冲区uint8_t SendDataBuf[1500 + 20];uint8_t RecvDataBuf[1500 + 20];
缓冲区的长度为mtu(1500)+ 地址 +类型 +CRC等(小于20)
low_level_output函数的主要功能将数据包发送出去
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
int framelength = 0;
u8 *buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
/* copy frame from pbufs to driver buffers */
for(q = p; q != NULL; q = q->next)
{//将pbuf所指向链表的数据复制到数据缓冲区中
memcpy((u8_t*)&buffer[framelength], q->payload, q->len);
framelength = framelength + q->len;
}
/* Note: padding and CRC for transmitted frame
are automatically inserted by DMA *//* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(framelength);return ERR_OK;
}
low_level_input该函数的主要功能是将接收到的数据并且分配到一个pbuf链表中
因为该工程是轮询的,在周期调用ethernetif_input的时候,ethernetif_input会调用该函数看是否有接收到的数据。
static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
u16_t len;
int l =0;
FrameTypeDef frame;
u8 *buffer;
uint32_t i=0;
__IO ETH_DMADESCTypeDef *DMARxNextDesc;
p = NULL;
/* get received frame */
frame = ETH_Get_Received_Frame();
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (u8 *)frame.buffer;
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);//申请与接收到数据大小相匹配的数据pbuf链表
/* copy received frame to pbuf chain */
if (p != NULL)
{
for (q = p; q != NULL; q = q->next)
{
memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);//将接收到的数据分配到p指向的pbuf链表中
l = l + q->len;
}
}
/* Release descriptors to DMA */
/* Check if frame with multiple DMA buffer segments */
if (DMA_RX_FRAME_infos->Seg_Count > 1)
{
DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
}
else
{
DMARxNextDesc = frame.descriptor;
}
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
return p;
}
参考:
https://blog.csdn.net/mcu_tian/article/details/49786375
https://blog.csdn.net/Firefly_cjd/article/details/79805977
https://blog.csdn.net/q361750389/article/details/52788005?locationNum=8&fps=1