Commit eef93632 authored by Maciej Lipinski's avatar Maciej Lipinski

Merge branch 'proposed_master' into 'master'

Tests: docker & compilation

See merge request !1
parents e6fbc7b4 dfee04e2
# .gitignore file
xcompiler/*
# OS generated files #
######################
*.bak
......
[submodule "spec-sw"]
path = spec-sw
url = git://ohwr.org/fmc-projects/spec/spec-sw.git
[submodule "etherbone"]
path = etherbone
url = git://ohwr.org/hdl-core-lib/etherbone-core.git
url = https://ohwr.org/project/spec-sw.git
[submodule "wr-nic"]
path = wr-nic
url = https://ohwr.org/project/wr-nic.git
[submodule "fmc-dio"]
path = fmc-dio
url = https://ohwr.org/project/fmc-dio-5chttla.git
[submodule "wrpc-sw"]
path = wrpc-sw
url = https://ohwr.org/project/wrpc-sw.git
[submodule "coht-vic"]
path = coht-vic
url = https://gitlab.cern.ch/cohtdrivers/coht-vic.git
......@@ -14,30 +14,40 @@
## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
########################################################################
SUBMOD_DIRS=spec-sw etherbone
MAKE_DIRS = spec-sw etherbone/api #tools
SUBMOD_DIRS=spec-sw wr-nic fmc-dio coht-vic
MAKE_DIRS = spec-sw wr-nic fmc-dio coht-vic #tools
#RUNME := $(shell test -d $(FMC_DRV) || git submodule update --init)
LM32_XCOMPILER_URL="https://www.ohwr.org/project/wrpc-sw/uploads/2776ce0ba43503d1486ae205b48fb450"
LM32_XCOMPILER_NAME="lm32_host_64bit.tar.xz"
XCOMPILER_DIR="xcompiler"
LM32_XCOMPILER_NAME_DIR="lm32-gcc-4.5.3"
#RUNME := $(shell test -d $(FMC_DRV) || git submodule update --init)
## Call the sub folder Makefiles
all clean install: init
@for d in $(MAKE_DIRS); do $(MAKE) -C $$d $@ || exit 1; done
@if [ "x$@" = "xinstall" ]; then ./scripts/wr-ssk-get -i; fi
@if [ "x$@" = "xinstall" ]; then ./scripts/wr-ssk-get -i; cp wrpc-sw/tools/wrpc-vuart /usr/local/sbin; fi
## Init repo and create the .INIT file to not do it again
init: .INIT
.INIT:
git submodule init
.INIT:
git submodule init
@ $(MAKE) update
@ $(MAKE) patch
@touch .INIT; \
patch:
./scripts/wr-git-patch
## Force updating the submodules and fetch new gateware
update:
./scripts/wr-ssk-get -f
git submodule update
cd spec-sw
git submodule update
@rm -rf $(XCOMPILER_DIR)
mkdir -p $(XCOMPILER_DIR)
cd $(XCOMPILER_DIR) && wget $(LM32_XCOMPILER_URL)/$(LM32_XCOMPILER_NAME) \
&& tar xvf $(LM32_XCOMPILER_NAME)
cd wrpc-sw && make spec_defconfig && \
CROSS_COMPILE="$(shell pwd)/$(XCOMPILER_DIR)/$(LM32_XCOMPILER_NAME_DIR)/bin/lm32-elf-" make
coht-vic @ b4431e73
Subproject commit b4431e739bbc5a4ed1701ab7f4a372fbb4f33cf8
......@@ -23,8 +23,8 @@ PDF=$(addprefix pdf/, $(SRC:.md=.pdf))
TEX=$(SRC:.md=.tex)
## Pandoc arguments
OPTIONS=-f markdown --toc --number-sections --smart
TEMPLATE=pandoc.latex
OPTIONS?=-s --from markdown+yaml_metadata_block --toc --number-sections --smart
TEMPLATE=pandoc.latex
ifneq "$(TEMPLATE)" ""
......@@ -42,11 +42,19 @@ DATE = $(shell date +"%d %b. %Y")
all: $(PDF)
tex: $(TEX)
pdf: $(PDF)
verbose:
make OPTIONS="-s --from markdown+yaml_metadata_block --toc --number-sections --smart --verbose" -C . pdf
## Special targets to create directory
DIR_%:
mkdir -p $(subst DIR_,,$@)
pdf/wr-starting-kit.pdf: wr-starting-kit.md Makefile $(TEMPLATE) DIR_pdf
pandoc $(OPTIONS) --latex-engine=xelatex --listings --highlight-style=haddock $(TEMPLATEARG) \
-V title="WR Starting Kit" -V subtitle="User Guide" -V author="Seven Solutions" \
-V lang=english -V fontsize=11pt -V documentclass=article -V bg-color=238,245,240 -V date="$(DATE) - $(VERSION)" -o $@ $<
pdf/%.pdf: %.md Makefile $(TEMPLATE) DIR_pdf
pandoc $(OPTIONS) --latex-engine=xelatex --listings --highlight-style=haddock $(TEMPLATEARG) \
-V lang=english -V fontsize=11pt -V documentclass=article -V bg-color=238,245,240 -V date="$(DATE) - $(VERSION)" -o $@ $<
......
---
title: 'Generate WR Starting Kit Documentation'
subtitle: "How to generate starting kit pdf from markdown using pandoc"
author: Seven Solutions
...
Intro
==========
The document has been written in markdown format and can be directly
read from github, gitlab or bitbucket
PDF Generation
===============
You might need to install `pandoc` software to generate `.pdf` from `.md`.
sudo apt-get install pandoc
To generate a specific document you should enter its own directory and execute
make
If you have some Latex compilation error please install the following packages
sudo apt-get install texlive texlive-latex-extra
### pandoc.latex
The file pandoc.latex is a latex template in order to add all special latex customization
to the markdown file. In case some of latex package are not working properly, the user
should try to modify this file.
Syntax
===========
> ***NOTES:*** The syntax used in this document is Markdown. We recommand to follow the strict
markdown syntax explained on [bitbucket](https://bitbucket.org/tutorials/markdowndemo).
Misc
======
Dirty tags
--------------
During compilation of `fmc-bus` kernel, the Make generated files that should be .gitignore.
If you want to clean the tags of the repos you can use the following command to manually clean
everything:
~~~~~{.bash}
### Find dirty files:
git submodule foreach --recursive git status
### Remove them
find ./ -wholename "*fmc-bus/kernel/.cache.mk" -delete
find ./ -wholename "*fmc-bus/kernel/fmc-chardev.o.ur-safe" -delete
~~~~~~~~
doc/img/ssk_ txpps.png

61.2 KB | W: | H:

doc/img/ssk_ txpps.png

90.5 KB | W: | H:

doc/img/ssk_ txpps.png
doc/img/ssk_ txpps.png
doc/img/ssk_ txpps.png
doc/img/ssk_ txpps.png
  • 2-up
  • Swipe
  • Onion skin
doc/img/ssk_100Hz.png

191 KB | W: | H:

doc/img/ssk_100Hz.png

140 KB | W: | H:

doc/img/ssk_100Hz.png
doc/img/ssk_100Hz.png
doc/img/ssk_100Hz.png
doc/img/ssk_100Hz.png
  • 2-up
  • Swipe
  • Onion skin
File mode changed from 100755 to 100644
doc/img/ssk_configs.png

72.8 KB | W: | H:

doc/img/ssk_configs.png

40.4 KB | W: | H:

doc/img/ssk_configs.png
doc/img/ssk_configs.png
doc/img/ssk_configs.png
doc/img/ssk_configs.png
  • 2-up
  • Swipe
  • Onion skin
doc/img/ssk_inside.jpg

460 KB | W: | H:

doc/img/ssk_inside.jpg

384 KB | W: | H:

doc/img/ssk_inside.jpg
doc/img/ssk_inside.jpg
doc/img/ssk_inside.jpg
doc/img/ssk_inside.jpg
  • 2-up
  • Swipe
  • Onion skin
File mode changed from 100755 to 100644
doc/img/ssk_playdio.png

15.9 KB | W: | H:

doc/img/ssk_playdio.png

41.4 KB | W: | H:

doc/img/ssk_playdio.png
doc/img/ssk_playdio.png
doc/img/ssk_playdio.png
doc/img/ssk_playdio.png
  • 2-up
  • Swipe
  • Onion skin
doc/img/ssk_pps-setup.png

34.8 KB | W: | H:

doc/img/ssk_pps-setup.png

67 KB | W: | H:

doc/img/ssk_pps-setup.png
doc/img/ssk_pps-setup.png
doc/img/ssk_pps-setup.png
doc/img/ssk_pps-setup.png
  • 2-up
  • Swipe
  • Onion skin
doc/img/ssk_sfp.jpg

351 KB | W: | H:

doc/img/ssk_sfp.jpg

285 KB | W: | H:

doc/img/ssk_sfp.jpg
doc/img/ssk_sfp.jpg
doc/img/ssk_sfp.jpg
doc/img/ssk_sfp.jpg
  • 2-up
  • Swipe
  • Onion skin
File mode changed from 100755 to 100644
This diff is collapsed.
This diff is collapsed.
etherbone @ d1b6b4bd
Subproject commit d1b6b4bd5b1fff8d50adc02665348814c40bb536
Subproject commit eea7bfc82e4cb3554d4343d93dfa75773d7b2fc2
Folder to places patches to apply before compiling the starting kit.
If empty calling this folder will do nothing
#! /bin/bash
# ******************************************************************************
# @file eb-mem.sh
# @brief Script to use easy Etherbone tools
#
# Copyright (C) 2013
#
# Memory access with Etherbone tools
#
# @author Miguel Jimenez Lopez <klyone@ugr.es>
#
# @bug none!
#
# ******************************************************************************
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http//www.gnu.org/licenses/>.
# ******************************************************************************
print_help() {
echo ""
echo "############################################################################"
echo ""
echo "Command: eb-mem <options>"
echo ""
echo "--read|-r: Perform a read operation. It needs a IP and memory address."
echo "--write|-w: Perform a write operation. It needs a IP, memory address and value."
echo "--scan|-s: Perform a scan operation. It needs a IP address."
echo "--compact|-c: Use compact format. Perform a read or write operation depending on arguments"
echo "--tcp|-t: Use TCP packets to communication."
echo "--udp|-u: Use UDP packets to communication."
echo "--bytes|-b: Indicates n-bytes alignment of memory."
echo "--ip|-i: Device IP address."
echo "--port|-p: Use a determinate port."
echo "--address|-a: Device address to read/write access."
echo "--value|-v: Value to write into device."
echo "--help|-h: Show this help."
echo ""
echo "NOTE: This script does not try to implement all options of Etherbone tools."
echo "If you want to execute these operations with other options, you must use "
echo "original tools developped by Etherbone team!!"
echo ""
echo "Examples:"
echo ""
echo "eb-mem --scan --ip 10.10.10.10"
echo "eb-mem --read --ip 10.10.10.10 --address 0x64233"
echo "eb-mem --write --ip 10.10.10.10 --address 0x64233 --value 0x123"
echo "(COMPACT READ) => eb-mem --compact --ip 10.10.10.10 --address 0x64233"
echo "(COMPACT WRITE) => eb-mem --compact --ip 10.10.10.10 --address 0x64233 --value 0x124"
echo ""
echo "############################################################################"
echo ""
}
nargs=$#
EB_TOOLS=${EB_TOOLS-../etherbone/api/tools}
n=0
mode='none'
t_transport='udp'
bytes=4
port=''
ip='none'
address='none'
value='none'
while (($n < $nargs)) ;
do
arg=$1
case $arg in
--read|-r) mode='read'; ;;
--write|-w) mode='write' ;;
--scan|-s) mode='scan' ;;
--compact|-c) mode='compact' ;;
--tcp|-t) t_transport='tcp' ;;
--udp|-u) t_transport='udp' ;;
--bytes|-b) shift; bytes=$1 ;;
--ip|-i) shift; ip=$1 ;;
--port|-p) shift; port="/$1";;
--address|-a) shift; address=$1 ;;
--value|-v) shift; value=$1 ;;
--help|-h) print_help ; exit 0;;
esac
n=$n+1
shift
done
if [ "$mode" = 'none' ];
then
echo "You must get access mode: --scan|--read|--write"
exit -1
fi
if [ "$ip" = 'none' ];
then
echo "You must get IP address to connect with Etherbone core"
exit -1
fi
case $mode in
scan) $EB_TOOLS/eb-ls $t_transport/$ip$port;;
read) if [ "$address" = 'none' ];
then
echo "You must get memory address in read operation"
exit -1
fi
$EB_TOOLS/eb-read $t_transport/$ip$port $address/$bytes
;;
write) if [ "$address" = 'none' ];
then
echo "You must get memory address in write operation"
exit -1
fi
if [ "$value" = 'none' ];
then
echo "You must get value in write operation"
exit -1
fi
$EB_TOOLS/eb-write $t_transport/$ip$port $address/$bytes $value
;;
compact) if [ "$address" = 'none' ];
then
echo "You must get memory address in read or write operation"
exit -1
fi
if [ "$value" = 'none' ];
then
$EB_TOOLS/eb-read $t_transport/$ip$port $address/$bytes
else
$EB_TOOLS/eb-write $t_transport/$ip$port $address/$bytes $value
fi
esac
#!/bin/dash
## Script to apply git patches for submodules.
##
## Authors:
## - Miguel Jimenez Lopez (Seven Solutions, www.sevensols.com)
##
## GNU Lesser General Public License Usage
## This file may be used under the terms of the GNU Lesser
## General Public License version 2.1 as published by the Free Software
## Foundation and appearing in the file LICENSE.LGPL included in the
## packaging of this file. Please review the following information to
## ensure the GNU Lesser General Public License version 2.1 requirements
## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
#######################################################################################################
### Show help of the function
help ()
{
cat << EOF
Usage: $(basename $0) [Options]
Options:
-h|--help) Show this little help
EOF
exit 0
}
#################################################
### Main execution
GIT_REPOS="spec-sw wrpc-sw wr-nic fmc-dio coht-vic"
MAIN_DIR=".."
PATCHES_DIR="patches"
# setup script dir
sdir=$(dirname $0)
cd $sdir
sdir=$(pwd)
while [ $# -gt 0 ]; do # Until you run out of parameters . . .
case "$1" in
-h|--help) help;;
*) help;;
esac
shift # Check next set of parameters.
done
for i in $GIT_REPOS
do
if [ -e "$sdir/$MAIN_DIR/$PATCHES_DIR/$i" ] ; then
echo "Patching $i submodule"
cd "$sdir/$MAIN_DIR/$i"
git am $sdir/$MAIN_DIR/$PATCHES_DIR/$i/*.patch
cd "$sdir"
fi
done
......@@ -106,7 +106,11 @@ insthdl()
if [ ! -d ${installdir} ]; then
sudo mkdir -p ${installdir}
fi
sudo cp -v ${DOWNLOADDIR}/spec-init.bin ${DOWNLOADDIR}/wr_nic_dio.bin ${installdir}
sudo cp -v ${DOWNLOADDIR}/spec-init.bin \
${DOWNLOADDIR}/wr_nic_dio.bin \
${DOWNLOADDIR}/wr_nic.bin \
${DOWNLOADDIR}/wr_nic_lm32_sw.bin \
${installdir}
wr_echoret $? "OK" "ERROR"
checkdrv;
......@@ -290,7 +294,7 @@ exit 0
# setup script dir
scriptdir=$(cd $(dirname $0); pwd)
DOWNLOADDIR=${scriptdir}/../firmware
PKGURL="http://www.ohwr.org/attachments/download/2744/wr-starting-kit-v2.0_gw.tar.gz 9e48bbe6c30b18864ecddceb7627e6e9"
PKGURL="https://ohwr.org/project/wr-starting-kit/wikis/uploads/b63d12f90cd0dbb89b78587603fdcfe6/wr-starting-kit-v3.0_bin.tar.gz"
while [ $# -gt 0 ]; do # Until you run out of parameters . . .
case "$1" in
......
Subproject commit eb9b9d03e3f54657fe29fca93021e2b45380da05
Subproject commit e76f5ca3bcda171318757b603abca131712d086e
# .gitignore file
# configuration file #
######################
configuration.cfg
Tests for WR-starting-kit.
This folder contains test files, documentation file and docker deployment files.
The folders are structured as following:
* `doc`: File documentation.
* `dockers`: Files Dockerfile to deploy WR-starting-kit in differents SO and kernerls.
* `validation`: Python files for tests.
\ No newline at end of file
Dokerfiles to deployment test
==========================
To build image
----------
You need to move to UbuntuXX folder and execute:
sudo docker build -t <name image> .
To run image
----------
You need to execute:
sudo docker run -it <name image>
Show images
----------
sudo docker images
Remove image
----------
sudo docker rmi -f <IMAGE ID>
\ No newline at end of file
# spec-sw Dockerfile ubuntu 16.04
#
#
# Pull base image.
FROM ubuntu:16.04
# Install.
RUN \
apt-get update &&\
apt-get upgrade -y &&\
apt-get install -y git \
build-essential \
python-minimal \
wget \
libreadline-dev \
kmod \
linux-headers-4.4.0-21-generic \
linux-headers-4.8.0-34-generic \
linux-headers-4.10.0-14-generic \
linux-headers-4.13.0-16-generic \
linux-headers-4.15.0-13-generic
# Clone repository and detach HEAD
RUN \
git clone https://ohwr.org/project/wr-starting-kit.git &&\
cd wr-starting-kit &&\
# TODO: preliminary commit for wr-starting-kit-v3.0
git checkout 50f368abff0d4aed8223858f552b3184249695d2
# The kernel version 4.4.0-21-generic does not work
#set enviroment variable for kernel version 4.8.0-34-generic
ENV LINUX /lib/modules/4.8.0-34-generic/build
#construction spec-sw for kernel version 4.8.0-34-generic
RUN \
cd wr-starting-kit &&\
make clean &&\
make &&\
make install
#set enviroment variable for kernel version 4.10.0-14-generic
ENV LINUX /lib/modules/4.10.0-14-generic/build
#construction spec-sw for kernel version 4.10.0-14-generic
RUN \
cd wr-starting-kit &&\
make clean &&\
make &&\
make install
#set enviroment variable for kernel version 4.13.0-16-generic
ENV LINUX /lib/modules/4.13.0-16-generic/build
#construction spec-sw for kernel version 4.13.0-16-generic
RUN \
cd wr-starting-kit &&\
make clean &&\
make &&\
make install
#set enviroment variable for kernel version 4.15.0-13-generic
ENV LINUX /lib/modules/4.15.0-13-generic/build
#construction spec-sw for kernel version 4.15.0-13-generic
RUN \
cd wr-starting-kit &&\
make clean &&\
make &&\
make install
#create file FRU
RUN \
cd /wr-starting-kit/spec-sw/fmc-bus/tools &&\
FRU_VENDOR="CERN" FRU_NAME="FmcDio5cha" FRU_PART="EDA-02408-V2-0" \
./fru-generator -s 7S-WR-FMCDIO5ch-2.0-Sx.yyy > example.bin
# Define default command.
CMD ["bash"]
#
# spec-sw Dockerfile ubuntu 18.04
#
#
# Pull base image.
FROM ubuntu:18.04
# Install.
RUN \
apt-get update &&\
apt-get upgrade -y &&\
apt-get install -y git \
build-essential \
python-minimal \
wget \
libreadline-dev \
kmod \
linux-headers-4.15.0-47-generic \
linux-headers-4.18.0-17-generic
# Clone repository and detach HEAD
RUN \
git clone https://ohwr.org/project/wr-starting-kit.git &&\
cd wr-starting-kit &&\
# TODO: preliminary commit for wr-starting-kit-v3.0
git checkout 50f368abff0d4aed8223858f552b3184249695d2
#set enviroment variable for kernel version 4.15.0-47-generic
ENV LINUX /lib/modules/4.15.0-47-generic/build
#construction spec-sw for kerner version 4.15.0-47-generic
RUN \
cd wr-starting-kit &&\
make &&\
make install
#set enviroment variable for kernel version 4.18.0-17-generic
ENV LINUX /lib/modules/4.18.0-17-generic/build
#construction spec-sw for kernel version 4.18.0-17-generic
RUN \
cd wr-starting-kit &&\
make clean &&\
make &&\
make install
#create file FRU
RUN \
cd /wr-starting-kit/spec-sw/fmc-bus/tools &&\
FRU_VENDOR="CERN" FRU_NAME="FmcDio5cha" FRU_PART="EDA-02408-V2-0" \
./fru-generator -s 7S-WR-FMCDIO5ch-2.0-Sx.yyy > example.bin
# Define default command.
CMD ["bash"]
The files in this folder are the following:
* `dio.py`: Class to interact with the ports of the board.
* `loadDriver.py`: Load the driver on the PC.
* `sample.cfg`: Sample configuration file of the tests, to execute the tests must be modified the parameters and renamed the file to `configuration.cfg`.
* `ssh.py`: Class used to execute commands by SSH.
* `testAdvDIO.py`: Verifies the correct reception and sending of packages.
* `testAll.py`: Execute all tests.
* `testDIO.py`: Check all ports of the boards.
* `testNIC.py`: Verifies the correct operation of the Network Interface Core.
* `testWR.py`: Check the correct operation of White Rabbit.
* `vuart.py`: Class to execute commands by virtual uart.
# @file dio.py
#
# @brief This class is to interact with the ports of the board
#
# @author Manuel Castilla
# @date 23/04/2019
#
###########################################################################
from ssh import SshCmd,SshCmdException
## Class DIO
#
class DIO ():
def __init__(self,hostName,userName,password,busId):
"""
Construcctor
Args:
hostName: ip or hostname
userName: username
password : password
busId: number PCIe bus
"""
self.hostName = hostName
self.userName = userName
self.password = password
self.busId = busId
self.command = "sudo wr-dio-cmd /dev/fmc-dio-%i:0" % int(busId,16)
self.sshCmd = SshCmd()
def configurePort(self,channel,mode):
"""
Configure the channel
Args:
channel: number 0 to 4
mode: I/i(Input), 0/1(Output, steady state fixed at 0 low or 1 high),D/d(DIO core output),
P/p(Channel 0 Output PPS),C/c(Channel 4 Clock Input to PTP core)
Raises:
error function
"""
try:
confCommand = self.command + " mode " + str(channel) + " " + mode
self.execCommand(confCommand)
except:
print("Error configure port, channel:",channel,"mode:",mode)
raise
def configurePorts(self,modechannels):
"""
Configure all channels
Args:
modechannels: <modech0><modech1><modech2><modech3><modech4>
Raises:
error function
"""
try:
confCommand = self.command + " mode " + modechannels
self.execCommand(confCommand)
except:
print("Error configure ports, mode channels:",modechannels)
raise
def armPulse(self,channel,period,count):
"""
generate a pulse in a channel
Args:
channel: number 0 to 4
period: pulse period
count: string whih number of instances to run
Raises:
error function
"""
try:
armCommand = self.command + " pulse " + str(channel) + " " + str(period) + " " + count
self.execCommand(armCommand)
except:
print("Error arm pulse, channel:",channel,"period:",period,"count:",count)
raise
def getTimestamp(self,channel):
"""
Get timestamp of channel
Args:
channel: number 0 to 4
Raises:
error function
"""
try:
ret = []
getCommand = self.command + " stamp " + str(channel) + " | cut -f2 -d ,"
stamp = self.execCommand(getCommand)
stampSplit = stamp.split()
for i in stampSplit:
ret.append(float(i))
return ret
except:
print("Error get timestamp, channel:",channel)
raise
def clearTimestamps(self):
"""
Clear all timestamps
Raises:
error function
"""
try:
command = self.command + " stamp &> /dev/null"
self.execCommand(command)
except:
print("Error clear timestamps")
raise
def execCommand(self,command):
"""
Execute a command
Args:
command: command to execute
Raises:
error function
"""
try:
return self.sshCmd.exec(self.hostName,command,self.userName,self.password)
except SshCmdException as e:
self.sshCmd.printSshErrorCommand(e.strError) #print error command
cleanup()
raise
#!/usr/bin/env python3
# @file loadDriver.py
#
# @brief Load the driver on the PC
#
# @author Manuel Castilla
# @date 16/04/2019
#
###########################################################################
from ssh import SshCmd,SshCmdException
import sys
import getpass
error = -1
def loadDriver(hostName,userName,password):
"""
This function load the driver on the PC
Args:
hostName: ip remote host
username: user name
password: password
Return:
True if the driver was loaded correctly, False otherwise
"""
ret = 0
try:
sshCmd = SshCmd()
command = "ifconfig | grep wr | wc -l"
value = sshCmd.exec(hostName,command,userName,password)
if (int(value) == 0):
commands = ["sudo modprobe spec","sudo modprobe htvic",
"sudo modprobe wr-nic","sudo modprobe wr-dio"]
for cmd in commands:
sshCmd.exec(hostName,cmd,userName,password)
command = "ifconfig | grep wr | wc -l"
value = sshCmd.exec(hostName,command,userName,password)
if (int(value) == 0):
ret = error
else:
print("The driver was previously loaded")
except SshCmdException as e:
sshCmd.printSshErrorCommand(e.strError)
ret = error
return ret
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
if len(sys.argv) < 2:
print("usage: app hostaname")
sys.exit(1)
hostName = sys.argv[1]
userName = input("Please enter username: ")
#password = getpass("Please enter password: ")
password = getpass.getpass()
if (loadDriver(hostName,userName,password) == 0):
print("Load driver: ok")
else:
print("Load driver: error")
[pc1]
hostName = 172.17.5.196
userName = test
password = test
busIdSpec = 0x01
interfaceName = wr0
ipWR = 192.168.2.100
[pc2]
hostName = 172.17.5.238
userName = test
password =test
busIdSpec = 0x01
ipWR = 192.168.2.200
interfaceName = wr0
\ No newline at end of file
# @file ssh.py
#
# @brief This class is used to execute commands by SSH
#
# @author Manuel Castilla
# @date 05/04/2019
#
###########################################################################
import paramiko
import os
import time
import warnings
warnings.filterwarnings(action='ignore',module='.*paramiko.*')
class SshCmdException (ValueError):
def __init__(self, arg):
self.strError = arg
self.args = {arg}
## Class SshCmd
# This class implements the snmpcmd command, used to send an
# SSH command to the target device.
class SshCmd ():
def __init__(self,timeWait=10):
"""
Constructor
Args:
timeWait: max time wait to execute commands
"""
self.timeWaitResponse = timeWait
self.ssh = None
def __del__(self):
"""
Destructor
"""
if (self.ssh != None):
self.ssh.close()
def exec(self,dev,command,user,passw=None,withResponse=True):
"""
Execute a command
Args:
dev: ip or hostname
command: command to execute
user: username
passw : password
withResponse: indicates if the command has a response
Raises:
SshCmdException
Return:
command result
"""
resp = ""
try:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(dev, username=user, password=passw,timeout=5)
except paramiko.AuthenticationException as error:
self.ssh.close()
raise SshCmdException("ssh failed autentication")
except:
self.ssh.close()
raise SshCmdException("ssh not connection")
# Send the command (non-blocking)
stdin, stdout, stderr = self.ssh.exec_command(command,get_pty=True)
stdin.close()
stderr.close()
if (withResponse):
# Wait for the command to terminate
i = 0
while not stdout.channel.exit_status_ready():
if i == self.timeWaitResponse:
stdout.channel.close()
stdout.close()
self.ssh.close()
raise SshCmdException("Not return command")
i = i + 1
time.sleep(1)
# Only print data if there is data to read in the channel
if stdout.channel.recv_exit_status() == 0:
resp = stdout.read().decode('utf-8')
else:
resp = stdout.read().decode('utf-8')
stdout.channel.close()
stdout.close()
self.ssh.close()
raise SshCmdException(resp)
#Close fds
stdout.channel.close()
stdout.close()
self.ssh.close()
return resp
def printSshErrorCommand(self,sshError,command = None):
"""
Print error command
Args:
sshError: error message
command: cammand executed
"""
if command != None:
print("Ssh error:",sshError,"Command:",command)
else:
print("Ssh error:",sshError)
#!/usr/bin/env python3
# @file testAdvDIO.py
#
# @brief Check the correct reception and sending of packages
#
# @author Manuel Castilla
# @date 25/04/2019
#
###########################################################################
import configparser
from dio import DIO
import time
from ssh import SshCmd,SshCmdException
delay = 0.001
maxOffset = 0.000000008
def findTimestamp(listStamp1,listStamp2,offset):
"""
This function compare two list and search if two timestamps match
Args:
listStamp1: first list of timestamps
listStamp2: second list of timestamps
offset: maximum offset between each comparison
Return:
True if it find a match in the two lists, False otherwise
"""
for i in listStamp1:
for j in listStamp2:
value = i - j
if (value <= offset and value >= -offset):
return True
return False
def testAdvDIO(hostName1,userName1,password1,interfaceName1,busId1,hostName2,userName2,password2,interfaceName2,busId2):
"""
Check the pulses generated on a remote board
Args:
hostName1: ip remote host 1
username1: user name host 1
password1: password
interfaceName1 : interface name
busId1: number PCIe bus PC 1
hostName2: ip remote host 2
username2: user name host 2
password2: password
interfaceName2 : interface name
busId2: number PCIe bus PC 2
Raises:
error test
"""
try:
sshCmd1 = SshCmd()
sshCmd2 = SshCmd()
dio1 = DIO(hostName1,userName1,password1,busId1)
dio2 = DIO(hostName2,userName2,password2,busId2)
dio1.configurePorts("pdiii")
dio2.configurePorts("iiiii")
dio1.clearTimestamps()
dio2.clearTimestamps()
command = "sudo wr-dio-agent %s /dev/fmc-dio-%i:0" % (interfaceName1,int(busId1,16))
sshCmd1.exec(hostName1,command,userName1,password1,False)
command = "sudo wr-dio-ruler %s /dev/fmc-dio-%i:0 IN0 R1+%s" % (interfaceName2,int(busId1,16),str(delay))
sshCmd2.exec(hostName2,command,userName2,password2,False)
totalOffset = delay + maxOffset
time.sleep(2)
if(not findTimestamp(dio1.getTimestamp(0),dio1.getTimestamp(1),totalOffset)):
raise
except SshCmdException as e:
SshCmd.printSshErrorCommand(e.strError,command)
raise
except:
print("Test advanced error")
raise
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
hostName1 = configuration["hostName1"]
userName1 = configuration["userName1"]
password1 = configuration["password1"]
interfaceName1 = configuration["interfaceName1"]
busIdSpec1 = configuration["busIdSpec1"]
hostName2 = configuration["hostName2"]
userName2 = configuration["userName2"]
password2 = configuration["password2"]
interfaceName2 = configuration["interfaceName2"]
busIdSpec2 = configuration["busIdSpec2"]
try:
print("\nExecuting advanced DIO test")
print("This test needs White Rabbit working")
testAdvDIO(hostName1,userName1,password1,interfaceName1,busIdSpec1,hostName2,userName2,password2,interfaceName2,busIdSpec2)
print("Test advanced DIO: successful")
except:
print("Test advanced DIO: error")
if __name__ == '__main__':
try:
configuration = {}
nameConfig = "configuration.cfg"
config = configparser.ConfigParser()
config.readfp(open(nameConfig))
configuration["hostName1"] = config.get('pc1',"hostName")
configuration["userName1"] = config.get('pc1',"userName")
configuration["password1"] = config.get('pc1',"password")
configuration["interfaceName1"] = config.get('pc1',"interfaceName")
configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
configuration["hostName2"] = config.get('pc2',"hostName")
configuration["userName2"] = config.get('pc2',"userName")
configuration["password2"] = config.get('pc2',"password")
configuration["interfaceName2"] = config.get('pc2',"interfaceName")
configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
main(configuration)
except configparser.Error as e:
print("Error load configuration:",e.message)
#!/usr/bin/env python3
# @file testAll.py
#
# @brief Execute all tests
#
# @author Manuel Castilla
# @date 29/04/2019
#
###########################################################################
import configparser
tests = ["testNIC","testWR","testDIO","testAdvDIO"]
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
print("Executing all tests")
for i in tests:
test = __import__(i)
test.main(configuration)
print("Test All: completed")
if __name__ == '__main__':
try:
configuration = {}
nameConfig = "configuration.cfg"
config = configparser.ConfigParser()
config.readfp(open(nameConfig))
configuration["hostName1"] = config.get('pc1',"hostName")
configuration["userName1"] = config.get('pc1',"userName")
configuration["password1"] = config.get('pc1',"password")
configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
configuration["ipWR1"] = config.get('pc1',"ipWR")
configuration["interfaceName1"] = config.get('pc1',"interfaceName")
configuration["hostName2"] = config.get('pc2',"hostName")
configuration["userName2"] = config.get('pc2',"userName")
configuration["password2"] = config.get('pc2',"password")
configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
configuration["ipWR2"] = config.get('pc2',"ipWR")
configuration["interfaceName2"] = config.get('pc2',"interfaceName")
main(configuration)
except configparser.Error as e:
print("Error load configuration:",e.message)
#!/usr/bin/env python3
# @file testDIO.py
#
# @brief Check all ports of the boards
#
# @author Manuel Castilla
# @date 25/04/2019
#
###########################################################################
import configparser
from dio import DIO
import time
maxOffset = 0.000000017 #offset 17 nanoseconds
def findTimestamp(listStamp1,listStamp2,offset):
"""
This function compare two list and search if two timestamps match
Args:
listStamp1: first list of timestamps
listStamp2: second list of timestamps
offset: maximum offset between each comparison
Return:
True if it find a match in the two lists, False otherwise
"""
for i in listStamp1:
for j in listStamp2:
value = i - j
if (value <= offset and value >= -offset):
return True
return False
def tryChannel(hostName1,userName1,password1,busId1,hostName2,userName2,password2,busId2,channel):
"""
Try the input and output of channel
Args:
hostName1: ip remote host 1
username1: user name host 1
password1: password
busId1: number PCIe bus PC 1
hostName2: ip remote host 2
username2: user name host 2
password2: password
busId2: number PCIe bus PC 2
channel: number of channel to try(0 to 4)
Return:
True if the channel fail, False otherwise
"""
try:
dio1 = DIO(hostName1,userName1,password1,busId1)
dio2 = DIO(hostName2,userName2,password2,busId2)
dio1.configurePorts("pdddd")
dio2.configurePorts("iiiii")
dio1.clearTimestamps()
dio2.clearTimestamps()
if (channel != 0):
dio1.armPulse(channel,0.1,"now")
else:
time.sleep(2) #wait 2 seconds to ensure some timestamp
if(findTimestamp(dio1.getTimestamp(channel),dio2.getTimestamp(channel),maxOffset)):
dio1.configurePorts("iiiii")
dio2.configurePorts("pdddd")
dio1.clearTimestamps()
dio2.clearTimestamps()
if (channel != 0):
dio2.armPulse(channel,0.1,"now")
else:
time.sleep(2) #wait 2 seconds to ensure some timestamp
if(findTimestamp(dio1.getTimestamp(channel),dio2.getTimestamp(channel),maxOffset)):
print("Channel",channel,": ok in host:",hostName1,"and host:",hostName2)
return False
else:
raise
else:
raise
except:
print("Channel",channel,": error in host:",hostName1,"or host:",hostName2)
return True
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
hostName1 = configuration["hostName1"]
userName1 = configuration["userName1"]
password1 = configuration["password1"]
busIdSpec1 = configuration["busIdSpec1"]
hostName2 = configuration["hostName2"]
userName2 = configuration["userName2"]
password2 = configuration["password2"]
busIdSpec2 = configuration["busIdSpec2"]
error = False
numberChannels = 5
print("\nExecuting DIO test")
print("This test needs White Rabbit working")
for i in range(numberChannels):
error |= tryChannel(hostName1,userName1,password1,busIdSpec1,hostName2,userName2,password2,busIdSpec2,i)
if(not error):
print("Test DIO: successful")
else:
print("Test DIO: error")
if __name__ == '__main__':
try:
configuration = {}
nameConfig = "configuration.cfg"
config = configparser.ConfigParser()
config.readfp(open(nameConfig))
configuration["hostName1"] = config.get('pc1',"hostName")
configuration["userName1"] = config.get('pc1',"userName")
configuration["password1"] = config.get('pc1',"password")
configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
configuration["hostName2"] = config.get('pc2',"hostName")
configuration["userName2"] = config.get('pc2',"userName")
configuration["password2"] = config.get('pc2',"password")
configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
main(configuration)
except configparser.Error as e:
print("Error load configuration:",e.message)
#!/usr/bin/env python3
# @file testNIC.py
#
# @brief Check the correct operation of the Network Interface Core
#
# @author Manuel Castilla
# @date 16/04/2019
#
###########################################################################
from ssh import SshCmd,SshCmdException
from vuart import Vuart
import configparser
def configurationIpInterface(hostName,userName,password,busId,interfaceName,ip):
"""
Set ip of white rabbit interface
Args:
hostName: ip remote host
username: user name
password: password
busId: number PCIe bus
interfaceName : interface name
ip : ip set interface
Raises:
error function
"""
try:
sshCmd = SshCmd()
#check network manager
command = "sudo service network-manager status | grep running"
value = sshCmd.exec(hostName,command,userName,password)
if ("running" in value):
print("\nWarning: The network manager is running on host %s, the test may not work correctly\n" % ip)
command = "sudo ifconfig " + interfaceName + " " + ip
sshCmd.exec(hostName,command,userName,password)
command = "ifconfig | grep " + ip + " | wc -l"
value = sshCmd.exec(hostName,command,userName,password)
if (int(value) == 1):
print("Configuration ip interface: ok on host:",hostName)
else:
raise
except SshCmdException as e:
sshCmd.printSshErrorCommand(e.strError,command)
print("Configuration ip interface: error on host:",hostName)
raise
except:
print("Configuration ip interface: error on host:",hostName)
raise
def testIperf(hostName,userName,password,ip,hostName2,userName2,password2):
"""
Test iperf by white rabbit interfaces
Args:
hostName: ip remote host client
username: user name client
password: password
ip : ip server
hostName2: ip remote host server
username2: user name server
password2: password
Raises:
error function
"""
try:
sshCmdServer = SshCmd()
sshCmdClient = SshCmd()
command = "iperf -s"
sshCmdServer.exec(hostName2,command,userName2,password2,withResponse=False)
command = "iperf -t 4 -c " + str(ip)
value = sshCmdClient.exec(hostName,command,userName,password)
if ("failed" in value):
print("Test iperf: error")
raise
else:
print(value)
print("Test iperf: ok")
except SshCmdException as e:
print("Test iperf: error")
print(e.strError)
raise
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
hostName1 = configuration["hostName1"]
userName1 = configuration["userName1"]
password1 = configuration["password1"]
busIdSpec1 = configuration["busIdSpec1"]
ipWR1 = configuration["ipWR1"]
interfaceName1 = configuration["interfaceName1"]
hostName2 = configuration["hostName2"]
userName2 = configuration["userName2"]
password2 = configuration["password2"]
busIdSpec2 = configuration["busIdSpec2"]
ipWR2 = configuration["ipWR2"]
interfaceName2 = configuration["interfaceName2"]
try:
print("\nExecuting NIC test")
print("This test needs the network manager stopped")
configurationIpInterface(hostName1,userName1,password1,busIdSpec1,interfaceName1,ipWR1)
configurationIpInterface(hostName2,userName2,password2,busIdSpec2,interfaceName2,ipWR2)
testIperf(hostName1,userName1,password1,ipWR2,hostName2,userName2,password2)
print("Test NIC: successful")
except:
print("Test NIC: error")
if __name__ == '__main__':
try:
configuration = {}
nameConfig = "configuration.cfg"
config = configparser.ConfigParser()
config.readfp(open(nameConfig))
configuration["hostName1"] = config.get('pc1',"hostName")
configuration["userName1"] = config.get('pc1',"userName")
configuration["password1"] = config.get('pc1',"password")
configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
configuration["ipWR1"] = config.get('pc1',"ipWR")
configuration["interfaceName1"] = config.get('pc1',"interfaceName")
configuration["hostName2"] = config.get('pc2',"hostName")
configuration["userName2"] = config.get('pc2',"userName")
configuration["password2"] = config.get('pc2',"password")
configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
configuration["ipWR2"] = config.get('pc2',"ipWR")
configuration["interfaceName2"] = config.get('pc2',"interfaceName")
main(configuration)
except configparser.Error as e:
print("Error load configuration:",e.message)
#!/usr/bin/env python3
# @file testWR.py
#
# @brief Check the correct operation of White Rabbit
#
# @author Manuel Castilla
# @date 23/04/2019
#
###########################################################################
from vuart import Vuart
import configparser
import time
def whoIsMaster(hostName,userName,password,busId):
"""
This function asks which spec has SFP purple (master)
Args:
hostName: ip remote host
username: user name
password: password
busId: number PCIe bus
Return:
True if the spec has SFP purple, False otherwise
"""
ret = False
try:
vuart = Vuart(hostName,userName,password,busId)
value = vuart.sfpDetect()
if ("AXGE-3454-0531" in value):
ret = True
except:
print("Who is master: error, host:",hostName)
raise
return ret
def putMode(hostName,userName,password,busId,mode):
"""
This function puts in mode master an spec
Args:
hostName: ip remote host
username: user name
password: password
busId: number PCIe bus
mode: mode ptp status("master","slave")
Raises:
error function
"""
try:
vuart = Vuart(hostName,userName,password,busId)
if (mode == "master"):
vuart.modeMaster()
else:
vuart.modeSlave()
vuart.ptpStart()
value = vuart.mode()
if(mode in value):
print("Put mode", mode,": ok, host:",hostName)
else:
raise
except:
print("Put mode: error, host:",hostName)
raise
def checkTrackPhase(hostName,userName,password,busId):
"""
This function check if the state is TRACK_PHASE
Args:
hostName: ip remote host
username: user name
password: password
busId: number PCIe bus
Raises:
error function
"""
try:
vuart = Vuart(hostName,userName,password,busId)
numberTimesTry = 15
i = 0
while not vuart.isTrackPhase():
if (i == numberTimesTry):
raise
i = i + 1
time.sleep(1)
print("Track Phase: ok")
except:
print("Track phase: error, host:",hostName)
raise
#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
hostName1 = configuration["hostName1"]
userName1 = configuration["userName1"]
password1 = configuration["password1"]
busIdSpec1 = configuration["busIdSpec1"]
interfaceName1 = configuration["interfaceName1"]
hostName2 = configuration["hostName2"]
userName2 = configuration["userName2"]
password2 = configuration["password2"]
busIdSpec2 = configuration["busIdSpec2"]
interfaceName2 = configuration["interfaceName2"]
try:
print("\nExecuting WR test")
masterSpec1 = whoIsMaster(hostName1,userName1,password1,busIdSpec1)
masterSpec2 = whoIsMaster(hostName2,userName2,password2,busIdSpec2)
if (masterSpec1 == 1 or masterSpec2 == 1):
if (masterSpec1 == 1):
putMode(hostName2,userName2,password2,busIdSpec2,"slave")
putMode(hostName1,userName1,password1,busIdSpec1,"master")
checkTrackPhase(hostName2,userName2,password2,busIdSpec2)
else:
putMode(hostName1,userName1,password1,busIdSpec1,"slave")
putMode(hostName2,userName2,password2,busIdSpec2,"master")
checkTrackPhase(hostName1,userName1,password1,busIdSpec1)
print("Test WR: successful")
else:
print("Error: It is not possible to know who is master")
raise
except:
print("Test WR: error")
if __name__ == '__main__':
try:
configuration = {}
nameConfig = "configuration.cfg"
config = configparser.ConfigParser()
config.readfp(open(nameConfig))
configuration["hostName1"] = config.get('pc1',"hostName")
configuration["userName1"] = config.get('pc1',"userName")
configuration["password1"] = config.get('pc1',"password")
configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
configuration["interfaceName1"] = config.get('pc1',"interfaceName")
configuration["hostName2"] = config.get('pc2',"hostName")
configuration["userName2"] = config.get('pc2',"userName")
configuration["password2"] = config.get('pc2',"password")
configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
configuration["interfaceName2"] = config.get('pc2',"interfaceName")
main(configuration)
except configparser.Error as e:
print("Error load configuration:",e.message)
# @file vuart.py
#
# @brief This class is to execute commands by virtual uart
#
# @author Manuel Castilla
# @date 23/04/2019
#
###########################################################################
from ssh import SshCmd,SshCmdException
## Class Vuart
#
class Vuart ():
def __init__(self,hostName,userName,password,busId):
"""
Construcctor
Args:
hostName: ip or hostname
userName: username
password : password
busId: bus ID PCIe
"""
self.hostName = hostName
self.userName = userName
self.password = password
self.busId = busId
self.sshCmd = SshCmd()
self.command = ""
parse_dev = self.vUartCommand("lspci | grep CERN | cut -f2 -d :").split(".")
if (len(parse_dev) > 1):
self.command = "sudo wrpc-vuart -f /sys/bus/pci/devices/0000\:00\:%02x.0/0000" \
"\:%02x\:%02x.0/resource0 -o 0x20500 -c " % (int(busId,16),int(busId,16),int(parse_dev[0],16))
else:
print("Error: Spec does not detected on host: %s" % hostName)
raise
def setIp(self,ip):
"""
Set IP
Args:
ip: IP to assing
Return:
Result set ip
Raises:
error function
"""
try:
command = "ip\ set\ " + str(ip)
return self.vUartCommand(command)
except:
print("Error set ip:",ip)
raise
def modeMaster(self):
"""
Configure the board in master mode
Return:
Result mode master
Raises:
error function
"""
try:
command = "mode\ master"
return self.vUartCommand(command)
except:
print("Error mode master")
raise
def modeSlave(self):
"""
Configure the board in slave mode
Return:
Result mode slave
Raises:
error function
"""
try:
command = "mode\ slave"
return self.vUartCommand(command)
except:
print("Error mode slave")
raise
def sfpDetect(self):
"""
Ask SFP value
Return:
SFP value
Raises:
error function
"""
try:
command = "sfp\ match"
return self.vUartCommand(command)
except:
print("Error sfp detect")
raise
def ptpStart(self):
"""
Start PTP daemon
Return:
Result
Raises:
error function
"""
try:
command = "ptp\ start"
return self.vUartCommand(command)
except:
print("Error ptp start")
raise
def ptpStop(self):
"""
Stop PTP daemon
Return:
Result
Raises:
error function
"""
try:
command = "ptp\ stop"
return self.vUartCommand(command)
except:
print("Error ptp stop")
raise
def mode(self):
"""
Ask board mode
Return:
Board mode ("master" or "slave")
Raises:
error function
"""
try:
command = "mode"
return self.vUartCommand(command)
except:
print("Error mode")
raise
def isTrackPhase(self):
"""
Ask if the slave board is in TRACK_PHASE
Return:
True if TRACK_PHASE, False otherwise
Raises:
error function
"""
try:
ret = False
command = "stat\ 1"
value = self.vUartCommand(command)
if ("sv:1 ss:'TRACK_PHASE'" in value):
ret = True
return ret
except:
print("Error track phase")
raise
def vUartCommand(self,command):
"""
Execute a command
Args:
command: command to execute
Raises:
error function
"""
try:
uartCommand = self.command + command
ret = self.sshCmd.exec(self.hostName,uartCommand,self.userName,self.password)
if ("Unrecognized command" in ret):
print(ret)
raise
return ret
except SshCmdException as e:
self.sshCmd.printSshErrorCommand(e.strError) #print error command
cleanup()
raise
Subproject commit 2ff6c419ea4a23cb9ffc043f6c03d831e81f9f2f
Subproject commit 3c9b25b8c9afff89f425f4974a361e1a0c8bed8d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment