本人在做LM3S8962作为客户端测试时,遇到个问题,如果TCP测试软件建立服务器后,客户端有可能会等很久才连上来,关掉了这个连接,就再也建立不上与8962的通信。迷惑中,请高手帮帮忙,万分感谢!我的源码如下:
//----------------------------------------------------------------------------- // // enet_lwip_tcp.c - 一个简单的lwIP tcp通信例程 // //-----------------------------------------------------------------------------
#include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_nvic.h" #include "inc/hw_types.h" #include "driverlib/ethernet.h" #include "driverlib/flash.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "utils/lwiplib.h" #include "utils/uartstdio.h" #include "utils/truly128x64.h" #include "utils/ustdlib.h" #include <LM3Sxxxx.h>
//---------------------------------------------------------------------------- //! 这个例子展示了对Stellaris以太网控制器的使用,通过lwIP TCP/IP 协议栈 // http://savannah.nongnu.org/projects/lwip/ //----------------------------------------------------------------------------
#define ulPORT 3000
//---------------------------------------------------------------------------- // // Defines for setting up the system clock. // 定义systick时钟 //----------------------------------------------------------------------------- #define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ)
unsigned char sent_ok_flag = 0; struct tcp_pcb *now_pcb; char tmpbuf[20]; void *ptr; struct ip_addr ipaddr;
//----------------------------------------------------------------------------- // // 显示lwip的IP地址信息函数 // //----------------------------------------------------------------------------- void DisplayIPAddress(unsigned long ipaddr, unsigned long ulCol, unsigned long ulRow) { char pucBuf[16]; unsigned char *pucTemp = (unsigned char *)&ipaddr;
// // 转换IP地址到字符串 // usprintf(pucBuf, "%d.%d.%d.%d", pucTemp[0], pucTemp[1], pucTemp[2], pucTemp[3]);
// //显示字符串 // Oled_Dis_string(ulCol,ulRow,pucBuf); } //----------------------------------------------------------------------------- // // 被lwIp库使用,用来支持任何主机相关的定时功能 // //----------------------------------------------------------------------------- void lwIPHostTimerHandler(void) { static unsigned long ulLastIPAddress = 0; unsigned long ulIPAddress; char pucBuf[16];
ulIPAddress = lwIPLocalIPAddrGet();
// // If IP Address has not yet been assigned, update the display accordingly // if(ulIPAddress == 0) {
} // // Check if IP address has changed, and display if it has. // else if(ulLastIPAddress != ulIPAddress) { ulLastIPAddress = ulIPAddress; Oled_Dis_string(2,2,"IP: "); Oled_Dis_string(3,2,"MASK: "); Oled_Dis_string(4,2,"GW: "); Oled_Dis_string(5,2,"Port: "); DisplayIPAddress(ulIPAddress, 2, 38); ulIPAddress = lwIPLocalNetMaskGet(); DisplayIPAddress(ulIPAddress, 3, 38); ulIPAddress = lwIPLocalGWAddrGet(); DisplayIPAddress(ulIPAddress, 4, 38); usprintf(pucBuf, "%d", ulPORT); Oled_Dis_string(5, 38,pucBuf); } }
//----------------------------------------------------------------------------- // // systick中断处理函数 // //----------------------------------------------------------------------------- void SysTickIntHandler(void) { // // 调用lwip定时处理函数 // lwIPTimer(SYSTICKMS); }
//----------------------------------------------------------------------------- // // 发送完成回调函数 // //----------------------------------------------------------------------------- err_t Sent_Ok(void *arg,struct tcp_pcb *pcb,u16_t err) { tcp_close(pcb); return ERR_OK; }
//----------------------------------------------------------------------------- // // 接收到数据的回调函数 // //----------------------------------------------------------------------------- err_t recv_now(void *arg,struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
if(p != NULL) //如果收到的数据不为空 { tcp_write(tpcb,p->payload,p->len,0); //将接收到的数据发送出去 pbuf_free(p); // 释放缓冲区数据 tcp_recved(tpcb,p->tot_len); //tcp_output(tpcb); } return ERR_OK; }
//----------------------------------------------------------------------------- // // 接受连接请求 // //----------------------------------------------------------------------------- err_t TCP_SER_Connected(void *arg, struct tcp_pcb *pcb, err_t err) { // // Clear out all of the TCP callbacks. // tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_err(pcb, NULL); tcp_poll(pcb, NULL, 1);
// // Close the TCP connection. // tcp_close(pcb);
tcp_recv(pcb,recv_now); return(ERR_OK); }
/***************************************************************************************** ** Function name: TCP_SER_Poll ** Descriptions: 接收处理函数 ** input parameters: 无 ** output parameters: 无 ** Returned value: 无 *****************************************************************************************/ err_t TCP_SER_Poll(void *arg, struct tcp_pcb *pcb) { err_t eError;
eError = tcp_connect(pcb, &ipaddr, ulPORT, TCP_SER_Connected);
if(eError != ERR_OK) { return 1; } return 0; }
/***************************************************************************************** ** Function name: TCP_Client_Init ** Descriptions: 客户端模式初始化网络连接 ** input parameters: ulIPAddr ** output parameters: 无 ** Returned value: 无 *****************************************************************************************/ void TCP_Client_Init(unsigned long ulIPAddr) { struct tcp_pcb *local_pcb;
err_t eError;
ipaddr.addr = htonl(ulIPAddr);
local_pcb = tcp_new(); tcp_poll(local_pcb, TCP_SER_Poll, (3000 / TCP_SLOW_INTERVAL)); eError = tcp_connect(local_pcb, &ipaddr, ulPORT, TCP_SER_Connected); if(eError != ERR_OK) { return; } }
//----------------------------------------------------------------------------- // // 使用以太网控制器的一个例子 // //----------------------------------------------------------------------------- int main(void) { unsigned long ulUser0 = 0x12345678, ulUser1 = 0x12345678 ; unsigned char pucMACArray[8]; unsigned long ulIPAddr,ulIPMask,ulIPGateWay,ulIPAddrR; // //设定系统时钟8MHZ // SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
// // 初始化 OLED 显示. // Oled_Init(); Oled_Dis_string(1,10,"Enet lwip Tcp Test");
// // 使能以太网控制器,然后复位以太网控制器 // SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH); SysCtlPeripheralReset(SYSCTL_PERIPH_ETH); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// // 使能端口F来作为以太网的LED使用 // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinConfigure(GPIO_PF2_LED1); GPIOPinConfigure(GPIO_PF3_LED0); GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); //使能Uart时钟 GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0 | GPIO_PIN_1); //配置引脚为Rx、Tx功能 // //配置UART0 // UARTConfigSetExpClk(UART0_BASE,SysCtlClockGet(),9600, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); //配置为9600,8位,1个停止位,无校验 UARTIntEnable(UART0_BASE,UART_INT_RT | UART_INT_RX); //使能接收中断和接受超时中断 UARTEnable(UART0_BASE); //启动Uart IntEnable(INT_UART0); //使能Uart中断
// // 配置systick // SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ); SysTickEnable(); SysTickIntEnable();
// //使能处理器中断 // IntMasterEnable();
// //从用户寄存器中 读取MAC地址 // //ROM_FlashUserGet(&ulUser0, &ulUser1); if((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff)) { // // MAC没有编程 // Oled_Dis_string(5,5,"MAC Not Programmed!"); while(1) { } }
// //转换用户寄存器到MAC地址 // pucMACArray[0] = ((ulUser0 >> 0) & 0xff); pucMACArray[1] = ((ulUser0 >> 8) & 0xff); pucMACArray[2] = ((ulUser0 >> 16) & 0xff); pucMACArray[3] = ((ulUser1 >> 0) & 0xff); pucMACArray[4] = ((ulUser1 >> 8) & 0xff); pucMACArray[5] = ((ulUser1 >> 16) & 0xff);
// // 初始化lwIP协议栈 静态IP // IP地址: 192.168.14.20 // 子网掩码:255.255.255.0 // 默认网关:192.168.14.254 ulIPAddr = (((unsigned long )192<<24)|(168<<16)|(2<<8)|20); ulIPMask = ((unsigned long )255<<24)|(255<<16)|(255<<8)|0; ulIPGateWay = ((unsigned long )192<<24)|(168<<16)|(2<<8)|254; ulIPAddrR = (((unsigned long )192<<24)|(168<<16)|(2<<8)|6); lwIPInit(pucMACArray, ulIPAddr, ulIPMask, ulIPGateWay, IPADDR_USE_STATIC);
// //初始化客户端TCP // TCP_Client_Init(ulIPAddrR);
// // 主循环 // while(1) { } }
|