使用enet_uip例程,每次修改完MAC地址后,重启设备后无法接收ARP应答,无法建立ARP表,每次都得重启2-3次才能成功,这问题有遇到的吗?
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.
就是下面这样处理的,改完后设备能正常运行,但掉电重启后,可能出现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();
}
}
}