/* * Function definition : ixDmaAccCodeletCallback() * See header file for documentation. */ void ixDmaAccCodeletCallback(IX_STATUS status) { /* Stop the time */ ixDmaAccCodeletTimeStore.stopTime[ixDmaAccCodeletLoopCount] = ixOsalTimestampGet(); /* Set the CallBack return flag to true */ ixDmaAccCodeletCallBackReturnFlag = TRUE; /* Set the CallBackStatus */ ixDmaAccCodeletCallBackStatus = status; return; }
PUBLIC void ixOsalBusySleep (UINT32 microseconds) { UINT32 delta; UINT32 lastTimestamp, currentTimestamp; UINT32 delay = 0; lastTimestamp = ixOsalTimestampGet (); while (delay < (UINT32) microseconds * IX_OSAL_OEM_APB_CLOCK) { currentTimestamp = ixOsalTimestampGet (); delta = currentTimestamp > lastTimestamp ? currentTimestamp - lastTimestamp : 0xffffffff - lastTimestamp + currentTimestamp; delay += delta; lastTimestamp = currentTimestamp; } }
/* * Function definition : ixDmaAccCodeletTestPerform() * See header file for documentation. */ IX_STATUS ixDmaAccCodeletTestPerform( UINT16 transferLength, IxDmaTransferMode transferMode, IxDmaAddressingMode addressingMode, IxDmaTransferWidth transferWidth) { UINT32 transferCounter; UINT32 counterTimeOut = 0; IX_STATUS retval; /* Initialise Source Address to ixDmaAccCodeletSrcBlock */ UINT32 sourceAddr = (UINT32) ixDmaAccCodeletSrcBlock; /* Initialise Destination Address to ixDmaAccCodeletDestBlock */ UINT32 destinationAddr = (UINT32) ixDmaAccCodeletDestBlock; /* Initialise Test Patterns */ ixDmaAccCodeletTestPatternReset(); printf ("\nTransferred %d times with the following parameters", PERFORMANCE_LOOP_NUM); printf ("\nSource Address : 0x%x", sourceAddr); printf ("\nDestination Address : 0x%x", destinationAddr); printf ("\nTransfer Length : %d", transferLength); printf ("\nTransfer Mode : %s", ixDmaAccCodeletMsgTM[transferMode]); printf ("\nAddressing Mode : %s", ixDmaAccCodeletMsgAM[addressingMode]); printf ("\nTransfer Width : %s", ixDmaAccCodeletMsgTW[transferWidth]); printf ("\n\n%d byte memory dump before transfer :", IX_DMA_CODELET_MEMDUMPSIZE ); /* Show memory dump before transfer */ ixDmaAccCodeletShow(); /* Do Dma transfer for PERFORMANCE_NUM_LOOP (i.e. 100 runs) for each different type of configuration */ for (transferCounter = 0; transferCounter < PERFORMANCE_LOOP_NUM; transferCounter++) { /* Initialise Test Patterns */ ixDmaAccCodeletTestPatternReset(); ixDmaAccCodeletLoopCount = transferCounter; ixDmaAccCodeletTimeStore.startTime[transferCounter] = ixOsalTimestampGet(); /* Perform Dma Transfer */ /* Callback function will update the status and CallBackReturn flag */ retval = ixDmaAccDmaTransfer( (IxDmaAccDmaCompleteCallback) ixDmaAccCodeletCallback, sourceAddr, destinationAddr, transferLength, transferMode, addressingMode, transferWidth ); /* Go into while loop if FIFO FULL happens */ while (IX_DMA_REQUEST_FIFO_FULL == retval) { printf ("\nFIFO is FULL. Going to sleep mode "); /*Delay in 1 MSecond before Dma Request Q recovers */ ixOsalSleep(IX_CLIENT_SLEEP_IN_MS); counterTimeOut++; if (IX_DMA_CODELET_MAX_TIME_OUT == counterTimeOut) { /* Stop the operation and return fail */ printf("\nTime out on FIFO full"); return IX_FAIL; } /* Retransmit after 1ms */ retval = ixDmaAccDmaTransfer( (IxDmaAccDmaCompleteCallback) ixDmaAccCodeletCallback, sourceAddr, destinationAddr, transferLength, transferMode, addressingMode, transferWidth ); } /* If retval is not successful returns failure */ if (IX_DMA_SUCCESS != retval) { printf("\nDma Transfer fail"); return IX_FAIL; } /* set to 0 used for callback return count time out */ counterTimeOut = 0; /* Wait for callback to return */ while (!ixDmaAccCodeletCallBackReturnFlag) { /*wait until current transfer complete */ ixOsalSleep(IX_CLIENT_SLEEP_IN_MS); counterTimeOut++; if (IX_DMA_CODELET_MAX_TIME_OUT == counterTimeOut) { /* Stop the operation and return fail */ printf("\nTime out on callback"); return IX_FAIL; } } /* set counter to 0 so that it will be used by the next iteration */ counterTimeOut = 0; /* When callback is returned, set flag to false */ ixDmaAccCodeletCallBackReturnFlag = FALSE; }/* End of for-loop for transfer counter*/ /* At the end of 100 runs and after callback returned successfully then do show here */ if (IX_SUCCESS == ixDmaAccCodeletCallBackStatus) { printf ("\n\n%d byte memory dump after transfer :", IX_DMA_CODELET_MEMDUMPSIZE ); /* Memory dump to show result of the current transfer */ ixDmaAccCodeletShow(); /* Print out the average time for that configuration */ ixDmaAccCodeletReportAverageTime(transferLength); } return IX_SUCCESS; }
/** * @fn void ixEthAccCodeletStatsPollTask * * This task polls the Codelet Stats and displays the rate of Rx and * Tx packets per second. * */ PRIVATE void ixEthAccCodeletStatsPollTask(void* arg, void** ptrRetObj) { int portNo = 0; static char stillRunning[] = "|/-\\"; static int stillRunningIndex = 0; static char displayString[20 + (21 * IX_ETHACC_CODELET_MAX_PORT)]; static char *stringPtr; static UINT32 busTimestampEnd = 0; static UINT32 busTimestampStart = 0; static UINT32 pTimeCycles = 0; static UINT64 rxCount = 0; static UINT64 txCount = 0; static UINT64 pTimeUsecs = 0; ixEthAccCodeletStatsPollTaskStop = FALSE; if (ixOsalMutexLock (&ixEthAccCodeletStatsPollTaskRunning, IX_OSAL_WAIT_FOREVER) != IX_SUCCESS) { printf("CodeletMain: Error starting Stats thread! Failed to lock mutex.\n"); return; } while (1) { while (ixEthAccCodeletTrafficPollEnabled == FALSE) { /* Sleep 1 sec */ ixOsalSleep(1000); if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } } if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } printf("\n"); #ifdef __wince printf("\r"); #endif for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { printf("Port%d Rates: |",portNo); } printf("\n"); #ifdef __wince printf("\r"); #endif for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { printf("====================="); } printf("=\n"); #ifdef __wince printf("\r"); #endif /* reset the stats */ for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { ixEthAccCodeletStats[portNo].rxCount=0; ixEthAccCodeletStats[portNo].txCount=0; } while (ixEthAccCodeletTrafficPollEnabled) { busTimestampStart = ixOsalTimestampGet(); /* Sleep approximatively 1 sec */ ixOsalSleep(1000); /* check if the task should stop */ if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } if (ixEthAccCodeletTrafficPollEnabled) { /* \r : reset print curser to beginning of line */ stringPtr = displayString; *stringPtr++ = '\r'; for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { /* get a snapshot */ busTimestampEnd = ixOsalTimestampGet(); rxCount = ixEthAccCodeletStats[portNo].rxCount; txCount = ixEthAccCodeletStats[portNo].txCount; /* Got stats, now clear counters */ ixEthAccCodeletStats[portNo].rxCount=0; ixEthAccCodeletStats[portNo].txCount=0; /* get the measurement interval using a unsigned * subtraction in order to handle wrap-around. The time unit * is in APB bus cycles. */ pTimeCycles = busTimestampEnd - busTimestampStart; /* convert the time in APB bus cycles to microseconds * * multiplications are done before divisions and * will not overflow the UINT64. */ pTimeUsecs = (UINT64)pTimeCycles; pTimeUsecs = IX_ETHACC_CODELET_MULDIV(pTimeUsecs, IX_ETHACC_CODELET_PCLOCK_DIVIDER, IX_ETHACC_CODELET_XCLOCK_FREQ); if (!pTimeUsecs) { /* time may be 0 as the result of the previous operation * In this case (very unlikely to occur), * just skip the remaining of this loop. * The display will not be updated before the next * loop. */ continue; } /* convert from the packet count to a rate in pkts per second * * rate = pkts * usecsPerSec / timeUsec * * multiplications are done before divisions and * will not overflow the UINT64. */ rxCount = IX_ETHACC_CODELET_MULDIV(rxCount, IX_ETHACC_CODELET_USEC_PER_SEC, pTimeUsecs); txCount = IX_ETHACC_CODELET_MULDIV(txCount, IX_ETHACC_CODELET_USEC_PER_SEC, pTimeUsecs); /* print stats */ stringPtr += sprintf(stringPtr, "Rx:%6u Tx:%6u |", (unsigned)rxCount, (unsigned)txCount); } *stringPtr++ = stillRunning[stillRunningIndex++ & 3]; *stringPtr = 0; printf("%s", displayString); } } printf("\n"); #ifdef __wince printf("\r"); #endif } ixOsalMutexUnlock (&ixEthAccCodeletStatsPollTaskRunning); }