DSP6678使用NDK网口通信

一,加载步骤

1,导入工程,project->import existing CCS eclipse project

2,在工程上右键,点击properties。然后在箭头处双击,进去过file等4个c文件的位置完成修改路径。右键工程选择Rebuild Project,编译就通过了。

3,右键工程,选择新建Target Configuration File,命名为evmc6678l.ccxml。选择仿真器型号和芯片,配置gel文件

4,【Gel文件的执行时间一般在DSP connect target之后,在download代码之前。因为gel文件通常会进行一些初始化的寄存器的设置,比如memory map,PLL和DDR初始化等。所以在download之前必须初始化这些。gel文件的脚本都可以找到的。CCS5的版本可以在这个目录下找到大部分EVM的gel脚本ccsv5ccs_baseemulationboards gel脚本类似于C语言函数,就是运行一些函数。比如DDR初始化函数。如果DDR没有初始化,是无法将代码download到DDR中去的。执行gel脚本有两种,一种是用户自己执行,另一种是CCS5自动将gel脚本关联到相关的操作中,比如connect target就自动关联了初始化PLL,初始化DDR的gel函数。可以找个gel脚本看看,这样更有助于理解。】

二,调试过程

1,在client.c中设置DSP IP地址的地方:

//---------------------------------------------------------------------------
// Configuration
char *HostName    = "tidsp";
char *LocalIPAddr = "192.168.2.100";
char *LocalIPMask = "255.255.255.0";    // Not used when using DHCP
char *GatewayIP   = "192.168.2.101";    // Not used when using DHCP
char *DomainName  = "demo.net";         // Not used when using DHCP
char *DNSServer   = "0.0.0.0";          // Used when set to anything but zero

2,rebuild project之后连接好线。板卡需要电源线,仿真器,网线。点击view里面的Target configurations。在弹出的界面右键ccxml文件,launch selected configuration。

连接之后打印信息:

C66xx_0: GEL Output: Setup_Memory_Map...
C66xx_0: GEL Output: Setup_Memory_Map... Done.
C66xx_0: GEL Output: 
Connecting Target...
C66xx_0: GEL Output: DSP core #0
C66xx_0: GEL Output: C6678L GEL file Ver is 2.005 
C66xx_0: GEL Output: Global Default Setup...
C66xx_0: GEL Output: Setup Cache... 
C66xx_0: GEL Output: L1P = 32K   
C66xx_0: GEL Output: L1D = 32K   
C66xx_0: GEL Output: L2 = ALL SRAM   
C66xx_0: GEL Output: Setup Cache... Done.
C66xx_0: GEL Output: Main PLL (PLL1) Setup ... 
C66xx_0: GEL Output: PLL in Bypass ... 
C66xx_0: GEL Output: PLL1 Setup for DSP @ 1000.0 MHz.
C66xx_0: GEL Output:            SYSCLK2 = 333.3333 MHz, SYSCLK5 = 200.0 MHz.
C66xx_0: GEL Output:            SYSCLK8 = 15.625 MHz.
C66xx_0: GEL Output: PLL1 Setup... Done.
C66xx_0: GEL Output: Power on all PSC modules and DSP domains... 
C66xx_0: GEL Output: Security Accelerator disabled!
C66xx_0: GEL Output: Power on all PSC modules and DSP domains... Done.
C66xx_0: GEL Output: PA PLL (PLL3) Setup ... 
C66xx_0: GEL Output: PA PLL Setup... Done.
C66xx_0: GEL Output: DDR3 PLL (PLL2) Setup ... 
C66xx_0: GEL Output: DDR3 PLL Setup... Done.
C66xx_0: GEL Output: DDR begin (1333 auto)
C66xx_0: GEL Output: XMC Setup ... Done 
C66xx_0: GEL Output: 
DDR3 initialization is complete.
C66xx_0: GEL Output: DDR done
C66xx_0: GEL Output: DDR3 memory test... Started
C66xx_0: GEL Output: DDR3 memory test... Passed
C66xx_0: GEL Output: PLL and DDR Initialization completed(0) ...
C66xx_0: GEL Output: configSGMIISerdes Setup... Begin
C66xx_0: GEL Output: 
SGMII SERDES has been configured.
C66xx_0: GEL Output: Enabling EDC ...
C66xx_0: GEL Output: L1P error detection logic is enabled.
C66xx_0: GEL Output: L2 error detection/correction logic is enabled.
C66xx_0: GEL Output: MSMC error detection/correction logic is enabled.
C66xx_0: GEL Output: Enabling EDC ...Done 
C66xx_0: GEL Output: Configuring CPSW ...
C66xx_0: GEL Output: Configuring CPSW ...Done 
C66xx_0: GEL Output: Global Default Setup... Done.

3,load .out文件,加载成功后的打印信息:

