Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | #!/usr/bin/env python """ Utility script to assist in the migration of a board from hardware model v1 (HWMv1) to hardware model v2 (HWMv2). .. warning:: This script is not a complete migration tool. It is meant to assist in the migration process, but it does not handle all cases. This script requires the following arguments: - ``-b|--board``: The name of the board to migrate. - ``-g|--group``: The group the board belongs to. This is used to group a set of boards in the same folder. In HWMv2, the boards are no longer organized by architecture. - ``-v|--vendor``: The vendor name. - ``-s|--soc``: The SoC name. In some cases, the new board name will differ from the old board name. For example, the old board name may have the SoC name as a suffix, while in HWMv2, this is no longer needed. In such cases, ``-n|--new-board`` needs to be provided. For boards with variants, ``--variants`` needs to be provided. For out-of-tree boards, provide ``--board-root`` pointing to the custom board root. Copyright (c) 2023 Nordic Semiconductor ASA SPDX-License-Identifier: Apache-2.0 """ import argparse from pathlib import Path import re import sys import ruamel.yaml ZEPHYR_BASE = Path(__file__).parents[2] def board_v1_to_v2(board_root, board, new_board, group, vendor, soc, variants): try: board_path = next(board_root.glob(f"boards/*/{board}")) except StopIteration: sys.exit(f"Board not found: {board}") new_board_path = board_root / "boards" / group / new_board if new_board_path.exists(): print("New board already exists, updating board with additional SoC") if not soc: sys.exit("No SoC provided") new_board_path.mkdir(parents=True, exist_ok=True) print("Moving files to the new board folder...") for f in board_path.iterdir(): f_new = new_board_path / f.name if f_new.exists(): print(f"Skipping existing file: {f_new}") continue f.rename(f_new) print("Creating or updating board.yaml...") board_settings_file = new_board_path / "board.yml" if not board_settings_file.exists(): board_settings = { "board": { "name": new_board, "vendor": vendor, "socs": [] } } else: with open(board_settings_file, encoding='utf-8') as f: yaml = ruamel.yaml.YAML(typ='safe', pure=True) board_settings = yaml.load(f) # pylint: disable=assignment-from-no-return soc = {"name": soc} if variants: soc["variants"] = [{"name": variant} for variant in variants] board_settings["board"]["socs"].append(soc) yaml = ruamel.yaml.YAML() yaml.indent(sequence=4, offset=2) with open(board_settings_file, "w") as f: yaml.dump(board_settings, f) print(f"Updating {board}_defconfig...") board_defconfig_file = new_board_path / f"{board}_defconfig" with open(board_defconfig_file) as f: board_soc_settings = [] board_defconfig = "" dropped_line = False for line in f.readlines(): m = re.match(r"^CONFIG_BOARD_.*$", line) if m: dropped_line = True continue m = re.match(r"^CONFIG_(SOC_[A-Z0-9_]+).*$", line) if m: dropped_line = True if not re.match(r"^CONFIG_SOC_SERIES_.*$", line): board_soc_settings.append(m.group(1)) continue if dropped_line and re.match(r"^$", line): continue dropped_line = False board_defconfig += line with open(board_defconfig_file, "w") as f: f.write(board_defconfig) print("Updating Kconfig.defconfig...") board_kconfig_defconfig_file = new_board_path / "Kconfig.defconfig" with open(board_kconfig_defconfig_file) as f: board_kconfig_defconfig = "" has_kconfig_defconfig_entries = False in_board = False for line in f.readlines(): # drop "config BOARD" entry from Kconfig.defconfig m = re.match(r"^config BOARD$", line) if m: in_board = True continue if in_board and re.match(r"^\s+.*$", line): continue in_board = False m = re.match(r"^config .*$", line) if m: has_kconfig_defconfig_entries = True m = re.match(rf"^(.*)BOARD_{board.upper()}(.*)$", line) if m: board_kconfig_defconfig += ( m.group(1) + "BOARD_" + new_board.upper() + m.group(2) + "\n" ) continue board_kconfig_defconfig += line if has_kconfig_defconfig_entries: with open(board_kconfig_defconfig_file, "w") as f: f.write(board_kconfig_defconfig) else: print("Removing empty Kconfig.defconfig after update...") board_kconfig_defconfig_file.unlink() print(f"Creating or updating Kconfig.{new_board}...") board_kconfig_file = new_board_path / "Kconfig.board" copyright = None with open(board_kconfig_file) as f: for line in f.readlines(): if "Copyright" in line: copyright = line new_board_kconfig_file = new_board_path / f"Kconfig.{new_board}" header = "# SPDX-License-Identifier: Apache-2.0\n" if copyright is not None: header = copyright + header selects = "\n\t" + "\n\t".join(["select " + setting for setting in board_soc_settings]) + "\n" if not new_board_kconfig_file.exists(): with open(new_board_kconfig_file, "w") as f: f.write( header + f"\nconfig BOARD_{new_board.upper()}{selects}" ) else: with open(new_board_kconfig_file, "a") as f: f.write(selects) print("Removing old Kconfig.board...") board_kconfig_file.unlink() print("Conversion done!") if __name__ == "__main__": parser = argparse.ArgumentParser(allow_abbrev=False) parser.add_argument( "--board-root", type=Path, default=ZEPHYR_BASE, help="Board root", ) parser.add_argument("-b", "--board", type=str, required=True, help="Board name") parser.add_argument("-n", "--new-board", type=str, help="New board name") parser.add_argument("-g", "--group", type=str, required=True, help="Board group") parser.add_argument("-v", "--vendor", type=str, required=True, help="Vendor name") parser.add_argument("-s", "--soc", type=str, required=True, help="Board SoC") parser.add_argument("--variants", nargs="+", default=[], help="Board variants") args = parser.parse_args() board_v1_to_v2( args.board_root, args.board, args.new_board or args.board, args.group, args.vendor, args.soc, args.variants, ) |