diff options
| author | hathach <[email protected]> | 2023-03-08 21:05:06 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2023-03-08 21:05:06 +0700 |
| commit | 05e0205ad0f2985909964174987088323724c5b8 (patch) | |
| tree | a24a1ee33e8350ff9cd3bec08adc8c04ea30a811 /tools | |
| parent | ea81d22f184fa8fd6c46c35c8be86e47996b46c8 (diff) | |
| parent | be66f5f57f435ef2d00b3e23f6bd850468d14942 (diff) | |
Merge branch 'master' into renesas-ra
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/build_board.py | 116 | ||||
| -rw-r--r-- | tools/build_family.py | 125 | ||||
| -rw-r--r-- | tools/build_utils.py | 96 | ||||
| -rw-r--r-- | tools/get_dependencies.py | 25 | ||||
| -rw-r--r-- | tools/make_release.py | 40 | ||||
| -rwxr-xr-x | tools/pcapng_to_corpus.py | 46 | ||||
| -rw-r--r-- | tools/top.mk | 30 |
7 files changed, 281 insertions, 197 deletions
diff --git a/tools/build_board.py b/tools/build_board.py index 4d895329a..4593dafa5 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -1,8 +1,8 @@ import os -import glob import sys -import subprocess import time +import subprocess +from multiprocessing import Pool import build_utils @@ -10,90 +10,60 @@ SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) -filter_with_input(all_examples) -all_examples.sort() - -# If boards are not specified in arguments, build all -all_boards = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): - all_boards.append(entry.name) -filter_with_input(all_boards) -all_boards.sort() -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" +if __name__ == '__main__': + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() - # Check if board is skipped - if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) - else: - subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + # If boards are not specified in arguments, build all + all_boards = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): + all_boards.append(entry.name) + filter_with_input(all_boards) + all_boards.sort() - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 + # Get dependencies + for b in all_boards: + subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(b), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) - - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) - -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) + print(build_separator) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + # succeeded, failed, skipped + total_result = [0, 0, 0] + for example in all_examples: + print(build_separator) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example, o='': [e, b, o], all_boards))) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + result = list(map(sum, list(zip(*result)))) + + # add to total result + total_result = list(map(lambda x, y: x + y, total_result, result)) -for example in all_examples: + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) print(build_separator) - for board in all_boards: - build_board(example, board) - -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) -sys.exit(exit_status) + sys.exit(total_result[1]) diff --git a/tools/build_family.py b/tools/build_family.py index 095ca4ff7..cdc099691 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -1,8 +1,7 @@ import os -import glob import sys -import subprocess import time +from multiprocessing import Pool import build_utils @@ -10,103 +9,71 @@ SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 +make_iar_option = 'CC=iccarm' + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) -filter_with_input(all_examples) -all_examples.sort() - -# If family are not specified in arguments, build all -all_families = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): - all_families.append(entry.name) - -filter_with_input(all_families) -all_families.sort() -def build_family(example, family): +def build_family(example, family, make_option): all_boards = [] for entry in os.scandir("hw/bsp/{}/boards".format(family)): - if entry.is_dir(): + if entry.is_dir() and entry.name != 'pico_sdk': all_boards.append(entry.name) filter_with_input(all_boards) all_boards.sort() - - for board in all_boards: - build_board(example, board) - -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" - # Check if board is skipped - if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) - else: - #subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example, o=make_option: [e, b, o], all_boards))) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + return list(map(sum, list(zip(*result)))) - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) +if __name__ == '__main__': + # IAR CC + if make_iar_option not in sys.argv: + make_iar_option = '' - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) + # If family are not specified in arguments, build all + all_families = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): + all_families.append(entry.name) + filter_with_input(all_families) + all_families.sort() -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - -for example in all_examples: print(build_separator) - for family in all_families: - build_family(example, family) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() + + # succeeded, failed, skipped + total_result = [0, 0, 0] + for example in all_examples: + print(build_separator) + for family in all_families: + fret = build_family(example, family, make_iar_option) + total_result = list(map(lambda x, y: x + y, total_result, fret)) -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) + print(build_separator) -sys.exit(exit_status) + sys.exit(total_result[1]) diff --git a/tools/build_utils.py b/tools/build_utils.py index 299fffa4d..de9052d2d 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -1,29 +1,45 @@ +import subprocess import pathlib +import time + +build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") - board_dir = list(bsp.glob("*/boards/" + board)) - if not board_dir: - # Skip unknown boards - return True + if (bsp / board / "board.mk").exists(): + # board without family + board_dir = bsp / board + family = "" + mk_contents = "" + else: + # board within family + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] - board_dir = list(board_dir)[0] - - family_dir = board_dir.parent.parent - family = family_dir.name + family_dir = board_dir.parent.parent + family = family_dir.name - # family CMake - family_mk = family_dir / "family.cmake" + # family CMake + family_mk = family_dir / "family.cmake" - # family.mk - if not family_mk.exists(): - family_mk = family_dir / "family.mk" + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" - mk_contents = family_mk.read_text() + mk_contents = family_mk.read_text() - # Find the mcu + # Find the mcu, first in family mk then board mk if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: board_mk = board_dir / "board.cmake" if not board_mk.exists(): @@ -59,3 +75,53 @@ def skip_example(example, board): "family:" + family in onlys) return False + + +def build_example(example, board, make_option): + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # succeeded, failed, skipped + ret = [0, 0, 0] + + make_cmd = "make -j -C examples/{} BOARD={} {}".format(example, board, make_option) + + # Check if board is skipped + if skip_example(example, board): + status = SKIPPED + ret[2] = 1 + print(build_format.format(example, board, status, '-', flash_size, sram_size)) + else: + subprocess.run(make_cmd + " clean", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_result = subprocess.run(make_cmd + " all", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + status = SUCCEEDED + ret[0] = 1 + (flash_size, sram_size) = build_size(make_cmd) + #subprocess.run(make_cmd + " copy-artifact", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + else: + status = FAILED + ret[1] = 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + + return ret + + +def build_size(make_cmd): + size_output = subprocess.run(make_cmd + ' size', shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8").splitlines() + for i, l in enumerate(size_output): + text_title = 'text data bss dec' + if text_title in l: + size_list = size_output[i+1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + + return (0, 0)
\ No newline at end of file diff --git a/tools/get_dependencies.py b/tools/get_dependencies.py new file mode 100644 index 000000000..e7d3e0a76 --- /dev/null +++ b/tools/get_dependencies.py @@ -0,0 +1,25 @@ +import os +import sys +import subprocess + + +# dependency lookup (ABC sorted) +# deps = { +# 'LPC11UXX' : [ [] ] +# } + + +def get_family_dep(family): + for entry in os.scandir("hw/bsp/{}/boards".format(family)): + if entry.is_dir(): + result = subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(entry.name), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print(result.stdout.decode("utf-8")) + return result.returncode + +status = 0 +all_family = sys.argv[1:] +for f in all_family: + status += get_family_dep(f) + +sys.exit(status)
\ No newline at end of file diff --git a/tools/make_release.py b/tools/make_release.py new file mode 100644 index 000000000..7481e8864 --- /dev/null +++ b/tools/make_release.py @@ -0,0 +1,40 @@ +import re + +version = '0.15.0' + +print('version {}'.format(version)) +ver_id = version.split('.') + +################### +# src/tusb_option.h +################### +f_option_h = 'src/tusb_option.h' + +with open(f_option_h) as f: + fdata = f.read() + +fdata = re.sub(r'(#define TUSB_VERSION_MAJOR *) \d+', r"\1 {}".format(ver_id[0]), fdata) +fdata = re.sub(r'(#define TUSB_VERSION_MINOR *) \d+', r"\1 {}".format(ver_id[1]), fdata) +fdata = re.sub(r'(#define TUSB_VERSION_REVISION *) \d+', r"\1 {}".format(ver_id[2]), fdata) + +# Write the file out again +with open(f_option_h, 'w') as f: + f.write(fdata) + +################### +# repository.yml +################### +f_repository_yml = 'repository.yml' +with open(f_repository_yml) as f: + fdata = f.read() + +if fdata.find(version) < 0: + fdata = re.sub(r'("0-latest"): "\d+\.\d+\.\d+"', r'"{}": "{}"\r\n \1: "{}"'.format(version, version, version), fdata) + with open(f_repository_yml, 'w') as f: + f.write(fdata) + +################### +# docs/info/changelog.rst +################### + +print("Update docs/info/changelog.rst") diff --git a/tools/pcapng_to_corpus.py b/tools/pcapng_to_corpus.py new file mode 100755 index 000000000..78b1f77a2 --- /dev/null +++ b/tools/pcapng_to_corpus.py @@ -0,0 +1,46 @@ +#!/bin/python3 +import argparse +import pcapng +import zipfile +import hashlib + +def extract_packets(pcap_file): + """Reads a wireshark packet capture and extracts the binary packets""" + packets = [] + with open(pcap_file, 'rb') as fp: + scanner = pcapng.FileScanner(fp) + for block in scanner: + if isinstance(block, pcapng.blocks.EnhancedPacket): + packets.append(block.packet_data) + return packets + +def build_corpus_zip(zip_file_output, packets): + """Builds a zip file with a file per packet + + The structure of this zip corpus is a simple content addressable storage + i.e. seed_file_name == sha256_digest(packet). + """ + with zipfile.ZipFile(zip_file_output, 'a') as out: + for packet in packets: + hash = hashlib.sha256(packet).hexdigest() + if hash not in out.namelist(): + out.writestr(hash, packet) + + +def main(pcap_file, output_zip_file): + packets = extract_packets(pcap_file) + build_corpus_zip(output_zip_file, packets) + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog = "pcapng_to_corpus.py", + description="""Converts a wireshark capture to a zip of binary packet + files suitable for an oss-fuzz corpus. In the case the + zip corpus already exists, this script will modify + the zip file in place adding seed entries.""") + parser.add_argument('pcapng_capture_file') + parser.add_argument('oss_fuzz_corpus_zip') + args = parser.parse_args() + main(args.pcapng_capture_file, args.oss_fuzz_corpus_zip) + + diff --git a/tools/top.mk b/tools/top.mk deleted file mode 100644 index 84523a557..000000000 --- a/tools/top.mk +++ /dev/null @@ -1,30 +0,0 @@ -ifneq ($(lastword a b),b) -$(error This Makefile require make 3.81 or newer) -endif - -# Detect whether shell style is windows or not -# https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069 -ifeq '$(findstring ;,$(PATH))' ';' -CMDEXE := 1 -endif - -# Set TOP to be the path to get from the current directory (where make was -# invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns -# the name of this makefile relative to where make was invoked. - -THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) -TOP := $(patsubst %/tools/top.mk,%,$(THIS_MAKEFILE)) - -ifeq ($(CMDEXE),1) -TOP := $(subst \,/,$(shell for %%i in ( $(TOP) ) do echo %%~fi)) -else -TOP := $(shell realpath $(TOP)) -endif -#$(info Top directory is $(TOP)) - -ifeq ($(CMDEXE),1) -CURRENT_PATH := $(subst $(TOP)/,,$(subst \,/,$(shell echo %CD%))) -else -CURRENT_PATH := $(shell realpath --relative-to=$(TOP) `pwd`) -endif -#$(info Path from top is $(CURRENT_PATH)) |
