Friday, June 17, 2016

Zynq Tango DCS Gateway

XUP Contest
A ZedBoard / RedPitayanew.jpg Tango Gateway

Participants :
ZULIC Dino
REYNIER Benjamin
LAFIOSCA Léo

Supervisor :

University :
Université Joseph Fourier, IUT GEII, Grenoble, FRANCE

Team number :
ZYNQ_XIL_16334
Dino, Léo, Benjamin with Jean-Michel in the ESRF control room
youtube:





TANGO @ ESRF


Forewords

Tango control system was elaborated at the ESRF, a large synchrotron radiation facility in Grenoble, France. The ESRF is a large research laboratory (1500 engineers, researchers, ), a kind of giant microscope to explore organic molecules or others and that uses X rays of high energy (6 GeV) issued from an 850 meters circumference accelerator in more than 40 beams lines operating simultaneously. See ww.esrf.eu for more info.
url
ESRF beam lines

Tango control system is a 100 man/years middleware, which aims at the monitoring 24/7 of more than 200 000 sensors & actuators in the facility. It features among other usage : logging, events driven communication, seamless integration to NI Labview, Matlab, Igor scientific toolboxes or OPC-UA plc, EPICS bus, ...
url
some Tango GUI and Tools

Tango is set of tools and protocol, with API in C++/Python/Java, free and open source, scalable from large synchrotron to small raspberry pi form factor embedded devices. It has many advantages over competition, either closed and expensive systems (ABB, SIEMENS, …) or even its direct competitor EPICS. It uses an object oriented paradigm to hide device complexity and promotes design reuse.

There are already several hundreds Device Server classes, written in C++, Python or Java, ready  to use for the most common devices udes at ESRF, Soleil, Alba, Elletra, Desy, … all free of charges and availables… see : www.tango-controls.org/resources/device-classes/
Tango Bus and ZedBorad / Redpitaya

There is a vivid and growing community of professional software developers (15 synchrotrons or laser research  facilities and a growing number of industrial company). see : www.tango-controls.org

Tango team is proud to announce that the new SKA Telescope (square kilometer array telescope featuring antennas spread thoroughly South Africa and Australia) recently adopts Tango as its control system framework. see www.skatelescope.org

Zedboard/Zynq uses case at the ESRF

Fpga are widely used at the ESRF for data high speed acquisition or very specific devices that can not be found COTS, as high precision motors controllers (IcePap), booster power controller, … All devices, either in linac, booster, accelerator, or beam lines experimental hutches are intended to be monitored by Tango and so need their Device Server.

Xilinx Zynq meets perfectly these requirements, offering in one chip the best of 2 worlds : Fpga (for data acquisition) and the ARM cpu dual core hosting linux, and its high level/networking stack, ...
ZedBoard_RevA_sideA_0_0 (1)_0.jpg
xilinx avnet ZedBoard

OpenEmbedded toolchain

We used Openembedded toolchain to build our dedicated Linux appliance. We find on GitHub all required bitbake recipes except a few : omniorb4, zeromq (old version) and of course Tango. But it was easy to write it from scratch because Tango already uses autoconf as its packaging tools.
OpenEmbedded toolchain

ZedBoard Tango Gateway

The design (vivado)

For now, the design is only a proof of concept, with gpio leds/switch & DAC adau1761, but could easily be improved with features as  Analog Device Inc pmods for example ...

Some vhdl IP (DAC) comes from Analog Devices Inc.

You can find a tcl script of the design. (Vivado 2015.1)
Screen Shot 2015-06-10 at 09.22.09.png
zedboard vivado design

generate dts and compile dtb

new vivado edition can generate dts. it was tricky before…

follow guidelines (git device-tree-xlnx and Add the BSP repository in SDK )
select "device-tree-xlnx" from the checked out git area):
SDK Menu: Xilinx Tools > Repositories > New... (<bsp repo>) > OK


