4574|0

19

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

CCS+C6678LE开发记录08:以太网接口测试续(大块数据传输) [复制链接]

通过网络连接,极大地提高了PC与DSP之间的数据传输速率(相对于USB连接而言)。

在记录06https://bbs.eeworld.com.cn/thread-476213-1-1.html中给出了一个简单的测试示例,但是那只能传输很少的数据。

如果将数据(buffer)尺寸设置为一个较大的值(如2048等)就会出现timeout的错误。

在这种情形下更不用说传输一个大文件了,因此我们需要寻找一种解决方案。

本文正是为此而展开。

核心思想是:

1.在PC端,打开文件,分块读取数据到buffer(比如每一块大小为2KB等)

2.在PC端,每次读取数据到bufer后将buffer数据发送到socket

3.数据经过网络连接传送到DSP端

4.DSP端不断处理(暂存)ETH0接口收到的数据并发送响应

5.在PC端,每次发送一个数据块之后等待来自DSP的响应,之后才发送下一块

6.在PC端,不断发送数据块,直到整个文件数据发送完毕,最后关闭连接

经过测试发现,将文件分成2048B(=2KB)大小的块进行发送是一个比较好的选择。

每次发送2KB被DSP收到后立即被处理,然后DSP发回响应,表示已经收到这个数据。

PC端收到应答后就知道刚才发给DSP的数据已经被接收了,可以发送下一块数据。

为了让测试更加严谨,我们找来几个大小不同的文件,具体测试过程截图如下


一幅普通尺寸(1000*1000以下)的图片,30KB左右,处理时间不到1秒

一幅稍大尺寸(1920*1080)的图片,不到1MB,处理时间1秒左右

测试一个较大的文件,44.13MB大小,处理用时25秒左右

测试一个更大的文件,191.82MB大小,处理用时103秒左右

最后测试传输一张大尺寸照片,4k*3k分辨率,5.28MB大小,用时约3秒

在CCS调试输出窗口的截图如下


对比一下发现,5次测试中都能正确收到全部数据。


这个测试表明,我们的流程设计是合理的。

