使用enet_uip例程,每次修改完MAC地址后,重启设备后无法接收ARP应答,无法建立ARP表,每次都得重启2-3次才能成功,这问题有遇到的吗?
Maka Luo:
修改MAC地址,你是怎么做的?
hao qing:
回复 Maka Luo:
就是下面这样处理的,改完后设备能正常运行,但掉电重启后,可能出现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,子网掩码,网关修改后本次应答不更新,下次操作时更新*****************/// 主机IPu8HostIpAddr[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];// 控制端主机IPu8CtrlIpAddr[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];// 将新数据写入EEPROMEEPROMProgram((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_UDPfor(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();}} }
xyz549040622:
回复 hao qing:
根据经验看,应该是你初始化完成后,有什么没有通讯上的问题。你可以在某些初始化后面加个延时试试,或者加入状态判断机制。