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的工程师们能够下载运行一下,如果有问题或者好的解决方案,希望我们可以详细探讨交流一下,不胜感激!