gpio dts section :
ps7_gpio_0: gpio@41200000 {
#gpio-cells = <2>;
compatible = "xlnx,xps-gpio-1.00.a";
gpio-controller ;
reg = <0x41200000 0x10000>;
xlnx,all-inputs = <0x0>;
xlnx,all-inputs-2 = <0x1>;
xlnx,all-outputs = <0x1>;
xlnx,all-outputs-2 = <0x0>;
xlnx,dout-default = <0x0000005f>;
xlnx,dout-default-2 = <0x00000000>;
xlnx,gpio-width = <0x8>;
xlnx,gpio2-width = <0x8>;
xlnx,interrupt-present = <0x0>;
xlnx,is-dual = <0x1>;
xlnx,tri-default = <0xFFFFFFFF>;
xlnx,tri-default-2 = <0xFFFFFFFF>;
};

use dtc to compile .dts to .dtb
./tmp/work/zedboard_zynq7-poky-linux-gnueabi/linux-adi/3.18-adi+gite81690980bfbd04227e171cdee79d1d5127d0f79-r0/build/scripts/dtc/dtc -I dts -O dtb -o my.dtb zed.dts

Prepare Linux to boot with OpenEmbedded


NEW : Poky from scratch

Asap on github with submodules


#poky
git clone -b jethro git://git.yoctoproject.org/poky.git
#meta-xilinx







now on github

full bitbake recipes available here :
https://github.com/raph38130/poky

It takes some time to bitbake linux kernel and filesystem… (fetching source code from the internet and (cross)compiling all)

bitbake conf repertory

recipes

omniorb4_4.1.7.bb and omniorb-native_4.1.7.bb

Tango DS OpenEmbedded recipes

the bitbake recipes can be found here.
SUMMARY = "tango control system DeviceServer"
LICENSE = "CLOSED"

DEPENDS = "tango omniorb4 zeromq"
SRC_URI = "file://*"

S = "${WORKDIR}/ds-${PV}/../"

EXTRA_OEMAKE = " 'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'BUILDDIR=${S}' \
'TANGO_HOME=${TMPDIR}/sysroots/zedboard-zynq7/usr' \
'OMNI_HOME=${TMPDIR}/sysroots/zedboard-zynq7/usr' \
'ZMQ_HOME=${TMPDIR}/sysroots/zedboard-zynq7/usr' \
'OUTPUT_DIR=${S}' \
"

do_compile () {
       export EmbeddedSystem=1
export TOOLBINDIR=${S}
oe_runmake
}

do_install() {
install -m 0755 -d ${D}${bindir}
install -m 0777 ${S}/ZedGPIO ${D}${bindir}
}

linux kernel config file

the linux configuration file is here.
Take care to include gpio driver, sysfs, arasan SD support, …

Linux kernel is configured without modules (all bundled in kernel image), and the file system could easily fit in a ram disk (no need for a SD)

Tftpboot the bitbaked linux kernel and file system

we use mainly tftpboot during debug…
copy everything required under tftpboot repertory :

  • fpga .bit and tcl configuration script
cp tango/tango.runs/impl_1/system_wrapper.bit /tftpboot/
cp tango/tango.srcs/sources_1/bd/system/ip/system_sys_ps7_1/ps7_init.tcl /tftpboot/

  • OpenEmbedded u-boot, kernel, file system, dtb
