📄 benchmark_main_bench_100.c
字号:
/* ***********************************************************
* THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
* REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
* INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
* COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
* TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
* POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
* INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
* YOUR USE OF THE PROGRAM.
*
* IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
* THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
* OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
* EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
* REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
* OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
* USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
* AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
* YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
* (U.S.$500).
*
* Unless otherwise stated, the Program written and copyrighted
* by Texas Instruments is distributed as "freeware". You may,
* only under TI's copyright in the Program, use and modify the
* Program without any charge or restriction. You may
* distribute to third parties, provided that you transfer a
* copy of this license to the third party and the third party
* agrees to these terms by its first use of the Program. You
* must reproduce the copyright notice and any other legend of
* ownership on each copy or partial copy, of the Program.
*
* You acknowledge and agree that the Program contains
* copyrighted material, trade secrets and other TI proprietary
* information and is protected by copyright laws,
* international copyright treaties, and trade secret laws, as
* well as other intellectual property laws. To protect TI's
* rights in the Program, you agree not to decompile, reverse
* engineer, disassemble or otherwise translate any object code
* versions of the Program to a human-readable form. You agree
* that in no event will you alter, remove or destroy any
* copyright notice included in the Program. TI reserves all
* rights not specifically granted under this license. Except
* as specifically provided herein, nothing in this agreement
* shall be construed as conferring by implication, estoppel,
* or otherwise, upon you, any license or other right under any
* TI patents, copyrights or trade secrets.
*
* You may not use the Program in non-TI devices.
* ********************************************************* */
//--------------------------------------------------------------------------
// EMAC Demo Software
//--------------------------------------------------------------------------
// benchmark_main.c
//
// This application calculates the CPU load for max throughput at various
// packet sizes. In order for this test to pass out of
// loopback mode, a loopback connector must be inserted into the RJ-45.
// When PHY loopback is used, the loopback connector is not required.
//
//--------------------------------------------------------------------------
#include <stdio.h>
#include <std.h>
#include <log.h>
#include <c6455_emac.h>
#include <c6455_mdio.h>
/*
// We'll use INT5 for the EMAC - this is an arbitrary choice
*/
#define EMAC_INT_VAL 5
#define EMAC_INT_FLAG (1<<EMAC_INT_VAL)
#define MAXPACKETSIZE 1514
#define BUFFSIZE ((MAXPACKETSIZE+127)&~0x7F)
#define RATE100 12500000
#define PKTPS100 148809
#define PKT_PRIME 20
unsigned int packetSizes[] = { 60, 124, 252, 508, 1020, MAXPACKETSIZE };
unsigned int packetCnts[] = { 2000000, 1000000, 500000, 250000, 150000, 100000 }; //100
/* Calculate time in 10ths of seconds on 100Mb/s network using
// packet size (supplied without CRC)
*/
#define TARGET_TIME(pkt,size) ((pkt*10)/(RATE100/(size+24)))
/* Allocate 33% RX, 33% TX, and 33% Free (for RX swap) */
#define PKT_MAX 60
#define PKT_RX (PKT_MAX/3)
/*
// Raw Data Buffers
//
// This test uses internal memory, so we could just use MAXPACKETSIZE+4 as our
// buffer size. However, if the buffers were in cacheable external
// memory, we'd have to make sure each was cache aligned, and
// thus use a size of at least 1536 because a buffer must fill an
// the entire cache line.
*/
#pragma DATA_SECTION(packet_header, "L2_DATA");
EMAC_Pkt packet_header[PKT_MAX];
#pragma DATA_SECTION(packet_buffer, "L2_DATA");
Uint8 packet_buffer[PKT_MAX][1536];
#pragma DATA_SECTION(packet_sourcedata, "L2_DATA");
Uint8 packet_sourcedata[BUFFSIZE];
/*
// ================================================================
//
// Packet Queue
//
// This simple queue object is just for our example packet
// queue. It is not requried for using EMAC/MDIO
//
*/
typedef struct _pktq {
uint Count; /* Number of packets in queue */
EMAC_Pkt *pHead; /* Pointer to first packet */
EMAC_Pkt *pTail; /* Pointer to last packet */
} PKTQ;
/*
// Queue Helper Functions
*/
static EMAC_Pkt *pqPop( PKTQ *pq );
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr );
/*
// Declare our packet queues
*/
PKTQ FreeQueue; /* Free packets for RX or TX */
PKTQ RxQueue; /* Received packets */
/*
// ================================================================
*/
/*
// Declare some local status variables
*/
Handle hEMAC = 0; /* Handle to our EMAC instance */
static volatile uint LinkStatus = 0; /* Our current link status */
static volatile uint LocalTicks = 0; /* Current time in 100ms ticks */
static volatile uint PacketTicks = 0; /* Time since last packet */
/*
// Non-Reentrancy
//
// We are not allowed to re-enter EMAC functions. We protect
// against other tasks via SWI_disable/SWI_enable(), and from the EMAC
// HW interrupt by masking it.
//
// Different software environments may have different methods
// for reentrance protection.
//
// We combine the semaphore and the INT masking to make two
// macros OUREMAC_enter() and OUREMAC_exit().
//
*/
static int intmask = 0; /* Saved interrupt status */
#define OUREMAC_enter() SWI_disable(); intmask = C64_disableIER( EMAC_INT_FLAG )
#define OUREMAC_exit() C64_enableIER( intmask ); SWI_enable();
//External references
extern LOG_Obj logTrace;
/*
// Declare some local functions
*/
static EMAC_Pkt *GetPacket(Handle hApplication);
static void FreePacket(Handle hApplication, EMAC_Pkt *pPKT);
static EMAC_Pkt *RxPacket( Handle hApplication, EMAC_Pkt *pPKT);
static void StatusUpdate(Handle hApplication);
static void StatisticsUpdate(Handle hApplication);
static EMAC_Status status;
static char *LinkStr[] = { "No Link",
"10Mb/s Half Duplex",
"10Mb/s Full Duplex",
"100Mb/s Half Duplex",
"100Mb/s Full Duplex",
"1000Mb/s Full Duplex" };
//---------------------------------------------------------------------
// Main Entry Point
//---------------------------------------------------------------------
int main()
{
}
//---------------------------------------------------------------------
// Main Test Entry Point
//---------------------------------------------------------------------
int TestMain()
{
EMAC_Config ecfg;
Uint32 i,j=0;
Uint32 TxCount=0, RxCount=0;
Uint32 SaveTicks;
unsigned int packetCnt=100000,packetSize=60;
volatile int loop,loop1=0,loop2=0;
EMAC_Pkt *pPkt;
/*
// Basic Test Initialization
*/
printf("\nEMAC Benchmarks - Full Wire Rate Loopback\n");
/* Init packet data array */
for( i=0; i<MAXPACKETSIZE; i++ )
packet_sourcedata[i] = i;
/* Initialize our buffer pool */
memset( &FreeQueue, 0, sizeof(PKTQ) );
memset( &RxQueue, 0, sizeof(PKTQ) );
for( i=0; i<PKT_MAX; i++ )
{
/*
// Init the buffer headers. Note that the buffer pointer
// and buffer length are fixed and do not change
*/
memset( &packet_header[i], 0, sizeof(EMAC_Pkt) );
memcpy( packet_buffer[i], packet_sourcedata, MAXPACKETSIZE );
packet_header[i].pDataBuffer = packet_buffer[i];
packet_header[i].BufferLen = MAXPACKETSIZE+4;
pqPush( &FreeQueue, &packet_header[i] );
}
/*
// Inialize Configuration and Open EMAC
*/
/* Setup the EMAC configuration */
ecfg.ModeFlags = 0;
ecfg.MdioModeFlags = MDIO_MODEFLG_FD100 | MDIO_MODEFLG_LOOPBACK; /* Internal PHY loopback */
ecfg.TxChannels = 1;
ecfg.RxMaxPktPool = PKT_RX;
ecfg.pfcbGetPacket = &GetPacket;
ecfg.pfcbFreePacket = &FreePacket;
ecfg.pfcbRxPacket = &RxPacket;
ecfg.pfcbStatus = &StatusUpdate;
ecfg.pfcbStatistics = &StatisticsUpdate;
/*
// For this test we'll set our EMAC address to be 00:01:02:03:04:05
// If this were a real driver, we'd have to read the EMAC
// address from where it is stored in hardware (board dependent)
*/
for( i=0; i<6; i++ )
ecfg.MacAddr[i] = i;
/* Open EMAC instance */
printf("Calling EMAC_open().\n");
i = EMAC_open( 1, (Handle)0x12345678, &ecfg, &hEMAC );
if(i)
{
printf("Returned error %08x\n",i);
goto exit;
}
/*
// Set the EMAC interrupt pacer to be no slower than one third the
// RX pool's worth of 64b packets at 166MHz peripheral clock
*/
ECTL_REGS->EWINTTCNT = 166000000/(PKTPS100/(PKT_RX/3)) ;
/* Enable EMAC Interrupt */
C64_enableIER( EMAC_INT_FLAG );
/* Set the receive filter */
/* Use our re-entrancy gate to call EMAC functions */
printf("Calling EMAC_setReceiveFilter()\n");
OUREMAC_enter();
i = EMAC_setReceiveFilter( hEMAC, EMAC_RXFILTER_DIRECT );
OUREMAC_exit();
if(i)
{
printf("Returned error %08x\n",i);
goto close_emac;
}
/*
// Wait for the device to link
//
// The device can not send or receive packets until it is
// linked.
//
*/
printf("Waiting for link...\n");
LocalTicks = 0;
while( !LinkStatus && LocalTicks < 100 );
if( !LinkStatus ) {
printf("\nWARNING: No device LINK.\n");
goto close_emac;
}
/* Print link status */
if( LinkStatus <= 5 )
printf("\nLink Status : %s on PHY number %d\n",
LinkStr[LinkStatus],status.PhyDev);
printf("Packets Held : %d-RX %d-TX\n",
status.RxPktHeld, status.TxPktHeld);
if( status.FatalError )
printf("Fatal Error : %d\n",status.FatalError);
/* Start the test */
printf("Starting dummy loop (wait 10 seconds)...\n");
TxCount = RxCount = 0;
PacketTicks = 0;
while( RxCount<packetCnt )
{
/* Check for timeout */
if( PacketTicks > 100 )
break;
/* See if we received a packet */
if( pPkt = pqPop( &RxQueue ) )
{
/* Bump the RX count */
RxCount++;
if( TxCount<packetCnt )
{
OUREMAC_enter();
i = EMAC_sendPacket( hEMAC, pPkt );
OUREMAC_exit();
if(i)
{
printf("EMAC_sendPacket() returned error %08x\n",i);
break;
}
/* Bump the RX count */
TxCount++;
}
else
pqPush( &FreeQueue, pPkt );
}
loop1++;
}
for( loop=0; loop<6; loop++ )
{
packetSize = packetSizes[loop];
packetCnt = packetCnts[loop];
/* Start the test */
printf("\nStarting packet test for size %d...\n", packetSize+4 );
printf("Target time for full wire rate: %d.%d seconds - %d pkt/s\n",
TARGET_TIME(packetCnt,packetSize)/10,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -