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. const char *TARGET = "169.254.11.123";
  10. #define PORT 7
  11. #define TIMEOUT 1 /* second(s) */
  12. int main(void)
  13. {
  14. system( "title Ethernet0 Transfer Test");
  15. system( "color 2e");
  16. printf( "Remote ( %s : %d )\n", TARGET, PORT);
  17. char fileName[ 256] = { 0 };
  18. printf( "Input filename:");
  19. scanf( "%s", fileName);
  20. FILE* fp = fopen(fileName, "rb");
  21. if (fp == NULL)
  22. {
  23. printf( "Failed to open file.\n");
  24. goto leave;
  25. }
  26. long fsize = 0;
  27. fseek(fp, 0L, SEEK_END);
  28. fsize = ftell(fp);
  29. double kilo = 1.0*fsize / 1024.0;
  30. if (kilo >= 1024.0)
  31. {
  32. printf( "File size: %.2fMB\n", kilo/ 1024.0);
  33. }
  34. else
  35. {
  36. printf( "File size: %.2fKB\n", kilo);
  37. }
  38. const int unit = 2048;
  39. int loop = fsize / unit;
  40. int residue = fsize - loop*unit;
  41. char* data = ( char*) malloc(unit + 1);
  42. struct in_addr dst;
  43. inet_pton(AF_INET, TARGET, &dst);
  44. unsigned short port = PORT;
  45. socketsStartup();
  46. SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
  47. if (s < 0)
  48. {
  49. printf( "failed socket (%d)\n", getError());
  50. goto leave;
  51. }
  52. struct sockaddr_in sin;
  53. sin.sin_family = AF_INET;
  54. sin.sin_addr.s_addr = 0;
  55. int status = 0;
  56. status = bind(s, ( const struct sockaddr *) & sin, sizeof( sin));
  57. if (status< 0)
  58. {
  59. printf( " failed bind (%d)\n", getError());
  60. goto leave;
  61. }
  62. sin.sin_addr = dst;
  63. sin.sin_port = htons(port);
  64. struct timeval timeout;
  65. timeout.tv_sec = TIMEOUT;
  66. timeout.tv_usec = 0;
  67. fd_set fds;
  68. int nr;
  69. char tmp[ 8] = { 0 };
  70. printf( "<Start sending data>\n");
  71. time_t time_start = time( 0);
  72. for ( int i = 1; i <= loop; ++i)
  73. {
  74. fread(data, unit, 1, fp);
  75. data[unit] = 0;
  76. status = sendto(s, data, strlen(data), 0, ( const struct sockaddr *)& sin, sizeof( sin));
  77. if (status< 0)
  78. {
  79. printf( "send failed (%d)\n", getError());
  80. goto leave;
  81. }
  82. FD_ZERO(&fds);
  83. FD_SET(s, &fds);
  84. select(s + 1, &fds, NULL, NULL, &timeout);
  85. nr = recv(s, tmp, 8, 0);
  86. if (i % 64 == 0)
  87. {
  88. printf( ".");
  89. if (i % 4096 == 0) printf( " (%4.1f%%)\n", 100.0*i / loop);
  90. }
  91. }
  92. if (residue > 0)
  93. {
  94. fread(data, residue, 1, fp);
  95. data[residue] = 0;
  96. status = sendto(s, data, strlen(data), 0, ( const struct sockaddr *)& sin, sizeof( sin));
  97. if ( status< 0)
  98. {
  99. printf( "send failed (%d)\n", getError());
  100. goto leave;
  101. }
  102. FD_ZERO(&fds);
  103. FD_SET(s, &fds);
  104. select(s + 1, &fds, NULL, NULL, &timeout);
  105. nr = recv(s, tmp, 8, 0);
  106. printf( " (100%%)\n");
  107. }
  108. fclose(fp);
  109. printf( "Finished transfer. Time = %d seconds\n", ( int)(time( 0) - time_start));
  110. leave:
  111. if(s>= 0) closesocket(s);
  112. if(data) free(data);
  113. socketsShutdown();
  114. system( "pause");
  115. return 0;
  116. }

DSP端接收数据的代码与本系列的06X篇( 点此跳转 )基本一致,

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值