cp tmp/deploy/images/zedboard-zynq7/* /tftpboot/

start Zynq Soc with xmd fpga debugger

xdisconnect -cable
source /tftpboot/ps7_init.tcl
connect arm hw
ps7_init
fpga -f /tftpboot/system_wrapper.bit
ps7_post_config
dow /tftpboot/u-boot.elf
con

use serial terminal (gtkterm) on /dev/ttyACM0 115200 8 N 1
set ipaddr 192.168.0.33
set serverip 192.168.0.4
tftpboot 0x3A00000 uImage
tftpboot 0x3900000 my.dtb
tftpboot 0x2000000 core-image-minimal-zedboard-zynq7-20150617082527.rootfs.ext4.gz.u-boot
bootm 0x3A00000 0x2000000 0x3900000

tftpboot


tftpboot + (large/permanent) filesystem on SD
gunzip /tftpboot/core-image-minimal-zedboard-zynq7-20150609193015.rootfs.ext4.gz
sudo dd if=/tftpboot/core-image-minimal-zedboard-zynq7-20150609193015.rootfs.ext4 bs=1M of=/dev/sdc1

booting everything from SD

  • partition SD memory in 2
mmcblkp1 is fat, contains BOOT.bin, a dtb, uImage.bin

    • BOOT.bin

contains hardware design (system_wrapper.bit and fsbl.exe, from vivado/xsdk)
and u-boot.elf
customize u-boot to boot straight from SD (uEnv.txt or edit zynq-common.h)

sdboot = ...
fatload mmc 0 0x0500000 my.dtb
fatload mmc 0 0x0600000 uImage.bin
bootm   0x0600000 - 0x0500000

use bootgen and boot.bif configuration file :
boot.bif
the_ROM_image:
{
[bootloader]/tftpboot/myfsbl.elf
/tftpboot/system_wrapper.bit
/tftpboot/u-boot.elf
}

bootgen -image boot.bif -o boot.bin -w

    • the .dtb file (so that linux identifies hardware)
in dts, check bootargs : (rootwait !!!)
bootargs = "console=ttyPS0,115200 rootfstype=ext4 root=/dev/mmcblk0p2 rw rootwait earlyprintk";

use dtc to convert dts->dtb
./tmp/sysroots/x86_64-linux/usr/bin/dtc -I dts -O dtb -o my.dtb zed.dts

    • uImage.bin

  • mmcblkp2 is ext4, contains linux FS
copy file system with dd

sudo dd bs=1M of=/dev/sdc2 \
if=./tmp/deploy/images/zedboard-zynq7/core-image-minimal-zedboard-zynq7-20151021125933.rootfs.ext4


Booting from qspi flash memory

our solution : no extra hardware required

need BOOT.bin to flash

boot.bif configuration file
the_ROM_image:
the_ROM_image:
{
[bootloader]/tftpboot/myfsbl.elf
/tftpboot/system_wrapper.bit
/tftpboot/u-boot.elf
[offset = 0x0500000]/tftpboot/my.dtb
[offset = 0x0600000]/tftpboot/uImage.bin
[offset = 0x0900000]/tftpboot/core-image-minimal-zedboard-zynq7.ext4.gz.u-boot
}

bootgen -image boot.bif -o boot.bin

take care to adapt sizes/offset to files length
fsbl + system.bit size : 0x4424E1

customize u-boot to qspiboot automatically :
edit zynq-common.h and recompile u-boot

./tmp/work/zedboard_zynq7-poky-linux-gnueabi/u-boot-xlnx/v2014.01-xilinx+gitAUTOINC+2a0536fa48-r0/git/include/configs/zynq-common.h

"qspiboot=echo Booting Linux from QSPI flash to RAM... && " \
"sf probe 0 0 0 && " \
"echo loading dtb && " \
"sf read 0x0500000 0x0500000 0x3000 && " \
"echo loading kernel && " \
"sf read 0x0600000 0x0600000 0x300000 && " \
"echo loading ramdisk && " \
"sf read 0x0900000 0x0900000 0xE00000 && " \
"echo booting linux && " \
"bootm   0x0600000 0x0900000 0x0500000 \0" \

"echo booting linux && " \
"bootm   0x1600000 0x1900000 0x0800000 \0" \


use xsdk | Xilinx Tools | Flash Tool (very slow)
(CAUTION : no success when flashing qspi from u-boot  !!!)

A simple GPIO Tango Device Server

DeviceServer Design

this Tango device is rather simple, for demonstration purpose only : it puts on tango bus the Leds and Switches of the Zedboard.
Two set of Tango attributes are defined :
  • Leds (8 boolean and UChar) Write only
  • Switches(8) Read Only (Uchar)

pogo wizard

generate C++ skeleton
Pogo wizard to generate C++/python/java skeleton of a DeviceServer

gpio access using linux sysfs

gpio N° changes  ? look for gpiochip
raw linux access /sys/class/gpio
echo 906 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio1016/direction
root@zedboard-zynq7:~# echo 1 > /sys/class/gpio/gpio1016/value     
root@zedboard-zynq7:~# echo 0 > /sys/class/gpio/gpio1016/value

Device Class C++ skeleton


Source code in C++ is here.
grayed code is generated by Pogo wizard

void ZedGPIO::init_device()
{
DEBUG_STREAM << "ZedGPIO::init_device() create device " << device_name << endl;
/*----- PROTECTED REGION ID(ZedGPIO::init_device_before) ENABLED START -----*/
// Initialization before get_device_property() call
/*----- PROTECTED REGION END -----*/ // ZedGPIO::init_device_before
// No device property to be read from database
attr_Switches_read = new Tango::DevUChar[1];
/*----- PROTECTED REGION ID(ZedGPIO::init_device) ENABLED START -----*/
// Initialize device
       char buffer [32];
    for (int i=0; i<8; i++)
   {
   int exp = open("/sys/class/gpio/export", O_WRONLY);
   sprintf(buffer, "%d", 1016+i);
   write(exp, buffer, 3);
   close(exp);
   sprintf(buffer,"/sys/class/gpio/gpio%d/direction",1016+i);
   int dir = open(buffer, O_WRONLY);
   write(dir, "out", 3);
   close(dir);
   }
    for (int i=0; i<8; i++)
   {
   int exp = open("/sys/class/gpio/export", O_WRONLY);
   sprintf(buffer, "%d", 1008+i);
   write(exp, buffer, 3);
   close(exp);
   sprintf(buffer,"/sys/class/gpio/gpio%d/direction",1008+i);
   int dir = open(buffer, O_WRONLY);
   write(dir, "in", 2);
   close(dir);
   }
