diff options
Diffstat (limited to 'meta-zephyr-core/classes')
-rw-r--r-- | meta-zephyr-core/classes/siteinfo-zephyr.bbclass | 27 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyr-flash-bossac.bbclass | 50 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyr-flash-dfu.bbclass | 65 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyr-flash-pyocd.bbclass | 64 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyr-qemuboot.bbclass | 55 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyr.bbclass | 55 | ||||
-rw-r--r-- | meta-zephyr-core/classes/zephyrtest.bbclass | 53 |
7 files changed, 369 insertions, 0 deletions
diff --git a/meta-zephyr-core/classes/siteinfo-zephyr.bbclass b/meta-zephyr-core/classes/siteinfo-zephyr.bbclass new file mode 100644 index 0000000..b84a9b2 --- /dev/null +++ b/meta-zephyr-core/classes/siteinfo-zephyr.bbclass @@ -0,0 +1,27 @@ +def arc_siteinfo_setfunc(archinfo, osinfo, targetinfo, d): + archinfo['arc'] = "endian-little bit-32 " + osinfo['linux'] = "common-linux common-glibc" + targetinfo['arc-linux'] = "arc-linux" + return archinfo, osinfo, targetinfo + +SITEINFO_EXTRA_DATAFUNCS += "arc_siteinfo_setfunc" + +def arc_machdata_setfunc(machdata, d): + machdata["elf"]["arc"] = (195, 0, 0, True, 32) + return machdata + +PACKAGEQA_EXTRA_MACHDEFFUNCS += "arc_machdata_setfunc" + +def iamcu_siteinfo_setfunc(archinfo, osinfo, targetinfo, d): + archinfo['iamcu'] = "endian-little bit-32 " + osinfo['linux'] = "common-linux common-glibc" + targetinfo['iamcu-linux'] = "iamcu-linux" + return archinfo, osinfo, targetinfo + +SITEINFO_EXTRA_DATAFUNCS += "iamcu_siteinfo_setfunc" + +def nios2_machdata_setfunc(machdata, d): + machdata["elf"]["nios2"] = (113, 0, 0, True, 32) + return machdata + +PACKAGEQA_EXTRA_MACHDEFFUNCS += "nios2_machdata_setfunc" diff --git a/meta-zephyr-core/classes/zephyr-flash-bossac.bbclass b/meta-zephyr-core/classes/zephyr-flash-bossac.bbclass new file mode 100644 index 0000000..50222d5 --- /dev/null +++ b/meta-zephyr-core/classes/zephyr-flash-bossac.bbclass @@ -0,0 +1,50 @@ +#@DESCRIPTION: class file to flash boards like Arduino Nano BLE which depends on bossac for flashing + +python do_flash_usb() { + import shutil + import subprocess + import serial.tools.list_ports + + # Note: make sure the installed bossac is set to PATH before running flash_usb() + # Check if bossac is avaiable for flashing + origbbenv = d.getVar("BB_ORIGENV", False) + bossac_path = shutil.which("bossac", path=origbbenv.getVar('PATH')) + + if not bossac_path: + bb.fatal("ERROR: bossac not found, please install first and add to PATH") + + board = d.getVar('BOARD') + + if board == 'arduino_nano_33_ble': + # find the serial port to which board is connected to + for port in serial.tools.list_ports.comports(): + if 'Arduino Nano 33 BLE' in port.description: + serial_port = port.device + break + else: + bb.fatal("ERROR: board not connected for flashing. Connect via USB and enable permission to connected port") + + image = "%s/%s.bin" % (d.getVar('DEPLOY_DIR_IMAGE'), d.getVar('PN')) + + command = [bossac_path, '-p', serial_port , '-R', '-e', '-w', '-v', '-b', image] + else: + bb.fatal("ERROR: Unsupported board %s" % board) + + bb.note("command: %s" % command) + bb.plain("Attempting to flash board: %s" % board) + + # Random failure are a possibility here, retry till there is a success for finite times + for _ in range(10, 0, -1): + try: + subprocess.check_call(command) + bb.plain("Bossac Flashing board: %s Success " % board) + break + except subprocess.CalledProcessError as e: + bb.warn("Failed to flash %s (error code: %s). Retrying after 1 second..." % (board, e.returncode)) + time.sleep(1) +} + +addtask do_flash_usb after do_deploy + +do_flash_usb[nostamp] = "1" +do_flash_usb[vardepsexclude] = "BB_ORIGENV" diff --git a/meta-zephyr-core/classes/zephyr-flash-dfu.bbclass b/meta-zephyr-core/classes/zephyr-flash-dfu.bbclass new file mode 100644 index 0000000..b4f3d49 --- /dev/null +++ b/meta-zephyr-core/classes/zephyr-flash-dfu.bbclass @@ -0,0 +1,65 @@ + +python do_flash_usb() { + import subprocess + + # Append the original PATH so we can find dfu-util... + origbbenv = d.getVar("BB_ORIGENV", False) + path = d.getVar('PATH') + ":" + origbbenv.getVar('PATH') + os.environ['PATH'] = path + + return_code = subprocess.call("which dfu-util", shell=True) + if return_code != 0: + bb.error("ERROR: dfu-util binary not in PATH") + sys.exit(1) + + board = d.getVar('BOARD') + + if board == 'arduino_101_sss': + iface = 'sensor_core' + elif board == 'arduino_101': + iface = 'x86_app' + elif board == 'arduino_101_ble': + iface = 'ble_core' + else: + bb.error(" Unsupported board %s" % board) + sys.exit(2) + + # We need to serialize flashing of separate images (when using multiconfig) + lock = bb.utils.lockfile(os.path.join(d.getVar('TOPDIR'),"flash-dfu.lock"), False, True) + image = "%s/%s.elf" % (d.getVar('DEPLOY_DIR_IMAGE'), d.getVar('PN')) + statement = 'dfu-util -v -a ' + iface + ' -d 8087:0aba -D ' + image.replace('elf','bin') + + bb.note("command: %s" % statement) + bb.plain("Attempting to flash board: %s" % board) + + # Arduino-101 needs to be reset in order to enter "flash mode". + # The flash window is about 5 seconds. + # However, if the device is flashed, it remains in the "flash mode" + # until it is reset again, so it needs to enter the flash mode via reset + # only once even if we flash images for multiple cores. So we only prompt + # for reset once. + + timeout = 5 + promptneeded = True + while (timeout > 0): + time.sleep(0.5) + timeout = timeout - 0.5 + return_code = subprocess.call(statement, shell=True) + if return_code == 0: + break + if promptneeded: + bb.warn("\n\n *** Failed to flash %s. *** \n Press reset, will retry for five seconds...\n" % board) + promptneeded = False + + if return_code != 0: + bb.error("Error flashing %s [%d]" % (board,return_code)) + else: + bb.plain("Success (return code %d)" % return_code) + + bb.utils.unlockfile(lock) +} + +addtask do_flash_usb after do_deploy + +do_flash_usb[nostamp] = "1" +do_flash_usb[vardepsexclude] = "BB_ORIGENV" diff --git a/meta-zephyr-core/classes/zephyr-flash-pyocd.bbclass b/meta-zephyr-core/classes/zephyr-flash-pyocd.bbclass new file mode 100644 index 0000000..6517945 --- /dev/null +++ b/meta-zephyr-core/classes/zephyr-flash-pyocd.bbclass @@ -0,0 +1,64 @@ +PYOCD_CONNECT_TIMEOUT_SECONDS ?= "30" +PYOCD_FLASH_IDS ?= "all" + +python do_flash_usb() { + try: + from pyocd.core.helpers import ConnectHelper + from pyocd.flash.file_programmer import FileProgrammer + except ImportError: + bb.fatal("Flashing with pyocd needs the relevant python package. Make sure your host provides it or consult your distribution packages for how to install this prerequisite.") + + try: + timeout = int(d.getVar('PYOCD_CONNECT_TIMEOUT_SECONDS')) + except ValueError: + bb.fatal(f"PYOCD_CONNECT_TIMEOUT_SECONDS was set to an invalid value: {d.getVar('PYOCD_CONNECT_TIMEOUT_SECONDS')}.") + image = f"{d.getVar('DEPLOY_DIR_IMAGE')}/{d.getVar('PN')}.elf" + ids = d.getVar('PYOCD_FLASH_IDS') + + # Compute the list of IDs to program + if ids == 'all': + ids = [] + for probe in ConnectHelper.get_all_connected_probes(blocking=False): + ids.append(probe.unique_id) + if not ids: + bb.fatal("No probe detected. Make sure your target is connected.") + else: + ids = ids.split() + if not ids: + bb.fatal("No probe requested for programming. Make sure PYOCD_FLASH_IDS is set.") + + # Fetch target type to pass to the ConnectHelper + target = d.getVar('PYOCD_TARGET') + + # Program each ID + for id in ids: + bb.plain(f"Attempting to flash {os.path.basename(image)} to board {d.getVar('BOARD')} [{id}]") + + # Try to connect to a probe with a timeout + now = 0 + step = 3 + while True: + if target is not None: + session = ConnectHelper.session_with_chosen_probe(blocking=False, return_first=True, unique_id=id, target_override=target) + else: + bb.warn(f"Target type not provided. Flashing may fail or result in an undefined behavior.") + session = ConnectHelper.session_with_chosen_probe(blocking=False, return_first=True, unique_id=id) + + if session: + break + if now >= timeout: + bb.fatal(f"Timeout while trying to connect to probe ID: {id}. Make sure the target device is connected and the udev is configured accordingly. See <https://github.com/mbedmicro/pyOCD/tree/master/udev> for help.") + bb.warn(f"Can't connect to the probe ID: {id}. Retrying in {step} seconds...") + time.sleep(step) + now += step + + # Program the selected probe + with session: + FileProgrammer(session).program(image) + session.board.target.reset() +} + +addtask do_flash_usb after do_deploy + +do_flash_usb[nostamp] = "1" +do_flash_usb[vardepsexclude] = "BB_ORIGENV" diff --git a/meta-zephyr-core/classes/zephyr-qemuboot.bbclass b/meta-zephyr-core/classes/zephyr-qemuboot.bbclass new file mode 100644 index 0000000..b45e6f6 --- /dev/null +++ b/meta-zephyr-core/classes/zephyr-qemuboot.bbclass @@ -0,0 +1,55 @@ +inherit qemuboot + +KERNEL_IMAGETYPE = "${PN}.elf" +QB_DEFAULT_FSTYPE = "elf" +QB_NETWORK_DEVICE = "none" +QB_NET = "none" +QB_ROOTFS = "none" + +IMAGE_LINK_NAME = "${PN}-image-${MACHINE}" + +# Create a link with "-image-" in the name just to keep runqemu happy +QEMU_IMAGE_LINK = "${DEPLOY_DIR_IMAGE}/${PN}-image-${MACHINE}.elf" + +CLEANFUNCS += "bootconf_clean" + +python bootconf_clean() { + import glob + files = glob.glob(d.getVar('IMGDEPLOYDIR', True)+'/'+ d.getVar('PN', True) + '*.qemuboot.conf') + for f in files: + os.remove(f) + + qemuimage_link = d.getVar('QEMU_IMAGE_LINK', True) + if os.path.lexists(qemuimage_link): + os.remove(qemuimage_link) +} + +python do_bootconf_write() { + bb.build.exec_func("do_write_qemuboot_conf", d) + + qemuimage = "%s/%s.elf" % (d.getVar('DEPLOY_DIR_IMAGE', True), d.getVar('PN', True)) + qemuimage_link = d.getVar('QEMU_IMAGE_LINK', True) + if os.path.lexists(qemuimage_link): + os.remove(qemuimage_link) + os.symlink(os.path.basename(qemuimage), qemuimage_link) +} + +addtask do_bootconf_write before do_build after do_deploy + +# The runqemu script requires the native sysroot populated for the +# qemu-helper-native recipes. Usually, this is pulled in by a do_image +# dependency (see baremetal-helloworld_git, for example), but in this case, +# there is no such task, so we hook in the dependency to do_bootconf_write. +# This also ensures that builds from sstate will also have this requirement +# satisfied. +python () { + def extraimage_getdepends(task): + deps = "" + for dep in (d.getVar('EXTRA_IMAGEDEPENDS') or "").split(): + # Make sure we only add it for qemu + if 'qemu-helper-native' in dep: + deps += " qemu-helper-native:%s" % (task) + return deps + d.appendVarFlag('do_bootconf_write', 'depends', extraimage_getdepends('do_addto_recipe_sysroot')) + d.appendVarFlag('do_bootconf_write', 'depends', extraimage_getdepends('do_populate_sysroot')) +} diff --git a/meta-zephyr-core/classes/zephyr.bbclass b/meta-zephyr-core/classes/zephyr.bbclass new file mode 100644 index 0000000..e1d3185 --- /dev/null +++ b/meta-zephyr-core/classes/zephyr.bbclass @@ -0,0 +1,55 @@ +inherit terminal + +OE_TERMINAL_EXPORTS += "HOST_EXTRACFLAGS HOSTLDFLAGS TERMINFO CROSS_CURSES_LIB CROSS_CURSES_INC" +HOST_EXTRACFLAGS = "${BUILD_CFLAGS} ${BUILD_LDFLAGS}" +HOSTLDFLAGS = "${BUILD_LDFLAGS}" +CROSS_CURSES_LIB = "-lncurses -ltinfo" +CROSS_CURSES_INC = '-DCURSES_LOC="<curses.h>"' +TERMINFO = "${STAGING_DATADIR_NATIVE}/terminfo" + +KCONFIG_CONFIG_COMMAND ??= "menuconfig" +ZEPHYR_BOARD ?= "${MACHINE}" + +# qemuboot writes into IMGDEPLOYDIR, force to write to DEPLOY_DIR_IMAGE +IMGDEPLOYDIR = "${DEPLOY_DIR_IMAGE}" + +python () { + # Translate MACHINE into Zephyr BOARD + # Zephyr BOARD is basically our MACHINE, except we must use "-" instead of "_" + board = d.getVar('ZEPHYR_BOARD', True) + board = board.replace('-', '_') + d.setVar('BOARD',board) +} + +python do_menuconfig() { + os.chdir(d.getVar('ZEPHYR_SRC_DIR', True)) + configdir = d.getVar('ZEPHYR_SRC_DIR', True) + '/outdir/' + d.getVar('BOARD', True) + try: + mtime = os.path.getmtime(configdir +"/.config") + except OSError: + mtime = 0 + + oe_terminal("${SHELL} -c \"ZEPHYR_BASE=%s make BOARD=%s %s; if [ \$? -ne 0 ]; then echo 'Command failed.'; \ + printf 'Press any key to continue... '; \ + read r; fi\"" % (d.getVar('ZEPHYR_BASE', True), d.getVar('BOARD', True),d.getVar('KCONFIG_CONFIG_COMMAND', True)), + d.getVar('PN', True) + ' Configuration', d) + + try: + newmtime = os.path.getmtime(configdir +"/.config") + except OSError: + newmtime = 0 + + if newmtime > mtime: + bb.warn("Configuration changed, recompile will be forced") + bb.build.write_taint('do_compile', d) +} +do_menuconfig[depends] += "ncurses-native:do_populate_sysroot" +do_menuconfig[nostamp] = "1" +do_menuconfig[dirs] = "${B}" +addtask menuconfig after do_configure + +python do_devshell:prepend () { + # Most likely we need to manually edit prj.conf... + os.chdir(d.getVar('ZEPHYR_SRC_DIR', True)) +} + diff --git a/meta-zephyr-core/classes/zephyrtest.bbclass b/meta-zephyr-core/classes/zephyrtest.bbclass new file mode 100644 index 0000000..248fd15 --- /dev/null +++ b/meta-zephyr-core/classes/zephyrtest.bbclass @@ -0,0 +1,53 @@ +inherit rootfs-postcommands + +python zephyrtest_virtclass_handler () { + variant = e.data.getVar("BBEXTENDVARIANT", True) + + # ipk doesn't like underscores in pacakges names. So just use dashes + # for PN and the image name. + variant_dashes = variant.replace('_', '-') + + pn = variant_dashes + pn_underscores = e.data.getVar("PN") + "-" + variant + + e.data.setVar("PN", pn) + e.data.setVar("ZEPHYR_IMAGENAME", pn + ".elf") + + # Most tests for Zephyr 1.6 are in the "legacy" folder + e.data.setVar("ZEPHYR_SRC_DIR", "tests/kernel/" + variant) + e.data.setVar("ZEPHYR_MAKE_OUTPUT", "zephyr.elf") + + # Allow to build using both foo-some_test form as well as foo-some-test + e.data.setVar("PROVIDES", e.data.getVar("PROVIDES") + pn_underscores) +} + +addhandler zephyrtest_virtclass_handler +zephyrtest_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise" + +IMAGE_LINK_NAME = "${PN}-image-${MACHINE}" + +# Generate test data json file +python do_testdata_write() { + bb.build.exec_func("write_image_test_data", d) + + # While at it, create dummy manifest files so testimage does not + # complain... + + fname = os.path.join(d.getVar('DEPLOY_DIR_IMAGE'), (d.getVar('IMAGE_LINK_NAME') + ".manifest")) + open(fname, 'w').close() +} + +CLEANFUNCS += "testdata_clean" + +python testdata_clean() { + import glob + + files = glob.glob(d.getVar('DEPLOY_DIR_IMAGE')+'/'+ d.getVar('PN') + '*.testdata.json') + for f in files: + os.remove(f) + fname = os.path.join(d.getVar('DEPLOY_DIR_IMAGE'), (d.getVar('IMAGE_LINK_NAME') + ".manifest")) + if os.path.exists(fname): + os.remove(fname) +} + +addtask do_testdata_write before do_build after do_deploy |