367 lines
9.4 KiB
C
367 lines
9.4 KiB
C
/* *********************************************************************************************
|
|
* @Title: TRACE32 Remote API sample program presenting a menu for sending various API commands.
|
|
* @Description:
|
|
* Console application creating a connection to TRACE32 and presenting
|
|
* a menu in the console for sending various API commands to TRACE32.
|
|
*
|
|
* The port on which TRACE32 listens for API connections can optionally
|
|
* be set with the port=<n> parameter. The port number must match with
|
|
* the definition in config.t32. The default value is 20000.
|
|
*
|
|
* a binary of this sample can be found in t32/bin/<arch>/
|
|
*
|
|
* Syntax: t32remtest [<ip-address> | <hostname>] [port=<number>]
|
|
*
|
|
* Example: t32remtest localhost port=10000
|
|
*
|
|
* $Id: t32remtest.c 161717 2023-08-09 08:37:44Z fsirl $
|
|
* $LastChangedRevision: 161717 $
|
|
* $LastChangedBy: fsirl $
|
|
*
|
|
* @Copyright: (C) 1989-2020 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
* *********************************************************************************************
|
|
* $Id: t32remtest.c 161717 2023-08-09 08:37:44Z fsirl $
|
|
*/
|
|
|
|
|
|
|
|
#include "t32.h"
|
|
|
|
#if defined(_MSC_VER)
|
|
# pragma warning( push )
|
|
# pragma warning( disable : 4255 )
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#if defined(_MSC_VER)
|
|
# pragma warning( pop )
|
|
#endif
|
|
|
|
static uint8_t buffer[12000];
|
|
static uint16_t wbuffer[12000];
|
|
|
|
int main(int argc, char ** argp)
|
|
{
|
|
int ch;
|
|
int i, j;
|
|
int statinfo;
|
|
uint32_t cpu_registers[64];
|
|
int retries = 0;
|
|
int argn;
|
|
|
|
retryit:
|
|
retries++;
|
|
|
|
|
|
if ( argc < 2 )
|
|
{
|
|
printf( "usage: t32remtest <host> [port=<n>]\n" );
|
|
exit(2);
|
|
}
|
|
|
|
if ( T32_Config( "NODE=", argp[1] ) == -1 )
|
|
{
|
|
printf( "hostname %s not accepted\n", argp[1] );
|
|
exit(2);
|
|
}
|
|
|
|
argn = 2;
|
|
|
|
if ( argc >= 3 && ((!strncmp(argp[2],"port=", 5)) || (!strncmp(argp[2],"PORT=", 5))))
|
|
{
|
|
if ( T32_Config( "PORT=", argp[2]+5 ) == -1 )
|
|
{
|
|
printf( "port number %s not accepted\n", argp[2] );
|
|
exit(2);
|
|
}
|
|
argn++;
|
|
}
|
|
|
|
|
|
if (T32_Init() == -1) {
|
|
printf("error initializing TRACE32\n");
|
|
T32_Exit();
|
|
if (retries < 2) {
|
|
goto retryit;
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
/* When attach fails, we close a (potentially) existing connection and retry */
|
|
if (T32_Attach(T32_DEV_ICD) != 0) {
|
|
|
|
T32_Exit();
|
|
T32_Init();
|
|
|
|
if (T32_Attach(T32_DEV_ICD) != 0) {
|
|
printf("Failure to connecting to TRACE32. Terminating.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
while (1) {
|
|
printf("\n Q Quit Program T Terminate PowerView");
|
|
printf("\n");
|
|
printf("\n s STOP Cmd");
|
|
printf("\n D DO test.cmm P PING Test");
|
|
printf("\n");
|
|
printf("\n n NOP Test p NOP_Fail Test");
|
|
printf("\n N 1000*NOP Test");
|
|
printf("\n");
|
|
printf("\n m Read Memory a Trace Readout");
|
|
printf("\n M Write Memory J Integrator Readout");
|
|
printf("\n W Write Memory Pipelined 1MB");
|
|
printf("\n");
|
|
printf("\n r Read Registers b Read Breakpoints");
|
|
printf("\n R Write Registers B Write Breakpoints");
|
|
printf("\n");
|
|
printf("\n S Single Step C CPU Reset");
|
|
printf("\n G Go c CPU State");
|
|
printf("\n g Break");
|
|
printf("\n");
|
|
printf("\n x Test j JTAG TAP Access Test");
|
|
printf("\n");
|
|
printf("\nCMD> ");
|
|
|
|
|
|
if (T32_Cmd("print") == -1)
|
|
goto error;
|
|
|
|
|
|
do {
|
|
ch = getchar();
|
|
}
|
|
while (ch == '\n');
|
|
|
|
if (ch == 'Q' || ch == 'q')
|
|
break;
|
|
|
|
switch (ch) {
|
|
case 'n': /* NOP */
|
|
if (T32_Nop() == -1)
|
|
goto error;
|
|
break;
|
|
case 'p': /* NOP */
|
|
if (T32_NopFail() == -1)
|
|
goto error;
|
|
break;
|
|
case 'N': /* 1000*NOP */
|
|
for (i = 0; i < 1000; i++) {
|
|
if (T32_Nop() == -1)
|
|
goto error;
|
|
}
|
|
break;
|
|
case 's': /* STOP */
|
|
if (T32_Stop() == -1)
|
|
goto error;
|
|
break;
|
|
case 'P': /* PING */
|
|
if (T32_Ping() == -1)
|
|
goto error;
|
|
break;
|
|
case 'D': /* DO */
|
|
if (T32_Cmd("do test") == -1)
|
|
goto error;
|
|
break;
|
|
case 'T': /* Terminate */
|
|
if (T32_Terminate(0) == -1)
|
|
goto error;
|
|
T32_Exit();
|
|
return 0;
|
|
case 'M': /* Memory Write */
|
|
if ((T32_WriteMemory(0x1234l, 0x40, (const unsigned char *) "hello world", 12)))
|
|
goto error;
|
|
break;
|
|
case 'W': /* DOWNLOAD */
|
|
for (i = 0; i < 256; i++) {
|
|
if ((T32_WriteMemoryPipe(0x1234l, 0x40, (const unsigned char *) "hello world", 4096)))
|
|
goto error;
|
|
}
|
|
if (T32_WriteMemoryPipe(0l, 0, (unsigned char *) 0, 0))
|
|
goto error;
|
|
break;
|
|
case 'm': /* Memory Read */
|
|
if ((T32_ReadMemory(0x1234l, 0, buffer, 200)))
|
|
goto error;
|
|
printf("\n");
|
|
for (i = 0; i < 16; i++)
|
|
printf(" %02x", buffer[i]);
|
|
printf("\n");
|
|
break;
|
|
case 'r': /* Register Read */
|
|
if ((T32_ReadRegister(0xffffffffl, 0l, cpu_registers)))
|
|
goto error;
|
|
printf("\n");
|
|
for (i = 0; i < 32; i++)
|
|
printf(" %08x", cpu_registers[i]);
|
|
printf("\n");
|
|
break;
|
|
case 'R': /* Register Write */
|
|
for (i = 0; i < 8; i++)
|
|
cpu_registers[i]++;
|
|
if ((T32_WriteRegister(0xffl, 0l, cpu_registers)))
|
|
goto error;
|
|
break;
|
|
case 'Y': /* Register Read */
|
|
for (i = 0; i < 1000000; i++) {
|
|
if ((T32_ReadRegister(0xffffffffl, 0l, cpu_registers)))
|
|
goto error;
|
|
}
|
|
break;
|
|
case 'b': /* Breakpoint Read */
|
|
if ((T32_ReadBreakpoint(0x1234l, 0, wbuffer, 8)))
|
|
goto error;
|
|
printf("\n");
|
|
for (i = 0; i < 8; i++)
|
|
printf(" %04x", wbuffer[i]);
|
|
printf("\n");
|
|
break;
|
|
case 'B': /* Breakpoint Write */
|
|
if ((T32_WriteBreakpoint(0x1234l, 0x80, 0x18, 4))) /* Set */
|
|
goto error;
|
|
if ((T32_WriteBreakpoint(0x1238l, 0x80, 0x118, 4))) /* Clear */
|
|
goto error;
|
|
if ((T32_WriteBreakpoint(0x123cl, 0x80, 0x01, 1))) /* Set */
|
|
goto error;
|
|
if ((T32_WriteBreakpoint(0x1240l, 0x80, 0x101, 1))) /* Clear */
|
|
goto error;
|
|
if ((T32_WriteBreakpoint(0x1250l, 0x80, 0x01, 1))) /* Set */
|
|
goto error;
|
|
if ((T32_WriteBreakpoint(0x1250l, 0x80, 0x101, 1))) /* Clear */
|
|
goto error;
|
|
break;
|
|
case 'c': /* STATE */
|
|
if ((i = T32_GetState(&statinfo)))
|
|
goto error;
|
|
switch (statinfo) {
|
|
case 0:
|
|
printf("\ndown\n");
|
|
break;
|
|
case 1:
|
|
printf("\nhalted\n");
|
|
break;
|
|
case 2:
|
|
printf("\nstopped\n");
|
|
break;
|
|
case 3:
|
|
printf("\nrunning\n");
|
|
break;
|
|
}
|
|
break;
|
|
case 'C': /* CPU Reset/Prepare */
|
|
if (T32_ResetCPU())
|
|
goto error;
|
|
break;
|
|
case 'S': /* Single Step */
|
|
if (T32_Step())
|
|
goto error;
|
|
break;
|
|
case 'G': /* Start Realtime */
|
|
if (T32_Go())
|
|
goto error;
|
|
break;
|
|
case 'g': /* Stop Realtime */
|
|
if (T32_Break())
|
|
goto error;
|
|
break;
|
|
case 'j': /* JTAG tap access */
|
|
buffer[0] = 'a';
|
|
buffer[1] = 'b';
|
|
buffer[2] = 'c';
|
|
buffer[3] = 'd';
|
|
if (T32_TAPAccessShiftIR(0, 32, buffer, buffer))
|
|
goto error;
|
|
printf("\n");
|
|
for (i = 0; i < 4; i++)
|
|
printf(" %02x", buffer[i]);
|
|
printf("\n");
|
|
break;
|
|
case 'x': /* test */
|
|
for (i = 0; i < 10; i++) {
|
|
int state;
|
|
uint32_t pcvalue;
|
|
T32_GetState(&state);
|
|
printf("T32_GetState %d\n", state);
|
|
T32_Step();
|
|
printf("T32_Step\n");
|
|
T32_GetState(&state);
|
|
printf("T32_GetState %d\n", state);
|
|
T32_ReadPP(&pcvalue);
|
|
printf("T32_ReadPP %d\n", pcvalue);
|
|
T32_GetState(&state);
|
|
printf("T32_GetState %d\n", state);
|
|
T32_GetState(&state);
|
|
printf("T32_GetState %d\n", state);
|
|
T32_GetState(&state);
|
|
printf("T32_GetState %d\n", state);
|
|
}
|
|
break;
|
|
case 'a': /* Analyzer readout */
|
|
{
|
|
int width;
|
|
int state;
|
|
int32_t records, min, max;
|
|
|
|
if (T32_GetTraceState(0, &state, &records, &min, &max))
|
|
goto error;
|
|
|
|
printf("T32_GetTraceState state: %d, records: %d, min: %d, max: %d \n", state, records, min, max);
|
|
|
|
width = 17*4;
|
|
if (T32_ReadTrace(0, min, 100, 0x1ffff, buffer))
|
|
goto error;
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
printf("frame %10d: ", min+i);
|
|
for (j = 0; j < width; j += 4) {
|
|
printf("%02x%02x%02x%02x ", buffer[i * width + j + 3], buffer[i * width + j + 2], buffer[i * width + j + 1], buffer[i * width + j + 0]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
break;
|
|
case 'J': /* Integrator readout */
|
|
{
|
|
int width;
|
|
int state;
|
|
int32_t records, min, max;
|
|
|
|
if (T32_GetTraceState(1, &state, &records, &min, &max))
|
|
goto error;
|
|
|
|
printf("T32_GetTraceState state: %d, records: %d, min: %d, max: %d \n", state, records, min, max);
|
|
|
|
width = 3*4;
|
|
if (T32_ReadTrace(1, min, 100, 0x1000c, buffer))
|
|
goto error;
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
printf("frame %10d: ", min+i);
|
|
for (j = 0; j < width; j += 4) {
|
|
printf("%02x%02x%02x%02x ", buffer[i * width + j + 3], buffer[i * width + j + 2], buffer[i * width + j + 1], buffer[i * width + j + 0]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
printf("no such command\n");
|
|
}
|
|
continue;
|
|
error:
|
|
printf("error accessing TRACE32\n");
|
|
}
|
|
|
|
T32_Exit();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|