最后将PC端发送数据以及DSP端接收数据的代码贴上来以供参考。

  1. // PC端:发送数据  
  2. // fengyhack @ 20150203  
  3. #include <stdio.h>  
  4. #include <time.h>  
  5. #include <stdlib.h>  
  6. #include "sockets.h"  
  7. #pragma comment(lib,"ws2_32.lib")  
  8. #pragma warning(disable:4996)  
  9.   
  10. const char  *TARGET = "169.254.11.123";  
  11. #define PORT  7  
  12. #define TIMEOUT 1  /* second(s) */  
  13.   
  14. int main(void)  
  15. {  
  16.     system("title Ethernet0 Transfer Test");  
  17.     system("color 2e");  
  18.     printf("Remote ( %s : %d )\n", TARGET, PORT);  
  19.   
  20.     char fileName[256] = { 0 };  
  21.     printf("Input filename:");  
  22.     scanf("%s", fileName);  
  23.     FILE* fp = fopen(fileName, "rb");  
  24.     if (fp == NULL)  
  25.     {  
  26.         printf("Failed to open file.\n");  
  27.         goto leave;  
  28.     }  
  29.     long fsize = 0;  
  30.     fseek(fp, 0L, SEEK_END);  
  31.     fsize = ftell(fp);  
  32.     double kilo = 1.0*fsize / 1024.0;  
  33.     if (kilo >= 1024.0)  
  34.     {  
  35.         printf("File size: %.2fMB\n", kilo/1024.0);  
  36.     }  
  37.     else  
  38.     {  
  39.         printf("File size: %.2fKB\n", kilo);  
  40.     }  
  41.     const int unit = 2048;  
  42.     int loop = fsize / unit;  
  43.     int residue = fsize - loop*unit;  
  44.     char* data = (char*)malloc(unit + 1);  
  45.   
  46.     struct in_addr dst;  
  47.     inet_pton(AF_INET, TARGET, &dst);  
  48.     unsigned short port = PORT;  
  49.     socketsStartup();  
  50.     SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);  
  51.     if (s < 0)  
  52.     {  
  53.         printf("failed socket (%d)\n", getError());  
  54.         goto leave;  
  55.     }  
  56.   
  57.     struct sockaddr_in sin;  
  58.     sin.sin_family = AF_INET;  
  59.     sin.sin_addr.s_addr = 0;  
  60.   
  61.     int status = 0;  
  62.     status = bind(s, (const struct sockaddr *) &sin, sizeof(sin));  
  63.     if (status< 0)   
  64.     {  
  65.         printf(" failed bind (%d)\n", getError());  
  66.         goto leave;  
  67.     }  
  68.     sin.sin_addr = dst;  
  69.     sin.sin_port = htons(port);  
  70.   
  71.     struct timeval timeout;  
  72.     timeout.tv_sec = TIMEOUT;  
  73.     timeout.tv_usec = 0;  
  74.   
  75.     fd_set fds;  
  76.     int nr;  
  77.     char tmp[8] = { 0 };  
  78.   
  79.     printf("<Start sending data>\n");  
  80.   
  81.     time_t time_start = time(0);  
  82.   
  83.     for (int i = 1; i <= loop; ++i)  
  84.     {  
  85.         fread(data, unit, 1, fp);  
  86.         data[unit] = 0;  
  87.         status = sendto(s, data, strlen(data), 0, (const struct sockaddr *)&sin, sizeof(sin));  
  88.         if (status< 0)  
  89.         {  
  90.             printf("send failed (%d)\n", getError());  
  91.             goto leave;  
  92.         }  
  93.   
  94.         FD_ZERO(&fds);  
  95.         FD_SET(s, &fds);  
  96.   
  97.         select(s + 1, &fds, NULL, NULL, &timeout);  
  98.         nr = recv(s, tmp, 8, 0);  
  99.   
  100.         if (i % 64 == 0)  
  101.         {  
  102.             printf(".");  
  103.             if (i % 4096 == 0) printf(" (%4.1f%%)\n", 100.0*i / loop);  
  104.         }  
  105.     }  
  106.     if (residue > 0)  
  107.     {  
  108.         fread(data, residue, 1, fp);  
  109.         data[residue] = 0;  
  110.         status = sendto(s, data, strlen(data), 0, (const struct sockaddr *)&sin, sizeof(sin));  
  111.         if ( status< 0)  
  112.         {  
  113.             printf("send failed (%d)\n", getError());  
  114.             goto leave;  
  115.         }  
  116.   
  117.         FD_ZERO(&fds);  
  118.         FD_SET(s, &fds);  
  119.   
  120.         select(s + 1, &fds, NULL, NULL, &timeout);  
  121.         nr = recv(s, tmp, 8, 0);  
  122.         printf(" (100%%)\n");  
  123.     }  
  124.     fclose(fp);  
  125.   
  126.     printf("Finished transfer. Time = %d seconds\n", (int)(time(0) - time_start));  
  127.   
  128. leave:  
  129.     if(s>=0) closesocket(s);  
  130.     if(data) free(data);  
  131.     socketsShutdown();  
  132.   
  133.     system("pause");  
  134.     return 0;  
  135. }  
复制代码
DSP端接收数据的代码与本系列的06X篇https://bbs.eeworld.com.cn/thread-476213-1-1.html基本一致,


唯一改动的地方是在一个函数中,具体代码如下

  1. int udpTransferTask( SOCKET s, UINT32 unused )  
  2. {  
  3.     printf("TASK execution %d\n",++task_counter);  
  4.   
  5.         struct timeval tv;  
  6.         tv.tv_sec  = 1;  
  7.         tv.tv_usec = 0;  
  8.         setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv));  
  9.         setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));  
  10.   
  11.         struct sockaddr_in sin1;  
  12.         int sz=sizeof(sin1);  
  13.         int hlen=strlen(reply);  
  14.         int nr,total=0;  
  15.         HANDLE hBuffer;  
  16.         unsigned char* pBuf;  
  17.         while(1)  
  18.         {  
  19.             nr=recvncfrom( s, (void**)&pBuf, 0, (PSA)&sin1, &sz, &hBuffer );  
  20.             if(nr<=0) break;  
  21.             total+=nr;  
  22.             sendto( s, reply, hlen, 0, (PSA)&sin1, sz );  
  23.             recvncfree( hBuffer );  
  24.         }  
  25.   
  26.         double kilo_bytes=1.0*total/1024.0;  
  27.         if(kilo_bytes>=1024.0)  
  28.         {  
  29.             printf("Total size of data received: %.2fMB\n",kilo_bytes/1024.0);  
  30.         }  
  31.         else  
  32.         {  
  33.             printf("Total size of data received: %.2fKB\n",kilo_bytes);  
  34.         }  
  35.   
  36.         return 1;  
  37. }  
复制代码





点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表