NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
Migrating DCI Applications to CToolsLib
Contents
Migrating from DCI to the CToolsLib family of target libraries[edit]
Overview[edit]
The Debug Control Interface (DCI) is a target library created to implement a simple API that gives the user access to the Advanced Event Triggering (AET) and Trace capabilities on the 64x+ devices, along with support for logging of EDMA activity. It was written for the 64x+ family of devices. As the capabilities of the target's emulation hardware continue to increase, and as target applications continue to make use of this hardware, it became necessary to break this functionality up over a family of libraries in order to minimize the footprint required to get a specific combination of functionalities. Moving forward, DCI will not be supported, so users that want the same capabilites on the 66x will need to migrate their code to use a new family of libraries, the CToolsLib family of libraries. The CToolsLib family consists of a number of individual target libraries; AETLib, ETBLib, and DspTraceLib, among others. AETLib, which DCI was also built on top of, gives the user access to the triggering hardware built into the C66x device. It has an API very similar to that of DCI. ETBLib enables configuration of the Embedded Trace Buffers contained within each CorePac. A limited amount of this functionality was provided directly in DCI on the 64x+. DspTraceLib enables configuring of a Trace emulator to be used for capturing large amounts of trace data generated by an application. DCI enabled Export only via the ETB. The DspTraceLib adds the ability to export to a Trace Emulator.

