Skip to content
Snippets Groups Projects
Commit d53bb5fb authored by BRONES Romain's avatar BRONES Romain
Browse files

feat:ChimeraTK, OPCUA, FPGA XSA from server

* Add ChimeraTK generic server, uio backend and OPCUA CSA.
* Add script to configure and autostart ChimeraTK server.
* Use FPGA Manager to load bitstream, depending on user configuration at
  boot.
* Two variants of bitstream added: centralnode and cellnode.
* Add a begining of script to configure FPGA registers from a
  configuration file.
parents dde6fdf0 2848acf2
No related branches found
No related tags found
No related merge requests found
Showing
with 524 additions and 16 deletions
# Register configuration.
# Line begining with # or empty are ignored
# format is
# register.path.name value
# Everything not parsable will be ignored and reported as warning
FOFB_APP=centralnode
#!/usr/bin/env python3
import deviceaccess as da
import numpy as np
import logging
import argparse
#######################################################################
# MODULE CONFIGURATION
#######################################################################
# Logger
logger = logging.getLogger("fofb-configurator")
logger.setLevel(logging.INFO)
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
sh.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
logger.addHandler(sh)
# Argparse
parser=argparse.ArgumentParser(
prog="fofb-configurator",
description="Apply a default configuration file to a ChimeraTK device."
)
parser.add_argument(
"--config", help="Path to configuration file (%(default)s).",
default="/opt/fofb/cfg/regconfig",)
parser.add_argument(
"--dmap", help="ChimeraTK DMAP file (%(default)s).",
default="/opt/fofb/opcua-server/devices.dmap",)
parser.add_argument(
"--devname", help="ChimeraTK device name (%(default)s).",
default="APPUIO",)
#######################################################################
# GET DEVICE ACCESS
#######################################################################
def GetDeviceAccess(dmappath, devicename):
"""
Open the device access
"""
logger.info("Openning device {} in {}.".format(devicename, dmappath))
da.setDMapFilePath(dmappath)
dev=da.Device(devicename)
dev.open()
return dev
#######################################################################
# READ CONFIG FILE
#######################################################################
def ReadConfigFile(filepath):
"""
Read the configuration file, building a dictionnary
"""
logger.info("Reading configuration file {}.".format(filepath))
dcfg={}
with open(filepath, 'r') as fp:
for i, l in enumerate(fp.readlines()):
# Ignore empty or comment
if len(l.strip()) <1:
continue
if l.strip().startswith('#'):
continue
# Try to split in two, or pass
try:
k,v = l.split()
except ValueError:
logger.warning("{} ignore line {}:'{}'".format(filepath, i, l))
continue
# Understand hex format
if v.lower().startswith("0x"):
base=16
else:
base=10
# Try to cast value, or pass
try:
v = int(v, base)
except ValueError:
logger.warning("{} ignore line {}:'{}'".format(filepath, i, l))
continue
dcfg[k]=v
return dcfg
#######################################################################
# APPLY CONFIG
#######################################################################
def ApplyConfig(dev, config):
"""
Apply dictionnary config to device dev.
"""
for k, v in config.items():
try:
acc = dev.getScalarRegisterAccessor(np.int32, k)
acc.set(np.asarray([v], dtype=np.int32))
acc.write()
except:
logger.error("Could not apply value {} to {}".format(v,k))
raise
logger.info("Applied {} = {}".format(k,v))
#######################################################################
# MAIN
#######################################################################
if __name__ == '__main__':
args = parser.parse_args()
# Testing logger
logger.info("Welcome to FOFB-CONFIGURATOR")
try:
d=ReadConfigFile(args.config)
except FileNotFoundError:
logger.error("File not found: {}".format(args.config))
exit(1)
try:
dev=GetDeviceAccess(args.dmap, args.devname)
except Exception:
logger.error("Cannot open Device {} in {}".format(args.devname, args.dmap))
raise
ApplyConfig(dev, d)
dev.close()
#!/bin/bash
. /etc/init.d/functions
PATH_CONF="/opt/fofb/cfg/configuration"
logger -t "fofb-fpgainit" "Reading configuration file ${PATH_CONF}"
start() {
if [ ! -f ${PATH_CONF} ]; then
echo "Configuration file not found: ${PATH_CONF}"
exit 1
fi
source ${PATH_CONF}
case $FOFB_APP in
cellnode|centralnode)
echo "Found configuration ${FOFB_APP}"
;;
*)
echo "Could not establish FOFB application"
exit 1
;;
esac
# Taking the last binary file in the sorted list (higher tag)
PATH_FPGABIN=$(ls -S /lib/firmware/base/${FOFB_APP}/*.bin | tail -n 1)
echo "Loading FPGA image ${PATH_FPGABIN}"
fpgautil -b ${PATH_FPGABIN}
# Reset the FPGA
/etc/init.d/fw_plreset.sh
# Linking the correct MAP file
PATH_MAP="/opt/fofb/map/app_${FOFB_APP}.mapt"
echo "Linking map file ${PATH_MAP}"
ln -sf ${PATH_MAP} /opt/fofb/map/app.mapt
# Applying configuration
fofb-configurator --config /opt/fofb/cfg/config_register --dmap /opt/fofb/opcua-server/devices.dmap
}
stop() {
echo "Nothing to be done"
}
### main logic ###
case "$1" in
start)
start
;;
stop)
stop
;;
status)
echo "Cannot give any status"
;;
restart|reload|condrestart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
exit 1
esac
exit 0
#!/bin/bash
PATH_MAPT=/opt/fofb/map/app.mapt
function read_reg () {
# ARGS: regname
# Fix name for grep
fname="^${1} "
# Grep MAPT file for reg name
l=$(grep -e ${fname} ${PATH_MAPT})
if [[ -z "$l" ]]; then
echo "Could not find register named $1" >&2
exit 1
fi
# Retrieve fields
raddr=$(awk '{print $3}' <<<$l )
rsize=$(awk '{print $4}' <<<$l )
# Read register
data=$(devmem $raddr)
echo $((data))
}
function get_appname () {
appcode=$(read_reg APP.ID)
if [[ $appcode -eq 0x507E17A0 ]]; then
echo cellnode
return
fi
if [[ $appcode -eq 0x507E1722 ]]; then
echo centralnode
return
fi
printf "Application ID not recognized: %X\n" $appcode >&2
echo \#NA
return 1
}
function get_version () {
vers=$(read_reg BSP.PRJ_VERSION)
changes=$(($vers & 0xFF))
patch=$(( $(($vers>>8)) & 0xFF))
minor=$(( $(($vers>>16)) & 0xFF))
major=$(( $(($vers>>24)) & 0xFF))
shasum=$(printf "%x" $(read_reg BSP.PRJ_SHASUM))
echo "${major}.${minor}.${patch}-${changes}-(${shasum})"
}
printf "%10s %s\n" $(get_appname) $(get_version)
printf "SynthTime: %s\n" "$(date -d"@$(read_reg BSP.PRJ_TIMESTAMP)")"
SUMMARY = "Initialize the system for FOFB application"
SECTION = "opt"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
# This will add startup scripts
INITSCRIPT_NAME = "fofb-init.sh"
INITSCRIPT_PARAMS = "defaults 50 2"
inherit update-rc.d
SRC_URI = " file://fofb-init.sh"
SRC_URI += " file://configuration"
SRC_URI += " file://config_register"
SRC_URI += " file://fpgaversion.sh"
SRC_URI += " file://fofb-configurator.py"
RDEPENDS_${PN}=" fpga-manager-script bash"
FILES_${PN}+="/etc/init.d/fofb-init.sh"
FILES_${PN}+="/usr/bin/fpgaversion"
FILES_${PN}+="/usr/bin/fofb-configurator"
FILES_${PN}+="/opt/fofb/cfg/configuration"
FILES_${PN}+="/opt/fofb/cfg/config_register"
do_install() {
install -d ${D}/etc/init.d/
install -m 0755 ${WORKDIR}/fofb-init.sh ${D}/etc/init.d/fofb-init.sh
# Write default configuration
install -d ${D}/opt/fofb/cfg/
install -m 0666 ${WORKDIR}/configuration ${D}/opt/fofb/cfg/configuration
install -m 0666 ${WORKDIR}/config_register ${D}/opt/fofb/cfg/config_register
# Add FPGA version reader and FoFb Configurator
install -d ${D}/usr/bin/
install -m 0755 ${WORKDIR}/fpgaversion.sh ${D}/usr/bin/fpgaversion
install -m 0755 ${WORKDIR}/fofb-configurator.py ${D}/usr/bin/fofb-configurator
}
APPUIO (uio:uio0?map=/opt/fofb/map/app.mapt)
#!/bin/bash
. /etc/init.d/functions
LOG_FILE=/var/log/fofb-opcua-server.log
LOCK_FILE=/var/lock/subsys/fofb-opcua-server.log
# Start the service
start() {
if [ -f $LOCK_FILE ]; then
echo "fofb-opcua server already running"
exit 1
fi
echo "Starting fofb-opcua-server" >> $LOG_FILE
cd /opt/fofb/opcua-server
stdbuf -oL opcua-generic-chimeratk-server01 &>> $LOG_FILE &
### Create the lock file ###
touch $LOCK_FILE
success $"fofb-opcua server startup"
}
# Restart the service
stop() {
echo "Stopping fofb-opcua-server" >> $LOG_FILE
killproc opcua-generic-chimeratk-server01
### Now, delete the lock file ###
rm -f $LOCK_FILE
}
### main logic ###
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status opcua-generic-chimeratk-server01
;;
restart|reload|condrestart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
exit 1
esac
exit 0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<!-- Declare devices, aliases from .dmap file -->
<variable name="devices" type="string">
<value i="0" v="APPUIO"/>
</variable>
<!-- Declare timers for auto refresh -->
<variable name="periodicTimers" type="string">
<value i="0" v="secTimer"/>
</variable>
<!-- msTimer tick every second -->
<module name="secTimer">
<variable name="period" type="uint32" value="1000" />
</module>
<!-- Configure device -->
<module name="APPUIO">
<variable name="triggerPath" type="string" value="/manual/trigger" />
<variable name="pathInDevice" type="string" value="" />
<variable name="initScript" type="string" value="" />
</module>
</configuration>
SUMMARY = "Add an ChimeraTK OPCUA-GenericServer to access PL app"
SECTION = "opt"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
# This will add startup scripts
INITSCRIPT_NAME = "fofb-opcua-server.sh"
INITSCRIPT_PARAMS = "defaults 91 3"
inherit update-rc.d
MAP_REPO = "https://drive2.demo.renater.fr/index.php/s/xctBtbgTHLD2rpg/download?path/&files="
SRC_URI = " \
file://devices.dmap \
file://generic_chimeratk_server_configuration.xml \
file://fofb-opcua-server.sh \
"
RDEPENDS_${PN}=" genericdeviceserver-opcua bash"
FILES_${PN}+="/opt/fofb/opcua-server/*"
FILES_${PN}+="/etc/init.d/fofb-opcua-server.sh"
do_install() {
install -d ${D}/opt/fofb/opcua-server/
install -m 0644 ${WORKDIR}/devices.dmap ${D}/opt/fofb/opcua-server/devices.dmap
install -m 0644 ${WORKDIR}/generic_chimeratk_server_configuration.xml ${D}/opt/fofb/opcua-server/generic_chimeratk_server_configuration.xml
install -d ${D}/etc/init.d/
install -m 0755 ${WORKDIR}/fofb-opcua-server.sh ${D}/etc/init.d/fofb-opcua-server.sh
}
#include <ChimeraTK/Device.h>
int main(){
ChimeraTK::setDMapFilePath("soleil-fofb.dmap");
ChimeraTK::Device dev("CNUIO");
dev.open();
auto acc = dev.getScalarRegisterAccessor<uint32_t>("ccn_packeter_0.VERSION");
acc.read();
}
SUMMARY = "Simple test for ChimeraTK"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit pkgconfig
SRC_URI = "file://testread.cpp"
S = "${WORKDIR}"
DEPENDS = "deviceaccess"
do_compile() {
${CXX} `pkg-config ChimeraTK-DeviceAccess --cflags --libs` testread.cpp -o testread
}
do_install() {
install -d ${D}/${bindir}/
install -m 0755 testread ${D}/${bindir}
}
INSANE_SKIP_${PN} = "ldflags"
...@@ -4,3 +4,8 @@ SRC_URI_append = " \ ...@@ -4,3 +4,8 @@ SRC_URI_append = " \
file://pl-conf.dtsi \ file://pl-conf.dtsi \
" "
# We need what's in pl-conf.
# We are not using DTBO for now (cannot build)
do_configure_append() {
echo '/include/ "pl-conf.dtsi"' >> ${DT_FILES_PATH}/system-top.dts
}
...@@ -9,5 +9,9 @@ ...@@ -9,5 +9,9 @@
reg = < 0xA0820000 0x20 >; reg = < 0xA0820000 0x20 >;
}; };
};
&ins_bsp_fmc2zup_system_p_m_axi_app1 {
compatible = "generic-uio";
linux,uio-name = "axiapp";
}; };
File deleted
# Written from techlab demo. Only one FPGA is targeted for us # Written from techlab demo. Only one FPGA is targeted for us
PL_VARIANTS_damc-fmc2zup = "zu11eg zu19eg" PL_VARIANTS_damc-fmc2zup = "cellnode centralnode"
ZUP_FPGA_VARIANT ?= "zu11eg" PL_DEFAULT_VARIANT_damc-fmc2zup = "cellnode"
# Default variant is selected if fpga-manager is not enabled
PL_DEFAULT_VARIANT_damc-fmc2zup = "${ZUP_FPGA_VARIANT}"
# Give info on the HDF file # Give info on the HDF file
HDF_BASE = "file://${PL_DEFAULT_VARIANT}/"
HDF_PATH_damc-fmc2zup = "damc_fmc2zup_top.xsa" HDF_PATH_damc-fmc2zup = "damc_fmc2zup_top.xsa"
# Repository for xsa
XSA_REPO = "https://drive2.demo.renater.fr/index.php/s/xctBtbgTHLD2rpg/download?path/&files="
XSA_VERSION = "0.4.1-2"
S = "${WORKDIR}" S = "${WORKDIR}"
SRC_URI += " file://*" SRC_URI_remove = "${HDF_BASE}${HDF_PATH}"
SRC_URI += "${XSA_REPO}FofbNode_CellNode_${XSA_VERSION}.xsa;md5sum=7321e29ba73820bf94149291a96fdbb8;downloadfilename=cellnode_damc_fmc2zup_top.xsa"
SRC_URI += "${XSA_REPO}FofbNode_CentralNode_${XSA_VERSION}.xsa;md5sum=890db1cd21c83f410009cea2d6609d53;downloadfilename=centralnode_damc_fmc2zup_top.xsa"
SRC_URI += "${XSA_REPO}FofbNode_CellNode_${XSA_VERSION}.mapt;downloadfilename=app_cellnode.mapt;md5sum=f2bf02fb04d98a629db432b30d8f0645"
SRC_URI += "${XSA_REPO}FofbNode_CentralNode_${XSA_VERSION}.mapt;downloadfilename=app_centralnode.mapt;md5sum=8c8324fdbaa23ef1dc39d5b49a5c1b27"
FILES_${PN}+="/opt/fofb/map/*"
do_install_prepend() {
# Link .xsa file to match Techlab install
for VARIANT in ${PL_VARIANTS}; do
mkdir -p ${WORKDIR}/${VARIANT}
ln -sf ${S}/${VARIANT}_${HDF_PATH} ${VARIANT}/${HDF_PATH}
done
}
do_install_append() {
# Put map files into directory
install -d ${D}/opt/fofb/map
for VARIANT in ${PL_VARIANTS}
do
# replacing BAR by 0 on the way
awk 'FNR>1 {$5=0} {print}' ${WORKDIR}/app_${VARIANT}.mapt > ${WORKDIR}/app_${VARIANT}.mapt.bar0
install -m 0644 ${WORKDIR}/app_${VARIANT}.mapt.bar0 ${D}/opt/fofb/map/app_${VARIANT}.mapt
done
}
FILESEXTRAPATHS_prepend := "${THISDIR}/${MACHINE}:" FILESEXTRAPATHS_prepend := "${THISDIR}/${MACHINE}:"
...@@ -20,22 +20,19 @@ IMAGE_FEATURES_append = " \ ...@@ -20,22 +20,19 @@ IMAGE_FEATURES_append = " \
debug-tweaks \ debug-tweaks \
" "
# If we want FPGA manager
#IMAGE_FEATURES_append = " fpga-manager"
# Add applications # Add applications
IMAGE_INSTALL_append = " packagegroup-zup-support" IMAGE_INSTALL_append = " packagegroup-zup-support"
IMAGE_INSTALL_append = " util-linux glibc-utils sudo" IMAGE_INSTALL_append = " util-linux glibc-utils sudo"
IMAGE_INSTALL_append = " python3-asyncua" IMAGE_INSTALL_append = " python3-asyncua"
IMAGE_INSTALL_append = " deviceaccess" IMAGE_INSTALL_append = " deviceaccess"
IMAGE_INSTALL_append = " deviceaccess-python-bindings" IMAGE_INSTALL_append = " deviceaccess-python-bindings"
IMAGE_INSTALL_append = " fofb-opcua-server"
IMAGE_INSTALL_append = " fofb-init"
IMAGE_INSTALL_append = " xilinx-xvc-server" IMAGE_INSTALL_append = " xilinx-xvc-server"
#IMAGE_INSTALL_append = " python3-pytango"
#IMAGE_INSTALL_append = " cifs-utils"
#IMAGE_INSTALL_append = " boost"
# We do not need that # We do not need that
IMAGE_INSTALL_remove = " git python3-pip sudo" IMAGE_INSTALL_remove = " git python3-pip sudo"
IMAGE_INSTALL_remove = " fpgautil-init"
# Remove graphical features # Remove graphical features
DISTRO_FEATURES_remove = " x11 wayland opengl qt jupyter" DISTRO_FEATURES_remove = " x11 wayland opengl qt jupyter"
...@@ -51,6 +48,3 @@ EXTRA_USERS_PARAMS = "\ ...@@ -51,6 +48,3 @@ EXTRA_USERS_PARAMS = "\
usermod -s /bin/zsh -P 'fofb' root; \ usermod -s /bin/zsh -P 'fofb' root; \
useradd -s /bin/zsh -G sudo -P 'diag91' diag; \ useradd -s /bin/zsh -G sudo -P 'diag91' diag; \
" "
# If the FPGA system has a Block Design, try to generate the Device Tree
DT_FROM_BD_ENABLE = "1"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment