CCS+C6678LE开发记录09:以太网接口测试续(大块数据传输)

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

在记录06(点此跳转)中给出了一个简单的测试示例,但是那只能传输很少的数据。

如果将数据(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篇(点此跳转)基本一致,

 

 

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

 

 
  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. }

本文原创,博文地址

http://blog.csdn.net/fengyhack/article/details/43446989

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值