summaryrefslogtreecommitdiff
path: root/python/openvino/runtime/create_hps_image.sh
diff options
context:
space:
mode:
Diffstat (limited to 'python/openvino/runtime/create_hps_image.sh')
-rwxr-xr-xpython/openvino/runtime/create_hps_image.sh488
1 files changed, 488 insertions, 0 deletions
diff --git a/python/openvino/runtime/create_hps_image.sh b/python/openvino/runtime/create_hps_image.sh
new file mode 100755
index 0000000..74df01c
--- /dev/null
+++ b/python/openvino/runtime/create_hps_image.sh
@@ -0,0 +1,488 @@
+#! /bin/bash
+set -o errexit
+
+#
+# This script is a starter script for building an ED4 SD Card image on the HPS platform.
+# This script wraps the following steps:
+# 1. Build bitstreams (S2M) if specified
+# 2. Build Yocto SD card image (.wic) to obtain the toolchain SDK or use prebuilt .wic.
+# 3. Use the SDK to cross-build HPS packages and CoreDLA runtime
+# 4. Update the .wic image with CoreDLA executable, libraries, and FPGA bitstreams
+
+if [[ -z "${COREDLA_ROOT}" ]]; then
+ echo "Error: COREDLA_ROOT environment variable not set. Run init_env.sh script first."
+ exit 1
+fi
+
+
+SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+# runtime
+RUNTIME_DIR="${SCRIPT_PATH}" # this script should always be located in runtime
+RUNTIME_BUILD_TYPE="Release" # Release or Debug. Release will build OpenVINO and DLA in debug mode
+RUNTIME_BUILD_DIR="${RUNTIME_DIR}/build_${RUNTIME_BUILD_TYPE}"
+BUILD_RUNTIME_SCRIPT="${RUNTIME_DIR}/build_runtime.sh"
+
+# Yocto
+ED4_DIR="${COREDLA_ROOT}/hps/ed4"
+ED4_SCRIPT_DIR="${ED4_DIR}/scripts"
+UPDATE_SDCARD_SCRIPT="${ED4_SCRIPT_DIR}/update_sd_card.sh"
+USING_PREBUILT_YOCTO=false
+UPDATE_SDCARD=false
+YOCTO_DIR="${ED4_DIR}/yocto"
+YOCTO_BUILD_SCRIPT="${YOCTO_DIR}/run-build.sh"
+YOCTO_BUILD_DIR="${RUNTIME_DIR}/build_Yocto"
+MACHINE="arria10" # default device family
+
+# HPS packages
+BUILD_HPSPACKAGES_SCRIPT="${RUNTIME_DIR}/build_hpspackages.sh"
+HPSPACKAGES_BUILD_DIR="${RUNTIME_DIR}/hps_packages"
+
+# Build bitstreams
+BUILD_BITSTREAM=false
+BUILD_BITSTREAM_SCRIPT="${COREDLA_ROOT}/bin/dla_build_example_design.py"
+
+#################################################################
+function usage
+{
+ echo -e "\nThis script is a starter script for building an ED4 SD Card image on the HPS platform."\
+ "This script wraps the following steps:"\
+ "\n\t1. Build an S2M bitstream of choice for Arm-based SoC (if specified)"\
+ "\n\t2. Build a Yocto SD card image (.wic) and obtain the toolchain SDK."\
+ "\n\t3. Use the SDK from step 2 to cross-compile dependency packages and CoreDLA runtime"\
+ "\n\t4. Update the .wic image with CoreDLA runtime, libraries, and FPGA bitstream"\
+ "\n"
+ echo "create_hps_image.sh -o <PATH> [-f <PATH>] [-y] [-u] [-b] [-h] [-a <PATH>] [-m <FPGA Machine>]"
+ echo ""
+ echo "Options:"
+ echo -e " -h Display usage"
+ echo -e " -c Clean the runtime directory back to its default state"
+ echo -e " -o (Required) Path to the output directory to save the updated SD card image."
+ echo -e " -u (Optional) Specify this to update the SD card .wic image at the end. If this option is set, the DLA runtime"
+ echo -e " and the FPGA bitstream specified by -f will be written to .wic image at the end. This option is helpful"
+ echo -e " if a user only wants to build the DLA runtime without a working bitstream. In this case, you can skip"
+ echo -e " setting -u and -f."
+ echo -e " -b (Optional) Whether to build a bitstream (S2M) using the arch file specified by -a."
+ echo -e " -a (Optional) Path to the architecture file. Required if -b is set. "
+ echo -e " -f (Optional) Path to the FPGA directory that contains the target FPGA bitstreams."
+ echo -e " This is a REQUIRED argument if at least one of the following conditions is met: "
+ echo -e " 1. -u is set, i.e., update SD card with the bitstreams in this directory at the end."
+ echo -e " The directory must contain top.core.rbf top.periph.rbf;"
+ echo -e " 2. -b is set, i.e., build bitstream and save to this location"
+ echo -e " -y (Optional) Path to a pre-built Yocto image directory. If given, this script skips"
+ echo -e " building the Yocto image from scratch and use the .wic image and the poky SDK file from"
+ echo -e " this build directory instead"
+ echo -e " -m (Optional) FPGA Machine. Options: arria10 (Arria 10 SoC), agilex7_dk_si_agi027fa (Agilex 7 SoC). Default: arria10"
+ echo
+}
+
+function clean_runtime()
+{
+ echo "Cleaning runtime directory"
+
+ echo "rm -rf ${RUNTIME_BUILD_DIR}"
+ rm -rf ${RUNTIME_BUILD_DIR}
+
+ echo "rm -rf ${RUNTIME_DIR}/embedded_arm_sdk"
+ rm -rf ${RUNTIME_DIR}/embedded_arm_sdk
+
+ echo "rm -rf ${HPSPACKAGES_BUILD_DIR}"
+ rm -rf ${HPSPACKAGES_BUILD_DIR}
+
+ # Search for presence of Poky SDK file
+ ED4_POKY_SDK_NAME="poky*.sh"
+ ED4_POKY_SDK_FILE_LOC="$(find ${RUNTIME_DIR} -maxdepth 1 -type f -name ${ED4_POKY_SDK_NAME})"
+
+ # Confirm presence of Poky SDK file and remove it
+ if [ -e "${ED4_POKY_SDK_FILE_LOC}" ]; then
+ echo "rm -rf ${ED4_POKY_SDK_FILE_LOC}"
+ rm -rf ${ED4_POKY_SDK_FILE_LOC}
+ fi
+}
+
+while getopts "hcbuf:o:y:m:a:" optname; do
+ case "$optname" in
+ h)
+ usage
+ exit 0
+ ;;
+ c)
+ clean_runtime
+ exit 0
+ ;;
+ f)
+ if [[ ${OPTARG} != /* ]]; then
+ ED4_BITSTREAM_DIR="$(pwd)/${OPTARG}"
+ else
+ ED4_BITSTREAM_DIR=${OPTARG}
+ fi
+ ;;
+ o)
+ if [[ ${OPTARG} != /* ]]; then
+ ED4_SDCARD_DIR="$(pwd)/${OPTARG}"
+ else
+ ED4_SDCARD_DIR=${OPTARG}
+ fi
+ ED4_ROOTFS_DIR="${ED4_SDCARD_DIR}/ed4_root"
+ ED4_APP_DIR="${ED4_ROOTFS_DIR}/home/root/app"
+ ;;
+ u)
+ UPDATE_SDCARD=true
+ ;;
+ b)
+ BUILD_BITSTREAM=true
+ ;;
+ y)
+ if [[ ${OPTARG} != /* ]]; then
+ YOCTO_BUILD_DIR="$(pwd)/${OPTARG}"
+ else
+ YOCTO_BUILD_DIR=${OPTARG}
+ fi
+ USING_PREBUILT_YOCTO=true
+ ;;
+ m)
+ MACHINE=${OPTARG}
+ if ! [[ "${MACHINE}" == "agilex7_dk_si_agi027fa" || "${MACHINE}" == "stratix10" || "${MACHINE}" == "arria10" ]]; then
+ usage
+ exit 1
+ fi
+ ;;
+ a)
+ if [[ ${OPTARG} != /* ]]; then
+ ARCH_FILE="$(pwd)/${OPTARG}"
+ else
+ ARCH_FILE=${OPTARG}
+ fi
+ ;;
+ esac
+done
+
+if [[ -z ${ED4_SDCARD_DIR} ]]; then
+ usage
+ echo "Error: -o is required"
+ exit 1;
+fi
+
+if [[ "${UPDATE_SDCARD}" == true && ! -d ${ED4_BITSTREAM_DIR} && "${BUILD_BITSTREAM}" == false ]]; then
+ usage
+ echo "Error: -f is required and must exist if -u is set. "\
+ "Add -b if you want to build bitstreams"
+ exit 1;
+fi
+
+if [[ "${BUILD_BITSTREAM}" == true ]]; then
+ if [[ -z ${ED4_BITSTREAM_DIR} ]]; then
+ usage
+ echo "Error: -f must be specified if building a bitstream"
+ exit 1;
+ fi
+ if [[ -z ${ARCH_FILE} ]]; then
+ usage
+ echo "Error: -a must be specified if building a bitstream"
+ exit 1;
+ fi
+ if [[ -d ${ED4_BITSTREAM_DIR} && "$(ls -A ${ED4_BITSTREAM_DIR})" ]]; then
+ echo "Error: ${ED4_BITSTREAM_DIR} is not empty. "
+ exit 1;
+ fi
+ if [[ -n "${DISPLAY}" ]]; then
+ # Check if xdpyinfo command is available
+ if command -v xdpyinfo &> /dev/null; then
+ # xdpyinfo exits successfully if a valid display is detected
+ if ! xdpyinfo &> /dev/null; then
+ echo "Error: X-11 Forwarding is enabled and connected to an invalid display: ${DISPLAY}. Unset DISPLAY environment variable to continue."
+ exit 1;
+ fi
+ else
+ echo "Warning: X-11 Forwarding is enabled and potentially connected to an invalid display: ${DISPLAY}. Results may be unpredictable."
+ fi
+ fi
+fi
+
+function build_s2m_bitstream()
+{
+ if [ ! -f "${BUILD_BITSTREAM_SCRIPT}" ]; then
+ echo "Error: Cannot find ${BUILD_BITSTREAM_SCRIPT}."
+ exit 1
+ fi
+
+ echo "Building bitstream for ${MACHINE}"
+
+ ed="4_A10_S2M"
+ if [ "${MACHINE}" == "stratix10" ]; then
+ ed="4_S10_S2M"
+ elif [ "${MACHINE}" == "agilex7_dk_si_agi027fa" ]; then
+ ed="4_AGX7_S2M"
+ fi
+
+ ${BUILD_BITSTREAM_SCRIPT} -a ${ARCH_FILE} --build --output-dir=${ED4_BITSTREAM_DIR} -n 1 -ed=${ed}
+ BUILD_BITSTREAM_RESULT=$?
+ if [ $BUILD_BITSTREAM_RESULT -eq 1 ]; then
+ echo "Bitstream failed to build. "
+ exit 1
+ fi
+
+ if [ "${MACHINE}" == "arria10" ]; then
+ if [[ $(find ${ED4_BITSTREAM_DIR} -name '*.periph.rbf' | wc -l) -eq 1 &&
+ $(find ${ED4_BITSTREAM_DIR} -name '*.core.rbf' | wc -l) -eq 1 ]]; then
+ periph=$(find ${ED4_BITSTREAM_DIR} -name '*.periph.rbf')
+ core=$(find ${ED4_BITSTREAM_DIR} -name '*.core.rbf')
+ mv $periph "${ED4_BITSTREAM_DIR}/top.periph.rbf"
+ mv $core "${ED4_BITSTREAM_DIR}/top.core.rbf"
+ else
+ echo "Error: You should have exactly 1 periph.rbf and 1 core.rbf in ${ED4_BITSTREAM_DIR}"
+ exit 1
+ fi
+ else
+ if [[ $(find ${ED4_BITSTREAM_DIR} -name '*.sof' | wc -l) -eq 1 ]]; then
+ top=$(find ${ED4_BITSTREAM_DIR} -name '*.sof')
+ mv $top "${ED4_BITSTREAM_DIR}/top.sof"
+ else
+ echo "Error: You should have exactly 1 .sof file in ${ED4_BITSTREAM_DIR}"
+ exit 1
+ fi
+ fi
+}
+
+function build_yocto()
+{
+ if [ ! -f "${YOCTO_BUILD_SCRIPT}" ]; then
+ echo "Error: Cannot find run-build.sh at ${YOCTO_DIR}."
+ exit 1
+ fi
+ echo "Building Yocto for ${MACHINE}"
+ if [[ "${USING_PREBUILT_YOCTO}" == false ]]; then
+ umask a+rx u+rwx
+ fi
+ pushd $YOCTO_DIR
+ # -i: build_image; -s: build_sdk, -b <build_directory>: build location
+ if [[ "${USING_PREBUILT_YOCTO}" == false ]]; then
+ ${YOCTO_BUILD_SCRIPT} -is -b ${YOCTO_BUILD_DIR} ${MACHINE}
+ else
+ echo "Using prebuilt Yocto: ${YOCTO_BUILD_DIR}"
+ fi
+ YOCTO_BUILD_RESULT=$?
+ if [ $YOCTO_BUILD_RESULT -eq 0 ]; then
+ echo "Yocto built successfully. "
+ YOCTO_SDK_DIR="${YOCTO_BUILD_DIR}/build/tmp/deploy/sdk"
+ export SEARCH_NAME="poky*${MACHINE}*.sh"
+ export ED4_POKY_SDK_LOC="$(find ${YOCTO_SDK_DIR} -name ${SEARCH_NAME})"
+ if [ ! -f "${ED4_POKY_SDK_LOC}" ]; then
+ echo "Error: Cannot find the POKY SDK in ${YOCTO_SDK_DIR}. "
+ exit 1
+ else
+ echo "The POKY SDK can be found at ${ED4_POKY_SDK_LOC}"
+ fi
+
+ # Newer versions of Yocto generate a symlink to the .wic file with an extension of .rootfs.wic
+ # instead of just .wic. To keep everything working, make a copy of the file without the .rootfs extension.
+ YOCTO_WIC_DIR="${YOCTO_BUILD_DIR}/build/tmp/deploy/images/${MACHINE}"
+ YOCTO_WIC_FILE="coredla-image-${MACHINE}.wic"
+ YOCTO_ROOTFS_WIC_FILE="coredla-image-${MACHINE}.rootfs.wic"
+
+ # Check if the .wic file is missing
+ if [ ! -f "${YOCTO_WIC_DIR}/${YOCTO_WIC_FILE}" ]; then
+
+ # Check if the .rootfs.wic file is present
+ if [ -f "${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_WIC_FILE}" ]; then
+ cp -a "${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_WIC_FILE}" "${YOCTO_WIC_DIR}/${YOCTO_WIC_FILE}"
+ else
+ echo "Error: ${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_WIC_FILE} missing"
+ exit 1
+ fi
+ fi
+
+ WIC_COPY_RESULT=$?
+ if [ $WIC_COPY_RESULT -eq 0 ]; then
+ echo "The .wic file can be found at ${YOCTO_WIC_DIR}/${YOCTO_WIC_FILE}"
+ else
+ echo "Error: ${YOCTO_WIC_DIR}/${YOCTO_WIC_FILE} missing"
+ exit 1
+ fi
+
+ # The same issue as above applies to the .cpio file
+ YOCTO_CPIO_FILE="coredla-image-${MACHINE}.cpio"
+ YOCTO_ROOTFS_CPIO_FILE="coredla-image-${MACHINE}.rootfs.cpio"
+
+ # Check if the .cpio file is missing
+ if [ ! -f "${YOCTO_WIC_DIR}/${YOCTO_CPIO_FILE}" ]; then
+
+ # Check if the .rootfs.cpio file is present
+ if [ -f "${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_CPIO_FILE}" ]; then
+ cp -a "${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_CPIO_FILE}" "${YOCTO_WIC_DIR}/${YOCTO_CPIO_FILE}"
+ else
+ echo "Error: ${YOCTO_WIC_DIR}/${YOCTO_ROOTFS_CPIO_FILE} missing"
+ exit 1
+ fi
+ fi
+
+ CPIO_COPY_RESULT=$?
+ if [ $CPIO_COPY_RESULT -eq 0 ]; then
+ echo "The .cpio file can be found at ${YOCTO_WIC_DIR}/${YOCTO_CPIO_FILE}"
+ else
+ echo "Error: ${YOCTO_WIC_DIR}/${YOCTO_CPIO_FILE} missing"
+ exit 1
+ fi
+
+ else
+ echo "Yocto failed to build"
+ exit 1
+ fi
+ popd
+}
+
+function build_hpspackages()
+{
+ if [ ! -f "${BUILD_HPSPACKAGES_SCRIPT}" ]; then
+ echo "Error: Cannot find build_hpspackages.sh at ${RUNTIME_DIR}."
+ exit 1
+ fi
+
+ echo "Building hps packages..."
+ pushd $RUNTIME_DIR
+ if [[ $RUNTIME_BUILD_TYPE == "Release" ]]; then
+ ${BUILD_HPSPACKAGES_SCRIPT} -bs # -b: build; -s: get sources
+ elif [[ $RUNTIME_BUILD_TYPE == "Debug" ]]; then
+ ${BUILD_HPSPACKAGES_SCRIPT} -bds # -b: build; -s: get sources -d: build openvino with cmake debug
+ fi
+ HPSPACKAGES_BUILD_RESULT=$?
+ if [ $HPSPACKAGES_BUILD_RESULT -eq 0 ]; then
+ echo "HPS packages built successfully. "
+ else
+ echo "HPS packages failed to build. "
+ exit 1
+ fi
+ popd
+
+}
+
+function build_hps_dla_runtime()
+{
+ if [ ! -f "${BUILD_RUNTIME_SCRIPT}" ]; then
+ echo "Error: Cannot find build_runtime.sh at ${RUNTIME_DIR}."
+ exit 1
+ fi
+
+ # arm32 or arm64 platform depends on arria10 or stratix10
+ ARM_ARCH="armv7l"
+ if [[ "${MACHINE}" == "agilex7_dk_si_agi027fa" || "${MACHINE}" == "stratix10" ]]; then
+ ARM_ARCH="aarch64"
+ fi
+
+ echo "Building runtime with the HPS platform..."
+ pushd $RUNTIME_DIR
+ if [[ $RUNTIME_BUILD_TYPE == "Release" ]]; then
+ ${BUILD_RUNTIME_SCRIPT} --hps_platform --hps_machine=${MACHINE} --build_dir=${RUNTIME_BUILD_DIR}
+ elif [[ $RUNTIME_BUILD_TYPE == "Debug" ]]; then
+ ${BUILD_RUNTIME_SCRIPT} --hps_platform --hps_machine=${MACHINE} --build_dir=${RUNTIME_BUILD_DIR} -cmake_debug
+ else
+ echo "Unrecognized build type ${RUNTIME_BUILD_TYPE}. "
+ exit 1
+ fi
+
+ RUNTIME_BUILD_RESULT=$?
+ if [ $RUNTIME_BUILD_RESULT -eq 0 ]; then
+ echo "DLA runtime built successfully. "
+ else
+ echo "DLA runtime failed to build. "
+ exit 1
+ fi
+ popd
+
+ # extract executable and libraries for ED4
+ mkdir -p "${ED4_APP_DIR}"
+
+ pushd $ED4_APP_DIR
+ # rsync is used for convenience to select/exclude files destined for the SD card
+ rsync -avzP ${RUNTIME_BUILD_DIR}/dla_benchmark/dla_benchmark .
+
+ rsync -avzP ${HPSPACKAGES_BUILD_DIR}/openvino/bin/${ARM_ARCH}/${RUNTIME_BUILD_TYPE}/*.so* .
+ rsync -avzP ${HPSPACKAGES_BUILD_DIR}/openvino/bin/${ARM_ARCH}/Release/libopenvino_arm_cpu_plugin.so .
+
+ rsync -avzP ${RUNTIME_BUILD_DIR}/common/format_reader/libformat_reader.so .
+ rsync -avzP ${RUNTIME_BUILD_DIR}/coredla_device/mmd/hps_platform/libhps_platform_mmd.so .
+ rsync -avzP ${RUNTIME_BUILD_DIR}/hetero_plugin/libcoreDLAHeteroPlugin.so .
+ rsync -avzP ${RUNTIME_BUILD_DIR}/libcoreDlaRuntimePlugin.so .
+ rsync -avzP ${RUNTIME_BUILD_DIR}/plugins.xml .
+
+ rsync -avzP --exclude libopencv_highgui.so \
+ --exclude libopencv_core.so \
+ --exclude libopencv_imgcodecs.so \
+ --exclude libopencv_imgproc.so \
+ --exclude libopencv_videoio.so \
+ ${HPSPACKAGES_BUILD_DIR}/armcpu_package/opencv/lib/*.so* .
+
+ rsync -avzP ${RUNTIME_BUILD_DIR}/streaming/image_streaming_app/image_streaming_app .
+ rsync -avzP ${RUNTIME_BUILD_DIR}/streaming/streaming_inference_app/streaming_inference_app .
+ rsync -avzP ${RUNTIME_DIR}/streaming/runtime_scripts/run_image_stream.sh .
+ rsync -avzP ${RUNTIME_DIR}/streaming/runtime_scripts/run_inference_stream.sh .
+ rsync -avzP ${RUNTIME_DIR}/streaming/streaming_inference_app/categories.txt .
+ rsync -avzP ${COREDLA_ROOT}/build_version.txt .
+ rsync -avzP ${COREDLA_ROOT}/build_os.txt .
+ popd
+
+ # Derive the .arch file from the selected MACHINE
+ ARCH_FILE="A10_Performance.arch"
+ if [ "${MACHINE}" == "agilex7_dk_si_agi027fa" ]; then
+ ARCH_FILE="AGX7_Performance.arch"
+ elif [ "${MACHINE}" == "stratix10" ]; then
+ ARCH_FILE="S10_Performance.arch"
+ fi
+
+ # update the -arch flag in run_inference_stream.sh to match the selected MACHINE
+ sed -i "s/A10_Performance.arch/$ARCH_FILE/" $ED4_APP_DIR/run_inference_stream.sh
+
+ # change the CPU plugin in plugins.xml to armPlugin
+ sed -i "s/libopenvino_intel_cpu_plugin.so/libopenvino_arm_cpu_plugin.so/" $ED4_APP_DIR/plugins.xml
+}
+
+function update_sd_card_image()
+{
+ if [ ! -f "${UPDATE_SDCARD_SCRIPT}" ]; then
+ echo "Error: Cannot find update_sd_card.sh at ${ED4_SCRIPT_DIR}."
+ exit 1
+ fi
+ export SDCARD_IMAGE_LOC="$(find ${YOCTO_BUILD_DIR}/build/tmp/deploy/images -name *coredla-image-${MACHINE}.wic)"
+ if [ ! -f "${SDCARD_IMAGE_LOC}" ]; then
+ echo "Error: Cannot find SD Card image (.wic) at ${YOCTO_BUILD_DIR}/build/tmp/deploy/images. Have you built Yocto?."
+ exit 1
+ fi
+
+ echo "Updating SD Card image..."
+ pushd $ED4_SCRIPT_DIR
+ ${UPDATE_SDCARD_SCRIPT} -w ${SDCARD_IMAGE_LOC} -o ${ED4_SDCARD_DIR} -f ${ED4_BITSTREAM_DIR} -r ${ED4_ROOTFS_DIR}
+ UPDATE_SDCARD_RESULT=$?
+ if [ $UPDATE_SDCARD_RESULT -eq 0 ]; then
+ echo "Updated SD card image successfully. "
+ else
+ echo "Failed to update SD card image. "
+ exit 1
+ fi
+ popd
+
+ if [[ $(find ${ED4_SDCARD_DIR} -name '*.wic' | wc -l) ]]; then
+ echo "The .wic image can be found here:"
+ echo $(find ${ED4_SDCARD_DIR} -name '*.wic')
+ else
+ echo "Cannot find updated .wic image in ${ED4_SDCARD_DIR}"
+ exit 1
+ fi
+}
+#################################################################
+
+
+# step 0: build bitstream
+if [[ "${BUILD_BITSTREAM}" == true ]]; then
+ build_s2m_bitstream
+fi
+# step 1: build Yocto
+build_yocto
+# step 2: build hps packages
+build_hpspackages
+# step 3: build coredla runtime on the hps platform
+build_hps_dla_runtime
+# step 4: update the .wic image from step 1 with hps runtime and fpga bitstreams
+if [[ "${UPDATE_SDCARD}" == true ]]; then
+ update_sd_card_image
+fi
+
+echo "All steps succeeded"