大家好
我 需要 使用微控制器通信管理器上运行的 lwIP 堆栈从 Linux 进程与 TMDSCNCD28379D 控制卡进行通信。
我计划以大约50Hz 的速率向微控制器发送包含控制信息的 TCP 数据包、但似乎上述数据包的处理速度非常缓慢、并且在发送了几十个数据包后、 微控制器似乎不再回复任何传入的 TCP 数据包。
我从 Linux 计算机上制作了一段简短的视频、以展示流量在 Wireshark 中的样子(控制卡为192.168.0.4、Linux PC 为192.168.0.1):
我使用以下代码创建侦听 TCP 套接字:
void setupCommInterface(void){
//create a new tcp pcb
struct tcp_pcb* connection_pcb = tcp_new();
//bind the pcb to the port comm_port
err_t err=tcp_bind(connection_pcb,IP_ANY_TYPE,COMM_PORT);
if(err!=ERR_OK){
if(err==ERR_USE){
while(1){}
}
else if(err==ERR_VAL){
while(1){}
}
while(1){}
}
welcoming_socket_pcb=tcp_listen(connection_pcb);
//start accepting connections on port COMM_PORT
tcp_accept(welcoming_socket_pcb,accept_cb);
}
我使用以下代码接受传入的 TCP 连接:
err_t accept_cb(void * arg, struct tcp_pcb* new_pcb, err_t err){
if(err==ERR_OK){
//set the connection active flag
connection_active=true;
//register callback for received data
tcp_recv(new_pcb, tcp_recvd_cb);
return ERR_OK;
}
else{
while(1){
//wait forever to preserve debug state
}
}
}
我使用以下代码处理 TCP 包:
err_t tcp_recvd_cb(void* arg, struct tcp_pcb* tcppcb, struct pbuf* p,err_t err){
//payload being NULL indicated that the TCP connection has been terminated
if(p==NULL){
tcp_connection_reset_counter++;
connection_active=false;
// close the pcb
if(tcp_close(tcppcb)!=ERR_OK){
while(1){}
}
// listen to new connections again
//tcp_accept(welcoming_socket_pcb,accept_cb);
return ERR_OK;
}
else{
if(err==ERR_OK){
// -- process the data in p , p is NULL if the remote host terminated the connection --
memcpy(buffer,p->payload,p->len);
u16_t bytes_read=p->len;
//indicate that a new command is available for processing in the buffer
command_available=true;
// -- indicate that bytes were read and we are ready to receive more data --
tcp_recved(tcppcb,bytes_read); //indicate that no_bytes_read were read and we are ready to receive more data
// -- echo the received data back
//tcp_write(tcppcb,buffer,bytes_read,TCP_WRITE_FLAG_COPY);
return ERR_OK;
}
else{
//wait forever and preserve debug state
while(1);
}
}
}
除了基于中断的软件包处理之外、通信管理器不执行任何操作。 我以与 http 服务器示例相同的方式设置 CM、以下代码显示了主例程以及启动:
//*****************************************************************************
//
// This example demonstrates the use of the Ethernet Controller.
//
//*****************************************************************************
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 = 0xC0A80004;
unsigned long NetMask = 0xFFFFFF00;
unsigned long GWAddr = 0x00000000;
//
// Initializing the CM. Loading the required functions to SRAM.
//
CM_init();
//clear all ipc flags
IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);
//synchronize both core using ipc flag31
IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31);
//initial test ipc
int i;
for(i=0; i<10; i++){readData[i] = i;}
IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
IPC_CMD_READ_MEM, (uint32_t)readData, 10);
IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
if(IPC_getResponse(IPC_CM_L_CPU1_R) == TEST_PASS){pass = 1;}
else{pass = 0;}
//
// IPC Initialization for Communication with CPU1
//
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 MACOCT1
ulUser0 = 0x00F263A8;
// 0x00 MACOCT6 MACOCT5 MACOCT4
ulUser1 = 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();
//
// Initialize the ccard communication interface
//
setupCommInterface();
//
// Loop forever. All the work is done in interrupt handlers.
//
while(1){
if(reset_connection){
reset_connection=false;
tcp_recvd_cb(NULL,NULL,NULL,NULL);
}
if(command_available){
//processCommand();
command_available=false;
}
}
}
是否有人知道我可以如何解决这个问题?
非常感谢!