This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294KCPDT移植LWIP2.0.2时发送数据失败

初始化和收发函数是按官司主例子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.  Set the OWN bit here to make sure that the receiver can start writing anything immediately.
    for(ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++)
    {
        RxDescriptor[ui32Loop].ui32CtrlStatus	= DES0_RX_CTRL_OWN;
        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];
    }

    // 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 = 0;
	

	// Set the descriptor pointers in the hardware.
    EMACRxDMADescriptorListSet(EMAC0_BASE, RxDescriptor);
    EMACTxDMADescriptorListSet(EMAC0_BASE, TxDescriptor);
}

/*
******************************************************************************************************
**函数名称:	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];
    }

    // 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代码如附件

打开LWIP_DEBUG部分调试功能,ping 192.168.1.88时,串口输出如下:

如上图,说明以太网已正确收到ARP请求,可在发送以太网数据帧时一直在等待,

while(TxDescriptor[TxDescIndex].ui32CtrlStatus & DES0_TX_CTRL_OWN);
只打印出来
printf("ETH_FLAG_TXPKT = 1;\r\n");
而没有打印
printf("ETH_FLAG_TXPKT = 2;\r\n");

求大神帮忙~!谢谢!