DSP

DSP- 6678--------- 多核DSP图像处理(3)主核程序之TCP进程

2019-07-13 10:19发布

StartNetworkTask进程是在cfg文件中创建的进程。主要用于接收上位机通过TCP传来的图片数据以及将处理结果传输给上位机。具体流程本节介绍。 一、StartNetworkTask 1 TCP的配置     rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT ); if( rc ) { printf("NC_SystemOpen Failed (%d) ",rc); for(;;); } // Create and build the system configuration from scratch. // Create a new configuration hCfg = CfgNew(); if( !hCfg ) { printf("Unable to create configuration "); goto main_exit; } // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!! rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT ); if( rc ) { printf("NC_SystemOpen Failed (%d) ",rc); for(;;); } // Create and build the system configuration from scratch. // Create a new configuration hCfg = CfgNew(); if( !hCfg ) { printf("Unable to create configuration "); goto main_exit; } // We better validate the length of the supplied names if( strlen( DomainName ) >= CFG_DOMAIN_MAX || strlen( HostName ) >= CFG_HOSTNAME_MAX ) { printf("Names too long "); goto main_exit; } // Add our global hostname to hCfg (to be claimed in all connected domains) CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0, strlen(HostName), (UINT8 *)HostName, 0 ); // If the IP address is specified, manually configure IP and Gateway #if defined(_SCBP6618X_) || defined(_EVMTCI6614_) || defined(DEVICE_K2H) || defined(DEVICE_K2K) /* SCBP6618x, EVMTCI6614, EVMK2H, EVMK2K always uses DHCP */ if (0) #else if (1)//(!platform_get_switch_state(1)) #endif { CI_IPNET NA; CI_ROUTE RT; IPN IPTmp; // Setup manual IP address bzero( &NA, sizeof(NA) ); NA.IPAddr = inet_addr(LocalIPAddr); //设置IP NA.IPMask = inet_addr(LocalIPMask); //设置掩码 strcpy( NA.Domain, DomainName ); NA.NetType = 0; // Add the address to interface 1 CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0, sizeof(CI_IPNET), (UINT8 *)&NA, 0 ); // Add the default gateway. Since it is the default, the // destination address and mask are both zero (we go ahead // and show the assignment for clarity). bzero( &RT, sizeof(RT) ); RT.IPDestAddr = 0; RT.IPDestMask = 0; RT.IPGateAddr = inet_addr(GatewayIP); // Add the route CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0,sizeof(CI_ROUTE), (UINT8 *)&RT, 0 ); // Manually add the DNS server when specified IPTmp = inet_addr(DNSServer);// "0.0.0.0" if( IPTmp ) CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER, 0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 ); } // Else we specify DHCP else { CI_SERVICE_DHCPC dhcpc; // Specify DHCP Service on IF-1 bzero( &dhcpc, sizeof(dhcpc) ); dhcpc.cisargs.Mode = CIS_FLG_IFIDXVALID; dhcpc.cisargs.IfIdx = 1; dhcpc.cisargs.pCbSrv = &ServiceReport; CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0, sizeof(dhcpc), (UINT8 *)&dhcpc, 0 ); } // Configure IPStack/OS Options // We don't want to see debug messages less than WARNINGS rc = DBG_ERROR; CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // // This code sets up the TCP and UDP buffer sizes // (Note 8192 is actually the default. This code is here to // illustrate how the buffer and limit sizes are configured.) // /* TCP Transmit buffer size */ rc = 64000; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 ); /* TCP Receive buffer size (copy mode) */ rc = 64000; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 ); /* TCP Receive limit (non-copy mode) */ rc = 64000; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 ); // UDP Receive limit rc = 8192; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );  do     {     //                       调用起始函数      调用结束函数            调用IP地址设置函数         rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );     } while( rc > 0 ); //                       调用起始函数      调用结束函数            调用IP地址设置函数         rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );     } while( rc > 0 ); 以上代码基本上固定,注意最后一个函数  定义来创建连接之后的起始函数、结束函数、IP设置函数 2 NetworkOpen( ) static void NetworkOpen() { /*创建任务 dtask_tcp 在tcpServer.c中定义 */ (void)TaskCreate(dtask_tcp, "dtask_tcp", OS_TASKPRINORM, 0x20000/*OS_TASKSTKNORM*/, 0, 0, 0); /* Create a thread to receive data */ /*创建任务 TcpShareRX 在tcpServer.c中定义 */ (void)TaskCreate( TcpShareRX, "Receiver", OS_TASKPRINORM, 0x10000, 0, 0, 0); } 在NetworkOpen中创建了两个task  一个dtask_tcp  一个TcpShareRX。 一个用于创建TCP  一个用于接收数据 二、task1----dtask_tcp     2.1 建立socket结构体 /* create an Event Instance */ evt_rx = Event_create(NULL, NULL); /* Allocate the file environment for this task */     fdOpenSession( TaskSelf() ); printf(" == Start Shared TCP Socket Echo Test == "); /* Create test socket */ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( s == INVALID_SOCKET ) { printf("failed socket create (%d) ",fdError()); goto leave; } /* Set Port = 8080, IP address = IPAddrSend */ bzero( &sin1, sizeof(struct sockaddr_in) ); sin1.sin_family = AF_INET; sin1.sin_len = sizeof( sin1 ); sin1.sin_addr.s_addr = INADDR_ANY;//inet_addr(LOCAL_IPADDR_STRING); sin1.sin_port = htons(8080); 2.2 socket操作  bind listen accept if( bind( s, (struct sockaddr *)&sin1, sizeof(sin1) ) < 0 ) { fdClose( s); s = INVALID_SOCKET; printf("Fail to bind socket, %d ", fdError()); goto leave; } /* If the socket is bound and TCP, start listening */ if( listen( s, MAX_CONN) < 0 ) { fdClose( s ); printf("Fail to listen on socket, %d ", fdError()); s = INVALID_SOCKET; goto leave; } /* Configure our timeout to be 5 seconds */ timeout.tv_sec = 10; timeout.tv_usec = 0; setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) ); setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) ); while(1) { /* Get the accept socket */ size = sizeof(sin1); bzero( &sin1, sizeof(struct sockaddr_in) ); printf("accept1 "); skt = accept(s, (PSA)&sin1, &size); printf("accept2 "); if (INVALID_SOCKET == skt) {     continue; } printf("accept3 "); ss = skt; linkState = LINK_STATE_OK; Event_post(evt_rx, Event_Id_30); } 连接成功之后   linkState = LINK_STATE_OK; TCP开始接收数据  开始进行接收数据的task 三、task2----TcpShareRX 当第一步连接正确的时候,该进程得以开启。 3.1 接收数据头部 iRetRecv = recv( ss, (void *)&in_frame, SIZE_IN_FRAME_HEADER, MSG_WAITALL); 根据头部判断工作状态 3.2 接收数据 //================== 接受图像数据 每次接收1280, totalBytes += iRetRecv ===================// while(totalBytes < frame->header.len) {     iRetRecv = recv( ss, frame->data + totalBytes, MAX_RECV_LEN, 0);     if(iRetRecv == SOCKET_ERROR)     { printf("failed recv (%d) ",fdError()); if( ss != INVALID_SOCKET ) fdClose( ss ); ss = INVALID_SOCKET;     }     totalBytes += iRetRecv; } 3.3 Mailbox_post   从上位机PC接收TCP数据完毕后,发送邮箱 (主要传递输入图片的地址指针)   if (Mailbox_post(master_mbox_receive, &process_msg, BIOS_WAIT_FOREVER) == FALSE) { printf("Error in running edge detection: mbox_post"); return -1; } 3.4 Mailbox_pend 等待邮箱 等待数据全部处理完毕之后的mailbox if (Mailbox_pend(master_mbox_send, &response_msg, BIOS_WAIT_FOREVER) == FALSE) { printf("Error in running edge detection: mbox_pend"); return -1; } 3.5 发送数据到上位机 output_image = response_msg.output_image; delay = response_msg.processing_time; printf("processing_time = %fms ",delay); outheader.cmd = 2; outheader.para = 12; outheader.len = output_image.length; // 通过TCP协议 send data header tcp_data_send((unsigned int)(&outheader),sizeof(Net_InFrameHeader_t)); // 通过TCP协议 send data tcp_data_send((unsigned int)(output_image.data),outheader.len); printf("@Scheduler: back data message: %s ","SENDBACK_FINISHED"); if (output_image.data) { Memory_free(NULL, output_image.data, output_image.length); output_image.length = 0; } 程序下载地址: https://download.csdn.net/download/yunge812/10517028   ======================================================================= 最近新开的公众号,文章正在一篇篇的更新, 公众号名称:玩转电子世界 各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。 跟着阳光非宅男,一步步走进电子的世界。 关注之后回复  资料下载  关键词可以获得免费海量视频学习资料下载~~! 已共享的学习视频资料,共享资料正在不断更新中。。。 =======================================================================