初始化和收发函数是按官方例子enet_lwip、enet_uip改的,代码如下:
/*
******************************************************************************************************
** 标志位定义 **
******************************************************************************************************
*/
uint8_t ETH_FLAG_RXPKT; //->0:没收到数据包 1:接收到数据包
uint8_t ETH_FLAG_TXPKT; //->0:数据包发送完成 1:数据包等待发送
/*
******************************************************************************************************
** 描述和状态定义以及EMAC内存分配 **
******************************************************************************************************
*/
#define NUM_RX_DESCRIPTORS 3
#define NUM_TX_DESCRIPTORS 3
#define RX_BUFFER_SIZE 1536
#define TX_BUFFER_SIZE 1536
tEMACDMADescriptor RxDescriptor[NUM_TX_DESCRIPTORS];
tEMACDMADescriptor TxDescriptor[NUM_RX_DESCRIPTORS];
uint8_t RxBuffer[NUM_RX_DESCRIPTORS][RX_BUFFER_SIZE];
uint8_t TxBuffer[NUM_TX_DESCRIPTORS][TX_BUFFER_SIZE];
static uint32_t RxDescIndex;
static uint32_t TxDescIndex;
/*
******************************************************************************************************
** 设备信息定义 **
******************************************************************************************************
*/
typedef struct
{
uint8_t mac[6]; //MAC地址.
uint8_t ip[4]; //IP地址.
uint8_t mark[4]; //子网掩码.
uint8_t gate[4]; //默认网关.
}device_t;
device_t Device;
static const uint8_t IP[4] ={192,168,1,88}; //本机IP地址.
static const uint8_t MARK[4] ={255,255,255,0}; //子网掩码.
static const uint8_t GATE[4] ={192,168,1,1}; //默认网关.
/*
******************************************************************************************************
**函数名称: void InitDescriptors(void) **
**函数描述: 初始化发送、接收描述相关参量(OWN = 1:owned by the DMA OWN = 0:owned by the CPU) **
**参 数: 无 **
**返 回: 无 **
******************************************************************************************************
*/
void InitDescriptors(void)
{
uint32_t ui32Loop;
// Initialize each of the receive descriptors.
for(ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++)
{
RxDescriptor[ui32Loop].ui32CtrlStatus = 0;
RxDescriptor[ui32Loop].ui32Count = (DES1_RX_CTRL_CHAINED | (RX_BUFFER_SIZE << DES1_RX_CTRL_BUFF1_SIZE_S));
RxDescriptor[ui32Loop].pvBuffer1 = RxBuffer[ui32Loop];
RxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_RX_DESCRIPTORS - 1)) ? &RxDescriptor[0] : &RxDescriptor[ui32Loop + 1];
}
// Initialize each of the transmit descriptors. Note that we leave the OWN bit clear here since we have not set up any transmissions yet.
for(ui32Loop = 0; ui32Loop < NUM_TX_DESCRIPTORS; ui32Loop++)
{
TxDescriptor[ui32Loop].ui32CtrlStatus = (DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG | DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_CHAINED | DES0_TX_CTRL_IP_ALL_CKHSUMS);
TxDescriptor[ui32Loop].ui32Count = (DES1_TX_CTRL_SADDR_INSERT | (TX_BUFFER_SIZE << DES1_TX_CTRL_BUFF1_SIZE_S));
TxDescriptor[ui32Loop].pvBuffer1 = TxBuffer[ui32Loop];
TxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_TX_DESCRIPTORS - 1)) ? &TxDescriptor[0] : &TxDescriptor[ui32Loop + 1];
}
// Set the descriptor pointers in the hardware.
EMACRxDMADescriptorListSet(EMAC0_BASE, RxDescriptor);
EMACTxDMADescriptorListSet(EMAC0_BASE, TxDescriptor);
// Start from the beginning of both descriptor chains. We actually set the transmit descriptor index to the last descriptor in the chain
// since it will be incremented before use and this means the first transmission we perform will use the correct descriptor.
RxDescIndex = 0;
TxDescIndex = NUM_TX_DESCRIPTORS - 1;
// Mark the first receive descriptor as available to the DMA to start the receive processing.
RxDescriptor[RxDescIndex].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
}
/*
******************************************************************************************************
**函数名称: uint32_t PacketReceive(uint8_t *pui8Buf) **
**函数描述: 从DMA接收缓冲区读取一个数据包 **
**参 数: pui8Buf-------数据包存储缓冲区指针 **
**返 回: i32FrameLen---数据长度 **
******************************************************************************************************
*/
uint32_t PacketReceive(uint8_t *pui8Buf)
{
uint32_t i32FrameLen, i32Loop;
// Check the arguments.
ASSERT(pui8Buf != 0);
// By default, we assume we got a bad frame.
i32FrameLen = 0;
// Make sure that CPU own the receive descriptor.
if(!(RxDescriptor[RxDescIndex].ui32CtrlStatus & DES0_RX_CTRL_OWN))
{
// We own the receive descriptor so check to see if it contains a valid frame. Look for a descriptor error,
// indicating that the incoming packet was truncated or, if this is the last frame in a packet, the receive error bit.
if(!(RxDescriptor[RxDescIndex].ui32CtrlStatus & DES0_RX_STAT_ERR))
{
// We have a valid frame so copy the content to the supplied buffer. First check that the "last descriptor" flag is set.
// We sized the receive buffer such that it can always hold a valid frame so this flag should never be clear at this point but...
if(RxDescriptor[RxDescIndex].ui32CtrlStatus & DES0_RX_STAT_LAST_DESC)
{
i32FrameLen = ((RxDescriptor[RxDescIndex].ui32CtrlStatus & DES0_RX_STAT_FRAME_LENGTH_M) >> DES0_RX_STAT_FRAME_LENGTH_S);
// Sanity check.
if(i32FrameLen > RX_BUFFER_SIZE)
{
i32FrameLen = RX_BUFFER_SIZE;
}
// Copy the data from the DMA receive buffer into the provided frame buffer.
for(i32Loop = 0; i32Loop < i32FrameLen; i32Loop++)
{
pui8Buf[i32Loop] = RxBuffer[RxDescIndex][i32Loop];
}
}
}
// Move on to the next descriptor in the chain.
RxDescIndex++;
if(RxDescIndex == NUM_RX_DESCRIPTORS)
{
RxDescIndex = 0;
}
// Give this descriptor back to the DMA.
RxDescriptor[RxDescIndex].ui32CtrlStatus = DES0_RX_CTRL_OWN;
}
// Return the Frame Length.
return(i32FrameLen);
}
/*
******************************************************************************************************
**函数名称: uint32_t PacketTransmit(uint8_t *pui8Buf, uint32_t i32BufLen) **
**函数描述: 发送数据包 **
**参 数: pui8Buf-----待发送数据包缓冲区指针 **
** i32BufLen---待发送数据包的长度 **
**返 回: i32BufLen---实际发送数据的长度 **
******************************************************************************************************
*/
uint32_t PacketTransmit(uint8_t *pui8Buf, uint32_t i32BufLen)
{
uint32_t i32Loop;
// Indicate that a packet is being sent.
ETH_FLAG_TXPKT = 1;
printf("ETH_FLAG_TXPKT = 1;\r\n");
// Wait for the previous packet to be transmitted.
while(TxDescriptor[TxDescIndex].ui32CtrlStatus & DES0_TX_CTRL_OWN);
printf("ETH_FLAG_TXPKT = 2;\r\n");
// Sanity check.
if(i32BufLen > TX_BUFFER_SIZE)
{
i32BufLen = TX_BUFFER_SIZE;
}
// Copy the packet data into the transmit buffer.
for(i32Loop = 0; i32Loop < i32BufLen; i32Loop++)
{
TxBuffer[TxDescIndex][i32Loop] = pui8Buf[i32Loop];
printf("pui8Buf[%d] = %02X\r\n", i32Loop, pui8Buf[i32Loop]);
}
// Move to the next descriptor.
TxDescIndex++;
if(TxDescIndex == NUM_TX_DESCRIPTORS)
{
TxDescIndex = 0;
}
// Fill in the packet size and tell the transmitter to start work.
TxDescriptor[TxDescIndex].ui32Count = (uint32_t)i32BufLen;
TxDescriptor[TxDescIndex].ui32CtrlStatus = ( DES0_TX_CTRL_LAST_SEG |
DES0_TX_CTRL_FIRST_SEG |
DES0_TX_CTRL_INTERRUPT |
DES0_TX_CTRL_IP_ALL_CKHSUMS |
DES0_TX_CTRL_CHAINED |
DES0_TX_CTRL_OWN);
// Tell the DMA to reacquire the descriptor now that we've filled it in.
EMACTxDMAPollDemand(EMAC0_BASE);
printf("ETH_FLAG_TXPKT = 3;\r\n");
// Return the number of bytes sent.
return(i32BufLen);
}
/*
******************************************************************************************************
**函数名称: void HAL_EMAC_Init(void) **
**函数描述: 网口初始化 **
**参 数: 无 **
**返 回: 无 **
******************************************************************************************************
*/
void HAL_EMAC_Init(void)
{
// PF0/PF1/PF4 are used for Ethernet LEDs.
GPIOPinConfigure(GPIO_PF0_EN0LED0);
GPIOPinConfigure(GPIO_PF4_EN0LED1);
GPIOPinConfigure(GPIO_PF1_EN0LED2);
GPIOPinTypeEthernetLED(GPIOF_AHB_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4);
// Wait for the MAC to be ready.
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0));
// Configure for use with the internal PHY.
EMACPHYConfigSet(EMAC0_BASE, EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | EMAC_PHY_AN_100B_T_FULL_DUPLEX);
// Reset the MAC.
EMACReset(EMAC0_BASE);
// Initialize the MAC and set the DMA mode.
EMACInit(EMAC0_BASE, SystemCoreClock, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0);
// Set MAC configuration options.
EMACConfigSet(EMAC0_BASE,
(EMAC_CONFIG_FULL_DUPLEX |
EMAC_CONFIG_CHECKSUM_OFFLOAD |
EMAC_CONFIG_7BYTE_PREAMBLE |
EMAC_CONFIG_IF_GAP_96BITS |
EMAC_CONFIG_USE_MACADDR0 |
EMAC_CONFIG_SA_FROM_DESCRIPTOR |
EMAC_CONFIG_BO_LIMIT_1024),
(EMAC_MODE_RX_STORE_FORWARD |
EMAC_MODE_TX_STORE_FORWARD |
EMAC_MODE_TX_THRESHOLD_64_BYTES |
EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);
// Initialize the Ethernet DMA descriptors.
InitDescriptors();
// Program the hardware with its MAC address (for filtering).
EMACAddrSet(EMAC0_BASE, 0, Device.mac);
// Wait for the link to become active.
//while((EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & EPHY_BMSR_LINKSTAT) == 0);
// Set MAC filtering options. We receive all broadcast and multicast packets along with those addressed specifically for us.
EMACFrameFilterSet(EMAC0_BASE, (EMAC_FRMFILTER_SADDR | EMAC_FRMFILTER_PASS_MULTICAST | EMAC_FRMFILTER_PASS_NO_CTRL));
// Clear any pending interrupts.
EMACIntClear(EMAC0_BASE, EMACIntStatus(EMAC0_BASE, false));
// Enable the Ethernet MAC transmitter and receiver.
EMACTxEnable(EMAC0_BASE);
EMACRxEnable(EMAC0_BASE);
// Enable the Ethernet interrupt.
IntEnable(INT_EMAC0);
// Enable the Ethernet RX Packet interrupt source.
EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE | EMAC_INT_TRANSMIT);
}
/*
******************************************************************************************************
**函数名称: void ENET_IRQHandler(void) **
**函数描述: 以太网中断服务程序 **
**参 数: 无 **
**返 回: 无 **
******************************************************************************************************
*/
void ETH_Handler(void)
{
uint32_t IntStatus;
// Read and Clear the interrupt.
IntStatus = EMACIntStatus(EMAC0_BASE, true);
MAP_EMACIntClear(EMAC0_BASE, IntStatus);
// Check to see if an RX Interrupt has occurred.
if(IntStatus & EMAC_INT_RECEIVE)
{
// Indicate that a packet has been received.
ETH_FLAG_RXPKT = 1;
}
// Has the DMA finished transferring a packet to the transmitter?
if(IntStatus & EMAC_INT_TRANSMIT)
{
// Indicate that a packet has been sent.
ETH_FLAG_TXPKT = 0;
}
}
/*
******************************************************************************************************
**函数名称: void Config(void) **
**函数描述: 参数配置函数 **
**参 数: 无 **
**返 回: 无 **
******************************************************************************************************
*/
void Config(void)
{
uint32_t ui32User0, ui32User1;
FlashUserGet(&ui32User0, &ui32User1);
if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff))
{
//
// We should never get here. This is an error if the MAC address has
// not been programmed into the device. Exit the program.
// Let the user know there is no MAC address
//
printf("No MAC programmed!\n");
while(1)
{
}
}
Device.mac[0] = ((ui32User0 >> 0) & 0xff);
Device.mac[1] = ((ui32User0 >> 8) & 0xff);
Device.mac[2] = ((ui32User0 >> 16) & 0xff);
Device.mac[3] = ((ui32User1 >> 0) & 0xff);
Device.mac[4] = ((ui32User1 >> 8) & 0xff);
Device.mac[5] = ((ui32User1 >> 16) & 0xff);
memcpy(Device.ip, IP, 4); //IP
memcpy(Device.mark, MARK, 4); //MARK
memcpy(Device.gate, GATE, 4); //GATEWAY
}
/*
******************************************************************************************************
**函数名称: void APP_LWIP_Init(void) **
**函数描述: 初始化LWIP所有相关信息 **
**参 数: 无 **
**返 回: 无 **
******************************************************************************************************
*/
void APP_LWIP_Init(void)
{
Config();
HAL_EMAC_Init(); //初始化EMAC.
lwip_init(); //LwIP协议栈初始化.
// add the network interface.
netif_add(&my_netif, (ip4_addr_t *)&Device.ip, (ip4_addr_t *)&Device.mark, (ip4_addr_t *)&Device.gate, NULL, ethernetif_init, ethernet_input);
// Registers the default network interface.
netif_set_default(&my_netif);
netif_set_up(&my_netif);
//HTTP应用层初始化
//httpd_init(); //初始化HTTP服务器监听端口.
//httpd_cgi_ssi_init(); //CGI、SSI相关初始化.
//TCP应用层初始化
//tcp_server_init(); //初始化TCP服务器.
//UDP应用层初始化
//udp_server_init(); //初始化UDP服务器.
}
ethernetif.c代码如下:
/**
* @file
* Ethernet Interface Skeleton
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#if 1 /* don't build, this is only a skeleton, see previous comment */
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "netif/etharp.h"
#include "netif/ppp/pppoe.h"
#include "includes.h" // add by eBoy---2012-10-20
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
/**
* Helper struct to hold private data used to operate your ethernet interface.
* Keeping the ethernet address of the MAC in this struct is not necessary
* as it is already kept in the struct netif.
* But this is only an example, anyway...
*/
struct ethernetif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
/* Forward declarations. */
err_t ethernetif_input(struct netif *netif);
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void
low_level_init(struct netif *netif)
{
//struct ethernetif *ethernetif = netif->state;
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = Device.mac[0];
netif->hwaddr[1] = Device.mac[1];
netif->hwaddr[2] = Device.mac[2];
netif->hwaddr[3] = Device.mac[3];
netif->hwaddr[4] = Device.mac[4];
netif->hwaddr[5] = Device.mac[5];
/*
printf("netif->hwaddr[0] = %02X\r\n",netif->hwaddr[0]);
printf("netif->hwaddr[1] = %02X\r\n",netif->hwaddr[1]);
printf("netif->hwaddr[2] = %02X\r\n",netif->hwaddr[2]);
printf("netif->hwaddr[3] = %02X\r\n",netif->hwaddr[3]);
printf("netif->hwaddr[4] = %02X\r\n",netif->hwaddr[4]);
printf("netif->hwaddr[5] = %02X\r\n",netif->hwaddr[5]);
*/
/* 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;
/* Do whatever else is needed to initialize interface. */
}
/**
* 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 ethernetif *ethernetif = netif->state;
struct pbuf *q;
u16_t len=0;
u8_t buffer[1536];
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((u8_t*)&buffer[len], (u8_t*)q->payload, q->len);
len = len + q->len;
}
PacketTransmit(buffer, len);
return ERR_OK;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *
low_level_input(struct netif *netif)
{
//struct ethernetif *ethernetif = netif->state;
struct pbuf *p, *q;
u16_t len=0,i=0;
u8_t buffer[1536];
/* Obtain the size of the packet and put it into the "len"
variable. */
len = PacketReceive(buffer);
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for(q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* pbuf is the sum of the chained pbuf len members.
*/
memcpy((u8_t*)q->payload, (u8_t*)&buffer[i], q->len);
i = i + q->len;
}
}
return p;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
err_t
ethernetif_input(struct netif *netif)
{
//struct ethernetif *ethernetif = netif->state;
struct pbuf *p;
err_t err;
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p == NULL) return ERR_MEM;
err = netif->input(p, netif);
if (err != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
return err;
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t
ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;
LWIP_ASSERT("netif != NULL", (netif != NULL));
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
#endif /* 0 */
ping 192.168.1.88时,串口输出如下:

通过串口打印的信息看,回复的是ARP帧,可电脑好像收不到,导致后面的ICMP一直Ping不通。
求大神帮忙~!谢谢!




