通过网络连接,极大地提高了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端接收数据的代码贴上来以供参考。
-
// PC端:发送数据
-
// fengyhack @ 20150203
-
#include <stdio.h>
-
#include <time.h>
-
#include <stdlib.h>
-
#include "sockets.h"
-
#pragma comment(lib,"ws2_32.lib")
-
#pragma warning(disable:4996)
-
-
const
char *TARGET =
"169.254.11.123";
-
#define PORT 7
-
#define TIMEOUT 1 /* second(s) */
-
-
int main(void)
-
{
-
system(
"title Ethernet0 Transfer Test");
-
system(
"color 2e");
-
printf(
"Remote ( %s : %d )\n", TARGET, PORT);
-
-
char fileName[
256] = {
0 };
-
printf(
"Input filename:");
-
scanf(
"%s", fileName);
-
FILE* fp = fopen(fileName,
"rb");
-
if (fp ==
NULL)
-
{
-
printf(
"Failed to open file.\n");
-
goto leave;
-
}
-
long fsize =
0;
-
fseek(fp,
0L, SEEK_END);
-
fsize = ftell(fp);
-
double kilo =
1.0*fsize /
1024.0;
-
if (kilo >=
1024.0)
-
{
-
printf(
"File size: %.2fMB\n", kilo/
1024.0);
-
}
-
else
-
{
-
printf(
"File size: %.2fKB\n", kilo);
-
}
-
const
int unit =
2048;
-
int loop = fsize / unit;
-
int residue = fsize - loop*unit;
-
char* data = (
char*)
malloc(unit +
1);
-
-
struct in_addr dst;
-
inet_pton(AF_INET, TARGET, &dst);
-
unsigned
short port = PORT;
-
socketsStartup();
-
SOCKET s = socket(AF_INET, SOCK_DGRAM,
0);
-
if (s <
0)
-
{
-
printf(
"failed socket (%d)\n", getError());
-
goto leave;
-
}
-
-
struct sockaddr_in sin;
-
sin.sin_family = AF_INET;
-
sin.sin_addr.s_addr =
0;
-
-
int status =
0;
-
status = bind(s, (
const struct sockaddr *) &
sin,
sizeof(
sin));
-
if (status<
0)
-
{
-
printf(
" failed bind (%d)\n", getError());
-
goto leave;
-
}
-
sin.sin_addr = dst;
-
sin.sin_port = htons(port);
-
-
struct timeval timeout;
-
timeout.tv_sec = TIMEOUT;
-
timeout.tv_usec =
0;
-
-
fd_set fds;
-
int nr;
-
char tmp[
8] = {
0 };
-
-
printf(
"<Start sending data>\n");
-
-
time_t time_start = time(
0);
-
-
for (
int i =
1; i <= loop; ++i)
-
{
-
fread(data, unit,
1, fp);
-
data[unit] =
0;
-
status = sendto(s, data,
strlen(data),
0, (
const struct sockaddr *)&
sin,
sizeof(
sin));
-
if (status<
0)
-
{
-
printf(
"send failed (%d)\n", getError());
-
goto leave;
-
}
-
-
FD_ZERO(&fds);
-
FD_SET(s, &fds);
-
-
select(s +
1, &fds,
NULL,
NULL, &timeout);
-
nr = recv(s, tmp,
8,
0);
-
-
if (i %
64 ==
0)
-
{
-
printf(
".");
-
if (i %
4096 ==
0)
printf(
" (%4.1f%%)\n",
100.0*i / loop);
-
}
-
}
-
if (residue >
0)
-
{
-
fread(data, residue,
1, fp);
-
data[residue] =
0;
-
status = sendto(s, data,
strlen(data),
0, (
const struct sockaddr *)&
sin,
sizeof(
sin));
-
if ( status<
0)
-
{
-
printf(
"send failed (%d)\n", getError());
-
goto leave;
-
}
-
-
FD_ZERO(&fds);
-
FD_SET(s, &fds);
-
-
select(s +
1, &fds,
NULL,
NULL, &timeout);
-
nr = recv(s, tmp,
8,
0);
-
printf(
" (100%%)\n");
-
}
-
fclose(fp);
-
-
printf(
"Finished transfer. Time = %d seconds\n", (
int)(time(
0) - time_start));
-
-
leave:
-
if(s>=
0) closesocket(s);
-
if(data)
free(data);
-
socketsShutdown();
-
-
system(
"pause");
-
return
0;
-
}
DSP端接收数据的代码与本系列的06X篇( 点此跳转 )基本一致,
唯一改动的地方是在一个函数中,具体代码如下
-
int udpTransferTask( SOCKET s, UINT32 unused )
-
{
-
printf(
"TASK execution %d\n",++task_counter);
-
-
struct timeval tv;
-
tv.tv_sec =
1;
-
tv.tv_usec =
0;
-
setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,&tv,
sizeof(tv));
-
setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&tv,
sizeof(tv));
-
-
struct sockaddr_in sin1;
-
int sz=
sizeof(sin1);
-
int hlen=
strlen(reply);
-
int nr,total=
0;
-
HANDLE hBuffer;
-
unsigned
char* pBuf;
-
while(
1)
-
{
-
nr=recvncfrom( s, (
void**)&pBuf,
0, (PSA)&sin1, &sz, &hBuffer );
-
if(nr<=
0)
break;
-
total+=nr;
-
sendto( s, reply, hlen,
0, (PSA)&sin1, sz );
-
recvncfree( hBuffer );
-
}
-
-
double kilo_bytes=
1.0*total/
1024.0;
-
if(kilo_bytes>=
1024.0)
-
{
-
printf(
"Total size of data received: %.2fMB\n",kilo_bytes/
1024.0);
-
}
-
else
-
{
-
printf(
"Total size of data received: %.2fKB\n",kilo_bytes);
-
}
-
-
return
1;
-
}