C66xx_0: GEL Output: Invalidate All Cache...
C66xx_0: GEL Output: Invalidate All Cache... Done.
C66xx_0: GEL Output: GEL Reset...
C66xx_0: GEL Output: GEL Reset... Done.
C66xx_0: GEL Output: Disable all EDMA3 interrupts and events.

三, 代码部分解析

1,client.c

/*
 *  ======== client.c ========

#include <stdio.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/ndk/inc/_stack.h>
#include <ti/ndk/inc/tools/console.h>
#include <ti/ndk/inc/tools/servers.h>
#include "client.h"
/* BIOS6 include */
#include <ti/sysbios/BIOS.h>
/* Platform utilities include */
#include "ti/platform/platform.h"
/* Resource manager for QMSS, PA, CPPI */
#include "ti/platform/resource_mgr.h"
// When USE_OLD_SERVERS set to zero, server daemon is used
#define USE_OLD_SERVERS 0
//---------------------------------------------------------------------------
// Title String
char *VerStr = "\nTCP/IP Stack Example Client\n";
// Our NETCTRL callback functions
static void   NetworkOpen();
static void   NetworkClose();
static void   NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd );
// Fun reporting function
static void   ServiceReport( uint Item, uint Status, uint Report, HANDLE hCfgEntry );
/* Platform Information - we will read it form the Platform Library */
platform_info	gPlatformInfo;
//---------------------------------------------------------------------------
// Configuration
char *HostName    = "tidsp";
char *LocalIPAddr = "192.168.2.100";
char *LocalIPMask = "255.255.255.0";    // Not used when using DHCP
char *GatewayIP   = "192.168.2.101";    // Not used when using DHCP
char *DomainName  = "demo.net";         // Not used when using DHCP
char *DNSServer   = "0.0.0.0";          // Used when set to anything but zero


// Simulator EMAC Switch does not handle ALE_LEARN mode, so please configure the
// MAC address of the PC where you want to launch the webpages and initiate PING to NDK */
Uint8 clientMACAddress [6] = {0x5C, 0x26, 0x0A, 0x69, 0x44, 0x0B}; /* MAC address for my PC */

UINT8 DHCP_OPTIONS[] = { DHCPOPT_SERVER_IDENTIFIER, DHCPOPT_ROUTER };

#undef    	TEST_RAW_NC
#undef    	TEST_RAW_SEND
#undef    	TEST_RAW_RECV

#define     PACKET_SIZE     1000
#define     PACKET_COUNT    1

#ifdef      TEST_RAW_SEND
static HANDLE hSendRaw = 0;
static void SendRawEth();
#endif

#ifdef      TEST_RAW_RECV
static HANDLE hRecvRaw = 0;
static void RecvRawEth();
#endif

/*************************************************************************
 *  @b EVM_init()
 *
 *  @n
 *
 *  Initializes the platform hardware. This routine is configured to start in
 * 	the evm.cfg configuration file. It is the first routine that BIOS
 * 	calls and is executed before Main is called. If you are debugging within
 *  CCS the default option in your target configuration file may be to execute
 *  all code up until Main as the image loads. To debug this you should disable
 *  that option.
 *
 *  @param[in]  None
 *
 *  @retval
 *      None
 ************************************************************************/
