目录
网络调试
1、GE工程的研究与功能扩充
网络调试
网口测试,使用的是TI官方提供的GE网络测试例程。
主要注意的事项是:时钟的设置、相关设备的MAC地址和IP的设置、中断的设置。确定板子的port和phy。
GbE Switch Subsystem Initialization Procedure
Step 1. Configure the CPSW_CONTROL register
Step 2. Configure the MAC1_SA and MAC2_SA (MAC3_SA and MAC4_SA if KeyStone II) source
address hi and lo registers
Step 3. Enable the desired statistics ports by programming the CPSW_STAT_PORT_EN register
Step 4. Configure the ALE
Step 5. Configure MAC modules
Step 6. Configure the MDIO and external PHY (if used)
Step 7. Configure the SGMII modules
其中遇到最大的问题,可能是使用官方例程,直接运行,会while死循环,或者phy link up和link down等问题。这些主要是需要根据自己的板卡对应设置好时钟与MDIO、PHY的内容。
1、GE工程的研究与功能扩充
1、GE工程的收发包,需要通过wireshark抓包软件、TCP&UDP测试工具等软件来查看。在使用中也必须开启,不然发送的数据包均无法收取从而会造成线上拥堵而出现程序运行不对。
2、GE工程的发包,具有限制,最大一包发送1472字节。且有最小和最大限制46~9216,最短头信息长度至数据包巨帧长度。
for(j= 0; j< GE_NUM_ETHERNET_PORT; j++)
{
if(FALSE==Port_OK(j))
continue;
transferParam= &test_2DSP_cfg[j];
uiPayloadNumBytes= transferParam->payloadNumBytes;
if((uiPayloadNumBytes<46)||(uiPayloadNumBytes>9216))//数据量的一级限制
{
printf("invalid packet payload size %d for port %d\n", uiPayloadNumBytes, j+1);
continue;
}
if(uiPayloadNumBytes>DDR_PACKET_BUFFER_SIZE0)//数据量的二级限制,1536-64?=1472
uiFDQ= DDR_HOST_SIZE1_FDQ;
else
uiFDQ= DDR_HOST_SIZE0_FDQ;//这个值应该对应下方queuepop,硬件方面预计是只初始化了size0;故此对包的数据量有限制
for(i=0; i<transferParam->numPackets; i++)
{
hostDescriptor= (HostPacketDescriptor *)KeyStone_queuePop(uiFDQ);
if(NULL==hostDescriptor)
{
printf("Source queue %d is NULL\n", uiFDQ);
GE_Check_Free_Queues(); //for debug
break;
}
/*invalid cache before read descriptor RAM*/
InvalidCache((void *)hostDescriptor, 64);//64个描述符
/*Directed packet to port. Setting these bits to a non-zero value
indicates that the packet is a directed packet. Packets with the
these bits set will bypass the ALE and send the packet directly
to the port indicated.*/
hostDescriptor->ps_flags= j+1;
/*initialize the source buffer*/
ucpBuffer= (Uint8 *)hostDescriptor->buffer_ptr;
/*fill MAC header*/
Fill_EMAC_header(ucpBuffer, ETHERNET_IPV4_PACKET, Source_MAC_address[j],Dest_MAC_address[j]);
#if 1
Fill_UDP_header(ucpBuffer,SourPort,DestPort,UDP_HEADER_LEN+uiPayloadNumBytes);
Fill_IP_header(ucpBuffer,Recv_IP,Dest_IP, IP_HEADER_LEN+UDP_HEADER_LEN+uiPayloadNumBytes);
/*添加IP层的校验和*/
//Uint16 check;
Uint16 Buffer1[10]={0};
int a;
int b=0;
for(a=14;a<34;a=a+2){
Buffer1[b]=(ucpBuffer[a] &0xff)<<8 | (ucpBuffer[a+1] &0xff);
b++;
}
Uint16 check= checksum(Buffer1, 20);
ucpBuffer[24]=((check)>>8)&0xFF; // 头部校验 16位
ucpBuffer[25]= ((check)>>0)&0xFF;
#endif
/*fill data pattern*/
memset(ucpBuffer+EMAC_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN, transferParam->dataPattern, uiPayloadNumBytes);
hostDescriptor->packet_length= uiPayloadNumBytes+ EMAC_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN;
/*write back data from cache to descriptor RAM*/
WritebackCache((void *)hostDescriptor, 64);
WritebackCache((void *)ucpBuffer, uiPayloadNumBytes+EMAC_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN);
//save descriptors to temp buffer
TxDescriptorTempBuffer[uiTotalNumPackets]= (Uint32)hostDescriptor;
uiTotalBytes += uiPayloadNumBytes+EMAC_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN;//uiPayloadNumBytes
uiTotalNumPackets++;
}
}
3、除了通过MAC层收发数据外,可以通过添加相关的IP层信息头、UDP层信息头,来发送UDP数据包。
4、udp包发送原理,需要有ARP应答与回应;
//arp应答
Uint8* arp_reply(Uint8 * re_packet)
{
Uint8 *buffer; int i;
//unsigned short SourPort=8080,DestPort=8000;//端口不必一致
//unsigned int Recv_IP=0xC0A801FB,Dest_IP=0xC0A801DF;//DSP ip为 192.168.1.251,PC ip为192.168.1.223
buffer = re_packet;
buffer[0]= (Dest_MAC_address[0]>>40)&0xff;
buffer[1]= (Dest_MAC_address[0]>>32)&0xff;
buffer[2]= (Dest_MAC_address[0]>>24)&0xff;
buffer[3]= (Dest_MAC_address[0]>>16)&0xff;
buffer[4]= (Dest_MAC_address[0]>>8)&0xff;
buffer[5]= (Dest_MAC_address[0])&0xff;
buffer[6]= (Source_MAC_address[0]>>40)&0xff;
buffer[7]= (Source_MAC_address[0]>>32)&0xff;
buffer[8]= (Source_MAC_address[0]>>24)&0xff;
buffer[9]= (Source_MAC_address[0]>>16)&0xff;
buffer[10]= (Source_MAC_address[0]>>8)&0xff;
buffer[11]= (Source_MAC_address[0])&0xff;
buffer[21] = 0x02;//ARP应答操作码
buffer[22]= (Source_MAC_address[0]>>40)&0xff;
buffer[23]= (Source_MAC_address[0]>>32)&0xff;
buffer[24]= (Source_MAC_address[0]>>24)&0xff;
buffer[25]= (Source_MAC_address[0]>>16)&0xff;
buffer[26]= (Source_MAC_address[0]>>8)&0xff;
buffer[27]= (Source_MAC_address[0])&0xff;
buffer[28]= ((Recv_IP)>>24)&0xFF;
buffer[29]= ((Recv_IP)>>16)&0xFF;
buffer[30]= ((Recv_IP)>>8)&0xFF;
buffer[31]= ((Recv_IP)>>0)&0xFF;
buffer[32]= (Dest_MAC_address[0]>>40)&0xff;
buffer[33]= (Dest_MAC_address[0]>>32)&0xff;
buffer[34]= (Dest_MAC_address[0]>>24)&0xff;
buffer[35]= (Dest_MAC_address[0]>>16)&0xff;
buffer[36]= (Dest_MAC_address[0]>>8)&0xff;
buffer[37]= (Dest_MAC_address[0])&0xff;
buffer[38]= ((Dest_IP)>>24)&0xFF;
buffer[39]= ((Dest_IP)>>16)&0xFF;
buffer[40]= ((Dest_IP)>>8)&0xFF;
buffer[41]= ((Dest_IP)>>0)&0xFF;
for(i=42;i<60;i++)//补18个0x00
{
buffer[i]= 0x00;
}
return buffer;
}
//arp应答发送
void arp_transfer(Uint8 * buffer)
{
int i, j;
Uint32 uiFDQ;
Uint32 uiTotalNumPackets;
Uint8 * ucpBuffer;
HostPacketDescriptor * hostDescriptor;
uiTotalNumPackets= 0;
uiFDQ=2058;
for(i=0; i<1; i++)
{
hostDescriptor= (HostPacketDescriptor *)KeyStone_queuePop(uiFDQ);
if(NULL==hostDescriptor)
{
printf("Source queue %d is NULL\n", uiFDQ);
GE_Check_Free_Queues(); //for debug
break;
}
/*invalid cache before read descriptor RAM*/
InvalidCache((void *)hostDescriptor, 64);
hostDescriptor->ps_flags= 1;
/*initialize the source buffer*/
ucpBuffer= (Uint8 *)hostDescriptor->buffer_ptr;
/*fill data pattern*/
for(j = 0;j< 60;j++)
{
ucpBuffer[j] = buffer[j];
}
hostDescriptor->packet_length= 60;
/*write back data from cache to descriptor RAM*/
WritebackCache((void *)hostDescriptor, 64);
WritebackCache((void *)ucpBuffer,60);
//save descriptors to temp buffer
TxDescriptorBuffer[uiTotalNumPackets]= (Uint32)hostDescriptor;
uiTotalNumPackets++;
}
for(i=0; i< uiTotalNumPackets; i++)
{
/*push the packet descriptor to Packet DMA TX queue*/
KeyStone_queuePush(GE_DIRECT_TX_QUEUE,
TxDescriptorBuffer[i]|FETCH_SIZE_64);
}
}
5、为此,在中断中收取数据包中,将分别存在判读数据包正确性,以及数据存取的问题。从而加有CRC校验、IP、MAC判断等手段,来确定数据包的正确。
Bool CRC(Uint8 *buffer)
{
Uint16 check;
Uint16 Buffer1[10]={0};
Uint8 c1,c2;
int a;
int b=0;
for(a=14;a<34;a=a+2)
{
Buffer1[b]=(buffer[a] &0xff)<<8 | (buffer[a+1] &0xff);
b++;
}
check= checksum(Buffer1, 20);
c1=((check)>>8)&0xFF; // 头部校验 16位
c2 = ((check)>>0)&0xFF;
if(c1 == buffer[24] && c2 == buffer[25])
{
return TRUE;
}
else
{
return FALSE;
}
}