mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
commit
4e0d5343b4
@ -34,7 +34,7 @@ jobs:
|
||||
e_arr=($e)
|
||||
build_system="${e_arr[0]}"
|
||||
toolchain="${e_arr[1]}"
|
||||
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family")
|
||||
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"")
|
||||
echo "FAMILY_${toolchain}=$FAMILY"
|
||||
|
||||
# FAMILY_LARGE = FAMILY - RESOURCE_LARGE
|
||||
|
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -65,7 +65,7 @@ jobs:
|
||||
with:
|
||||
build-system: 'cmake'
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||
one-per-family: ${{ github.event_name == 'push' }}
|
||||
|
||||
# ---------------------------------------
|
||||
@ -89,7 +89,7 @@ jobs:
|
||||
with:
|
||||
build-system: 'make'
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||
one-per-family: true
|
||||
|
||||
# ---------------------------------------
|
||||
@ -117,7 +117,7 @@ jobs:
|
||||
needs: set-matrix
|
||||
runs-on: [self-hosted, Linux, X64, hifiphile]
|
||||
env:
|
||||
BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'].family, ' ') }}
|
||||
BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'], ' ') }}
|
||||
steps:
|
||||
- name: Clean workspace
|
||||
run: |
|
||||
|
2
.github/workflows/ci_set_matrix.py
vendored
2
.github/workflows/ci_set_matrix.py
vendored
@ -62,7 +62,7 @@ def set_matrix_json():
|
||||
hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']]
|
||||
filtered_families = filtered_families + hfp_boards
|
||||
|
||||
matrix[toolchain] = {"family": filtered_families}
|
||||
matrix[toolchain] = filtered_families
|
||||
|
||||
print(json.dumps(matrix))
|
||||
|
||||
|
13
.github/workflows/hil_test.yml
vendored
13
.github/workflows/hil_test.yml
vendored
@ -32,10 +32,7 @@ jobs:
|
||||
- name: Generate matrix json
|
||||
id: set-matrix-json
|
||||
run: |
|
||||
MATRIX_ARMGCC=$(jq -c '{ "arm-gcc": { "family": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
||||
MATRIX_ESP=$(jq -c '{ "esp-idf": { "family": [.boards[] | select(.flasher == "esptool") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
||||
MATRIX_RISCV=$(jq -c '{ "riscv-gcc": { "family": [.boards[] | select(.flasher == "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
||||
MATRIX_JSON=$(jq -nc --argjson arm "$MATRIX_ARMGCC" --argjson esp "$MATRIX_ESP" --argjson riscv "$MATRIX_RISCV" '$arm + $esp + $riscv')
|
||||
MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py ${{ env.HIL_JSON }})
|
||||
echo "matrix=$MATRIX_JSON"
|
||||
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
||||
|
||||
@ -55,13 +52,13 @@ jobs:
|
||||
with:
|
||||
build-system: 'cmake'
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||
one-per-family: true
|
||||
upload-artifacts: true
|
||||
|
||||
# ---------------------------------------
|
||||
# Hardware in the loop (HIL)
|
||||
# self-hosted running on an VM. For attached hardware checkout test/hil/tinyusb.json
|
||||
# self-hosted running on an VM. For attached hardware checkout HIL_JSON
|
||||
# ---------------------------------------
|
||||
hil-tinyusb:
|
||||
if: github.repository_owner == 'hathach'
|
||||
@ -86,4 +83,6 @@ jobs:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Test on actual hardware
|
||||
run: python3 test/hil/hil_test.py ${{ env.HIL_JSON }}
|
||||
run: |
|
||||
ls cmake-build/
|
||||
python3 test/hil/hil_test.py ${{ env.HIL_JSON }}
|
||||
|
43
test/hil/hil_ci_set_matrix.py
Normal file
43
test/hil/hil_ci_set_matrix.py
Normal file
@ -0,0 +1,43 @@
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('config_file', help='Configuration JSON file')
|
||||
args = parser.parse_args()
|
||||
|
||||
config_file = args.config_file
|
||||
|
||||
# if config file is not found, try to find it in the same directory as this script
|
||||
if not os.path.exists(config_file):
|
||||
config_file = os.path.join(os.path.dirname(__file__), config_file)
|
||||
with open(config_file) as f:
|
||||
config = json.load(f)
|
||||
|
||||
matrix = {
|
||||
'arm-gcc': [],
|
||||
'esp-idf': []
|
||||
}
|
||||
for board in config['boards']:
|
||||
name = board['name']
|
||||
if board['flasher'] == 'esptool':
|
||||
toolchain = 'esp-idf'
|
||||
else:
|
||||
toolchain = 'arm-gcc'
|
||||
|
||||
if 'build' in board and 'flags_on' in board['build']:
|
||||
for f in board['build']['flags_on']:
|
||||
if f == '':
|
||||
matrix[toolchain].append(f'-b {name}')
|
||||
else:
|
||||
matrix[toolchain].append(f'-b {name} -f1 {f.replace(" ", " -f1 ")}')
|
||||
else:
|
||||
matrix[toolchain].append(f'-b {name}')
|
||||
|
||||
print(json.dumps(matrix))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -424,37 +424,45 @@ def test_board(board):
|
||||
test_list.append('device/board_test')
|
||||
|
||||
err_count = 0
|
||||
for test in test_list:
|
||||
fw_dir = f'cmake-build/cmake-build-{name}/{test}'
|
||||
if not os.path.exists(fw_dir):
|
||||
fw_dir = f'examples/cmake-build-{name}/{test}'
|
||||
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
||||
print(f'{name:25} {test:30} ... ', end='')
|
||||
flags_on_list = [""]
|
||||
if 'build' in board and 'flags_on' in board['build']:
|
||||
flags_on_list = board['build']['flags_on']
|
||||
|
||||
if not os.path.exists(fw_dir):
|
||||
print('Skip (no binary)')
|
||||
continue
|
||||
for f1 in flags_on_list:
|
||||
f1_str = ""
|
||||
if f1 != "":
|
||||
f1_str = '-' + f1.replace(' ', '-')
|
||||
for test in test_list:
|
||||
fw_dir = f'cmake-build/cmake-build-{name}{f1_str}/{test}'
|
||||
if not os.path.exists(fw_dir):
|
||||
fw_dir = f'examples/cmake-build-{name}{f1_str}/{test}'
|
||||
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
||||
print(f'{name+f1_str:40} {test:30} ... ', end='')
|
||||
|
||||
if not os.path.exists(fw_dir):
|
||||
print('Skip (no binary)')
|
||||
continue
|
||||
|
||||
# flash firmware. It may fail randomly, retry a few times
|
||||
for i in range(3):
|
||||
ret = globals()[f'flash_{flasher}'](board, fw_name)
|
||||
if ret.returncode == 0:
|
||||
break
|
||||
else:
|
||||
print(f'Flashing failed, retry {i+1}')
|
||||
time.sleep(1)
|
||||
|
||||
# flash firmware. It may fail randomly, retry a few times
|
||||
for i in range(3):
|
||||
ret = globals()[f'flash_{flasher}'](board, fw_name)
|
||||
if ret.returncode == 0:
|
||||
break
|
||||
try:
|
||||
ret = globals()[f'test_{test.replace("/", "_")}'](board)
|
||||
print('OK')
|
||||
except Exception as e:
|
||||
err_count += 1
|
||||
print(STATUS_FAILED)
|
||||
print(f' {e}')
|
||||
else:
|
||||
print(f'Flashing failed, retry {i+1}')
|
||||
time.sleep(1)
|
||||
|
||||
if ret.returncode == 0:
|
||||
try:
|
||||
ret = globals()[f'test_{test.replace("/", "_")}'](board)
|
||||
print('OK')
|
||||
except Exception as e:
|
||||
err_count += 1
|
||||
print(STATUS_FAILED)
|
||||
print(f' {e}')
|
||||
else:
|
||||
err_count += 1
|
||||
print(f'Flash {STATUS_FAILED}')
|
||||
print(f'Flash {STATUS_FAILED}')
|
||||
return err_count
|
||||
|
||||
|
||||
|
@ -79,6 +79,9 @@
|
||||
{
|
||||
"name": "espressif_s3_devkitm",
|
||||
"uid": "84F703C084E4",
|
||||
"build" : {
|
||||
"flags_on": ["", "CFG_TUD_DWC2_DMA"]
|
||||
},
|
||||
"tests": {
|
||||
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"]
|
||||
},
|
||||
|
@ -21,6 +21,7 @@ build_format = '| {:30} | {:40} | {:16} | {:5} |'
|
||||
build_separator = '-' * 95
|
||||
build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED]
|
||||
|
||||
verbose = False
|
||||
|
||||
# -----------------------------
|
||||
# Helper
|
||||
@ -38,6 +39,9 @@ def run_cmd(cmd):
|
||||
else:
|
||||
print(title)
|
||||
print(r.stdout.decode("utf-8"))
|
||||
elif verbose:
|
||||
print(cmd)
|
||||
print(r.stdout.decode("utf-8"))
|
||||
return r
|
||||
|
||||
|
||||
@ -75,10 +79,17 @@ def print_build_result(board, example, status, duration):
|
||||
# -----------------------------
|
||||
# CMake
|
||||
# -----------------------------
|
||||
def cmake_board(board, toolchain):
|
||||
def cmake_board(board, toolchain, build_flags_on):
|
||||
ret = [0, 0, 0]
|
||||
start_time = time.monotonic()
|
||||
build_dir = f"cmake-build/cmake-build-{board}"
|
||||
|
||||
build_dir = f'cmake-build/cmake-build-{board}'
|
||||
build_flags = ''
|
||||
if len(build_flags_on) > 0:
|
||||
build_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on)
|
||||
build_flags = f'-DCFLAGS_CLI="{build_flags}"'
|
||||
build_dir += '-' + '-'.join(build_flags_on)
|
||||
|
||||
family = find_family(board)
|
||||
if family == 'espressif':
|
||||
# for espressif, we have to build example individually
|
||||
@ -87,12 +98,14 @@ def cmake_board(board, toolchain):
|
||||
if build_utils.skip_example(example, board):
|
||||
ret[2] += 1
|
||||
else:
|
||||
rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board}')
|
||||
rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" '
|
||||
f'-DBOARD={board} {build_flags}')
|
||||
if rcmd.returncode == 0:
|
||||
rcmd = run_cmd(f'cmake --build {build_dir}/{example}')
|
||||
ret[0 if rcmd.returncode == 0 else 1] += 1
|
||||
else:
|
||||
rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}')
|
||||
rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel '
|
||||
f'-DTOOLCHAIN={toolchain} {build_flags}')
|
||||
if rcmd.returncode == 0:
|
||||
rcmd = run_cmd(f"cmake --build {build_dir}")
|
||||
ret[0 if rcmd.returncode == 0 else 1] += 1
|
||||
@ -144,12 +157,12 @@ def make_board(board, toolchain):
|
||||
# -----------------------------
|
||||
# Build Family
|
||||
# -----------------------------
|
||||
def build_boards_list(boards, toolchain, build_system):
|
||||
def build_boards_list(boards, toolchain, build_system, build_flags_on):
|
||||
ret = [0, 0, 0]
|
||||
for b in boards:
|
||||
r = [0, 0, 0]
|
||||
if build_system == 'cmake':
|
||||
r = cmake_board(b, toolchain)
|
||||
r = cmake_board(b, toolchain, build_flags_on)
|
||||
elif build_system == 'make':
|
||||
r = make_board(b, toolchain)
|
||||
ret[0] += r[0]
|
||||
@ -158,7 +171,7 @@ def build_boards_list(boards, toolchain, build_system):
|
||||
return ret
|
||||
|
||||
|
||||
def build_family(family, toolchain, build_system, one_per_family, boards):
|
||||
def build_family(family, toolchain, build_system, build_flags_on, one_per_family, boards):
|
||||
all_boards = []
|
||||
for entry in os.scandir(f"hw/bsp/{family}/boards"):
|
||||
if entry.is_dir() and entry.name != 'pico_sdk':
|
||||
@ -174,7 +187,7 @@ def build_family(family, toolchain, build_system, one_per_family, boards):
|
||||
return ret
|
||||
all_boards = [random.choice(all_boards)]
|
||||
|
||||
ret = build_boards_list(all_boards, toolchain, build_system)
|
||||
ret = build_boards_list(all_boards, toolchain, build_system, build_flags_on)
|
||||
return ret
|
||||
|
||||
|
||||
@ -182,19 +195,25 @@ def build_family(family, toolchain, build_system, one_per_family, boards):
|
||||
# Main
|
||||
# -----------------------------
|
||||
def main():
|
||||
global verbose
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('families', nargs='*', default=[], help='Families to build')
|
||||
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build')
|
||||
parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc')
|
||||
parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake')
|
||||
parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system')
|
||||
parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family')
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
||||
args = parser.parse_args()
|
||||
|
||||
families = args.families
|
||||
boards = args.board
|
||||
toolchain = args.toolchain
|
||||
build_system = args.build_system
|
||||
build_flags_on = args.build_flags_on
|
||||
one_per_family = args.one_per_family
|
||||
verbose = args.verbose
|
||||
|
||||
if len(families) == 0 and len(boards) == 0:
|
||||
print("Please specify families or board to build")
|
||||
@ -217,13 +236,13 @@ def main():
|
||||
|
||||
# succeeded, failed, skipped
|
||||
for f in all_families:
|
||||
r = build_family(f, toolchain, build_system, one_per_family, boards)
|
||||
r = build_family(f, toolchain, build_system, build_flags_on, one_per_family, boards)
|
||||
result[0] += r[0]
|
||||
result[1] += r[1]
|
||||
result[2] += r[2]
|
||||
|
||||
# build boards
|
||||
r = build_boards_list(boards, toolchain, build_system)
|
||||
r = build_boards_list(boards, toolchain, build_system, build_flags_on)
|
||||
result[0] += r[0]
|
||||
result[1] += r[1]
|
||||
result[2] += r[2]
|
||||
|
@ -251,6 +251,7 @@ def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('families', nargs='*', default=[], help='Families to fetch')
|
||||
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch')
|
||||
parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Have no effect')
|
||||
parser.add_argument('--print', action='store_true', help='Print commit hash only')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user