void EVM_init()
{
	platform_init_flags  	sFlags;
	platform_init_config 	sConfig;
	/* Status of the call to initialize the platform */
	int32_t pform_status;

	/*
	 * You can choose what to initialize on the platform by setting the following
	 * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
	*/
	memset( (void *) &sFlags,  0, sizeof(platform_init_flags));
	memset( (void *) &sConfig, 0, sizeof(platform_init_config));

	sFlags.pll  = 0;	/* PLLs for clocking  	*/
	sFlags.ddr  = 0;   	/* External memory 		*/
    sFlags.tcsl = 1;	/* Time stamp counter 	*/
#ifdef _SCBP6618X_
    sFlags.phy  = 0;	/* Ethernet 			*/
#else
    sFlags.phy  = 1;	/* Ethernet 			*/
#endif
  	sFlags.ecc  = 0;	/* Memory ECC 			*/

    sConfig.pllm = 0;	/* Use libraries default clock divisor */

	pform_status = platform_init(&sFlags, &sConfig);

	/* If we initialized the platform okay */
	if (pform_status != Platform_EOK) {
		/* Initialization of the platform failed... die */
		while (1) {
			(void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
			(void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
		}
	}
}

//---------------------------------------------------------------------
// Main Entry Point
//---------------------------------------------------------------------
int main()
{
 /* Start the BIOS 6 Scheduler */
	BIOS_start ();
}

//
// Main Thread
//
//
int StackTest()
{
    int               rc;
    int				  i;
    HANDLE            hCfg;
    CI_SERVICE_TELNET telnet;
    CI_SERVICE_HTTP   http;
    QMSS_CFG_T      qmss_cfg;
    CPPI_CFG_T      cppi_cfg;

	/* Get information about the platform so we can use it in various places */
	memset( (void *) &gPlatformInfo, 0, sizeof(platform_info));
	(void) platform_get_info(&gPlatformInfo);

	(void) platform_uart_init();
	(void) platform_uart_set_baudrate(115200);
	(void) platform_write_configure(PLATFORM_WRITE_ALL);

	/* Clear the state of the User LEDs to OFF */
	for (i=0; i < gPlatformInfo.led[PLATFORM_USER_LED_CLASS].count; i++) {
		(void) platform_led(i, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
	}

    /* Initialize the components required to run this application:
     *  (1) QMSS
     *  (2) CPPI
     *  (3) Packet Accelerator
     */
    /* Initialize QMSS */
    if (platform_get_coreid() == 0)
    {
        qmss_cfg.master_core        = 1;
    }
    else
    {
        qmss_cfg.master_core        = 0;
    }
    qmss_cfg.max_num_desc       = MAX_NUM_DESC;
    qmss_cfg.desc_size          = MAX_DESC_SIZE;
    qmss_cfg.mem_region         = Qmss_MemRegion_MEMORY_REGION0;
    if (res_mgr_init_qmss (&qmss_cfg) != 0)
    {
        platform_write ("Failed to initialize the QMSS subsystem \n");
        goto main_exit;
    }
    else
    {
    	platform_write ("QMSS successfully initialized \n");
    }

    /* Initialize CPPI */
    if (platform_get_coreid() == 0)
    {
        cppi_cfg.master_core        = 1;
    }
    else
    {
        cppi_cfg.master_core        = 0;
    }
    cppi_cfg.dma_num            = Cppi_CpDma_PASS_CPDMA;
    cppi_cfg.num_tx_queues      = NUM_PA_TX_QUEUES;
    cppi_cfg.num_rx_channels    = NUM_PA_RX_CHANNELS;
    if (res_mgr_init_cppi (&cppi_cfg) != 0)
    {
        platform_write ("Failed to initialize CPPI subsystem \n");
        goto main_exit;
    }
    else
    {
    	platform_write ("CPPI successfully initialized \n");
    }


    if (res_mgr_init_pass()!= 0) {
        platform_write ("Failed to initialize the Packet Accelerator \n");
        goto main_exit;
    }
    else
    {
    	platform_write ("PA successfully initialized \n");
    }

    //
    // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION before
    //  using the stack!!
    //
    rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
    if( rc )
    {
        platform_write("NC_SystemOpen Failed (%d)\n",rc);
        for(;;);
    }

    // Print out our banner
    platform_write(VerStr);

    //
    // Create and build the system configuration from scratch.
    //

    // Create a new configuration
    hCfg = CfgNew();
    if( !hCfg )
    {
        platform_write("Unable to create configuration\n");
        goto main_exit;
    }

    // We better validate the length of the supplied names
    if( strlen( DomainName ) >= CFG_DOMAIN_MAX ||
        strlen( HostName ) >= CFG_HOSTNAME_MAX )
    {
        platform_write("Names too long\n");
        goto main_exit;
    }

    // Add our global hostname to hCfg (to be claimed in all connected domains)
    CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0,
                 strlen(HostName), (UINT8 *)HostName, 0 );

    // If the IP address is specified, manually configure IP and Gateway
#if defined(_SCBP6618X_) || defined(_EVMTCI6614_) || defined(DEVICE_K2H) || defined(DEVICE_K2K)
    /* SCBP6618x, EVMTCI6614, EVMK2H, EVMK2K always uses DHCP */
    if (0)
#else
    if (!platform_get_switch_state(1))
#endif
    {
        CI_IPNET NA;
        CI_ROUTE RT;
        IPN      IPTmp;

        // Setup manual IP address
        bzero( &NA, sizeof(NA) );
        NA.IPAddr  = inet_addr(LocalIPAddr);
        NA.IPMask  = inet_addr(LocalIPMask);
        strcpy( NA.Domain, DomainName );
        NA.NetType = 0;

        // Add the address to interface 1
        CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0,
                           sizeof(CI_IPNET), (UINT8 *)&NA, 0 );

        // Add the default gateway. Since it is the default, the
        // destination address and mask are both zero (we go ahead
        // and show the assignment for clarity).
        bzero( &RT, sizeof(RT) );
        RT.IPDestAddr = 0;
        RT.IPDestMask = 0;
        RT.IPGateAddr = inet_addr(GatewayIP);

        // Add the route
        CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0,
                           sizeof(CI_ROUTE), (UINT8 *)&RT, 0 );

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
    }
    // Else we specify DHCP
    else
    {
        CI_SERVICE_DHCPC dhcpc;

        platform_write("Configuring DHCP client\n");

        // Specify DHCP Service on IF-1
        bzero( &dhcpc, sizeof(dhcpc) );
        dhcpc.cisargs.Mode   = CIS_FLG_IFIDXVALID;
        dhcpc.cisargs.IfIdx  = 1;
        dhcpc.cisargs.pCbSrv = &ServiceReport;
        dhcpc.param.pOptions = DHCP_OPTIONS;
        dhcpc.param.len = 2;

        CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0,
                     sizeof(dhcpc), (UINT8 *)&dhcpc, 0 );
    }

    // Specify TELNET service for our Console example
    bzero( &telnet, sizeof(telnet) );
    telnet.cisargs.IPAddr = INADDR_ANY;
    telnet.cisargs.pCbSrv = &ServiceReport;
    telnet.param.MaxCon   = 2;
    telnet.param.Callback = &ConsoleOpen;
    CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_TELNET, 0,
                 sizeof(telnet), (UINT8 *)&telnet, 0 );

    // Create RAM based WEB files for HTTP
    AddWebFiles();

    // HTTP Authentication
    {
        CI_ACCT CA;

        // Name our authentication group for HTTP (Max size = 31)
        // This is the authentication "realm" name returned by the HTTP
        // server when authentication is required on group 1.
        CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_SYSINFO_REALM1,
                     0, 30, (UINT8 *)"DSP_CLIENT_DEMO_AUTHENTICATE1", 0 );

        // Create a sample user account who is a member of realm 1.
        // The username and password are just "username" and "password"
        strcpy( CA.Username, "username" );
        strcpy( CA.Password, "password" );
        CA.Flags = CFG_ACCTFLG_CH1;  // Make a member of realm 1
        rc = CfgAddEntry( hCfg, CFGTAG_ACCT, CFGITEM_ACCT_REALM,
                          0, sizeof(CI_ACCT), (UINT8 *)&CA, 0 );
    }

    // Specify HTTP service
    bzero( &http, sizeof(http) );
    http.cisargs.IPAddr = INADDR_ANY;
    http.cisargs.pCbSrv = &ServiceReport;
    CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_HTTP, 0,
                 sizeof(http), (UINT8 *)&http, 0 );

    //
    // Configure IPStack/OS Options
    //

    // We don't want to see debug messages less than WARNINGS
    rc = DBG_INFO;
    CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    //
    // This code sets up the TCP and UDP buffer sizes
    // (Note 8192 is actually the default. This code is here to
    // illustrate how the buffer and limit sizes are configured.)
    //

    // TCP Transmit buffer size
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Receive buffer size (copy mode)
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Receive limit (non-copy mode)
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // UDP Receive limit
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

