通過網絡連接配接,極大地提高了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
-
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;
-
}
本文原創,博文位址
http://blog.csdn.net/fengyhack/article/details/43446989