This document is meant to provide a road map for migration from the Debug Control Interface to the CTools family of libraries. Functionally, CToolsLib provides all of the capabilities of DCI, except for the support for EDMA logging. This document is not meant as a substitute for the documentation of each of the individual libraries. It is merely meant as a roadmap for migration between the two.
Each individual library has doxygen generated documentation that details the APIs and enumerations supported within that library. This documentation will also be valuable in your migration efforts.
Feature Comparison[edit]
The table below details the feature comparison between the DCI Library and the CTools family of libraries. Note that the CToolsLib feature list is not comprehensive. Only features with analogous functions in DCI are mentioned here.
DCI | CToolsLib |
---|---|
Advanced Event Triggering (AET) Support | Advanced Event Triggering (AET) Support |
Embedded Trace Buffer (ETB) Support | Embedded Trace Buffer (ETB) Support |
DSP Trace Export Support (Limited to ETB) | DSP Trace Export Support |
DMA Logging | |
System Trace (STM) Support |
Key Differences[edit]
- DCI is a single library that encapsulates the functionality of the AETLib and ETBLib libraries, along with some additional support for EDMA logging. The CTools family of libraries breaks these functions out into a set of smaller libraries and the user can choose which libraries he prefers to use.
- CToolsLib does NOT support the EDMA Logging.
The CTools Family of Libraries[edit]
Documentation and the location for download of the CTools Family of libraries can be found {{#tiwikiurl:CToolsLib|here}}
AETLIb[edit]
- Find additional information on AETlib {{#tiwikiurl:AETLib|here}}
AETLib is a library that supports programming the Advanced Event Triggering unit to generate specific triggers based on sets of events that occur in an application. These triggers can be used for halting the CPU, incrementing a counter, generating an interrupt, telling the trace unit to start or stop capturing Trace data, and much more. AETLib only configures the AET hardware to generate these triggers. It does not configure any separate hardware to capture the results of those triggers. For example, if AET is configured to generate Trace Data, the user must also configure the Trace receiver to capture the data, otherwise, no trace data will be captured.
ETBLib[edit]
ETBLib is a library that supports configuration and reading of the on-chip embedded trace buffer.
DSPTraceLib[edit]
DSPTraceLib provides the ability to generate trace information and export it to a Trace buffer on an external emulator such as the XDS560T. DCI only provided support for exporting trace data to the ETB, so there will be no direct use of DSPTraceLib in this document.
Functional API Migration[edit]
This section details the relationship between the APIs provided in DCI, and the corresponding APIs in the CToolsLib family of libraries.
DCI_Control(DCI_command *command, void *params)[edit]
The heart of the DCI API is the DCI_control(DCI_command *command, void *params) function. This is where the majority of the actions performed by DCI are defined, based on the DCI_command parameter that is passed to the function. In the Command Migration table, each DCI_command value is correlated with the associated functions that will now be used from CToolsLib. Note that in some cases, there is not a 1-1 correspondence between a DCI command and the function that needs to be called. This is due to the DCI Layer abstracting away some of the details of the underlying code.
DCI Command | New Command | New Location | Parameters |
---|---|---|---|
DCI_CMD_AET_CLAIM | AET_claim() | AETlib | |
DCI_CMD_AET_RELEASE | AET_release() | AETlib | |
DCI_CMD_AET_ENABLE | AET_enable() | AETlib | |
DCI_CMD_AET_CLEAR_JOB | AET_releaseJob() | AETlib | |
DCI_CMD_AET_PAP | AET_setupJob() | AETlib | AET_JOB_TRIG_ON_PC |
DCI_CMD_PAR | AET_setupJob() | AETlib | AET_JOB_TRIG_ON_PC_RANGE |
DCI_CMD_AET_DAP | AET_setupJob() | AETlib | AET_JOB_TRIG_ON_DATA |
DCI_CMD_AET_DAPVAL | AET_setupJob() | AETlib | AET_JOB_TRIG_ON_DATA_WITH_VAL |
DCI_CMD_AET_DAR | AET_SetupJob() | AETlib | AET_JOB_TRACE_IN_DATA_RANGE |
DCI_CMD_AET_EVT | Multiple Functions | AETlib | |
DCI_CMD_AET_CFG_CNT | AET_configCounter | AETlib | Counter Number |
DCI_CMD_AET_GET_CNT | AET_readCounter | AETlib | Counter Number |
DCI_CMD_ETB_RESET | ETB_close(), ETB_open() | ETBlib | |
DCI_CMD_ETB_ENABLE | ETB_enable(), DSPTrace_enable() | ETBlib | |
DCI_CMD_ETB_DISABLE | ETB_disable(), DSPTrace_disable() | ETBlib | |
DCI_CMD_ETB_DRAIN | ETB_read() | ETBlib | |
DCI_CMD_ETB_IDLE_EXIT | NOT NEEDED | ||
DCI_CMD_LOG_ALLOC_DMA | NOT SUPPORTED | ||
DCI_CMD_LOG_ALLOC_CPU | NOT SUPPORTED | ||
DCI_CMD_LOG_FREE_DMA | NOT SUPPORTED | ||
DCI_CMD_LOG_FREE_CPU | NOT SUPPORTED | ||
DCI_CMD_LOG_EDMASTART | NOT SUPPORTED | ||
DCI_CMD_LOG_ENABLE | NOT SUPPORTED | ||
DCI_CMD_LOG_DISABLE | NOT SUPPORTED | ||
DCI_CMD_LOG_TRIG_CPU | NOT SUPPORTED | ||
DCI_CMD_LOG_GET_TCC_INFO | NOT SUPPORTED |
DCI_open(DCI_Config *config)[edit]
- Purpose: Initialize Debug Hardware and Software
- Migration Notes: There are different functions that need to be called in place of DCI open based on the implementation. Any or all of the following functions may be needed.
Function | Library | Purpose | Needed IF |
---|---|---|---|
AET_init() | AETlib | Initializes AET variables and data | Any AET Commands Will Be Used |
ETB_open() | ETBLib | Open and initialize ETB | Using ETB To capture Trace Data |
DCI_close()[edit]
- Purpose: Close Debug Hardware and Software Cleanup
- Migration Notes: There are different functions that need to be called in place of DCI open based on the implementation. Any or all of the following functions may be needed.
Function | Library | Purpose | Needed IF |
---|---|---|---|
AET_release() | AETlib | Relinquishes Ownership of the AET unit | If AET_claim() was called, AET_release() should be called |
ETB_close() | ETBLib | Close the ETB and release the ETB Handle Pointer | If ETB_open() was called, ETB_close() should be called |
Enumeration Migration[edit]
These tables list AET configuration enumerations from DCI Lib and their equivalent enumerations for AETLIb.
Trigger Type[edit]
The TriggerType Parameter specifies the "Action" that will occur whenever the parameters set by the AET Job are met
- Examples (not exhaustive)
- CPU Halt
- CPU Interrupt
- Start Trace
DCI Parameter | AETlib Parameter | Description |
---|---|---|
DCI_TRIG_BAD | No Correlated AET TriggerType | |
DCI_TRIG_CPU_HALT | AET_TRIG_HALT_CPU | Halt CPU |
DCI_TRIG_CPU_INT | AET_TRIG_AINT | Generate a CPU interrupt |
DCI_TRIG_WM0S | AET_TRIG_WM0START | Start watermark 0 |
DCI_TRIG_WM0E | AET_TRIG_WM0STOP | End watermark 0 |
DCI_TRIG_WM1S | AET_TRIG_WM1START | Start watermark 1 |
DCI_TRIG_WM1E | AET_TRIG_WM1STOP | End watermark 1 |
DCI_TRIG_CNT0S | AET_TRIG_CNT0_START | Start timer / Decrement counter 0 |
DCI_TRIG_CNT0E | AET_TRIG_CNT0_STOP | End timer / Reload counter 0 |
DCI_TRIG_CNT1S | AET_TRIG_CNT1_START | Start timer / Decrement counter 1 |
DCI_TRIG_CNT1E | AET_TRIG_CNT1_STOP | End timer / Reload counter 1 |
DCI_TRIG_ET0 | AET_TRIG_ET0 | External Trigger 0 |
DCI_TRIG_ET1 | AET_TRIG_ET1 | External Trigger 1 |
DCI_TRIG_TRCS | AET_TRIG_TRACE_TRIGGER | Start trace |
DCI_TRIG_TRCE | AET_TRIG_TRACE_END | End trace |
DCI_TRIG_STATE_0_TO_1 | AET_TRIG_STATE_0_TO_1 | State Machine 0-1 |
DCI_TRIG_STATE_0_TO_2 | AET_TRIG_STATE_0_TO_2 | State Machine 0-2 |
DCI_TRIG_STATE_0_TO_3 | AET_TRIG_STATE_0_TO_3 | State Machine 0-3 |
DCI_TRIG_STATE_1_TO_0 | AET_TRIG_STATE_1_TO_0 | State Machine 1-0 |
DCI_TRIG_STATE_1_TO_2 | AET_TRIG_STATE_1_TO_2 | State Machine 1-2 |
DCI_TRIG_STATE_1_TO_3 | AET_TRIG_STATE_1_TO_3 | State Machine 1-3 |
DCI_TRIG_STATE_2_TO_0 | AET_TRIG_STATE_2_TO_0 | State Machine 2-0 |
DCI_TRIG_STATE_2_TO_1 | AET_TRIG_STATE_2_TO_1 | State Machine 2-1 |
DCI_TRIG_STATE_2_TO_3 | AET_TRIG_STATE_2_TO_3 | State Machine 2-3 |
DCI_TRIG_STATE_3_TO_0 | AET_TRIG_STATE_3_TO_0 | State Machine 3-0 |
DCI_TRIG_STATE_3_TO_1 | AET_TRIG_STATE_3_TO_1 | State Machine 3-1 |
DCI_TRIG_STATE_3_TO_2 | AET_TRIG_STATE_3_TO_2 | State Machine 3-2 |
DCI_TRIG_TRCA | Trace Active | |
DCI_TRIG_TRCI | Trace Inactive | |
DCI_TRIG_MAX |
Trigger Logic Orientation[edit]
The Logic Orientation parameter specifies when AET will trigger. A Straightforward or Normal trigger specifies to trigger whenever the set of AET parameters is true. An inverted orientation specifies for the trigger to occur whenever the set of AET Parameters is false.
- Example - Consider a Trace in Range job where a range of addresses is specified
- A Normal/Straightforward Logic Orientation will trace whenever the PC is within the range of addresses
- An Inverted Logic orientation will trace whenever the PC is outside the range of addresses
DCI Parameter | AETlib Parameter |
---|---|
DCI_TRIG_LOGIC_NORMAL | AET_TRIG_LOGIC_STRAIGHTFORWARD |
DCI_TRIG_LOGIC_INVERTED | AET_TRIG_LOGIC_INVERTED |
Data Access Type[edit]
The Data Access Type determines the type of access to be monitored by AET (read/write).
DCI Parameter | AETlib Parameter |
---|---|
DCI_DATACC_WRITE | AET_WATCH_WRITE |
DCI_DATACC_READ | AET_WATCH_READ |
Reference Access Size[edit]
The Data Access Size determines the reference size of the access to be monitored by AET. It is important to make the distinction between the reference size of the access, and the access size. The reference size of the access essentially is the span of bytes past the read/write address that is considered to be a "Hit"
- Example - An AET Job is configured to generate an interrupt when address 0x08000000 is written to. A 16-bit write to address 0x08000002 occurs
- If the Reference Size is Byte (8-bits), no interrupt is generated because the reference size specifies to not look past byte 0x08000000
- If the Reference Size is Half Word (16-bits), no interrupt is generated because the reference size specifies to not look past byte 0x08000001
- If the Reference Size is Word (32-bits), an interrupt is generated because the reference size specifies to not look past byte 0x08000003 and our write is within that range
- If the Reference Size is Double Word (64-bits), an interrupt is generated because the reference size specifies to not look past byte 0x08000007 and our write is within that range
DCI Parameter | AETlib Parameter |
---|---|
DCI_DATACCSIZE_BYTE | AET_REF_SIZE_BYTE |
DCI_DATACCSIZE_HALFWORD | AET_REF_SIZE_HALFWORD |
DCI_DATACCSIZE_WORD | AET_REF_SIZE_WORD |
DCI_DATACCSIZE_DOUBLEWORD | AET_REF_SIZE_DOUBLEWORD |
Error Status[edit]
Each DCI command can return an error status to be handled by the application. Each DCI Status is shown below, along with the new status, the library that will generate the new status, and an explanation of the error message. Note that much of the error handling is now done within DSPTraceLib and ETBLib. These libraries will typically only give a pass/fail status in the cases where DCI might return a status that is a bit more meaningful.
DCI Status | New Status | Generating Lib | Description |
---|---|---|---|
DCI_STATUS_BAD | |||
DCI_STATUS_OK | AET_SOK, eETB_Success | AETLib, ETBLib | Command executed properly |
DCI_STATUS_NORESOURCES | AET_FNOTAVAIL, AET_FNOTAVAILACMP, AET_FNOTAVAILAEG, AET_FNOTAVAILCNT, AET_FNOTAVAILDCMP, AET_FNOTAVAILSM, AET_FNOTAVAILTB1, AET_FNOTAVAILTB3, AET_FNOTAVAILTB7 | AETLib | Resources were not available - AETlib gives a more descriptive error code based on which resources were not available. |
DCI_STATUS_OPENFAIL | DCI interface already open - This error does not exist outside of DCI | ||
DCI_STATUS_AETBUSY | AET_FNOCLAIM | AETLib | Could not claim AET unit access |
DCI_STATUS_ETB_DTFINITFAIL | eDSPTrace_Error_Program | DSPTraceLib | DTF CSL could not be initialized - |
DCI_STATUS_ETB_DTFOPENFAIL | eDSPTrace_Error_Program | DSPTraceLib | DTF CSL could not be opened |
DCI_STATUS_ETB_DTFCLOSEFAIL | eDSPTrace_Error_Program | DSPTraceLib | DTF CSL could not be closed |
DCI_STATUS_ETB_DTFBUSY | eDSPTrace_Error_Program | DSPTraceLib | DTF HW could not be accessed |
DCI_STATUS_ETB_TRXPBUSY | eDSPTrace_Error_Program | DSPTraceLib | Trace export block could not be accessed |
DCI_STATUS_ETB_INITFAIL | eETB_Error_Program | ETBLib | ETB CSL module could not be initialized |
DCI_STATUS_ETB_OPENFAIL | eETB_Error_Program | ETBLib | ETB CSL module could not be opened |
DCI_STATUS_ETB_CLOSEFAIL | eETB_Error_Program | ETBLib | ETB CSL module could not be closed |
DCI_STATUS_ETB_ENAFAIL | eETB_Error_Program | ETBLib | ETB HW module could not be enabled |
DCI_STATUS_ETB_BUSY | eETB_Error_Program | ETBLib | ETB module could not be accessed |
DCI_STATUS_ETB_OVERWRITE | eETB_Error_Program | ETBLib | ETB buffer has been overwritten by new data before old data has been read out |
DCI_STATUS_ETB_DISABLED | eETB_Error_Program | ETBLib | ETB is disabled |
DCI_STATUS_ETB_TCD_TIMEOUT | eETB_Error_Program | ETBLib | Timeout in disabling trace capture |
DCI_STATUS_ETB_TCE_TIMEOUT | eETB_Error_Program | ETBLib | Timeout in enabling trace capture |
DCI_STATUS_ETB_ACQC_TIMEOUT | eETB_Error_Program | ETBLib | Timeout in Acquisition Completion |
DCI_STATUS_ETB_DRAINNUMWORDSFAIL | eETB_Error_Program | ETBLib | etbDrainNumWords too large |
DCI_STATUS_ETB_DEPTHERROR | None | None | ETB depth was not expected. This can only be caused by a DCI build configuration error. |
DCI_STATUS_INVALIDCOUNTERMODE | AET_FINVALIDCNTMODE | AETLib | Invalid counter mode |
DCI_STATUS_INVALIDCOMMAND | AET_FJOBNOTSUPPORTED, AET_FNOJOBIMPLEMENTED | AETLib | Invalid command |
DCI_STATUS_INVALIDINDEX | AET_FJOBNOTPROGRAMMED | AETLib | Invalid job index |
DCI_STATUS_INVALIDLOGMETHOD | None | None | Invalid log method |
DCI_STATUS_LOGNOTSUPPORTED | None | None | Unsupported log type for this channel |
DCI_STATUS_LOGSOURCENOTALLOCATED | None | None | Log source is not allocated |
DCI_STATUS_LOGFREEFAIL | None | None | Logs did not exist for the channel or source |
DCI_STATUS_INVALIDHANDLE | Invalid handle given as parameter | ||
DCI_STATUS_ERROR | Error in executing command |
Code Example[edit]
Overview[edit]
This example details the migration of an Application using DCI to an equivalent application using the CToolsLib family of libraries. In both cases, the application is attempting to capture trace data into the Embedded Trace Buffer while the Program Counter is within a specified range. Once the data is captured, the application will read it out of the Embedded trace buffer and store it in a binary file on the host in the same directory as the .out file. The same flow executes two times and generates two .bin files which can then be translated into human readable trace output by using a utility called bin2tdf supplied with Code Composer Studio.
Header Section[edit]
Note the removal of the DCI header file, and the inclusions of the header files of the CToolsLib libraries that we will need for this specific task.
DCI | CToolsLib |
---|---|
<syntaxhighlight lang="c" enclose="div">
</syntaxhighlight> |
<syntaxhighlight lang="c" enclose="div">
</syntaxhighlight> |
Parameter Structures And Variables[edit]
It up to the user to decide how to allocate these variables, as global or local. With CToolsLib, there are parameters structures for each of the libraries used.
DCI | CToolsLib |
---|---|
<syntaxhighlight lang="c" enclose="div">
/* ======== DCI command structure ======== */ DCI_Command dciCmd; /* Trace Configuration Parameters */ DCI_TraceConfig trcCfg; DCI_Config dciCfg = DCI_CONFIG_DEFAULT; /* Initialize to defaults */ DCI_ActionRange parTrcRange; /* </syntaxhighlight> |
<syntaxhighlight lang="c" enclose="div">
/* ======== AETLib Related Variables ======== */ AET_jobParams traceRangeParams = AET_JOBPARAMS; /* Parameters Structure Initialized to defaults */ AET_jobIndex traceRangeJob; /* Job Index Variable */ AET_error aetRet; /* Function Return Status */
/* ETBLib Error Code */ ETB_errorCallback pETBErrCallBack =0; /* Pointer to Error Callback Function */ ETBHandle* pETBHandle[NUM_CORES]; /* Array of pointers to ETB Interface Handle (one per core) */ /* ======== DSPTraceLib Related Variables ======== */ eDSPTrace_Error dspRet; /* DSPTraceLib Error Code */ DSPTrace_errorCallback pDSPErrorCallBack=0; /* Pointer to Error Callback Function */ DSPTraceHandle* pDSPHandle=0; /* DSPTraceLib Interface Handle */ </syntaxhighlight> |
DoTest Function[edit]
DCI | CToolsLib |
---|---|
<syntaxhighlight lang="c" enclose=div>
Uint32 doTest() { Uint32 callCnt, dNum; /* DCI config structure */ DCI_Config dciCfg = DCI_CONFIG_DEFAULT; /* Trigger Event Parameters */ DCI_ActionRange parTrcRange; Uint32 iter; /* ======== Initialize the Trace PLL ======== */ trace_pll_init(PLL_DIV_VALUE);
/* ======== Configure ETB Parameters ======== */ dciCfg.etbDrainBuffer = drainBuffer; /* Set the location where the ETB data will be drained to */ dciCfg.etbDrainBufferSize = DRAINBUF_SIZE; /* Set the size of the ETB drain buffer. This should be at least the size of the ETB which is device dependent. */ dciCfg.etbDrainNumWords = 1023; /* Set the number of words in the ETB drain again, this is device dependent. For the TMS320C6474, this is 1023. For the TMS320C6472, this is 511. */
/* ======== Initialize DCI =======*/ if (DCI_open(&dciCfg)!=DCI_STATUS_OK) { printf ("Could not open DCI.\n"); return 1; }
/* ======== Configrue Trace Params ========*/ trcCfg.cpuStallEnable = 0; trcCfg.cpuStallDbgmEnable = 0; trcCfg.cpuStallHpiEnable = 0; trcCfg.mode = DCI_TRCMODE_NORMAL; trcCfg.timingStreamEnable = timingStream; trcCfg.pcStreamEnable = pcStream; trcCfg.readStreamEnable = readStream; trcCfg.writeStreamEnable = writeStream; /* ======== Enable ETB ======== */ dciCmd.command = DCI_CMD_ETB_ENABLE; DCI_control(&dciCmd, &trcCfg); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not enable ETB (status = 0x%x).\n",dciCmd.status); return 1; } /* Do two trials */ for(iter=0; iter<2; iter++) { /* Initialize output buffers */ initBuffers(); /* Reset ETB */ dciCmd.command = DCI_CMD_ETB_RESET; DCI_control(&dciCmd, &dNum); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not reset ETB (status = 0x%x).\n",dciCmd.status); return 1; } /* ======== Claim the AET resource ======== */ dciCmd.command = DCI_CMD_AET_CLAIM; DCI_control(&dciCmd, NULL); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not claim AET (status = 0x%x).\n",dciCmd.status); return 1; } /* ======== Set the trigger parameters ========*/ parTrcRange.triggerType = DCI_TRIG_TRCA; parTrcRange.startAddr = (Uint32)&func_dummy; parTrcRange.endAddr = (Uint32)&func_dummy + (Uint32)&func_dummy_size; parTrcRange.trig.pc=pcStream; parTrcRange.trig.timing=timingStream; parTrcRange.trig.rAddr=readStream; parTrcRange.trig.wAddr=writeStream; parTrcRange.trig.rData=readStream; parTrcRange.trig.wData=writeStream; parTrcRange.trig.pcTag=(readStream&pcStream)|(writeStream&pcStream); /* Adjust to last non-zero instruction */ /* Note we use -ml3 and --no_compress to get rid of trampolines and fp headers */ while (!*(Uint8*)(parTrcRange.endAddr-=4)); /* ======== Program the action range ======== */ dciCmd.command = DCI_CMD_AET_PAR; DCI_control(&dciCmd, &parTrcRange); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not configure program action range (status = 0x%x).\n",dciCmd.status); return 1; } /* ======== Enable AET ======== */ dciCmd.command = DCI_CMD_AET_ENABLE; DCI_control(&dciCmd, NULL); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not enable AET (status = 0x%x).\n",dciCmd.status); return 1; } /* Loop for NUM_CALLS iterations */ for(callCnt=0;callCnt<NUM_CALLS;callCnt++) { func_dummy(); /* Read all trace data from ETB */ if (drainEtb()) return 1; } /* Send the rest of traced data into output buffer */ sendBuffer(nDrainedWords); /* Dump drain buffer to file */ dumpTraceToFile(iter+1); /* ======== Clear AET jobs ======== */ dciCmd.command = DCI_CMD_AET_CLEAR_JOB; DCI_control(&dciCmd, &parTrcRange); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not clear program action range (status = 0x%x).\n",dciCmd.status); return 1; } /* ======== Release AET ======== */ dciCmd.command = DCI_CMD_AET_RELEASE; DCI_control(&dciCmd, NULL); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not release AET (status = 0x%x).\n",dciCmd.status); return 1; } } /* ======== Disable ETB ======== */ dciCmd.command = DCI_CMD_ETB_DISABLE; DCI_control(&dciCmd, NULL); if (dciCmd.status!=DCI_STATUS_OK) { printf ("Could not disable ETB (status = 0x%x).\n",dciCmd.status); return 1; } /* ======== Close DCI ======== */ if (DCI_close()!=DCI_STATUS_OK) { printf ("Could not close DCI (status = 0x%x).\n",dciCmd.status); return 1; } </syntaxhighlight> |
<syntaxhighlight lang="c" enclose="div">
Uint32 callCnt, dNum, i; ETB_errorCallback pETBErrCallBack =0; Uint32 etbWidth; eDSPTrace_Error dspRet; DSPTrace_errorCallback pDSPErrorCallBack=0; DSPTraceHandle* pDSPHandle=0; /* jobParams Structure for the Trace in range job */ AET_jobParams traceRangeParams = AET_JOBPARAMS; /* jobIndex holders for the Trace in range job */ AET_jobIndex traceRangeJob; AET_error aetRet; Uint32 iter; dNum = DNUM; setMPAX(); syncPtr = (Uint32*)(0xD0000000 + (Uint32)&syncPoint - 0x0C000000); /* Initialize trace word counters */ for (i=0; i<NUM_CORES; i++) nTotalTraceWords[i] = 0; /* ======== Initialize the Trace PLL ======== */ /* In CToolsLib, this functionality comes from DSPTraceLib. This PLL will get initialized later, when we call DSPTrace_setClock() */ /* ======== Configure ETB Parameters ======== */ /* Since we're using ETBLib, we don't need to specify the drain buffer location and size ahead of time. This can be done later. What we will do here is to initialize and enable all of the libraries that we are using. */ /*** Setup ETB receiver ***/ /* Open the ETB Interface on each core */ for (i=0; i<NUM_CORES; i++) { etbRet = ETB_open(pETBErrCallBack, eETB_Circular, (Uint8)i, &pETBHandle[i], &etbWidth); if(etbRet != eETB_Success) { printf("Error opening ETB%d (status = 0x%x).\n",i,etbRet); return 1; } } /* Enable ETB receiver On This Core */ etbRet = ETB_enable(pETBHandle[dNum], 0); if(etbRet != eETB_Success) { printf("Error enabling ETB (status = 0x%x).\n",etbRet); return 1; } /*** Setup Trace Export ***/ /* Open DSP Trace export module */ dspRet = DSPTrace_open( pDSPErrorCallBack, &pDSPHandle); if(dspRet != eDSPTrace_Success) { printf("Error opening DSP Trace Export block (status = 0x%x).\n",dspRet); return 1; } /* Setup trace export clock to FCLK/3 */ dspRet= DSPTrace_setClock(pDSPHandle, PLL_DIV_VALUE); if(dspRet != eDSPTrace_Success) { printf("Error setting up DSP trace export clock (status = 0x%x).\n",dspRet); return 1; } dspRet= DSPTrace_enable(pDSPHandle, 0, 0); if(dspRet != eDSPTrace_Success) { printf("Error enabling DSP trace export (status = 0x%x).\n",dspRet); return 1; } /* Init the AET resource */ AET_init();
/* Sync the cores */ if (dNum == 0) { *syncPtr = 1; while(*syncPtr<NUM_CORES); } else if (dNum == 1) { while (*syncPtr<1); *syncPtr = 2; while(*syncPtr<NUM_CORES); } else if (dNum == 2) { while (*syncPtr<2); *syncPtr = 3; while (*syncPtr<NUM_CORES); } else if (dNum == 3) { while (*syncPtr<3); *syncPtr = 4; while (*syncPtr<NUM_CORES); } /* Do one trial. At this point, nothing will be traced because we haven't yet configured AET to generate any triggers. So, while the ETB is listening, and Trace is configured to output to the ETB, there are no triggers to start/stop trace */ for(iter=0; iter<1; iter++) { printf("Test iteration started on core %d\n",dNum); /* Initialize output buffers */ if (dNum==0) initBuffers(); /* Reset ETB (disable --> enable ETB receiver */ etbRet = ETB_disable(pETBHandle[dNum]); if(etbRet != eETB_Success) { printf("Error disabling ETB 1 (status = 0x%x).\n",etbRet); return 1; } etbRet = ETB_enable(pETBHandle[dNum],0); if(etbRet != eETB_Success) { printf("Error enabling ETB (status = 0x%x).\n",etbRet); return 1; }
/* Claim the AET resource */ if (aetRet = AET_claim()) { printf("Error claiming AET resources (status = 0x%x).\n",aetRet); return 1; } /* Set the trigger parameters */ traceRangeParams.traceActive = AET_TRACE_ACTIVE; traceRangeParams.traceStartAddress = (Uint32)&func_dummy; traceRangeParams.traceEndAddress = (Uint32)&dummyfunc; /* Adjust to last non-zero instruction */ /* Note we use -ml3 and --no_compress to get rid of trampolines and fp headers */ while (!*(Uint8*)(traceRangeParams.traceEndAddress-=4)); traceRangeParams.traceTriggers = timingStream*AET_TRACE_TIMING | pcStream*AET_TRACE_PA | readStream*AET_TRACE_RA | readStream*AET_TRACE_RD | writeStream*AET_TRACE_WA | writeStream*AET_TRACE_WD | readStream*AET_TRACE_RA | ((readStream&pcStream)|(writeStream&pcStream))*AET_TRACE_PCTAG; /* Set up the Trace Start job */ if (aetRet = AET_setupJob( AET_JOB_TRACE_IN_PC_RANGE, &traceRangeParams)) { printf("Error: could not setup AET job (status = 0x%x).\n",aetRet); return 1; } /* Remember the Number of the Trace Job */ traceRangeJob = traceRangeParams.jobIndex; printf("The Trace in Range Job index is %d\n", traceRangeJob); /* Enable AET */ if (aetRet = AET_enable()) { printf("Error: could not enable AET (status = 0x%x).\n",aetRet); return 1; } /* Loop for NUM_CALLS iterations */ for(callCnt=0;callCnt<NUM_CALLS;callCnt++) { func_dummy(); } /* Sync the cores */ if (dNum == 0) { *syncPtr = NUM_CORES+1; while(*syncPtr<2*NUM_CORES); } else if (dNum == 1) { while (*syncPtr<NUM_CORES+1); *syncPtr = NUM_CORES+2; while(*syncPtr<2*NUM_CORES+1); } else if (dNum == 2) { while (*syncPtr<NUM_CORES+2); *syncPtr = NUM_CORES+3; while (*syncPtr<2*NUM_CORES+1); } else if (dNum == 3) { while (*syncPtr<NUM_CORES+3); *syncPtr = NUM_CORES+4; while (*syncPtr<2*NUM_CORES+1); } if (dNum==0) { /* Drain the ETBs of other cores*/ /* Read all trace data from ETB */ for (i=0; i < NUM_CORES; i++) if (drainEtb(i)) return 1; /* Dump drain buffer to file */ for (i=0; i < NUM_CORES; i++) dumpTraceToFile(iter+1,i); *syncPtr = 2*NUM_CORES+1; } /* Clear AET jobs */ AET_releaseJob(traceRangeJob); /* Release AET */ AET_release(); } etbRet = ETB_disable(pETBHandle[dNum]); if(etbRet != eETB_Success) { printf("Error disabling ETB 3 (status = 0x%x).\n",etbRet); return 1; } /* Disable DSP Trace Export */ dspRet= DSPTrace_disable(pDSPHandle); if(dspRet != eDSPTrace_Success) { printf("Error disabling DSP trace export (status = 0x%x).\n",dspRet); return 1; } /*** Now we are done and close all the handles **/ etbRet = ETB_close(pETBHandle[dNum]); if(etbRet != eETB_Success) { printf("Error closing ETB (status = 0x%x).\n",etbRet); return 1; }
dspRet= DSPTrace_close(pDSPHandle); if(dspRet != eDSPTrace_Success) { printf("Error closing DSP trace export module (status = 0x%x).\n",dspRet); return 1; } AET_releaseJob(traceRangeJob); AET_release(); return 0; </syntaxhighlight> |
Auxilliary Functions[edit]
DCI | CToolsLib |
---|---|
<syntaxhighlight lang="c" enclose="div">
void trace_pll_init ( Uint32 div_val ) { /* turn on trace clock from PLL here. */ volatile Uint32 *pllcmd_addr = (volatile Uint32 *)0x029A0138; volatile Uint32 *pllstat_addr = (volatile Uint32 *)0x029A013C; volatile Uint32 *plldiv_addr = (volatile Uint32 *)0x029A0184; /* Wait for any concurrent GOSET to complete */ while (*pllstat_addr&0x1); /* PLLDIV register value: bit 4:0 -- ratio = 00011b (/4), 11111b (/32) bit 15 -- DnEn = 1 */ /* PLL divider value could be from 1 to 32. */ *plldiv_addr = (1<<15) | (div_val-1); /* PLLCMD register value: bit 1 -- GOSET */ *(unsigned int*)pllcmd_addr = 0x1; return; } void func_dummy() { Uint32 i; for (i=0;i<ARRAY_SIZE;i++) { array1[i] = rand(); } for (i=0;i<ARRAY_SIZE-1;i++) { array2[i] = array1[i+1]/3 + array1[i]/5; } } void func_dummy_kick() { return; }
Uint32 *p, i; char filename[20]; sprintf(filename,"myfile%d.bin\0",testNum); fid = fopen(filename,"wb"); /* Dump drain buffer to file */ p=traceOutputBuffer; for (i=0;i<nTotalTraceWords;i++) fwrite32(*(p++),fid); //fwrite(p++,4,1,fid); fflush(fid); fclose(fid); } void sendBuffer(Uint32 nWords) { memcpy(&traceOutputBuffer[nTotalTraceWords],&drainBuffer,nWords*4); nTotalTraceWords+=nWords; } Uint32 drainEtb() { drainParams.etbInstanceNumber = DNUM; dciCmd.command = DCI_CMD_ETB_DRAIN; do{ DCI_control(&dciCmd, &drainParams); if (dciCmd.status != DCI_STATUS_OK) { printf ("Drain ETB failed (status = 0x%x).\n",dciCmd.status); return 1; } nDrainedWords += drainParams.nWordsRead; if (drainParams.etbDrainBufferFull) { sendBuffer(nDrainedWords); nDrainedWords = 0; } } while(!drainParams.etbEmpty);
return 0; } void initBuffers() { memset(drainBuffer,0,2*DRAINBUF_SIZE); memset(traceOutputBuffer,0,2*DRAINBUF_SIZE*4); nTotalTraceWords = 0; nDrainedWords = 0; } </syntaxhighlight> |
<syntaxhighlight lang="c" enclose="div">
void func_dummy() { Uint32 i, dnum; dnum=DNUM; for (i=0;i<ARRAY_SIZE;i++) { if (dnum==0) array1[i]=rand(); else if (dnum==1) array1[i]=i*i; else if (dnum==2) array1[i]=i^0xFFFF; else if (dnum==3) array1[i]=_lmbd(1,i); } for (i=0;i<ARRAY_SIZE-1;i++) { array2[i] = array1[i+1]/3 + array1[i]/5; }
asm ("dummyfunc:"); /* This label marks the end of func1(); */
asm ("_dummyfunc:"); /* This label marks the end of func1(); */
} void dumpTraceToFile(Uint32 testNum, Uint32 etbNum) { Uint32 *p, i; char filename[20]; sprintf(filename,"etb%d_test%d.bin\0",etbNum,testNum); fid = fopen(filename,"wb"); /* Dump drain buffer to file */ p=&traceOutputBuffer[0][etbNum]; for (i=0;i<nTotalTraceWords[etbNum];i++) fwrite32(*(p++),fid); //fwrite(p++,4,1,fid); fflush(fid); fclose(fid); } void sendBuffer(Uint32 nWords, Uint32 etbNum) { memcpy(&traceOutputBuffer[nTotalTraceWords[etbNum]][etbNum],drainBuffer,nWords*4); nTotalTraceWords[etbNum]+=nWords; } Uint32 drainEtb(Uint32 etbNum) { ETBStatus etbStatus; Uint32 retSize=0; /* Now disable trace capture - ETB receiver */ etbRet = ETB_disable(pETBHandle[etbNum]); if(etbRet != eETB_Success) { printf("Error disabling ETB 2 (status = 0x%x).\n",etbRet); return 1; } /*** Get ETB data ***/ /* Check the ETB status */ etbRet= ETB_status(pETBHandle[etbNum], &etbStatus); if(etbRet != eETB_Success) { printf("Error getting ETB status (status = 0x%x).\n",etbRet); return 1; } if(etbStatus.canRead == 1) { if(etbStatus.isWrapped == 1) printf ("ETB is wrapped; ETB words = %d\n", etbStatus.availableWords); else printf ("ETB is not wrapped; ETB words = %d\n", etbStatus.availableWords); etbRet = ETB_read(pETBHandle[etbNum], drainBuffer, etbStatus.availableWords, 0, etbStatus.availableWords, &retSize); if(etbRet != eETB_Success) { printf("Error reading ETB data (status = 0x%x).\n",etbRet); return 1; } sendBuffer(etbStatus.availableWords,etbNum); } else { printf("Error reading ETB: ETB status was not readable\n"); return 1; } /* Now re-enable trace capture - ETB receiver */ etbRet = ETB_enable(pETBHandle[etbNum],0); if(etbRet != eETB_Success) { printf("Error enabling ETB (status = 0x%x).\n",etbRet); return 1; } return 0; } void initBuffers() { int i; memset(drainBuffer,0,2*DRAINBUF_SIZE); memset(traceOutputBuffer,0,2*DRAINBUF_SIZE*4*NUM_CORES); for (i=0;i<NUM_CORES;i++) nTotalTraceWords[i] = 0; } void coreSync() { }
void setMPAX() { /* Mapping for non-cached view for MSMC*/ *(unsigned int *)(XMC_CFG_BASE+0x18) = 0x00C0003F; /* replacement addr + perm */ *(unsigned int *)(XMC_CFG_BASE+0x1C) = 0xD0000014; /* base addr + seg size (2MB) */ } </syntaxhighlight> |
Additional Information[edit]
Should you need additional information or feel that this document is lacking in some detail, please leave a comment here or click the "Leave a Comment" link below.