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