#if 0
    // TCP Keep Idle (10 seconds)
    rc = 100;
    //   This is the time a connection is idle before TCP will probe
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_TCPKEEPIDLE,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Keep Interval (1 second)
    //   This is the time between TCP KEEP probes
    rc = 10;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_TCPKEEPINTVL,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Max Keep Idle (5 seconds)
    //   This is the TCP KEEP will probe before dropping the connection
    rc = 50;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_TCPKEEPMAXIDLE,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
#endif

    //
    // Boot the system using this configuration
    //
    // We keep booting until the function returns 0. This allows
    // us to have a "reboot" command.
    //
    do
    {
        rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
    } while( rc > 0 );

    // Free the WEB files
    RemoveWebFiles();

    // Delete Configuration
    CfgFree( hCfg );

    // Close the OS
main_exit:
    NC_SystemClose();
    return(0);
}




//
// System Task Code [ Server Daemon Servers ]
//
static HANDLE hEcho=0,hEchoUdp=0,hData=0,hNull=0,hOob=0;

#ifdef _INCLUDE_IPv6_CODE
static HANDLE hEcho6=0, hEchoUdp6=0, hTelnet6=0, hOob6=0, hWeb6=0;
#endif
static void NetworkOpen()
{
    // Create our local servers
    hEcho = DaemonNew( SOCK_STREAMNC, 0, 7, dtask_tcp_echo,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hEchoUdp = DaemonNew( SOCK_DGRAM, 0, 7, dtask_udp_echo,
                          OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
    hData = DaemonNew( SOCK_STREAM, 0, 1000, dtask_tcp_datasrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hNull = DaemonNew( SOCK_STREAMNC, 0, 1001, dtask_tcp_nullsrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hOob  = DaemonNew( SOCK_STREAMNC, 0, 999, dtask_tcp_oobsrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );

    // Create the IPv6 Local Servers.
#ifdef _INCLUDE_IPv6_CODE
    hEcho6    = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 7, dtask_tcp_echo6,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hEchoUdp6 = Daemon6New (SOCK_DGRAM, IPV6_UNSPECIFIED_ADDRESS, 7, dtask_udp_echo6,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
    hTelnet6  = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 23,
                            (int(*)(SOCKET,UINT32))telnetClientProcess, OS_TASKPRINORM, OS_TASKSTKLOW,
                            (UINT32)ConsoleOpen, 2 );
    hOob6     = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 999, dtask_tcp_oobsrv,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hWeb6     = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, HTTPPORT, httpClientProcess,
                            OS_TASKPRINORM, OS_TASKSTKHIGH, 0, 4);
#endif
}
static void NetworkClose()
{
    DaemonFree( hOob );
    DaemonFree( hNull );
    DaemonFree( hData );
    DaemonFree( hEchoUdp );
    DaemonFree( hEcho );

#ifdef _INCLUDE_IPv6_CODE
    Daemon6Free (hEcho6);
    Daemon6Free (hEchoUdp6);
    Daemon6Free (hTelnet6);
    Daemon6Free (hOob6);
    Daemon6Free (hWeb6);
#endif

#ifdef  TEST_RAW_SEND
    TaskDestroy (hSendRaw);
#endif
#ifdef  TEST_RAW_RECV
    TaskDestroy (hRecvRaw);
#endif

    // Kill any active console
    ConsoleClose();
}


//
// NetworkIPAddr
//
// This function is called whenever an IP address binding is
// added or removed from the system.
//
static void NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd )
{
    static uint fAddGroups = 0;
    IPN IPTmp;

    if( fAdd )
        platform_write("Network Added: ");
    else
        platform_write("Network Removed: ");

    // Print a message
    IPTmp = ntohl( IPAddr );
    platform_write("If-%d:%d.%d.%d.%d\n", IfIdx,
            (UINT8)(IPTmp>>24)&0xFF, (UINT8)(IPTmp>>16)&0xFF,
            (UINT8)(IPTmp>>8)&0xFF, (UINT8)IPTmp&0xFF );

    // This is a good time to join any multicast group we require
    if( fAdd && !fAddGroups )
    {
        fAddGroups = 1;
//              IGMPJoinHostGroup( inet_addr("224.1.2.3"), IfIdx );
    }

    /* Create a Task to send/receive Raw ethernet traffic */
#ifdef  TEST_RAW_SEND
    hSendRaw = TaskCreate( SendRawEth, "TxRawEthTsk", OS_TASKPRINORM, 0x1400, 0, 0, 0 );
#endif
#ifdef  TEST_RAW_RECV
    hRecvRaw = TaskCreate( RecvRawEth, "PerformRawRX", OS_TASKPRIHIGH, 0x1400, 0, 0, 0 );
#endif
}

//
// DHCP_reset()
//
// Code to reset DHCP client by removing it from the active config,
// and then reinstalling it.
//
// Called with:
// IfIdx    set to the interface (1-n) that is using DHCP.
// fOwnTask set when called on a new task thread (via TaskCreate()).
//
void DHCP_reset( uint IfIdx, uint fOwnTask )
{
    CI_SERVICE_DHCPC dhcpc;
    HANDLE h;
    int    rc,tmp;
    uint   idx;

    // If we were called from a newly created task thread, allow
    // the entity that created us to complete
    if( fOwnTask )
        TaskSleep(500);

    // Find DHCP on the supplied interface
    for(idx=1; ; idx++)
    {
        // Find a DHCP entry
        rc = CfgGetEntry( 0, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT,
                          idx, &h );
        if( rc != 1 )
            goto RESET_EXIT;

        // Get DHCP entry data
        tmp = sizeof(dhcpc);
        rc = CfgEntryGetData( h, &tmp, (UINT8 *)&dhcpc );

        // If not the right entry, continue
        if( (rc<=0) || dhcpc.cisargs.IfIdx != IfIdx )
        {
            CfgEntryDeRef(h);
            h = 0;
            continue;
        }

        // This is the entry we want!

        // Remove the current DHCP service
        CfgRemoveEntry( 0, h );

        // Specify DHCP Service on specified IF
        bzero( &dhcpc, sizeof(dhcpc) );
        dhcpc.cisargs.Mode   = CIS_FLG_IFIDXVALID;
        dhcpc.cisargs.IfIdx  = IfIdx;
        dhcpc.cisargs.pCbSrv = &ServiceReport;
        CfgAddEntry( 0, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0,
                     sizeof(dhcpc), (UINT8 *)&dhcpc, 0 );
        break;
    }

RESET_EXIT:
    // If we are a function, return, otherwise, call TaskExit()
    if( fOwnTask )
        TaskExit();
}


void CheckDHCPOptions();

//
// Service Status Reports
//
// Here's a quick example of using service status updates
//
static char *TaskName[]  = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };
static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };
static char *StatusStr[] = { "Disabled","Waiting","IPTerm","Failed","Enabled" };
static void ServiceReport( uint Item, uint Status, uint Report, HANDLE h )
{
    platform_write( "Service Status: %-9s: %-9s: %-9s: %03d\n",
            TaskName[Item-1], StatusStr[Status],
            ReportStr[Report/256], Report&0xFF );

    //
    // Example of adding to the DHCP configuration space
    //
    // When using the DHCP client, the client has full control over access
    // to the first 256 entries in the CFGTAG_SYSINFO space.
    //
    // Note that the DHCP client will erase all CFGTAG_SYSINFO tags except
    // CFGITEM_DHCP_HOSTNAME. If the application needs to keep manual
    // entries in the DHCP tag range, then the code to maintain them should
    // be placed here.
    //
    // Here, we want to manually add a DNS server to the configuration, but
    // we can only do it once DHCP has finished its programming.
    //
    if( Item == CFGITEM_SERVICE_DHCPCLIENT &&
        Status == CIS_SRV_STATUS_ENABLED &&
        (Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPADD) ||
         Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPRENEW)) )
    {
        IPN IPTmp;

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
#if 0
        // We can now check on what the DHCP server supplied in
        // response to our DHCP option tags.
        CheckDHCPOptions();
#endif

    }

    // Reset DHCP client service on failure
    if( Item==CFGITEM_SERVICE_DHCPCLIENT && (Report&~0xFF)==NETTOOLS_STAT_FAULT )
    {
        CI_SERVICE_DHCPC dhcpc;
        int tmp;

        // Get DHCP entry data (for index to pass to DHCP_reset).
        tmp = sizeof(dhcpc);
        CfgEntryGetData( h, &tmp, (UINT8 *)&dhcpc );

        // Create the task to reset DHCP on its designated IF
        // We must use TaskCreate instead of just calling the function as
        // we are in a callback function.
        TaskCreate( DHCP_reset, "DHCPreset", OS_TASKPRINORM, 0x1000,
                    dhcpc.cisargs.IfIdx, 1, 0 );
    }
}

