DSP

TMS320C6678---基于K1_STK_v1.1 的GE程序的 UDP发包程序

2019-07-13 17:19发布

软件版本来源:K1_STK_v1.1 硬件平台:自己做的板子 以下是实现DSP向PC发送UDP包修改代码说明!!!

GE_TEST.c

1: /*select between internal/external loopback test or test between two DSPs*/
//GE_Test_Data_Path test_data_path= GE_TEST_SGMII_LOOPBACK;
//GE_Test_Data_Path test_data_path= GE_TEST_EMAC_LOOPBACK;
//GE_Test_Data_Path test_data_path= GE_TEST_SERDES_LOOPBACK;
GE_Test_Data_Path test_data_path= GE_TEST_DSP0_TO_DSP1;
/*select between 10/100/1000Mbps or auto negotiation mode*/
//Ethernet_Mode ethernet_mode = ETHERNET_1000M_FULLDUPLEX;
//Ethernet_Mode ethernet_mode =ETHERNET_100M_FULLDUPLEX;
Ethernet_Mode ethernet_mode = ETHERNET_AUTO_NEGOTIAT_SLAVE;
//Ethernet_Mode ethernet_mode = ETHERNET_AUTO_NEGOTIAT_MASTER;
//The port connection state for the test
GE_Port_Connection port_connect[GE_NUM_ETHERNET_PORT] =
{
    GE_PORT_CABLE_CONNECT,//SGMII port 0
//    GE_PORT_SGMII_CONNECT,
//    GE_PORT_NO_CONNECT,
//    GE_PORT_NOT_USED,
//    GE_PORT_CABLE_CONNECT, //SGMII port 1
//    GE_PORT_SGMII_CONNECT,
//    GE_PORT_NO_CONNECT,
    GE_PORT_NOT_USED
};
GE_TEST_DSP0_TO_DSP1用来完成两个DSP或者DSP与PC通信功能按上图修改,其中GE_Port_Connection port_connect[GE_NUM_ETHERNET_PORT]内容根据具体使用C6678网口决定,若用SGMII1连接网线,则更改成GE_PORT_CABLE_CONNECT 2: /*use long long type (8 bytes) for MAC address, but only lower 6 bytes are valid.
Please note the byte order, MAC address byte 5 is in the lowest bits.
Each MAC address corresponding to a Ethernet port*/
unsigned long long Source_MAC_address[GE_NUM_ETHERNET_PORT]  =
{
    0x888888000001,
    0x888888000002
};
unsigned long long Dest_MAC_address[GE_NUM_ETHERNET_PORT]=
{
    0x507B9D882B18,//PC MAC ADDR
    0x507B9D882B18,
}; MAC物理地址修改,Source是DSP配置的物理地址,可根据喜好更改,第2个是接收端PC的MAC物理地址,对应的是50:7B:9D:88:2B:18,在PC命令提示符敲入ipconfig –all查看到连接的有线网卡的MAC物理地址。 3: /*        if(uiDspNum)     //the second DSP
        {
            //swap the master/slave for the second DSP
            if(ethernet_mode == ETHERNET_AUTO_NEGOTIAT_MASTER)
                ethernet_mode = ETHERNET_AUTO_NEGOTIAT_SLAVE;
            else
                ethernet_mode = ETHERNET_AUTO_NEGOTIAT_MASTER;
        }*/
该出代码注释掉,只有一个DSP发送UDP,且运行在core0,不需要判断第二个DSP 4:     //DDR init 66.66667*20/1= 1333
    KeyStone_DDR_init (66.66667, 20, 1, NULL);
DDR初始化函数,在KeyStone_DDR_Init.c文件的C6678_EVM_DDR_Init函数中根据原厂提供的EXCEL表配置相关寄存器,根据DDR走线的PCB Layout配置相关writing leving寄存器 5:         /*The MDIO clock can operate at up to 2.5 MHz, 
        but typically operates at 1.0 MHz.*/
//        mdio_cfg.clock_div= 350;     /*350MHz/350= 1MHz*/
        mdio_cfg.clock_div= 156.25;     /*350MHz/350= 1MHz*/
        mdio_cfg.link_INT0_PHY_select= MDIO_INT_SELECT_PHY_0;
        mdio_cfg.link_INT1_PHY_select= MDIO_INT_SELECT_PHY_1;
MDIO初始化部分,注意根据PHY芯片地址选择,本项目SGMII0的PHY芯片地址配置成000,SGMII1的PHY芯片地址配置成001,此处是片选信号,如果配置错误会导致PHY芯片配置错。

GE_2DSP_Test.c

1: /*Fllowing table specifies the packet transfered on 2 ports,
number of packets of each port should be less than 64 for this test*/
GE_2DSP_Transfer_Param test_2DSP_cfg[GE_NUM_ETHERNET_PORT]=
{
    /*payloadNumBytes, dataPattern, numPackets*/
    {46,                0x12,        4},  /*SGMII port0*/
//    {1500,              0x55,        2},  /*SGMII port0*/
    {46,                0x01,        32}  /*SGMII port1*/
};
该内容表示要发送的数据,第一个参数是数据字节数,第二个参数表示数据的每个字节是0x12,第三个参数是发送的包数量 2: /*Ethernet IP header length in bytes*/
#define IP_HEADER_LEN             20
/*Ethernet UDP header length in bytes*/
#define UDP_HEADER_LEN             8 unsigned short SourPort=8080,DestPort=8080;
unsigned  int Recv_IP=0xC0A8000B,DestIP=0xC0A8000A; 添加IP报头长度、UDP头长度,UDP源、目的端口,IP地址(本地IP192.168.0.11,目的IP192.168.0.10) 3:         /*fill MAC header*/
            Fill_EMAC_header(ucpBuffer, ETHERNET_IPV4_PACKET, Source_MAC_address[j],
                Dest_MAC_address[j]);
            /*******************************************************/
            Fill_IP_header(ucpBuffer,Recv_IP,DestIP, IP_HEADER_LEN+UDP_HEADER_LEN+uiPayloadNumBytes);
            Fill_UDP_header(ucpBuffer,SourPort,DestPort,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++;
                }
            check= checksum(Buffer1, 20);
            ucpBuffer[24]=((check)>>8)&0xFF; // 头部校验  16位
            ucpBuffer[25]= ((check)>>0)&0xFF;
            /*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;
在TI源代码的GE_2DSP_Test函数基础上(只有MAC帧头)添加IP报头,UDP头,并添加IP报头内的CRC校验和,函数代码也在该文件中。TxDescriptorTempBuffer是用来存放描述符的地址,并不是存放数据的若想发送自己的数据,需要将自己的数据填充至每个描述符所指向的ucpBuffer中。 HostPacketDescriptor * hostDescriptor是一种描述符类型,详细参数说明请参考Multicore Navigator手册中对于Descriptor的描述,其中的buffer 0 pointer就是指向自定义的数据包的指针。 Memset函数是把要发送的数据字节0x12填到帧中,应用时可改这部分,将要发送的数据写到ucpBuffer中。MAC帧CRC校验由DSPMAC自己添加,UDP的校验可以不做。

参考文献

https://blog.csdn.net/weixin_38250828/article/details/83416986 KeyStone_1_GE_STK_User's_Guide.doc