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
=======================================================================
最近新开的公众号,文章正在一篇篇的更新,
公众号名称:
玩转电子世界
各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。
跟着阳光非宅男,一步步走进电子的世界。
关注之后回复 资料下载 关键词可以获得
免费海量的视频学习资料下载~~!
已共享的学习视频资料,共享资料正在不断更新中。。。
=======================================================================