void CheckDHCPOptions()
{
    char IPString[16];
    IPN  IPAddr;
    int  i, rc;

    // Now scan for DHCPOPT_SERVER_IDENTIFIER via configuration
    platform_write("\nDHCP Server ID:\n");
    for(i=1;;i++)
    {
        // Try and get a DNS server
        rc = CfgGetImmediate( 0, CFGTAG_SYSINFO, DHCPOPT_SERVER_IDENTIFIER,
                              i, 4, (UINT8 *)&IPAddr );
        if( rc != 4 )
            break;

        // We got something

        // Convert IP to a string:
        NtIPN2Str( IPAddr, IPString );
        platform_write("DHCP Server %d = '%s'\n", i, IPString);
    }
    if( i==1 )
        platform_write("None\n\n");
    else
        platform_write("\n");

    // Now scan for DHCPOPT_ROUTER via the configuration
    platform_write("Router Information:\n");
    for(i=1;;i++)
    {
        // Try and get a DNS server
        rc = CfgGetImmediate( 0, CFGTAG_SYSINFO, DHCPOPT_ROUTER,
                              i, 4, (UINT8 *)&IPAddr );
        if( rc != 4 )
            break;

        // We got something

        // Convert IP to a string:
        NtIPN2Str( IPAddr, IPString );
        platform_write("Router %d = '%s'\n", i, IPString);
    }
    if( i==1 )
        platform_write("None\n\n");
    else
        platform_write("\n");
}

