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

StartNetworkTask进程是在cfg文件中创建的进程。主要用于接收上位机通过TCP传来的图片数据以及将处理结果传输给上位机。具体流程本节介绍。

一、StartNetworkTask

1 TCP的配置

    rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
    if( rc )
    {
    	printf("NC_SystemOpen Failed (%d)\n",rc);
        for(;;);
    }

    // Create and build the system configuration from scratch.

    // Create a new configuration
    hCfg = CfgNew();
    if( !hCfg )
    {
        printf("Unable to create configuration\n");
        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)\n",rc);
        for(;;);
    }

    // Create and build the system configuration from scratch.

    // Create a new configuration
    hCfg = CfgNew();
    if( !hCfg )
    {
        printf("Unable to create configuration\n");
        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\n");
        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设置函数

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("\n== Start Shared TCP Socket Echo Test ==\n");

    /* Create test socket */
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if( s == INVALID_SOCKET )
    {
        printf("failed socket create (%d)\n",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\n", 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\n", 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\n");
   skt = accept(s, (PSA)&sin1, &size);
   printf("accept2\n");
   if (INVALID_SOCKET == skt)
   {
       continue;
   }
   printf("accept3\n");
   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)\n",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\n",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\n","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

猜你喜欢

转载自blog.csdn.net/yunge812/article/details/80899872
dsp