-
Notifications
You must be signed in to change notification settings - Fork 0
Yocto Layer for Odin Control
The Yocto recipe layer is a directory that specifies how the application-specific code should be baked into the Linux image. The is combined with general layers for the hardware provided by the vendor, as well as additional layers for supporting the LOKI infrastructure. In a typical LOKI application repository, this layer is used to create recipe derived from an odin-control base recipe to install the custom adapter into the image such that resources end up in a predictable place, and everything is executed automatically.
A good example of how this can work is in the BabyD repository.
- Create the parent directories from your project root. The name
meta-<project>
is just a convention, but the other directories and files must have the same names to overlay properly.
mkdir meta-<project>
cd meta-<project>
mkdir conf
touch conf/petalinuxbsp.conf
touch conf/user-rootfsconfig
touch conf/layer.conf
- Edit the main config file.
layer.conf
describes the contents of this layer as well as how it overlays. These settings should work fine, but remember to replace "" with whatever your project's name is.
# layer.conf
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "<project>"
BBFILE_PATTERN_<project> = "^${LAYERDIR}/"
BBFILE_PRIORITY_<project> = "9"
LAYERVERSION_<project> = "1"
LAYERSERIES_COMPAT_<project> = "zeus"
-
Create an odin-detector recipe instance (see Creating a Recipe for an Odin-Control Instance), by convention called
<project>-detector
. -
Add the recipe name to the
layer.conf
so that it will always be brought into the Linux image without being a dependency.
IMAGE_INSTALL_APPENDS = " <project>-detector"
- Update your repository environment file to include the location of the new user layer (see Repository Configuration Files for more information). In
repo.env
:
yocto_user_layer_0=$(shell pwd)/meta-<project>
Note that you may have to clean and re-build the entire project for this to take effect.
An instance of odin-control
is the combination of odin-control
adapter(s), configuration files(s), sequences for odin-sequencer
(optional) any other supporting files.
To make this easier -and to standardise installation locations- a base recipe from which application-specific recipes can be derived has been created.
This means that everything to do with automatically starting the process, system outputs and static resource target locations are all handled.
Additionally, it includes the the odin-control
software, dependencies, and supporting code (odin-devices
and odin-sequencer
) in the image.
This guide assumes that you have already created an odin-control
adapter for your project, and that it is present in the repository's /control
directory, or is in another known repository.
The recipe must be created inside a subdirectory recipes-apps
in the user layer. This step takes place assuming the user is CD'ed into /meta-<project>/
mkdir recipes-apps
mkdir recipes-apps/detector
cd recipes-apps/detector
Create a directory for any files that the recipe will need to import later:
mkdir files
Create the recipe file itself (update the name to match your project):
touch <project>-detector.bb
If your control code is in the current repository, create a relative symlink to it (if your control code is in a repository, skip this step).
This way, the logic for moving the control software into the image is kept in the Yocto layer, and the control software is in the toplevel with no required knowledge of how this is done, making it easier to work in in isolation.
ln -s ../../../../control files/control
Edit the recipe file <project>-detector.bb
, initially creating it from this template:
inherit odin-control-instance
RDEPENDS_${PN} += " python3-tabulate"
RDEPENDS_${PN} += " odin-control (=1.5.0)"
SUMMARY = "This is a recipe for the <Project> Odin-Control Instance"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI = "file://control/config/config.cfg \
file://control/* \
"
# This has to be in the format expected in Yocto's license list...
LICENSE = "CLOSED"
S = "${WORKDIR}/"
# Used to specify the repository location of setup.py
DISTUTILS_SETUP_PATH = "./control"
# Relative repository locations of standard resources
REPO_STATIC_PATH = 'control/static/'
REPO_SEQUENCES_PATH = 'control/sequences/'
REPO_CONFIG_PATH = 'control/config/config.cfg'
# include the rootfs build directory locations in the yocto rootfs on exit
FILES_${PN} += "${base_prefix}/opt/loki-detector/*"
- The
RDEPENDS
is used to specify any dependencies you need along with your recipe -
SUMMARY
should be updated for your project ` This example is using a react-based UI, which has already been compiled and made available as a build artifact from a separate repository. This is the recommended way of producing a UI. See below. -
DISTUTILS_SETUP_PATH
tells the recipe where to look for thesetup.py
-
REPO_STATIC_PATH
is used to point the base recipe to static resources from this repository, if there are any (see UI options below) -
REPO_SEQUENCES_PATH
is used to point the base recipe toodin-sequencer
sequences that should be baked into the image -
REPO_CONFIG_PATH
is used to point the base recipe to theodin-control
config file for starting the server
A UI is optional
- Add the target repository location so that it will grab a certain tag's build outputs, assuming that the repository has been set up with automation to build tagged versions:
# The react UI tag is a separate repository, used to download pre-built static assets
# This will only accept tags that have been built (releases)
REACT_UI_TAG = "v0.0.4"
REACT_SOURCE_PATH = "babyd-ui-${REACT_UI_TAG}"
- Add the following to the
SRC_URI
so that the recipe will pull it (corrected for your repository):
https://github.com/stfc-aeg/hexitec-mhz-ui/releases/download/${REACT_UI_TAG}/build.zip;subdir=${REACT_SOURCE_PATH};name=react-build-zip \
#TODO add how to get it included in the image
A UI is optional
#TODO
A UI is optional
#TODO
For example:
do_install_append() {
# Add a directory to the image for the clock configs at the same relative place
loki_mkdir 'carrier' # Must create parent
copy_resource_protected '${MERCURY_REPO_CLONED_BASE}/control/test/carrier/clk_config' 'carrier/clk_config'
}
#TODO there are helpers to build things into the image in known locations, explain them.
Check that this is still a requirement; it is only used while
odin-sequencer
is not available as part ofodin-react
and must therefore be included separately. WARNING: This is hacky.
Essentially this boils down to three steps:
- Install the sequencer UI as a static page, using the instructions above
- Move the sequencer's
index.html
to a page with a different name post-install, to clear the way for the React UI:
do_install_prepend() {
# Rename the original UI index.html to prevent conflict. This means the sequencer
# can be accessed at <IP>:8888/original.html
# TEMPORARY UNTIL SEQUENCER IS INCLUDED IN REACT UI
mv '${REPO_STATIC_PATH}/index.html' '${REPO_STATIC_PATH}/original.html'
}
- Copy of the React resources manually, hoping that none of the filenames conflict with filenames of the sequencer UI already added to the same location:
do_install_append() {
# Directly copy the react resources into the default working static location.
# This is an untidy way of doing things, and relies on a lack of conflicts
# (apart from the manually handled index.html), but means the two 'separate'
# UI's can be used a the same time.
# A better future solution would be to integrate the sequencer UI into react.
# TEMPORARY UNTIL SEQUENCER IS INCLUDED IN REACT UI
copy_resource_protected '${REACT_SOURCE_PATH}/.' ${LOKI_STATIC_DESTINATION}
}
Generally if all else fails (and your issue is not mentioned below), a make clean && make
should sort most issues out.
Sometimes the PetaLinux tools just get in a state where things are broken and can't easily be recovered.
To save time, try this first in the PetaLinux directory only (cd loki/os/petalinux-custom; make clean && make
) before doing the same in the root directory (since the latter will also rebuild the hardware).
In addition, ensure that you are not using the same Yocto cache location (in machine.env
) for more than one of the Yocto builds, as they will interfere with each other at some point (traditionally later on, once you've forgotten about this).
This is not really a specific error in itself, but to find out more to aid in debugging, you should attempt to build the recipe on its own. This may allow you to spot errors that were masked during the build process (sometimes errors occur and the PetaLinux build just carriers on anyway...).
- Make sure you have the correct PetaLinux tools activated (
module load xilinx/2020-1; petalinux_env
) - Change directory to the PetaLinux root (
cd loki/os/petalinux-custom/
) - Build just your recipe's name (e.g.
petalinux-build -c <projectname>-detector
)
This should build properly by itself, or otherwise print out errors with more information.
If you get the following error, it may not exactly be what it suggests:
'PATCHTOOL = "git" set for source tree that is not a git repository.
This is actually returned by the patch.bbclass
when