/*----- PROTECTED REGION END -----*/ // ZedGPIO::init_device
}

void ZedGPIO::write_Leds(Tango::WAttribute &attr)
{
DEBUG_STREAM << "ZedGPIO::write_Leds(Tango::WAttribute &attr) entering... " << endl;
// Retrieve write value
Tango::DevUChar w_val;
attr.get_write_value(w_val);
/*----- PROTECTED REGION ID(ZedGPIO::write_Leds) ENABLED START -----*/
DEBUG_STREAM << "ZedGPIO val " << (int) w_val << endl;
char buffer[32];
    for (int i=0; i<8; i++)
   {
   sprintf(buffer,"/sys/class/gpio/gpio%d/value",1016+i);
   int gpio = open(buffer, O_WRONLY);
   if (((((int) w_val) >> i) & 1) == 1)
write(gpio, "1", 1);
   else
write(gpio, "0", 1);
   close(gpio);
   }
/*----- PROTECTED REGION END -----*/ // ZedGPIO::write_Leds
}

Using ZedGPIOds

testing with Jive tool


export TANGO_HOST=192.168.0.4:10000
ZedGPIO z0 -v4
Jive and AtkPanel : swiss knife of Tango


Remote launch with Starter tool

Starter is a Tango DeviceServer that starts other Devices Servers remotely.
Astor is the Tango tool dedicated to DS admin (support pool of devices, run level, events management, logging …)
Screen Shot 2015-06-17 at 11.21.48.png
Starter and Astor : remote DS administration & event monitoring

Interactive Python / Tango demo

We can use itango (interactive python with Tango wrapper) to easily create customs applications.

