Hi,all
A I using Ti's dm8168_evm demo board ,using kernel uImage and file system of the newest DVRRDK_03.00.01.03.tar.gz , and execute UDP server and client program in the 100M network environmen ,find out dm8168_evm lossing packet is serious .
I trace the kernel code ,find that : CPDMA desc be release is very very slowly , cause that new skb data packet getting new CPDMA desc to be sent out is very very hard , than cause lossing packet .
everone can using my UDP server and client program to test and Reproduct this case,the code is in bottom .
the UDP server and client usage way:
change UDP_SERVER_IP value in the client.c to you linux PC IP address .
the server program is run in your linux PC , and client run in your dm8168 develop board.
server:
gcc server.c -o ts
your linux PC:
./ts
client:
arm-none-linux-gnueabi-gcc client.c -o tc
your dm8168 board:
./tc
than telnet to your dm8168, repeat run " ifconfig " ,
you can find that your alive ethernet dropped packet is increasing very fast , lossing packet rate is reaching 60% !!
because I use Ti's dm8168_evm demo board ,Ti's newest kernel and file system . and my UDP server and client code is very simple ,firm,and correct .
according my watching and trace , I can reach a conclusion that DM8168 chip hardware or kernel code has serious problem .
Hope Ti can resolve this problem soon !!
************************************************the server code ******************************************************************************************************************
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <asm/types.h>
#include <time.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <pthread.h>
#include <poll.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#if 1
#define JPGOFFSET 21
typedef enum {
eNITPVer11 = 1
} ENITPVer;
typedef struct PicResolution {
short Width; //
short Height; //
} PicResolution;
typedef enum {
eOldPic = 1,
eStreamPic = 2,
eSnapPicCloseLamp = 3,
eSnapPicOpenLamp = 4
} EStreamPicType;
typedef enum {
eSoft, // <8f><91>
ebayonet, // <8d> <8f>
eRedlight, // <97>
eRS485, // RS485 <8f><91>
eRS232, // RS232 <9b> <8f><91>
eSpeed, // <85> <80><9f> <8f><91>
eStream // <81>
} ESnapType;
#define TriType ESnapType
#define PicType EStreamPicType
#define MAC_LENGTH 6
#define VER_MAX_LENGTH 16
typedef struct FlashTrigInfo {
unsigned char isFlashOn; // 0 bit[7:0] 1
unsigned char FlashType; // 0 ( ) 1 LED
unsigned char isForceFlash; // 1
unsigned char isTurnFlash; //
unsigned char Reserve[4]; //
} FlashTrigInfo;
typedef struct TrigInfo {
int RedLightAfterTime; //
struct timeval RedLightOnTime; //
short SnapRoadNo; // // 1
short SnapPicNo; // // 1
short ttlNO; //TTL TTL
char ExtSuffix[4]; //
TriType TriSource; //
char DevName[16]; //
int illegalType;
short CarSpeedVal; // 0.1km/h
short RoadSpeedMax; // 0.1km/h
int RoadSpeedPer; //
int CoilInterval_1; // 1
int CoilInterval_2; // 1
int CoilDistance_1; // 1 0.1
int CoilDistance_2; // 2 0.1
char LicenseTag[16]; //
char LicenseTagColor[8]; //
int nReliability; //
int pContext; //
FlashTrigInfo nFlash; //
int SaveToStorage; //
int nSpeedCorrect; //
short SnapInterval; //
short Reserv; //
int Reserve[3]; //
} TrigInfo;
typedef struct H264Prm {
short FrameRate; //
short BitRate; // Kbps
short idrFrameRate; //I
short BitContrl; //
int Reserve[2]; //
} H264Prm;
typedef struct EditionInfo {
char FirmWareVer[32]; //
char AlgVer[VER_MAX_LENGTH]; //
char DspAppsVer[VER_MAX_LENGTH]; //dsp
char SDKVer[32]; //SDK windows
unsigned int FpgaVer; //FPGA
unsigned int UbootVer; //Uboot
unsigned int KernlVer; //
unsigned int ArmAppsVer; //arm
unsigned int HardwarePcbVer; // byte[0] 8bit byte[1] 8bit byte[2] sensor 8bit byte[3] sensor 8bit
unsigned int Reserve[2]; //
} EditionInfo;
typedef struct DeviceInfo {
char CamraType[16]; //
char SensorType[16]; //
struct in_addr IpAddr_1; //IP 1
struct in_addr IpAddr_2; //IP 2
char MacAddr[MAC_LENGTH]; // MAC
EditionInfo VerInfo; //
short PowerType; // 0:DC 1: AC 2:
short AcDelay; //
short armMHz; //arm
short ddrMHz; //ddr
short dspMHz; //dsp
short Gyroscope; //
short FocusDeepness; //
char DeviceName[12]; //
char DeviceNO[12]; //
char DeviceDirection[16]; //
char DeviceAddr[64]; //
char SecretID[12]; // ID
char SN[20]; //
int Reserve[4];
} DeviceInfo;
typedef struct SysParam {
short nShutterMax; // 10us
short nShutterMin; // 10us
short nGainMax; //
short nGainMin; //
short nShutter; // 10us
short nGain; //
short nSharpness; //
short nSharpReserve[4]; //
short nBrightness; //
short nContrast; //
short nSaturation; //
short nRed; //
short nGreen; //
short nBlue; //
short nEV; //
short nQuality; //
short nGamma; //gamma
short nBlacklevel; //
short nSceneMode; //
short nRotationAngle;
short nMirror; //
short nThreLightOn; //
short nThreManualWB; //
short enRealTimeSnap; //
short nFrameInterval; //
short nAverageLuma; //
short nTemperature; //
short nSubarea; //
short nAutoExpo; // , 0, 1:
short nAutoWB; // 0, ; 1:
short nDenoise; // 0: 1
short nFrameTimeInterval;
short npExp; // 1--300
short npGain; // 1--300
} SysParam;
typedef struct ExtJfif {
char Header[4]; // header[0:1] 0xFF 0xE1 header[2:3]=unsigned short (sizeof(EXT_JFIF)-2)
char Company[8]; // itarge itargeb itargek ......
ENITPVer NicpVer; //NITP
int PicLen; //
PicResolution ImageRes; //
PicType ImageType; //
unsigned int PicFrameCnt; //
struct timeval ExpoTime; // linux timeval
TrigInfo PicTrig; //
H264Prm H264Info; //h264
DeviceInfo DevInfo; //
SysParam sysInfo; //
unsigned char xzxSecretID[4]; // ID4 byte
int Reserve[63]; //
} ExtJfif;
#endif
#define UDP_SERVER_PORT 34444 //接收端口
#define RECV_PACK_SIZE 1024 //每包数据发送大小
typedef struct udpHandl
{
int srvFd;
}udpHandl;
char tmpBuffer[RECV_PACK_SIZE];
char headBuf[RECV_PACK_SIZE];
/////////////////////////////////////////////////////////////////////////////
//参数ip地址和端口
//
int Speed_udpCreate(udpHandl *udpHandl, char * addr, unsigned short port)
{
int sock;
struct sockaddr_in s_addr;
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(errno);
}
printf("ceate socket \n");
memset(&s_addr, 0, sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
if(addr)
s_addr.sin_addr.s_addr = inet_addr(addr);
else
s_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)) < 0)
{
perror("bind");
exit(errno);
}
printf("bind address to socket\n");
udpHandl->srvFd = sock;
return 0;
}
int recvBytes(struct udpHandl *udpHandl, char *buf, int len)
{
int res;
int n;
char *ptr;
struct sockaddr_in c_addr;
socklen_t addr_len;
addr_len = sizeof(c_addr);
n = len;
ptr = buf;
res = recvfrom(udpHandl->srvFd, ptr, len, 0, (struct sockaddr *)&c_addr, &addr_len);
if(res < 0)
return -1;
else
return (res );
}
//////////////////////////////////////////////////////////////////////
int udpRcvOneFrame(udpHandl *udpHandl,char * buf)
{
int rlen = 0;
int headLen;
int dataSize = 0;
int frameCount = 0;
char *pHead;
char * pbuf;
char * ptmp;
struct sockaddr_in c_addr;
socklen_t addr_len;
ExtJfif head;
headLen = sizeof(ExtJfif) +21;
printf("headLen %d\n",headLen);
while(1)
{
int i=0;
rlen = 0;
dataSize = 0;
frameCount = 0;
pbuf = buf;
ptmp = tmpBuffer;
//取整个数据包得大小
memset (headBuf, 0, RECV_PACK_SIZE);
memset(tmpBuffer, 0, RECV_PACK_SIZE);
rlen = recvBytes(udpHandl, headBuf, RECV_PACK_SIZE);
if(rlen < 0)
break;
pHead = headBuf+0;
if(*(int *)pHead != 0)
{
printf(" pack %d not itarge jpeg header \n",*(int *)pHead);
continue;
}
memcpy(&head, headBuf+25, sizeof(head));
dataSize = head.PicLen;
printf("jpg len %d \n",dataSize);
if(dataSize < 0)
break;
memcpy(pbuf, headBuf+4, RECV_PACK_SIZE-4);
pbuf = pbuf + RECV_PACK_SIZE-4;
frameCount = dataSize/(RECV_PACK_SIZE-4);
if(frameCount * (RECV_PACK_SIZE-4) != dataSize)
frameCount++;
//接收实际的图片大小
printf("frameCount:%d \n",frameCount) ;
for(i = 1; i < frameCount; i++)
{
rlen = recvBytes(udpHandl, ptmp, RECV_PACK_SIZE);
if(*(int *)ptmp == i)
{
printf("pack num %d pack size %d \n", *(int *)ptmp,rlen);
memcpy(pbuf, ptmp+4, rlen-4);
pbuf = pbuf+rlen-4;
}
else
{
printf("====================>>>>miss pack No %d %d len %d \n", *(int *)ptmp,i,rlen);
}
}
break;
}
return (headLen+dataSize);
}
////////////////////////////////////////
//接收JPG图片的buff 线程函数
//
char VideoBuffer[0x100000];
int UdpRcvStreamThr()
{
udpHandl test;
int videoServersockFd=-1;
int alljpg=0,allbyte=0;
Speed_udpCreate(&test,NULL,UDP_SERVER_PORT);
int nRcvBuf=0x100000;
setsockopt(test.srvFd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRcvBuf,sizeof(int));//设置缓冲区大小
if(test.srvFd>0)
{
while(1)
{
allbyte=udpRcvOneFrame(&test,VideoBuffer);
}
}
else
{
printf(" test.srvFd error \n");
}
}
int main()
{
printf("udp server recv start \n");
UdpRcvStreamThr();
}
**************************************************** the client code ****************************************************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#define UDP_SERVER_IP "192.168.88.186" // IP
#define UDP_SERVER_PORT 34444 //
#define SEND_SPEED_FPS 25 //
#define SEND_PACK_SIZE 1024 //
#if 1
#define JPGOFFSET 21
typedef enum {
eNITPVer11 = 1
} ENITPVer;
typedef struct PicResolution {
short Width; //
short Height; //
} PicResolution;
typedef enum {
eOldPic = 1,
eStreamPic = 2,
eSnapPicCloseLamp = 3,
eSnapPicOpenLamp = 4
} EStreamPicType;
typedef enum {
eSoft, // <8f><91>
ebayonet, // <8d> <8f>
eRedlight, // <97>
eRS485, // RS485 <8f><91>
eRS232, // RS232 <9b> <8f><91>
eSpeed, // <85> <80><9f> <8f><91>
eStream // <81>
} ESnapType;
#define TriType ESnapType
#define PicType EStreamPicType
#define MAC_LENGTH 6
#define VER_MAX_LENGTH 16
typedef struct FlashTrigInfo {
unsigned char isFlashOn; // 0 bit[7:0] 1
unsigned char FlashType; // 0 ( ) 1 LED
unsigned char isForceFlash; // 1
unsigned char isTurnFlash; //
unsigned char Reserve[4]; //
} FlashTrigInfo;
typedef struct TrigInfo {
int RedLightAfterTime; //
struct timeval RedLightOnTime; //
short SnapRoadNo; // // 1
short SnapPicNo; // // 1
short ttlNO; //TTL TTL
char ExtSuffix[4]; //
TriType TriSource; //
char DevName[16]; //
int illegalType;
short CarSpeedVal; // 0.1km/h
short RoadSpeedMax; // 0.1km/h
int RoadSpeedPer; //
int CoilInterval_1; // 1
int CoilInterval_2; // 1
int CoilDistance_1; // 1 0.1
int CoilDistance_2; // 2 0.1
char LicenseTag[16]; //
char LicenseTagColor[8]; //
int nReliability; //
int pContext; //
FlashTrigInfo nFlash; //
int SaveToStorage; //
int nSpeedCorrect; //
short SnapInterval; //
short Reserv; //
int Reserve[3]; //
} TrigInfo;
typedef struct H264Prm {
short FrameRate; //
short BitRate; // Kbps
short idrFrameRate; //I
short BitContrl; //
int Reserve[2]; //
} H264Prm;
typedef struct EditionInfo {
char FirmWareVer[32]; //
char AlgVer[VER_MAX_LENGTH]; //
char DspAppsVer[VER_MAX_LENGTH]; //dsp
char SDKVer[32]; //SDK windows
unsigned int FpgaVer; //FPGA
unsigned int UbootVer; //Uboot
unsigned int KernlVer; //
unsigned int ArmAppsVer; //arm
unsigned int HardwarePcbVer; // byte[0] 8bit byte[1] 8bit byte[2] sensor 8bit byte[3] sensor 8bit
unsigned int Reserve[2]; //
} EditionInfo;
typedef struct DeviceInfo {
char CamraType[16]; //
char SensorType[16]; //
struct in_addr IpAddr_1; //IP 1
struct in_addr IpAddr_2; //IP 2
char MacAddr[MAC_LENGTH]; // MAC
EditionInfo VerInfo; //
short PowerType; // 0:DC 1: AC 2:
short AcDelay; //
short armMHz; //arm
short ddrMHz; //ddr
short dspMHz; //dsp
short Gyroscope; //
short FocusDeepness; //
char DeviceName[12]; //
char DeviceNO[12]; //
char DeviceDirection[16]; //
char DeviceAddr[64]; //
char SecretID[12]; // ID
char SN[20]; //
int Reserve[4];
} DeviceInfo;
typedef struct SysParam {
short nShutterMax; // 10us
short nShutterMin; // 10us
short nGainMax; //
short nGainMin; //
short nShutter; // 10us
short nGain; //
short nSharpness; //
short nSharpReserve[4]; //
short nBrightness; //
short nContrast; //
short nSaturation; //
short nRed; //
short nGreen; //
short nBlue; //
short nEV; //
short nQuality; //
short nGamma; //gamma
short nBlacklevel; //
short nSceneMode; //
short nRotationAngle;
short nMirror; //
short nThreLightOn; //
short nThreManualWB; //
short enRealTimeSnap; //
short nFrameInterval; //
short nAverageLuma; //
short nTemperature; //
short nSubarea; //
short nAutoExpo; // , 0, 1:
short nAutoWB; // 0, ; 1:
short nDenoise; // 0: 1
short nFrameTimeInterval;
short npExp; // 1--300
short npGain; // 1--300
} SysParam;
typedef struct ExtJfif {
char Header[4]; // header[0:1] 0xFF 0xE1 header[2:3]=unsigned short (sizeof(EXT_JFIF)-2)
char Company[8]; // itarge itargeb itargek ......
ENITPVer NicpVer; //NITP
int PicLen; //
PicResolution ImageRes; //
PicType ImageType; //
unsigned int PicFrameCnt; //
struct timeval ExpoTime; // linux timeval
TrigInfo PicTrig; //
H264Prm H264Info; //h264
DeviceInfo DevInfo; //
SysParam sysInfo; //
unsigned char xzxSecretID[4]; // ID4 byte
int Reserve[63]; //
} ExtJfif;
#endif
char jpeghead[] = {
0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x07, 0x90, 0x0a, 0x20, 0x03,
0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01
} ;
char pic[0x100000];
static flag = 0 ;
static int frameCount = 0 ;
static unsigned int jpg_len = 204265;
static unsigned int frag_size = 1020 ;
static unsigned int frame_size ;
static unsigned int total_size ;
void make_data()
{
int jfif_h_size = 0 ;
unsigned int tmpjpg_len = 0 ;
char * tmpbuf = NULL ;
struct timeval t;
int i = 0;
total_size = jpg_len + sizeof(ExtJfif) ;
frame_size = 4 + frag_size ;
frameCount = total_size / frag_size ;
if (frameCount * frag_size < total_size) {
flag = 1 ;
frameCount++ ;
}
jfif_h_size = sizeof(ExtJfif);
printf("jfif len:%d \n",jfif_h_size) ;
ExtJfif ext_jfif;
memset(&ext_jfif, 0x0, sizeof(ExtJfif));
ext_jfif.Header[0] = 0xff;
ext_jfif.Header[1] = 0xe1;
ext_jfif.Header[2] = (sizeof(ExtJfif) - 2) >> 8;
ext_jfif.Header[3] = (sizeof(ExtJfif) - 2) & 0xff;
ext_jfif.PicFrameCnt = 1888 ;
memset(ext_jfif.Company, 0, 8);
memcpy(ext_jfif.Company, "itargek", 7);
ext_jfif.PicLen = total_size ; //sizeof(EXT_JFIF_SNAP);
ext_jfif.NicpVer = eNITPVer11;
ext_jfif.ImageType = eStreamPic; //StreamHeadEx.PicType = eStreamPic;
ext_jfif.ImageRes.Height = 1920 ;
ext_jfif.ImageRes.Width = 1080 ;
ext_jfif.ExpoTime.tv_sec = 0;
ext_jfif.ExpoTime.tv_usec = 0;
memcpy(ext_jfif.DevInfo.SensorType, "CCD", 3);
gettimeofday(&t, NULL);
ext_jfif.ExpoTime.tv_sec = t.tv_sec; //daguerre_tri_time.tv_sec;//+8*3600;
ext_jfif.ExpoTime.tv_usec = t.tv_usec;
{
*(int *)pic = total_size ;
#if 1
*(int *)(pic + 4) = 0;
#endif
memcpy(pic + 8, jpeghead, JPGOFFSET);
memcpy(pic + 8 + JPGOFFSET, &ext_jfif, sizeof(ExtJfif));
#if 0
memcpy(pic + 8 + JPGOFFSET + sizeof(ExtJfif), buf_addr + JPGOFFSET, buf_size - JPGOFFSET);
#endif
}
tmpbuf = pic + 4 ;
i = 0 ;
*(int *)(tmpbuf + i * frame_size) = i ; //frame_0 index
for (i = 1 ; i < frameCount - 1 ; i++) {
*(int *)(tmpbuf + i * frame_size) = i ;
memset((tmpbuf + i * frame_size + 4), 0xff, frag_size);
}
*(int *)(tmpbuf + i * frame_size) = i ; //last frme index
memset((tmpbuf + i * frame_size + 4), 0xff, (flag == 1) ? (total_size % frag_size) : frag_size);
}
int UdpSndThr()
{
int fd;
int wlen;
int i;
int buf_size;
int len;
int times = 0;
char *tmpbuf;
int delay = 100; //ms
struct sockaddr_in address;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
return -1;
}
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);
address.sin_port = htons(UDP_SERVER_PORT);
printf("send data to --> server %s port %d \n", UDP_SERVER_IP, htons(UDP_SERVER_PORT));
make_data() ;
while (1) {
{
delay = (1000 / SEND_SPEED_FPS);
usleep((delay * 1000));
} //
tmpbuf = pic + 4;
for (i = 0 ; i < frameCount - 1 ; i++) {
wlen = sendto(fd, (tmpbuf + i * frame_size), frame_size, 0, (struct sockaddr*)&address, sizeof(address));
}
wlen = sendto(fd, (tmpbuf + i * frame_size), (flag == 1) ? (total_size % frag_size + 4) : frame_size, 0, (struct sockaddr*)&address, sizeof(address)) ;
printf("send %d data over.....\n\n\n", times);
times++;
}
close(fd);
return 0 ;
}
int main()
{
printf("send start \n");
UdpSndThr();
}