New 'labman' tool

Simon Glass sjg at
Tue Apr 21 19:24:46 CEST 2020

Hi Stefano,

On Mon, 20 Apr 2020 at 02:47, Stefano Babic <sbabic at> wrote:
> Hi Simon,
> On 19.04.20 20:31, Simon Glass wrote:
> > Hi,
> >
> > I have been fiddling with setting up a lab and have found it quite a
> > pain. Lots of USB connections and things sometimes break.
> >
> > The collection of pytest, udev and tbot scripts that I end up with is
> > hard to manage and error-prone. I decided that I really wanted a
> > central database to keep control of this.
> >
> > Hubs are a pain because their internal numbering does not always
> > correspond to their visible port numbers.
> >
> > Also when something goes wrong with a component in the lab, it is hard
> > to know which one is broken and which port it is on.
> >
> > So I have started something called labman to help with this. It can
> > generate simple tbot scripts, check that all components are working
> > and help with simple management tasks.
> >
> > Please see the README and let me know what you think.
> >
> >
> >
> Thanks to share this - I will check this in my environment. Anyway, we
> are fighting with same problems, and Wolfgang has exposed an alternative
> way to do this. So I take the occasion because I have a different way,
> too, and I would like to share - I am also not very fond of WiFI actors
> in my network, and I mostly work with USB serial adapter.
> My way is to use a Raspi as terminal server with "ser2net". Because
> ttyUSB changes at each boot, I decided to detect which is the new ttyUSB
> instead of trying to force it via udev rule - let's say, if you cannot
> fight them, join them !
> I built an Image for Raspberry based on OE
> (github/sbabic/meta-swupdate-boards), the image contains:
> - ser2net
> - python3
> - openOCD for JTAG over Ethernet
> - Lua
> - a tool to driver a Lab PowerSupply (Power / Power off)
> I wrote a small Python daemon that returns the mapping between target
> and tty. In fact, if the ttyUSBX changes, the topology is always the
> same. A target "X" that is connected to port 4 of second Hub will always
> be connected to that port.
> The small daemon checks in a file-database as "target" <--> "topology" like:
> wandboard       usb     usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0
> mira            usb     usb1/1-1/1-1.2/1-1.2.4/1-1.2.4:1.0
> target1         usb     usb1/1-1/1-1.2/1-1.2.7/1-1.2.7:1.0
> target2         usb     usb1/1-1/1-1.2/1-1.2.2/1-1.2.2:1.0
> target3         usb     usb1/1-1/1-1.2/1-1.2.6/1-1.2.6:1.0
> target4         usb     usb1/1-1/1-1.2/1-1.2.5/1-1.2.5:1.0
> On tbot lab host, I have then just a simple script "connect":
> !/bin/bash
> if [ "x$2" != "x" ];then
>         SERVERS=$2
> fi
> PORT=5005
> for server in ${SERVERS};do
>         target=`echo $1 | nc ${server} ${PORT}`
>         echo TARGET $target
>         tserver=`echo $target| awk -F':'  '{print $1}'`
>         port=`echo $target | awk -F':' '{print $2}'`
>         if [ ! -z $port ];then
>                 telnet ${tserver} ${port}
>                 exit 0
>         fi
> done
> echo "Target not found" $1
> And at the end, this simplifies my board setup in tbot, because I have
> the same way to connect to the board:
>     def connect(self, mach):
>         return mach.open_channel("connect",

Thanks for this.

I am actually a big fan of ser2net.

I've added support for 'servo' in labman, which is a little (USB!)
board which provides serial, reset, Ethernet, etc. It seems to me that
having a rpi could do a similar thing for other boards, and be on
Ethernet which is nicer. If it could handle SDwire too that would be

Yet another thing for me to try!

I 'deployed' two more boards last night, like this:

1. Plug in the device, with USB serial, SDwire, power on the DLI.
2. Find the new connections:

$ labman -D -l tools/labman/kea_lab.yaml -r kea scan
2 new part(s) found
            Hub  Port   Part          Description
           huba  3      uart          ttyUSB12
           huba  4      sdwire        sdwireda3

(it can't detect that I plugged the power cable into a YKUSB board port 2)

3. Updated the yaml a bit:
  sdwire10: &sdwire10
    serial: sdwireda3
    symlink: sdwire10
    hub-port: *huba_4
    block-symlink: sdcard6

  usbport15: &ttyusb_port15
    type: usb-uart
    symlink: ttyusb_port15
    hub-port: *hubb_13

    desc: Banana Pi
    console: *ttyusb_port15
    bootdev: *sdwire11
    power: *ykush1_port2
      method: sunxi
        target: Bananapi
        toolchain: armv7-a

4. 'labman emit' to write out the udev and tbot scripts
5. 'labman check' to make sure everything is working

It is so much easier than before. I did two boards in about 40mins,
including getting the UART wrong on one.

$ tbot -l -b interactive_board
tbot starting ...
├─Calling interactive_board ...
│   ├─POWERON (bpi)
│   ├─Entering interactive shell (CTRL+D to exit) ...

U-Boot SPL 2015.07-rc1-00527-ge08ac7c (Jun 06 2015 - 22:08:16)
DRAM: 1024 MiB
CPU: 912000000Hz, AXI/AHB/APB: 3/2/2

U-Boot 2015.07-rc1-00527-ge08ac7c (Jun 06 2015 - 22:08:16 -0600)
Allwinner Technology

CPU:   Allwinner A20 (SUN7I)
I2C:   ready
DRAM:  1 GiB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
SATA link 0 timeout.
AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
flags: ncq stag pm led clo only pmp pio slum part ccc apst
Net:   PH: dir_output: error: gpio PH23 not reserved
Phy 1 not found
PHY reset timed out
eth0: ethernet at 01c50000
starting USB...
USB0:   USB EHCI 1.00
USB1:   USB OHCI 1.0
USB2:   USB EHCI 1.00
USB3:   USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
Hit any key to stop autoboot:  0
│   ├─POWEROFF (bpi)
│   └─Done. (5.821s)
└─SUCCESS (5.958s)


More information about the tbot mailing list