diff --git a/kas/opt/module.yml b/kas/opt/module.yml new file mode 100644 index 000000000..5cf905aa3 --- /dev/null +++ b/kas/opt/module.yml @@ -0,0 +1,16 @@ +# +# Copyright (c) Siemens AG, 2024 +# +# Authors: +# Li Hua Qian +# +# This file is subject to the terms and conditions of the MIT License. See +# COPYING.MIT file in the top-level directory. +# + +header: + version: 14 + +local_conf_header: + no-module: | + IOT2050_MODULE_FWU = "1" diff --git a/recipes-app/iot2050-module-firmware-update/files/iot2050-module-firmware-update.tmpl b/recipes-app/iot2050-module-firmware-update/files/iot2050-module-firmware-update.tmpl new file mode 100755 index 000000000..b193ba4c1 --- /dev/null +++ b/recipes-app/iot2050-module-firmware-update/files/iot2050-module-firmware-update.tmpl @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# +# Copyright (c) Siemens AG, 2024 +# +# Authors: +# Li Hua Qian +# +# SPDX-License-Identifier: MIT + +import os +import sys +import argparse +import textwrap + +def main(args): + description=textwrap.dedent('''\ + Script for updating module firmware on IoT2050 + Examples usage: + 1. iot2050-module-firmware-update -s 1 -fwa firmwareA.bin + 2. iot2050-module-firmware-update -s 1 -fwa firmwareA.bin -fwb firmwareB.bin + ''') + parser = argparse.ArgumentParser( + description=description, + formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "-s", "--slot", + type=int, + required=True, + help="Slot number" + ) + parser.add_argument( + "-fwa", "--firmware-a", + help="Path to firmware A file", + type=argparse.FileType('rb') + ) + parser.add_argument( + "-fwb", "--firmware-b", + help="Path to firmware B file", + type=argparse.FileType('rb') + ) + args = parser.parse_args(args) + + if not args.firmware_a and not args.firmware_b: + print("Error: No firmware file specified") + parser.print_help() + return 1 + + slot_path = f"/eiofs/controller/slot{args.slot}" + if args.firmware_a: + print("Updating firmware A ...") + try: + with open(slot_path + "/fwa", "wb") as f: + f.write(args.firmware_a.read()) + except Exception as e: + print(f"Error: Failed to write firmware A, {e}") + return 1 + + if args.firmware_b: + print("Updating firmware B ...") + try: + with open(slot_path + "/fwb", "wb") as f: + f.write(args.firmware_b.read()) + except Exception as e: + print(f"Error: Failed to write firmware B, {e}") + return 1 + + print("Firmware updated successfully. Please reboot the upgraded module.") + + return 0 + +if __name__ == '__main__': + CODE = main(sys.argv[1:]) + sys.exit(CODE) + diff --git a/recipes-app/iot2050-module-firmware-update/iot2050-module-firmware-update_01.bb b/recipes-app/iot2050-module-firmware-update/iot2050-module-firmware-update_01.bb new file mode 100644 index 000000000..9365572fc --- /dev/null +++ b/recipes-app/iot2050-module-firmware-update/iot2050-module-firmware-update_01.bb @@ -0,0 +1,26 @@ +# +# Copyright (c) Siemens AG, 2024 +# +# Authors: +# Li Hua Qian +# +# This file is subject to the terms and conditions of the MIT License. See +# COPYING.MIT file in the top-level directory. +# + +DESCRIPTION = "IOT2050 Customized External Signal Module Firmware Update" +MAINTAINER = "huaqian.li@siemens.com" + +SRC_URI = " \ + file://iot2050-module-firmware-update.tmpl" + +TEMPLATE_FILES = "iot2050-module-firmware-update.tmpl" + +inherit dpkg-raw + +do_install() { + install -v -d ${D}/usr/sbin/ + install -v -m 755 ${WORKDIR}/iot2050-module-firmware-update ${D}/usr/sbin/ +} + +do_deploy_deb[dirs] = "${DEPLOY_DIR_IMAGE}" diff --git a/recipes-core/images/iot2050-image-example.bb b/recipes-core/images/iot2050-image-example.bb index cc9fdae3c..9208b2189 100644 --- a/recipes-core/images/iot2050-image-example.bb +++ b/recipes-core/images/iot2050-image-example.bb @@ -58,3 +58,8 @@ IMAGE_INSTALL += "${@ ' \ iot2050-eio-manager \ iot2050-conf-webui \ ' if d.getVar('IOT2050_EIO_SUPPORT') == '1' else ''}" + +IOT2050_MODULE_FWU ?= "0" +IMAGE_INSTALL += "${@ ' \ + iot2050-module-firmware-update \ + ' if d.getVar('IOT2050_MODULE_FWU') == '1' else '' }"