tango@raph-VirtualBox0:~$ itango
ITango 8.1.4 -- An interactive Tango client.
Running on top of Python 3.4, IPython 1.2.1 and PyTango 8.1.4
help      -> ITango's help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.
IPython profile: tango
hint: Try typing: mydev = Device("<tab>

ITango [2]: gpio=Device("rp/zed/0")
ITango [3]: import time
ITango [4]: gpio.leds=gpio.switches
ITango [5]: while True:
   time.sleep(0.1)
   gpio.leds=gpio.switches




itango k2000

ipython script to play k2000 with leds
while True:
      ...:     for i in range(7,-1,-1):
      ...:         d.leds = 1 << i
      ...:         time.sleep(0.1)
      ...:     for i in range(0,8):
      ...:         d.leds = 1 << i
      ...:         time.sleep(0.1)
      ...:         

k2000 python device server

we could also write a Python K2000 device server
Pogo xmi and code is here.


JDraw synoptic

without a single line of code, Jdraw creates your synoptic :
Jdraw tool can build interactive synoptics

here is an example zedgui.jdw

Testing ZedBoardTangoGateway

CAUTION : this is not a stand alone application software and there is a learning curve with TANGO concepts and tools. We provide here only a few guidelines…

download “tangobox” virtual machine and ZedBoard BOOT.bin

to test this project, you need a Tango remote station. Either d  ownload a Tango Virtualbox or install debian packages on your linux host.

Download a ready to launch TangoBox (ubuntu 14.04.2) here :
(64 bit OS /VirtualBox required)

flash zedboard with :

debian packages

Tango require a mysql server and root access
sudo apt-get install mysql-server libmysqlclient-dev

grant access to DB tango to your tangobox user

sudo apt-get install tango-db libtango8-dev tango-test
update tools (Jive, Pogo, Astor) from http://www.tango-controls.org/tools/

sudo service tango-db start

itango (python with Tango wrapper) :
sudo apt-get install python3-pytango

database configuration

Tango Database stores devices configurations, properties, connections details, … it is used mainly at device launch. Devices communication are highly optimized, peer to peer,  

with Jive Tools | Server wizard
server name : ZedGPIO
instance name : z0
hit next

Start the server on zedboard (before, you need to :
export TANGO_HOST=ipaddr_of_tango_database server:10000 to tell device server where is the tango database)
ZedGPIO z0 -v4

back to Jive
hit next
select ZedGPIO class

declare a device (naming convention is ([tango_network/]facility/class/name)
xilinx/zedgpio/0

DataBase contents


do the same to register Starter instance in zedboard
the screenshot show database contents for our use case.

event subsystem issue

there is an issue the way tango-db starts DataBase on some distributions (affecting events subscription within zeromq layer)
the tangobox ip addr should appear in ORBendPoint (after tcp, before 10000)


ps axww | grep giop
4771 ?        Sl     0:00 /usr/lib/tango/DataBaseds 2 -ORBendPoint giop:tcp::10000

either launch it that way :
/usr/lib/tango/DataBaseds 2 -ORBendPoint giop:tcp:192.168.0.16:10000
using tangobox ip addr

or patch /etc/init.d/tango-db do_start()  : remove if (localhost) …. and replace

       ip=`ifconfig eth0 | awk -F"[: ]+" '/inet addr:/ {print $4}'`
       DAEMON_ARGS="2 -ORBendPoint giop:tcp:$ip:$PORT"




now double click in Jive over xilinx/zedgpio/0 and AtKPanel should be launched

try some itango script
or jdraw drawing...


RedPitaya Oscilloscope

rp uses a “smaller” SoC than zedboard : zynq xc7z010clg400 vs xc7z020clg484 but ARM executable code from Zedboard can be reused in Redpitaya (but be carefull with libraries requirements)

RedPitaya open source open-source measurement and control tool

Tango Redpitaya in action

build DeviceServer

bitbake redpitaya

upload to rp

tar czvf ds.tgz usr/lib/libstdc++.* usr/lib/libtango.* usr/lib/libzmq.* usr/lib/libCOS* usr/lib/libomni* usr/lib/liblog4tango.* usr/bin/Redpitaya

download ds.tgz here for your trial
a preconfigured virtual disk (VDI ubuntu 64 bits) aka “tango box” is available here)
scp ds.tgz root@192.168.0.8:

install in rp

ssh redpitaya
cd /
gzip -d /root/ds.tgz
tar xvf ds.tar

launch ds

export TANGO_HOST=192.168.0.3:10000
./Redpitaya 0

(need to register DS with jive the first time)

ds / instance / class / device

thank you for reading !
if you want more information on Tango : www.tango-controls.org


Merci beaucoup à toute l’équipe de l’ESRF et notamment :
Jean Michel Chaize, Antonin Broquet, Andy Goetz

sans lesquels rien n’aurait été possible !