#ifdef TEST_RAW_SEND
/* Routine to demonstrate sending raw ethernet packets using
 * send() / sendnc() APIs and AF_RAWETH family socket.
 */
static void SendRawEth()
{
    char*       pBuffer = NULL;
    ETHHDR*     ptr_eth_header;
    UINT32      rawether_type = 0x300, rawchannel_num = 0;
    UINT8       src_mac[6], dst_mac[6], bData[20];
    int         i, j, val, bytes, retVal;
    SOCKET      sraw = INVALID_SOCKET;
#ifdef TEST_RAW_NC
    PBM_Handle  hPkt = NULL;
#endif

    /* Allocate the file environment for this task */
    fdOpenSession( TaskSelf() );

    /* wait for the ethernet link to come up. */
	TaskSleep(20000);

    platform_write("Raw Eth Task Started ... \n");

    /* Demonstrating use of SO_PRIORITY to configure
     * custom properties for all packets travelling
     * using this socket.
     *
     * Here, in this example we will use it for
     * configuring a distinct EMAC channel number for each
     * of the raw ethernet sockets.
     *
     * For example, Channel Assignment:
     *      Chan 0 - IP
     *      Chan 3 - Raw
     */
    rawchannel_num = 3;

    /* Create the raw ethernet socket */
    sraw = socket(AF_RAWETH, SOCK_RAWETH, rawether_type);
    if( sraw == INVALID_SOCKET )
    {
        platform_write("Fail socket, %d\n", fdError());
        fdCloseSession (TaskSelf());
        return;
    }

    /* Configure the transmit device */
    val = 1;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
	if(retVal)
		platform_write("error in setsockopt \n");

    /* Configure the EMAC channel number */
    val = rawchannel_num;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
	if(retVal)
		platform_write("error in setsockopt \n");

    /* Send the RAW eth packets out */
	for(j = 0; j < PACKET_COUNT; j++)
    {
#ifndef  TEST_RAW_NC
        if ((pBuffer = mmAlloc (sizeof(char) * PACKET_SIZE)) == NULL)
        {
            platform_write("OOM ?? \n");
            TaskExit();
        }
#else
    	if(getsendncbuff(sraw, PACKET_SIZE, (void **) &pBuffer, &hPkt))
        {
            platform_write("Error: Raw Eth getsendncbuff failed Error:%d\n", fdError());
		    fdCloseSession( TaskSelf() );
            fdClose(sraw);
		    TaskExit();
		}
#endif

	    /* Configure the Source MAC, Destination MAC, Protocol and Payload */
	    for (i = 0; i < 6; i++)
		{
	    	src_mac[i] = 0x10 + i;
		}

	    for (i = 0; i < 6; i++)
	        dst_mac[i] = 0x20 + i + 2;

	    for (i = 0; i < 20; i++)
	        bData[i] = 0x60 + i;

	    ptr_eth_header = (ETHHDR*)pBuffer;

	    /* Copy the source MAC address as is. */
	    mmCopy (ptr_eth_header->SrcMac, src_mac, 6);

	    /* Copy the destination MAC address as is. */
	    mmCopy (ptr_eth_header->DstMac, dst_mac, 6);

	    /* Configure the type in network order. */
	    ptr_eth_header->Type = HNC16(rawether_type);

	    /* Copy over the payload to the buffer */
	    mmCopy(pBuffer + ETHHDR_SIZE, bData, 20);


#ifndef TEST_RAW_NC
        /* Send the packet using the copy version of send() API. */
        bytes = send(sraw, (char *)pBuffer, PACKET_SIZE, 0);
#else
        /* Use the no-copy version of send, sendnc() to send out the data */
        bytes = sendnc(sraw, (char *)pBuffer, PACKET_SIZE, hPkt, 0);
#endif

#ifndef TEST_RAW_NC
        /* If we allocated the buffer, free it up. If we used up the sendnc()
         * API, the buffer will be freed up by the stack.
         */
	    mmFree(pBuffer);
#endif

		if( bytes < 0 )
        {
            platform_write("Error: Raw Eth Send failed Error:%d\n", fdError());

#ifdef TEST_RAW_NC
            sendncfree(hPkt);
#endif

		    fdCloseSession( TaskSelf() );
            fdClose(sraw);
		    TaskExit();
        }
    }

    platform_write("Raw Eth Task Ended ... \n");

    fdClose(sraw);

	/* Close the session & kill the task */
    fdCloseSession( TaskSelf() );
    TaskExit();
}
#endif

#ifdef TEST_RAW_RECV

/* Routine to demonstrate packet receive using recvnc() API
 * and AF_RAWETH family sockets.
 */
static void RecvRawEth()
{
	SOCKET      sraw;
	INT32       val,retVal, count = 0, bytes;
    char*    	pBuf;
    HANDLE   	hBuffer;
	UINT32      rawchannel_num;
	ETHHDR*     ptr_eth_header;

	platform_write ("Raw Eth Rx Task has been started\n");

    /* Allocate the file environment for this task */
    fdOpenSession( TaskSelf() );

    /* Demonstrating use of SO_PRIORITY to configure
     * custom properties for all packets travelling
     * using this socket.
     *
     * Here, in this example we will use it for
     * configuring a distinct EMAC channel number for each
     * of the raw ethernet sockets.
     *
     * For example, Channel Assignment:
     *      Chan 0 - IP
     *      Chan 3 - Raw
     */
    rawchannel_num = 3;

    /* Create the main UDP listen socket */
    sraw = socket(AF_RAWETH, SOCK_RAWETH, 0x300);
    if( sraw == INVALID_SOCKET )
        return;

    /* Configure the transmit device */
    val = 1;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
	if(retVal)
		platform_write("error in setsockopt \n");

    /* Configure the EMAC channel number as the priority tag for packets */
    val = rawchannel_num;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
	if(retVal)
		platform_write("error in setsockopt \n");

    /* Configure the Receive buffer size */
    val = 1000;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
	if(retVal)
		platform_write("error in setsockopt \n");


    while (count < PACKET_COUNT)
    {
		bytes = (int)recvnc( sraw, (void **)&pBuf, 0, &hBuffer );

        if (bytes < 0)
        {
			/* Receive failed: Close the session & kill the task */
			platform_write("Receive failed after packets Error:%d\n",fdError());
		    fdCloseSession( TaskSelf() );
		    TaskExit();
        }
		else
		{
    		ptr_eth_header = (ETHHDR*)pBuf;

		    platform_write("Received RAW ETH packet, len: %d \n", PBM_getValidLen((PBM_Handle)hBuffer));
			platform_write("Dst MAC Address = %02x-%02x-%02x-%02x-%02x-%02x Src MAC Address = %02x-%02x-%02x-%02x-%02x-%02x Eth Type = %d Data = %s \n",
           			ptr_eth_header->DstMac[0],ptr_eth_header->DstMac[1],ptr_eth_header->DstMac[2],
           			ptr_eth_header->DstMac[3],ptr_eth_header->DstMac[4],ptr_eth_header->DstMac[5],
           			ptr_eth_header->SrcMac[0],ptr_eth_header->SrcMac[1],ptr_eth_header->SrcMac[2],
           			ptr_eth_header->SrcMac[3],ptr_eth_header->SrcMac[4],ptr_eth_header->SrcMac[5],
           			ntohs(ptr_eth_header->Type), (pBuf + ETHHDR_SIZE));
		}


		count++;

		/* Clean out the buffer */
		recvncfree( hBuffer );
    }

	/* Close the session & kill the task */
    fdCloseSession( TaskSelf() );
    TaskExit();

    return;
}

