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.

TM4C1294NCPDT MAC地址问题

使用enet_uip例程,每次修改完MAC地址后,重启设备后无法接收ARP应答,无法建立ARP表,每次都得重启2-3次才能成功,这问题有遇到的吗?

  • 修改MAC地址,你是怎么做的?

  • 就是下面这样处理的,改完后设备能正常运行,但掉电重启后,可能出现PING不通的情况,但是重启几次肯定能PING通,不知道是什么情况,不知道我的初始化有没有什么问题?

    修改MAC地址:

    ROM_EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)&sTempAddr);

    uip_ethaddr.addr[0] = u8HostMACAddr[0];
    uip_ethaddr.addr[1] = u8HostMACAddr[1];
    uip_ethaddr.addr[2] = u8HostMACAddr[2]; 
    uip_ethaddr.addr[3] = u8HostMACAddr[3];
    uip_ethaddr.addr[4] = u8HostMACAddr[4];
    uip_ethaddr.addr[5] = u8HostMACAddr[5];

    初始化:

    {
        uip_ipaddr_t sIPAddr;
        static struct uip_eth_addr sTempAddr;
        static struct uip_eth_addr sTempAddr1;
        int32_t i32PeriodicTimer, i32ARPTimer;
    	uint32_t i;//ui32User0, ui32User1;
        uint32_t ui32Temp, ui32PHYConfig;
        static u8_t u8Test[3] = {0xff,0xff,0xff};					// 建立新连接发送的测试数据(无效数据)
    
        // Run from the PLL at 120 MHz.
       	ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                               SYSCTL_OSC_MAIN |
                                               SYSCTL_USE_PLL |
                                               SYSCTL_CFG_VCO_480), 120000000);
         
        // Initialize the UART, clear the terminal, and print banner.
        ui32PHYConfig = (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN |
                         EMAC_PHY_AN_100B_T_FULL_DUPLEX);
        PinoutSet(true, false);								// 系统管脚初始化
    	EEPROMInit();										// eeprom初始化
        Spi_Init();											// SSI管脚初始化
    
    	/*
    	MAP_FlashUserGet(&ui32User0, &ui32User1);
    	if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff))
        {	
        	ui32User0 = 0x00002058;
        	ui32User1 = 0x00002058;
    		MAP_FlashUserSet(ui32User0, ui32User1);    	
        }
    	
    	sTempAddr.addr[0] = ((ui32User0 >> 0) & 0xff);
        sTempAddr.addr[1] = ((ui32User0 >> 8) & 0xff);
        sTempAddr.addr[2] = ((ui32User0 >> 16) & 0xff);
        sTempAddr.addr[3] = ((ui32User1 >> 0) & 0xff);
        sTempAddr.addr[4] = ((ui32User1 >> 8) & 0xff);
        sTempAddr.addr[5] = ((ui32User1 >> 16) & 0xff);
    	*/
    	// MAC地址
        sTempAddr.addr[0] = u8HostMACAddr[0];
        sTempAddr.addr[1] = u8HostMACAddr[1];
        sTempAddr.addr[2] = u8HostMACAddr[2];
        sTempAddr.addr[3] = u8HostMACAddr[3];
        sTempAddr.addr[4] = u8HostMACAddr[4];
        sTempAddr.addr[5] = u8HostMACAddr[5];
    	
    	// 读取系统设置参数
    	EEPROMRead((uint32_t *)ipSeting,0x0400,sizeof(ipSeting));
    
    	// 若当前地址无有效数据,则写入初始数据
        //if ((ipSeting[0] != 0xff) && (ipSeting[1] != 0xff) && (ipSeting[2] != 0xff) && (ipSeting[3] != 0xff))
     	if ((ipSeting[0] == 0xff) && (ipSeting[1] == 0xff) && (ipSeting[2] == 0xff) && (ipSeting[3] == 0xff))
        {
    		InitNetPara();													// 网络参数初始化
    		InitSysPara();													// 初始化默认数据
            uip_setethaddr(sTempAddr);
    		Sc16is752ipw_Uart_Init(); 										// Sc16is752ipw spi转串口初始化
    		EEPROMProgram((uint32_t *)ipSeting,0x0400,sizeof(ipSeting));	// 写入EEPROM
    	}
    	else
    	{      
    		// 更新参数值
    		/***********************IP,子网掩码,网关修改后本次应答不更新,下次操作时更新*****************/
    		// 主机IP
    		u8HostIpAddr[0] = ipSeting[39] | (((uint16_t)ipSeting[38]) << 8); 	 
    		u8HostIpAddr[1] = ipSeting[37] | (((uint16_t)ipSeting[36]) << 8);
    		
    		// 子网掩码
    		u8HostNetMask[0] = ipSeting[43] | (((uint16_t)ipSeting[42]) << 8);
    		u8HostNetMask[1] = ipSeting[41] | (((uint16_t)ipSeting[40]) << 8);
    		
    		// 网关
    		u8HostGetWay[0] = ipSeting[47] | (((uint16_t)ipSeting[46]) << 8);
    		u8HostGetWay[1] = ipSeting[45] | (((uint16_t)ipSeting[44]) << 8);
    		/*******************************************************************************************/
    		
    		/************************************下列参数实时更新***************************************/
    		// MAC地址
    		u8HostMACAddr[0] = ipSeting[28];
    		u8HostMACAddr[1] = ipSeting[29];
    		u8HostMACAddr[2] = ipSeting[30];
    		u8HostMACAddr[3] = ipSeting[31];
    		u8HostMACAddr[4] = ipSeting[32];
    		u8HostMACAddr[5] = ipSeting[33];
            
    		// 控制端主机IP
    		u8CtrlIpAddr[0] = ipSeting[51] | (((uint16_t)ipSeting[50]) << 8);
    		u8CtrlIpAddr[1] = ipSeting[49] | (((uint16_t)ipSeting[48]) << 8);
    		
    		// 串口1相关
    		u32UartBaud[0] = ipSeting[56] | (((uint32_t)(ipSeting[57])) << 8)
    			| (((uint32_t)(ipSeting[58])) << 16)| (((uint32_t)(ipSeting[59])) << 24);
    		u8UartDataBit[0] = ipSeting[60];		
    		u8UartStopBit[0] = ipSeting[62];
    		u8UartParityBit[0] = ipSeting[61];
    		
    		// 串口2相关
    		u32UartBaud[1] = ipSeting[64] | (((uint32_t)(ipSeting[65])) << 8)
    			| (((uint32_t)(ipSeting[66])) << 16)| (((uint32_t)(ipSeting[67])) << 24);
    		u8UartDataBit[1] = ipSeting[68];	
    		u8UartStopBit[1] = ipSeting[70];	
    		u8UartParityBit[1] = ipSeting[69];
    		
    		// 串口3相关
    		u32UartBaud[2] = ipSeting[80] | (((uint32_t)(ipSeting[81])) << 8)
    			| (((uint32_t)(ipSeting[82])) << 16)| (((uint32_t)(ipSeting[83])) << 24);
    		u8UartDataBit[2] = ipSeting[84];	
    		u8UartStopBit[2] = ipSeting[86];		
    		u8UartParityBit[2] = ipSeting[85];
    		
    		// 485相关
    		u32UartBaud[3] = ipSeting[72] | (((uint32_t)(ipSeting[73])) << 8)
    			| (((uint32_t)(ipSeting[74])) << 16)| (((uint32_t)(ipSeting[75])) << 24);
    		u8UartDataBit[3] = ipSeting[76];	
    		u8UartStopBit[3] = ipSeting[78];	
    		u8UartParityBit[3] = ipSeting[77];  
    
    		// MAC地址
    	    sTempAddr.addr[0] = u8HostMACAddr[0];
    	    sTempAddr.addr[1] = u8HostMACAddr[1];
    	    sTempAddr.addr[2] = u8HostMACAddr[2];
    	    sTempAddr.addr[3] = u8HostMACAddr[3];
    	    sTempAddr.addr[4] = u8HostMACAddr[4];
    	    sTempAddr.addr[5] = u8HostMACAddr[5];
    		/*******************************************************************************************/
    	}
    
        Delay_us(500);
        // Configure SysTick for a periodic interrupt.
        ROM_SysTickPeriodSet(ui32SysClock / SYSTICKHZ);
        ROM_SysTickEnable();
        ROM_SysTickIntEnable();
    
        // Enable and reset the Ethernet modules.
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
    
        // Wait for the MAC to be ready.
        while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
        {
        }
        
        // Configure for use with the internal PHY.
        EMACPHYConfigSet(EMAC0_BASE, ui32PHYConfig);
        
        // Reset the MAC.
        ROM_EMACReset(EMAC0_BASE);
    
        // Initialize the MAC and set the DMA mode.
        ROM_EMACInit(EMAC0_BASE, ui32SysClock,
                     EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4,
                     0);
    
        // Set MAC configuration options.
        ROM_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(EMAC0_BASE);
    
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    	EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
        Delay_us(5000);
        // Program the hardware with its MAC address (for filtering).
        MAP_EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)&sTempAddr);
    	Delay_us(5000);
    
        // 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.
        ROM_EMACFrameFilterSet(EMAC0_BASE, (EMAC_FRMFILTER_SADDR |
                                            EMAC_FRMFILTER_PASS_MULTICAST |
                                            EMAC_FRMFILTER_PASS_NO_CTRL));
    
        // Clear any pending interrupts.
        ROM_EMACIntClear(EMAC0_BASE, EMACIntStatus(EMAC0_BASE, false));
    
        // Initialize the uIP TCP/IP stack.
        uip_init();
    
        // Set the local MAC address (for uIP).
        // EMACHashFilterSet(EMAC0_BASE,pui32HashHi1,pui32HashLo1);
        // EMACHashFilterGet(EMAC0_BASE,pui32HashLo,pui32HashHi);
    	   
    	uip_ethaddr.addr[0] = u8HostMACAddr[0];
    	uip_ethaddr.addr[1] = u8HostMACAddr[1];
    	uip_ethaddr.addr[2] = u8HostMACAddr[2]; 	
    	uip_ethaddr.addr[3] = u8HostMACAddr[3];
    	uip_ethaddr.addr[4] = u8HostMACAddr[4];
    	uip_ethaddr.addr[5] = u8HostMACAddr[5];
    	
        uip_ipaddr(sIPAddr, (u8HostIpAddr[0] & 0x00ff),(u8HostIpAddr[0] >> 8), (u8HostIpAddr[1] & 0x00ff), (u8HostIpAddr[1] >> 8));
        uip_sethostaddr(sIPAddr);
        uip_ipaddr(sIPAddr, (u8HostGetWay[0] & 0x00ff),(u8HostGetWay[0] >> 8), (u8HostGetWay[1] & 0x00ff), (u8HostGetWay[1] >> 8));
        uip_setdraddr(sIPAddr);
        uip_ipaddr(sIPAddr, (u8HostNetMask[0] & 0x00ff),(u8HostNetMask[0] >> 8), (u8HostNetMask[1] & 0x00ff), (u8HostNetMask[1] >> 8));
        uip_setnetmask(sIPAddr);
    
        Rs485_Init();							// 485初始化(必须放在读取系统参数后)
    	Sc16is752ipw_Uart_Init();				// Sc16is752ipw spi转串口初始化
    
        // Uart_SetPara(ChannelB,u16UartBaud[2],GetUartDataBit(u8UartDataBit[2]),GetUartStopBit(u8UartStopBit[2]),GetUartParBit(u8UartParityBit[2]));
    	// Sc16is752ipw_Uart_Enable();
    	
        // Enable the Ethernet MAC transmitter and receiver.
        ROM_EMACTxEnable(EMAC0_BASE);
        ROM_EMACRxEnable(EMAC0_BASE);
    
        // Enable the Ethernet interrupt.
        ROM_IntEnable(INT_EMAC0);
    
        // Enable the Ethernet RX Packet interrupt source.
        ROM_EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);
    
        // Mark the first receive descriptor as available to the DMA to start
        // the receive processing.
        g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
    
    	myudp_init();
    	udp_server_connected(UDP_SERVER_PORT,0);			// 用于UDP广播(未指定客户端端口)
    
    	// Main Application Loop.
        i32PeriodicTimer = 0;
        i32ARPTimer = 0;
        
        uip_len = 1;
       
        while(1)
        {
            // Wait for an event to occur.  This can be either a System Tick event,
            // or an RX Packet event.
            while(!g_ui32Flags)
            {
            }
    
            // If SysTick, Clear the SysTick interrupt flag and increment the
            // timers.
            if(HWREGBITW(&g_ui32Flags, FLAG_SYSTICK) == 1)
            {
                HWREGBITW(&g_ui32Flags, FLAG_SYSTICK) = 0;
                i32PeriodicTimer += SYSTICKMS;
                i32ARPTimer += SYSTICKMS;
            }
            
    		if (u8NetFlag)
    		{
    			HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + (GPIO_PIN_3 << 2))) = 0;
    			u8NetFlag++;
    			if (u8NetFlag >= 25)
    			{
    				u8NetFlag = 0;
    				HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + (GPIO_PIN_3 << 2))) = GPIO_PIN_3;
    			}
    		}
    
    
    		// 串口接收转发处理
    		SmartUartPoll();
    		SmartSpiUartPoll();
    
    		if (1 == u8NetSendFlag)
    		{	
    			u8NetSendFlag = 0;
    			PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
    			uip_len = 0;
    		}
            else if (2 == u8NetSendFlag)
            {
                Udp_SendData(u8Test,sizeof(u8Test));
    			uip_arp_out();
    			u8NetSendFlag = 0;
    			PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
    			uip_len = 0;       
            }
    
    		
            // Check for an RX Packet and read it.
            if(HWREGBITW(&g_ui32Flags, FLAG_RXPKT))
            {
                // Clear the RX Packet event flag.
                HWREGBITW(&g_ui32Flags, FLAG_RXPKT) = 0;
    
                // Get the packet and set uip_len for uIP stack usage.
                uip_len = (unsigned short)PacketReceive(EMAC0_BASE, uip_buf,sizeof(g_pui8UIPBuffer));
    
                // Process incoming IP packets here.
                if (BUF->type == htons(UIP_ETHTYPE_IP))
                {
                    uip_arp_ipin(); 	// 进行IP包Arp部分的处理(更新ARP缓冲表)
                    uip_input();		// 处理缓存uip_buf中的IP数据
                    
                    // If the above function invocation resulted in data that
                    // should be sent out on the network, the global variable
                    // uip_len is set to a value > 0.
                    if (uip_len > 0)
                    {
                        uip_arp_out();
                        PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
                        uip_len = 0;
    										
    					/*************本次应答后更新网络相关参数**********************/
    					if (1 == u8UpdateParaFlag)
    					{                    
                            sTempAddr.addr[0] = u8HostMACAddr[0];
    					    sTempAddr.addr[1] = u8HostMACAddr[1];
    					    sTempAddr.addr[2] = u8HostMACAddr[2];
    					    sTempAddr.addr[3] = u8HostMACAddr[3];
    					    sTempAddr.addr[4] = u8HostMACAddr[4];
    					    sTempAddr.addr[5] = u8HostMACAddr[5];
    
    						/*
                            ui32User0 = (uint32_t)(0x000000ff & u8HostMACAddr[0]) | (uint32_t)((0x000000ff & u8HostMACAddr[1]) << 8) |
    							(uint32_t)((0x000000ff & u8HostMACAddr[2]) << 16);
    						
                            ui32User1 = (uint32_t)(0x000000ff & u8HostMACAddr[3]) | (uint32_t)((0x000000ff & u8HostMACAddr[4]) << 8) |
    							(uint32_t)((0x000000ff & u8HostMACAddr[5]) << 16);
                            
                            FlashUserSet(ui32User0,ui32User1);
                            */
                            			/************************************下列参数实时更新***************************************/
    			
    						if ((uip_ethaddr.addr[0] != sTempAddr.addr[0]) || (uip_ethaddr.addr[1] != sTempAddr.addr[1]) ||
    							(uip_ethaddr.addr[0] != sTempAddr.addr[2]) || (uip_ethaddr.addr[1] != sTempAddr.addr[3]) ||
    							(uip_ethaddr.addr[0] != sTempAddr.addr[4]) || (uip_ethaddr.addr[1] != sTempAddr.addr[5]))
    						{
    							for(i = 0; i < 4; ++i)
    							{
    								arp_table[i].ipaddr[0] = 0;
    								arp_table[i].ipaddr[1] = 0;
    							}
    						}
    						
                            EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);	
                            EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
                            EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
                            EMACAddrGet(EMAC0_BASE,0,(uint8_t *)&sTempAddr1);
    						ROM_EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)&sTempAddr);
                            Delay_us(500);
    						
    						uip_ethaddr.addr[0] = u8HostMACAddr[0];
    						uip_ethaddr.addr[1] = u8HostMACAddr[1];
    						uip_ethaddr.addr[2] = u8HostMACAddr[2];		
    						uip_ethaddr.addr[3] = u8HostMACAddr[3];
    						uip_ethaddr.addr[4] = u8HostMACAddr[4];
    						uip_ethaddr.addr[5] = u8HostMACAddr[5]; 
                            
    						uip_hostaddr[0] = u8HostIpAddr[0];
    						uip_hostaddr[1] = u8HostIpAddr[1];
    						
    						uip_netmask[0] = u8HostNetMask[0];
    						uip_netmask[1] = u8HostNetMask[1];
    
    						uip_draddr[0] = u8HostGetWay[0];
    						uip_draddr[1] = u8HostGetWay[1];
    						
    						// 将新数据写入EEPROM
    						EEPROMProgram((uint32_t *)ipSeting,0x0400,sizeof(ipSeting));
    						u8UpdateParaFlag = 0;					// 清零
    					}
    					/*************本次应答后更新网络相关参数**********************/
                    }
                }
    
                // Process incoming ARP packets here.
                else if(BUF->type == htons(UIP_ETHTYPE_ARP))
                {
                	// uip_arp_arpin判断ARP包的类型是响应包还是请求包,如果是响应包,那么更新ARP表。
    				// 如果是请求包,那么发送ARP回复帧包括本机的IP地址和MAC地址
                    uip_arp_arpin();
    
                    // If the above function invocation resulted in data that
                    // should be sent out on the network, the global variable
                    // uip_len is set to a value > 0.
                    if(uip_len > 0)
                    {
                        PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
                        uip_len = 0;
                    }
                }
            }
    
            // Process TCP/IP Periodic Timer here.
            if (i32PeriodicTimer > UIP_PERIODIC_TIMER_MS)
            {
                i32PeriodicTimer = 0;
                for(ui32Temp = 0; ui32Temp < UIP_CONNS; ui32Temp++)
                {
                    uip_periodic(ui32Temp);
    
                    // If the above function invocation resulted in data that
                    // should be sent out on the network, the global variable
                    // uip_len is set to a value > 0.
                    if(uip_len > 0)
                    {
                        uip_arp_out();
                        PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
                        uip_len = 0;
                    }
                }
    
    			#if UIP_UDP
                for(ui32Temp = 0; ui32Temp < UIP_UDP_CONNS; ui32Temp++)
                {
                    uip_udp_periodic(ui32Temp);
    
                    // If the above function invocation resulted in data that
                    // should be sent out on the network, the global variable
                    // uip_len is set to a value > 0.
                    if(uip_len > 0)
                    {
                        uip_arp_out();
                        PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
                        uip_len = 0;
                    }
                }
    			#endif
            }
    
            // Process ARP Timer here.
            if(i32ARPTimer > UIP_ARP_TIMER_MS)
            {
                i32ARPTimer = 0;
                uip_arp_timer();
            }
        }
    }
  • 根据经验看,应该是你初始化完成后,有什么没有通讯上的问题。你可以在某些初始化后面加个延时试试,或者加入状态判断机制。