Part Number:TMS320F28388DOther Parts Discussed in Thread:TMDSCNCD28388D
您好,我使用TI的开发板TMDSCNCD28388D测试网络通信时出现两个问题:
一是 连续发送数据时会有粘包现象
二是 通信一段时间后会断开连接
下面是实验代码:
(1)CM上的主程序和http处理程序
int main(void) {unsigned long ulUser0, ulUser1;unsigned char pucMACArray[8];//// User specific IP Address Configuration.// Current implementation works with Static IP address only.//unsigned long IPAddr = 0xC0A80101;unsigned long NetMask = 0xFFFFFF00;unsigned long GWAddr = 0x00000000;// Initializing the CM. Loading the required functions to SRAM.CM_init();SYSTICK_setPeriod(systickPeriodValue);SYSTICK_enableCounter();SYSTICK_registerInterruptHandler(SysTickIntHandler);SYSTICK_enableInterrupt();//// Enable processor interrupts.//Interrupt_enableInProcessor();// Set user/company specific MAC octets// (for this code we are using A8-63-F2-00-00-80)// 0x00 MACOCT3 MACOCT2 MACOCT1ulUser0 = 0x00F263A8;// 0x00 MACOCT6 MACOCT5 MACOCT4ulUser1 = 0x00800000;//// Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC// address needed to program the hardware registers, then program the MAC// address into the Ethernet Controller registers.//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);//// Initialize ethernet module.//Ethernet_init(pucMACArray);//// Initialze the lwIP library, using DHCP.//lwIPInit(0, pucMACArray, IPAddr, NetMask, GWAddr, IPADDR_USE_STATIC);//// Initialize the HTTP webserver daemon.//httpd_init();IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31); // 等待远端IPC初始化//// Loop forever. All the work is done in interrupt handlers.//while(1); }
static err_t http_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err) {struct http_state *hs = (struct http_state *)arg;char *data = NULL;if(err==ERR_OK && p!=NULL){tcp_recved(pcb,p->tot_len);data = p->payload;pbuf_free(p);if(data[0]=='A' && data[1]=='O'){tcp_write(pcb,"led1 open",10, 1);GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);}else if(data[0]=='A' && data[1]=='C'){tcp_write(pcb,"led1 close",10, 1);GPIO_writePin(DEVICE_GPIO_PIN_LED1, 1);}if(data[0]=='B' && data[1]=='O'){tcp_write(pcb,"led2 open",10, 1);GPIO_writePin(DEVICE_GPIO_PIN_LED2, 0);}else if(data[0]=='B' && data[1]=='C'){tcp_write(pcb,"led2 close",10, 1);GPIO_writePin(DEVICE_GPIO_PIN_LED2, 1);}else if(data[0]=='P' && data[1]=='L'){tcp_write(pcb,"TESTOK",10, 1);}}else{pbuf_free(p);}if(err==ERR_OK && p==NULL){http_close_conn(pcb,hs);}return ERR_OK; }
(2)CPU1上的主程序
void main(void) {//// Initialize device clock and peripherals//Device_init();//// Boot CM core// #ifdef _FLASHDevice_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0); #elseDevice_bootCM(BOOTMODE_BOOT_TO_S0RAM); #endif//// Disable pin locks and enable internal pull-ups.//Device_initGPIO();GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);GPIO_setPadConfig(DEVICE_GPIO_PIN_LED2, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED2, GPIO_DIR_MODE_OUT);GPIO_setMasterCore(31, GPIO_CORE_CM);GPIO_setMasterCore(34, GPIO_CORE_CM); #ifdef ETHERNET//// Set up EnetCLK to use SYSPLL as the clock source and set the// clock divider to 2.//// This way we ensure that the PTP clock is 100 MHz. Note that this value// is not automatically/dynamically known to the CM core and hence it needs// to be made available to the CM side code beforehand.SysCtl_setEnetClk(SYSCTL_ENETCLKOUT_DIV_2, SYSCTL_SOURCE_SYSPLL);//// Configure the GPIOs for ETHERNET.////// MDIO Signals//GPIO_setPinConfig(GPIO_105_ENET_MDIO_CLK);GPIO_setPinConfig(GPIO_106_ENET_MDIO_DATA);//// Use this only for RMII Mode//GPIO_setPinConfig(GPIO_73_ENET_RMII_CLK);//////MII Signals//GPIO_setPinConfig(GPIO_109_ENET_MII_CRS);GPIO_setPinConfig(GPIO_110_ENET_MII_COL);GPIO_setPinConfig(GPIO_75_ENET_MII_TX_DATA0);GPIO_setPinConfig(GPIO_122_ENET_MII_TX_DATA1);GPIO_setPinConfig(GPIO_123_ENET_MII_TX_DATA2);GPIO_setPinConfig(GPIO_124_ENET_MII_TX_DATA3);////Use this only if the TX Error pin has to be connected//GPIO_setPinConfig(GPIO_46_ENET_MII_TX_ERR);//GPIO_setPinConfig(GPIO_118_ENET_MII_TX_EN);GPIO_setPinConfig(GPIO_114_ENET_MII_RX_DATA0);GPIO_setPinConfig(GPIO_115_ENET_MII_RX_DATA1);GPIO_setPinConfig(GPIO_116_ENET_MII_RX_DATA2);GPIO_setPinConfig(GPIO_117_ENET_MII_RX_DATA3);GPIO_setPinConfig(GPIO_113_ENET_MII_RX_ERR);GPIO_setPinConfig(GPIO_112_ENET_MII_RX_DV);GPIO_setPinConfig(GPIO_44_ENET_MII_TX_CLK);GPIO_setPinConfig(GPIO_111_ENET_MII_RX_CLK);////Power down pin to bring the external PHY out of Power down//GPIO_setDirectionMode(108, GPIO_DIR_MODE_OUT);GPIO_setPadConfig(108, GPIO_PIN_TYPE_PULLUP);GPIO_writePin(108,1);////PHY Reset Pin to be driven High to bring external PHY out of Reset//GPIO_setDirectionMode(119, GPIO_DIR_MODE_OUT);GPIO_setPadConfig(119, GPIO_PIN_TYPE_PULLUP);GPIO_writePin(119,1); #endif }
(3)上位机的连接和发送接收函数
#include "DLL_28388.h" #ifdef _DEBUG #define new DEBUG_NEW #endif #include <iostream> #include<winSock2.h> #include<WS2tcpip.h> #define WIN32_LEAN_AND_MEAN #include<windows.h> #pragma comment(lib,"ws2_32.lib") SOCKET CDll::F28388D_Lwip_Connect(const std::string& ipAddress, int port) { // 初始化Winsock WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { return INVALID_SOCKET; } // 创建SOCKET SOCKET ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { WSACleanup(); return INVALID_SOCKET; } // 设置服务器地址 sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); // 将IP地址从字符串转换为二进制形式 in_addr addr; if (inet_pton(AF_INET, ipAddress.c_str(), &addr) <= 0) { closesocket(ConnectSocket); WSACleanup(); return INVALID_SOCKET; } serverAddress.sin_addr = addr; // 连接到服务器 iResult = connect(ConnectSocket, (SOCKADDR*)&serverAddress, sizeof(serverAddress)); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); WSACleanup(); return INVALID_SOCKET; } return ConnectSocket; // 返回已连接的socket句柄 } int CDll::F28388D_Lwip_Send(SOCKET sock, const std::string& msg) { int bytesSent = send(sock, msg.c_str(), static_cast<int>(msg.size()), 0); if (bytesSent == SOCKET_ERROR) { std::cerr << "send failed with error: " << WSAGetLastError() << std::endl; return 1; } return 0; } std::string CDll::F28388D_Lwip_Recv(SOCKET sock) { char recvbuf[512]; int bytesRecvd = recv(sock, recvbuf, sizeof(recvbuf) - 1, 0); if (bytesRecvd > 0) { recvbuf[bytesRecvd] = '\0'; // 确保字符串以null终止 return std::string(recvbuf); } else if (bytesRecvd == 0) { std::cout << "Connection closed" << std::endl; } else { std::cerr << "recv failed with error: " << WSAGetLastError() << std::endl; } return ""; }
在wireshark软件中,显示的粘包错误:
AC命令对应返回值为led1 close
BC命令对应返回值为led2 close
AO命令对应返回值为led1 open
BO命令对应返回值为led2 open
在上位机程序的定时器中,这些命令分开 依次 发送,但是抓包数据显示,有三个命令是放到一个TCP数据包中发送出去的,请问这可能是什么原因造成的
Gao Tian:
dsptest_lwip.rar这是我的工程文件,希望各位大佬和TI的工程师们能够下载运行一下,如果有问题或者好的解决方案,希望我们可以详细探讨交流一下,不胜感激!