#endif

2,在main函数中执行BIOS_start(),并创建进程StackTest()

int main()
{
 /* Start the BIOS 6 Scheduler */
	BIOS_start ();
}

3,首先执行EVM_init()函数,也就是在main()函数之前执行,具体设置在一个*.cfg文件中

void EVM_init()
{
	platform_init_flags  	sFlags;
	platform_init_config 	sConfig;
	/* Status of the call to initialize the platform */
	int32_t pform_status;

	/*
	 * You can choose what to initialize on the platform by setting the following
	 * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
	*/
	memset( (void *) &sFlags,  0, sizeof(platform_init_flags));
	memset( (void *) &sConfig, 0, sizeof(platform_init_config));

	sFlags.pll  = 0;	/* PLLs for clocking  	*/
	sFlags.ddr  = 0;   	/* External memory 		*/
    sFlags.tcsl = 1;	/* Time stamp counter 	*/
#ifdef _SCBP6618X_
    sFlags.phy  = 0;	/* Ethernet 			*/
#else
    sFlags.phy  = 1;	/* Ethernet 			*/
#endif
  	sFlags.ecc  = 0;	/* Memory ECC 			*/

    sConfig.pllm = 0;	/* Use libraries default clock divisor */

	pform_status = platform_init(&sFlags, &sConfig);

	/* If we initialized the platform okay */
	if (pform_status != Platform_EOK) {
		/* Initialization of the platform failed... die */
		while (1) {
			(void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
			(void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
		}
	}
}

4,完成相应配置后启动NetworkOpen服务后,关联了dtask_udp_hello任务,等待UDP连接,并执行相关操作

static void NetworkOpen()
{
    // Create our local servers
    hEcho = DaemonNew( SOCK_STREAMNC, 0, 7, dtask_tcp_echo,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hEchoUdp = DaemonNew( SOCK_DGRAM, 0, 7, dtask_udp_echo,
                          OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
    hData = DaemonNew( SOCK_STREAM, 0, 1000, dtask_tcp_datasrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hNull = DaemonNew( SOCK_STREAMNC, 0, 1001, dtask_tcp_nullsrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hOob  = DaemonNew( SOCK_STREAMNC, 0, 999, dtask_tcp_oobsrv,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );

    // Create the IPv6 Local Servers.
#ifdef _INCLUDE_IPv6_CODE
    hEcho6    = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 7, dtask_tcp_echo6,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hEchoUdp6 = Daemon6New (SOCK_DGRAM, IPV6_UNSPECIFIED_ADDRESS, 7, dtask_udp_echo6,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
    hTelnet6  = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 23,
                            (int(*)(SOCKET,UINT32))telnetClientProcess, OS_TASKPRINORM, OS_TASKSTKLOW,
                            (UINT32)ConsoleOpen, 2 );
    hOob6     = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, 999, dtask_tcp_oobsrv,
                            OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
    hWeb6     = Daemon6New (SOCK_STREAM, IPV6_UNSPECIFIED_ADDRESS, HTTPPORT, httpClientProcess,
                            OS_TASKPRINORM, OS_TASKSTKHIGH, 0, 4);
#endif
}

猜你喜欢

转载自blog.csdn.net/wangjie36/article/details/117909235