Files
Gen4_R-Car_Trace32/2_Trunk/demo/api/capi/test/t32rem.c
2025-10-14 09:52:32 +09:00

292 lines
8.2 KiB
C

/* *********************************************************************************************
* @Title: Sample program to execute TRACE32 commands from a system shell.
* @Description:
* This application creates a connection to a TRACE32 PowerView instance and sends a
* TRACE32 command to that PowerView instance for execution.
*
* By default the port on which TRACE32 PowerView listens for API connections is 20000.
* Optionally the port can be send with the port=<n> parameter.
* The port number must match with the definition in config.t32 of the PowerView instance you
* want to receive the command
*.
* The optional parameter wait=<ms> will cause t32rem to wait (after sending its command) until
* no more PRACTICE scripts are running in TRACE32 - or the given timeout elapses. Without the
* parameter wait=<ms>, t32rem will not wait until all PRACTICE scripts stop running.
*
* A binary of this sample can be found in <t32>/bin/<os>/t32rem[.exe]
*
* Syntax: t32rem <hostname or ip-address> [port=<number>] [protocol=NETASSIST|NETTCP]
* [timeout=<s>] [wait=<ms>] <command>
*
* Example1: Set a breakpoint on main():
* t32rem localhost port=20000 Break.Set main
*
* Example2: Open the Break.List window:
* t32rem localhost port=20000 Break.List
*
* Example3: Start a PRACTICE script and waits up to 5000.ms until it stops:
* t32rem localhost port=20000 wait=5000 DO ~~/demo/practice/pcmd.cmm
*
* Return values:
* 0 OK
* 1 Error accessing TRACE32.
* 2 Failed to connect to TRACE32. (No TRACE32 with an open API port at that socket)
* 3 Invalid input. (Invalid ip-address/hostname/port or too long command)
* 4 Timeout while waiting for PRACTICE scripts to stop running.
*
* $Id: t32rem.c 168156 2024-03-30 11:49:30Z fsirl $
* $LastChangedRevision: 168156 $
* $LastChangedBy: fsirl $
*
* @Copyright: (C) 1989-2020 Lauterbach GmbH, licensed for use with TRACE32(R) only
* *********************************************************************************************
* $Id: t32rem.c 168156 2024-03-30 11:49:30Z fsirl $
*/
#if defined(_MSC_VER)
# pragma warning( push )
# pragma warning( disable : 4255 4005)
# include <stdint.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
# include <string.h>
# include <Windows.h>
# pragma warning( pop )
# define strncasecmp(S1,S2,N) _strnicmp((S1), (S2), (N))
#else
# ifdef __linux__
/* for usleep() declaration */
# define _BSD_SOURCE
# endif
# include <stdint.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
# include <string.h>
# include <strings.h>
# include <unistd.h>
# include <sys/time.h>
# define Sleep(t) usleep((t)*1000)
#endif
#include "t32.h"
#if !defined(_MSC_VER)
static uint32_t GetTickCount(void)
{
struct timeval now;
if ( gettimeofday( &now, NULL ) == -1 )
return 0;
return (now.tv_sec*1000 + now.tv_usec/1000) & UINT32_MAX;
}
#endif
int main(int argc, char **argp)
{
typedef enum { RESULT_OK = 0, RESULT_NOACCESS, RESULT_NOCONNECTION, RESULT_INVALIDINPUT, RESULT_TIMEOUT} result_t;
char cmd[2048];
char * port = NULL;
char * api_timeout = NULL;
uint16_t msgMode, msgLen;
unsigned long int wait = 0;
uint8_t is_nettcp = false;
result_t result = RESULT_OK;
if (argc < 2) {
printf( "Usage: t32rem <host> [port=<n>] [protocol=NETASSIST|NETTCP] [timeout=<s>] [wait=<ms>] <cmd>\n" );
printf( "Send a TRACE32 command to a running TRACE32 PowerView instance.\n");
printf( "The receiving TRACE32 instance needs to have an enabled API port.\n\n");
printf( " <host> IP address or hostname of the machine running the receiving TRACE32.\n");
printf( " port=<n> API port opened on the receiving TRACE32 (Default is 20000)\n");
printf( " protocol=NETASSIST|NETTCP Communication protocol used for the communication with TRACE32 (Default is NETASSIST)\n");
printf( " timeout=<s> Communication timeout for the execution of API functions (Default is 5 seconds)\n");
printf( " wait=<ms> Wait up to the given milliseconds until all PRACTICE scripts on the\n"
" receiving TRACE32 stop, after sending the command. This is useful in\n"
" combination with a command starting a PRACTICE script like \"run\" or\n"
" \"do\". Without this option t32rem will not wait for scripts to end.\n");
exit(RESULT_INVALIDINPUT);
}
/*
* The executable path is at argp[0] and the position of <host>
* are fixed. The positions of port=<n>, wait=<ms>, timeout=<s> and
* protocol=NETASSIST|NETTCP can be flexible.
*/
int idx_last_option_flag = 0;
for (int idx = 2; idx < argc; idx++) {
char * arg = argp[idx];
if (strncasecmp(arg, "port=", 5) == 0) {
if (T32_Config("PORT=", &arg[5]) == -1) {
printf( "port number %s not accepted\n", arg);
exit(RESULT_INVALIDINPUT);
}
port = &arg[5];
idx_last_option_flag = idx;
}
else if (strncasecmp(arg, "protocol=", 9) == 0) {
if (strcmp(&arg[9], "NETASSIST") == 0) {
is_nettcp = false;
}
else if (strcmp(&arg[9], "NETTCP") == 0) {
is_nettcp = true;
}
else {
printf( "communication protocol \"%s\" not supported\n", arg);
exit(RESULT_INVALIDINPUT);
}
idx_last_option_flag = idx;
}
else if (strncasecmp(arg, "timeout=", 8) == 0) {
api_timeout = &arg[8];
idx_last_option_flag = idx;
}
else if (strncasecmp(arg, "wait=", 5) == 0) {
wait = strtoul(&arg[5], NULL, 10);
idx_last_option_flag = idx;
}
else {
/* Abort on first positional/unknown flag */
break;
}
}
int idx_command = 2;
if (idx_last_option_flag > 0) {
/* Command line has optional parameters */
idx_command = idx_last_option_flag + 1u;
}
strcpy(cmd, "");
while (idx_command < argc) {
if ( (strlen(cmd) + strlen(argp[idx_command]) + 1) > (sizeof(cmd) - 1) ) {
printf( "actual command line exceeds maximum internal bufferlength of %d\n", (int) sizeof(cmd) - 1 );
exit(RESULT_INVALIDINPUT);
}
strcat( cmd, argp[idx_command] );
strcat( cmd, " " );
idx_command++;
}
/* NETASSIST is the default protocol */
void * channel = NULL;
if (is_nettcp) {
T32_RequestChannelNetTcp(&channel);
T32_SetChannel(channel);
}
char default_port[] = "20000";
if (port == NULL) {
port = default_port;
}
if (T32_Config( "NODE=", argp[1]) == -1 ) {
printf( "hostname %s not accepted\n", argp[1] );
exit(RESULT_INVALIDINPUT);
}
if (T32_Config("PORT=", port) == -1) {
printf("error initializing TRACE32\n");
exit(RESULT_NOCONNECTION);
}
if (api_timeout != NULL) {
if (T32_Config("TIMEOUT=", api_timeout) == -1) {
printf("error initializing TRACE32\n");
exit(RESULT_NOCONNECTION);
}
}
if ( T32_Init() != T32_OK ) {
printf( "error initializing TRACE32\n" );
exit(RESULT_NOCONNECTION);
}
if (T32_Attach(1) != T32_OK) {
printf("error no device\n");
exit(RESULT_NOCONNECTION);
}
int rc = T32_Nop();
if ( rc != T32_OK ) {
goto error;
}
rc = T32_Stop();
if (T32_Errno != T32_OK && T32_Errno != 1) {
goto error;
}
rc = T32_Cmd( cmd );
if ( rc != T32_OK ) {
goto error;
}
if (wait) {
uint32_t start, now;
start = GetTickCount();
int pstate = -1;
rc = T32_OK;
while ((rc == T32_OK) && (pstate != 0)) {
rc = T32_GetPracticeState(&pstate);
now = GetTickCount();
// handle GetTickCount() overflow
if (now < start) {
wait = UINT32_MAX - start;
start = 0;
}
if ((now - start) >= wait) {
result = RESULT_TIMEOUT;
break;
}
Sleep(1);
}
if (rc != T32_OK) {
goto error;
}
}
rc = T32_GetMessageString( cmd, (uint16_t)sizeof(cmd), &msgMode, &msgLen);
if ( rc != T32_OK ) {
goto error;
}
printf( "command returned ");
if (msgMode & 1)
printf ("General Information, ");
if (msgMode & 2)
printf ("Error, ");
if (msgMode & 8)
printf ("Status Information, ");
if (msgMode & 16)
printf ("Error Information, ");
if (msgMode & 32)
printf ("Temporary Display, ");
if (msgMode & 64)
printf ("Temporary Information, ");
if (msgMode & 128)
printf ("Empty, ");
printf ("message: %s\n", cmd);
T32_Exit();
return result;
error:
printf( "error accessing TRACE32 [#%x]\n", rc);
T32_Exit();
return RESULT_NOACCESS;
}