0

I need to debug a serial protocol between two embedded microcontrollers.

Between them there's a serial line compatible with my FT2232h mini-module.

Situation is very similar to what described in this question except:

  • lines are driven at 3.3V (not 5V).
  • development station is running Linux (not windows).
  • I have lower timing requirements (more-or-less I care only about actual sequence and very large delays).
  • Baud-rate is "standard" 115200.

I could write my own monitor program, but I'm very surprised my search did not give results.

---delete---Can someone suggest which (possibly free) project can help me?---

UPDATE: I didn't find anything suitable, so I started writing a simple monitor in python (current source below). This more-or-less works, but it still seem to buffer chars so that a sequence like:

  • rqst1 -->
  • <-- ack1
  • rqst2 -->
  • <-- ack2

MIGHT end up written as:

I do not know if buffering is done at FT2232H, USB, Linux driver or Python level (possibly at several levels!).

Is there any way I can force "no buffering" in the code below? (before I start to rewriting the whole crap in plain C for speed).

#!/usr/bin/python3

import serial, time, sys, threading
from colorama import Fore, Style, init as colorama_init
from binascii import hexlify

colorama_init()

# lock to serialize console output
lock = threading.Lock()


class Highlight:
    def __init__(self, clazz, color):
        self.color = color
        self.clazz = clazz

    def __enter__(self):
        print(self.color, end="")

    def __exit__(self, type, value, traceback):
        if self.clazz == Fore:
            print(Fore.RESET, end="")
        else:
            assert self.clazz == Style
            print(Style.RESET_ALL, end="")
        sys.stdout.flush()


if len(sys.argv) != 3 and len(sys.argv) != 4:
    sys.stderr.write("Usage: %s <baud> <port1> [<port2>]\n" % (sys.argv[0]))
    exit(1)


def open_serial(port, baud):
    ser = serial.Serial()
    ser.port = port

    ser.baudrate = baud
    ser.bytesize = serial.EIGHTBITS  # number of bits per bytes
    ser.parity = serial.PARITY_NONE  # set parity check: no parity
    ser.stopbits = serial.STOPBITS_ONE  # number of stop bits
    # ser.timeout = None          #block read
    ser.timeout = 0  # non blocking read
    ser.xonxoff = False  # disable software flow control
    ser.rtscts = False  # disable hardware (RTS/CTS) flow control
    ser.dsrdtr = False  # disable hardware (DSR/DTR) flow control
    ser.writeTimeout = 2  # timeout for write

    try:
        ser.open()
    except Exception as e:
        print("error open serial port: " + str(e))
        exit()
    return ser


def sprint(c, color):
    if len(c) > 0:
        print(color)
        h = hexlify(c)
        h += b' ' * (120 - len(h))
        s = bytes(x if 31 < x < 128 else 46 for x in c)
        with lock:
            sys.stdout.buffer.write(h)
            sys.stdout.buffer.write(s)
            sys.stdout.flush()


s1 = open_serial(sys.argv[2], sys.argv[1])
s2 = open_serial(sys.argv[3], sys.argv[1])

running = True
try:
    while running:
        n = s1.in_waiting
        if n > 0:
            c = s1.read(n)
            sprint(c, Fore.CYAN)
        n = s2.in_waiting
        if n > 0:
            c = s2.read(n)
            sprint(c, Fore.GREEN)

except Exception as e1:
    print("error communicating...: " + str(e1))
    s1.close()
    s2.close()

except KeyboardInterrupt:
    exit()
ZioByte
  • 2,690
  • 1
  • 32
  • 68

1 Answers1

0

Use strace, a system utitlity to trace system calls and signals:

how should I use strace to snif the serial port?

or:

jpnevulator

I find the latter simpler to use as you just need to issue a command like:

jpnevulator --ascii --timing-print --tty /dev/ttyS0:SB115200d

to debug your port.

Should you need to implement a more complex debugging tool you could start forking its source code on github:

snarlistic/jpnevulator

luigif
  • 544
  • 4
  • 8