Search code examples
trace32lauterbach

How to wait for t32rem DO script to complete?


It seems that doing t32rem localhost DO script.cmm is non-blocking. How can I block in a shell script until the cmm script is done?

Here is an abbreviated example:

$ time t32rem localhost wait 5s
real    0m5.048s

$ cat wait-5s.cmm 
WAIT 5s
ENDDO    
$ time t32rem localhost do wait-5s
real    0m0.225s

I can try to do some sort of t32rem localhost wait STATE.RUN() based on whatever the exact script is doing but this is not a very good solution.

Reading through api_remote.pdf it does note that T32_Cmd for DO is non-blocking and recommends polling using T32_GetPractice but it's not clear how to translate this to t32rem.


Solution

  • In my opinion you questions is a rather good one.

    First the bummer: t32rem is not suitable to wait for the execution of a script. In fact t32rem cancels any running script before executing a command with T32_Stop(). (You can find the source code of t32rem in your TRACE32 installation at "C:\T32\demo\api\capi\test\t32rem.c")

    So your suggestion to use t32rem localhost wait STATE.RUN() will definitely not work because it would cancel the running script. Furthermore STATE.RUN()returns the running state of the debugged CPU and not of the PRACTICE interpreter.

    So in fact you have to use T32_GetPractice() to wait for the PRACTICE script to terminate. To use T32_GetPractice() you either have to link statically or dynamically the "API for Remote Control and JTAG Access in C" to an application that launches your script.

    For dynamic linking (e.g. from a Python script) load "C:\T32\demo\api\capi\dll\t32api.dll". (Depending on your host operation system you might need t32api64.dll, t32api.so, or t32api64.so instead.)

    For static linking (e.g. from a binary application written in C) add the files from "C:\T32\demo\api\capi\src" to your project.

    And here is the code to write a command line application t32do, which starts a PRACTICE script and waits until the script terminates:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include "t32.h"
    
    int main(int argc, char *argv[])
    {
        int         pstate;
        const char *script;
    
        if (argc == 4  &&  !strncmp(argv[2],"port=", 5)) {
            if ( T32_Config( "PORT=", argv[2]+5 ) == -1 ) {
                printf("Port number %s not accepted\n", argv[2] );
                exit(2);
            }
            script = argv[3];
        } else {
            if (argc != 3) {
                printf( "Usage: t32do <host> [port=<n>] <script>\n" );
                exit(2);
            }
            script = argv[2];
        }
        if ( T32_Config( "NODE=", argv[1] ) == -1 ) {
            printf( "Hostname %s not accepted\n", argv[1] );
            exit(2);
        }
        if ( T32_Init() != 0 ||  T32_Attach(1) != 0){
            printf( "Failed to connect to TRACE32\n" );
            exit(2);
        }
    
        if ( T32_Cmd_f("DO \"%s\"", script) != 0 ){   // Launch PRACTICE script
            printf( "Failed to start PRACTICE script\n" );
            T32_Exit();
            exit(1);
        }
        while (T32_GetPracticeState(&pstate) == 0  &&  pstate != 0){   // Wait until PRACTICE script terminates 
            usleep(10000);
        }
        T32_Exit();
        return 0;
    }
    

    Put the source in a file named t32do.c in "C:\T32\demo\api\capi\src" and build the application with the following makefile, which works on both Windows (by using the MinGW compiler of Cygwin) and Linux:

    BIN   := t32do
    OBJ   := t32do.o hremote.o hlinknet.o
    
    OS := $(shell uname -s)
    
    ifneq ($(findstring CYGWIN,$(OS)),)
    CC    := x86_64-w64-mingw32-gcc
    LOPT  := -lws2_32
    COPT  := -DT32HOST_LE
    endif
    
    ifneq ($(findstring Linux,$(OS)),)
    CC    := gcc
    COPT  := -DT32HOST_LE
    endif
    
    all: $(BIN)
    
    $(BIN): $(OBJ)
        $(CC) $^ -s -o $@  $(LOPT)
    
    %.o: %.c t32.h
        $(CC) -c $(COPT) -o $@  $<
    
    clean:
        -rm $(OBJ) $(BIN)
    

    If it compiles and links fine, you'll get an application t32do.exe. Use it in the form: t32do <host> [port=<n>] <practice script>

    My example code above is licensed under Creative Commons Zero 1.0. Use it any way you wish, in any code you want.