diff --git a/recipes-app/fofb-init/files/config_register b/recipes-app/fofb-init/files/config_register new file mode 100644 index 0000000000000000000000000000000000000000..02710f55dbc02bab93a9d5eccd0b32877090e011 --- /dev/null +++ b/recipes-app/fofb-init/files/config_register @@ -0,0 +1,7 @@ +# 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 + diff --git a/recipes-app/fofb-init/files/configuration b/recipes-app/fofb-init/files/configuration new file mode 100644 index 0000000000000000000000000000000000000000..bf0d291929d1bed53b6902884141cb19b7771519 --- /dev/null +++ b/recipes-app/fofb-init/files/configuration @@ -0,0 +1 @@ +FOFB_APP=centralnode diff --git a/recipes-app/fofb-init/files/fofb-configurator.py b/recipes-app/fofb-init/files/fofb-configurator.py new file mode 100755 index 0000000000000000000000000000000000000000..60bbbe35cfe7bf4fc3403275f7e1aa1032f84a21 --- /dev/null +++ b/recipes-app/fofb-init/files/fofb-configurator.py @@ -0,0 +1,145 @@ +#!/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() + + diff --git a/recipes-app/fofb-init/files/fofb-init.sh b/recipes-app/fofb-init/files/fofb-init.sh new file mode 100644 index 0000000000000000000000000000000000000000..c452d9f51aa53c1ee3e9dd6dfcfee7ca7b9136c4 --- /dev/null +++ b/recipes-app/fofb-init/files/fofb-init.sh @@ -0,0 +1,74 @@ +#!/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 diff --git a/recipes-app/fofb-init/files/fpgaversion.sh b/recipes-app/fofb-init/files/fpgaversion.sh new file mode 100644 index 0000000000000000000000000000000000000000..2474f3aceb6cf469c6cb63e62287da2f718e49f5 --- /dev/null +++ b/recipes-app/fofb-init/files/fpgaversion.sh @@ -0,0 +1,64 @@ +#!/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)")" diff --git a/recipes-app/fofb-init/fofb-init_1.0.bb b/recipes-app/fofb-init/fofb-init_1.0.bb new file mode 100644 index 0000000000000000000000000000000000000000..5edd85a7a8c4af1d176f3955df395fd3d49af753 --- /dev/null +++ b/recipes-app/fofb-init/fofb-init_1.0.bb @@ -0,0 +1,39 @@ +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 +} diff --git a/recipes-app/fofb-opcua-server/files/devices.dmap b/recipes-app/fofb-opcua-server/files/devices.dmap new file mode 100644 index 0000000000000000000000000000000000000000..db9e2c8f802f72e0b15240d5afdd2792f8951a37 --- /dev/null +++ b/recipes-app/fofb-opcua-server/files/devices.dmap @@ -0,0 +1 @@ +APPUIO (uio:uio0?map=/opt/fofb/map/app.mapt) diff --git a/recipes-app/fofb-opcua-server/files/fofb-opcua-server.sh b/recipes-app/fofb-opcua-server/files/fofb-opcua-server.sh new file mode 100644 index 0000000000000000000000000000000000000000..abb62bad93ffaddf175dcea79b595877ff62976e --- /dev/null +++ b/recipes-app/fofb-opcua-server/files/fofb-opcua-server.sh @@ -0,0 +1,56 @@ +#!/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 + + + diff --git a/recipes-app/fofb-opcua-server/files/generic_chimeratk_server_configuration.xml b/recipes-app/fofb-opcua-server/files/generic_chimeratk_server_configuration.xml new file mode 100644 index 0000000000000000000000000000000000000000..0edecb604d1511b7774ac027bf37cc8e99ccc61d --- /dev/null +++ b/recipes-app/fofb-opcua-server/files/generic_chimeratk_server_configuration.xml @@ -0,0 +1,27 @@ +<?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> diff --git a/recipes-app/fofb-opcua-server/fofb-opcua-server_0.1.bb b/recipes-app/fofb-opcua-server/fofb-opcua-server_0.1.bb new file mode 100644 index 0000000000000000000000000000000000000000..ff0c7c15eb30e32728c96375f591dc7958d9d9eb --- /dev/null +++ b/recipes-app/fofb-opcua-server/fofb-opcua-server_0.1.bb @@ -0,0 +1,31 @@ +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 +} diff --git a/recipes-app/simple-test/files/testread.cpp b/recipes-app/simple-test/files/testread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e58ffaba248140e1800e892e048cfcc3876459c --- /dev/null +++ b/recipes-app/simple-test/files/testread.cpp @@ -0,0 +1,10 @@ +#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(); +} diff --git a/recipes-app/simple-test/simple-test_0.1.bb b/recipes-app/simple-test/simple-test_0.1.bb new file mode 100644 index 0000000000000000000000000000000000000000..75b9e5210f2508a321c83a9ba9a5099d3d4be2b7 --- /dev/null +++ b/recipes-app/simple-test/simple-test_0.1.bb @@ -0,0 +1,23 @@ +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" diff --git a/recipes-bsp/device-tree/device-tree.bbappend b/recipes-bsp/device-tree/device-tree.bbappend index 92035eca431db5790d67ba9408ad0979db9a6631..c7e30fcb4e443679d854ac106b32ce196b64e220 100644 --- a/recipes-bsp/device-tree/device-tree.bbappend +++ b/recipes-bsp/device-tree/device-tree.bbappend @@ -4,3 +4,8 @@ SRC_URI_append = " \ 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 +} diff --git a/recipes-bsp/device-tree/files/damc-fmc2zup/pl-conf.dtsi b/recipes-bsp/device-tree/files/damc-fmc2zup/pl-conf.dtsi index 667f705d7892c423cb00193341df87634254acd5..00cfcd49a0609587cd1dfca85ab6d382f5baf633 100644 --- a/recipes-bsp/device-tree/files/damc-fmc2zup/pl-conf.dtsi +++ b/recipes-bsp/device-tree/files/damc-fmc2zup/pl-conf.dtsi @@ -9,5 +9,9 @@ reg = < 0xA0820000 0x20 >; }; +}; +&ins_bsp_fmc2zup_system_p_m_axi_app1 { + compatible = "generic-uio"; + linux,uio-name = "axiapp"; }; diff --git a/recipes-bsp/hdf/damc-fmc2zup/zu11eg/damc_fmc2zup_top.xsa b/recipes-bsp/hdf/damc-fmc2zup/zu11eg/damc_fmc2zup_top.xsa deleted file mode 100644 index e1b29125160f430ed2352dce529b8c82874ba82a..0000000000000000000000000000000000000000 Binary files a/recipes-bsp/hdf/damc-fmc2zup/zu11eg/damc_fmc2zup_top.xsa and /dev/null differ diff --git a/recipes-bsp/hdf/external-hdf.bbappend b/recipes-bsp/hdf/external-hdf.bbappend index 7e56da4175046af6ce35a9a4c7db483758dfc1fd..6c32f154887691d1992edf25fa6446c8b168f1ad 100644 --- a/recipes-bsp/hdf/external-hdf.bbappend +++ b/recipes-bsp/hdf/external-hdf.bbappend @@ -1,16 +1,43 @@ # Written from techlab demo. Only one FPGA is targeted for us -PL_VARIANTS_damc-fmc2zup = "zu11eg zu19eg" -ZUP_FPGA_VARIANT ?= "zu11eg" - -# Default variant is selected if fpga-manager is not enabled -PL_DEFAULT_VARIANT_damc-fmc2zup = "${ZUP_FPGA_VARIANT}" +PL_VARIANTS_damc-fmc2zup = "cellnode centralnode" +PL_DEFAULT_VARIANT_damc-fmc2zup = "cellnode" # Give info on the HDF file -HDF_BASE = "file://${PL_DEFAULT_VARIANT}/" 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}" -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}:" diff --git a/recipes-core/images/zup-image-soleil-fofb.bb b/recipes-core/images/zup-image-soleil-fofb.bb index aaf748cc73108b133b97325bd5c92d6e09c28869..7324be19b8e88c683b94983975693b05532ba121 100644 --- a/recipes-core/images/zup-image-soleil-fofb.bb +++ b/recipes-core/images/zup-image-soleil-fofb.bb @@ -20,22 +20,19 @@ IMAGE_FEATURES_append = " \ debug-tweaks \ " -# If we want FPGA manager -#IMAGE_FEATURES_append = " fpga-manager" - # Add applications IMAGE_INSTALL_append = " packagegroup-zup-support" IMAGE_INSTALL_append = " util-linux glibc-utils sudo" IMAGE_INSTALL_append = " python3-asyncua" IMAGE_INSTALL_append = " deviceaccess" 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 = " python3-pytango" -#IMAGE_INSTALL_append = " cifs-utils" -#IMAGE_INSTALL_append = " boost" # We do not need that IMAGE_INSTALL_remove = " git python3-pip sudo" +IMAGE_INSTALL_remove = " fpgautil-init" # Remove graphical features DISTRO_FEATURES_remove = " x11 wayland opengl qt jupyter" @@ -51,6 +48,3 @@ EXTRA_USERS_PARAMS = "\ usermod -s /bin/zsh -P 'fofb' root; \ 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"