mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
Merge pull request #2367 from hathach/add-hil-s3
Add esp32s3 to hardware in the loop test
This commit is contained in:
commit
37158eddcb
49
.github/workflows/build_esp.yml
vendored
49
.github/workflows/build_esp.yml
vendored
@ -33,7 +33,6 @@ jobs:
|
|||||||
- 'espressif_kaluga_1'
|
- 'espressif_kaluga_1'
|
||||||
# ESP32-S3
|
# ESP32-S3
|
||||||
- 'espressif_s3_devkitc'
|
- 'espressif_s3_devkitc'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -48,3 +47,51 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }}
|
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }}
|
||||||
|
|
||||||
|
- name: Upload Artifacts for Hardware Testing
|
||||||
|
if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.board }}
|
||||||
|
path: |
|
||||||
|
cmake-build/cmake-build-${{ matrix.board }}/*/*/bootloader/bootloader.bin
|
||||||
|
cmake-build/cmake-build-${{ matrix.board }}/*/*/*.bin
|
||||||
|
cmake-build/cmake-build-${{ matrix.board }}/*/*/partition_table/partition-table.bin
|
||||||
|
cmake-build/cmake-build-${{ matrix.board }}/*/*/config.env
|
||||||
|
cmake-build/cmake-build-${{ matrix.board }}/*/*/flash_args
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Hardware in the loop (HIL)
|
||||||
|
# Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json
|
||||||
|
# ---------------------------------------
|
||||||
|
hil-test:
|
||||||
|
# run only with hathach's commit due to limited resource on RPI4
|
||||||
|
if: github.repository_owner == 'hathach'
|
||||||
|
needs: build-esp
|
||||||
|
runs-on: [self-hosted, esp32s3, hardware-in-the-loop]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
board:
|
||||||
|
- 'espressif_s3_devkitc'
|
||||||
|
steps:
|
||||||
|
- name: Clean workspace
|
||||||
|
run: |
|
||||||
|
echo "Cleaning up previous run"
|
||||||
|
rm -rf "${{ github.workspace }}"
|
||||||
|
mkdir -p "${{ github.workspace }}"
|
||||||
|
|
||||||
|
- name: Checkout test/hil
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
sparse-checkout: test/hil
|
||||||
|
|
||||||
|
- name: Download Artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.board }}
|
||||||
|
path: cmake-build/cmake-build-${{ matrix.board }}
|
||||||
|
|
||||||
|
- name: Test on actual hardware
|
||||||
|
run: |
|
||||||
|
python3 test/hil/hil_test.py --board ${{ matrix.board }} hil_pi4.json
|
||||||
|
2
.github/workflows/build_iar.yml
vendored
2
.github/workflows/build_iar.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
|||||||
# Alphabetical order
|
# Alphabetical order
|
||||||
# Note: bundle multiple families into a matrix since there is only one self-hosted instance can
|
# Note: bundle multiple families into a matrix since there is only one self-hosted instance can
|
||||||
# run IAR build. Too many matrix can hurt due to setup/teardown overhead.
|
# run IAR build. Too many matrix can hurt due to setup/teardown overhead.
|
||||||
- 'lpc43 stm32f0 stm32f1 stm32f4 stm32f7 stm32g0 stm32g4 stm32h7 stm32l4'
|
- 'lpc43 stm32f0 stm32f1 stm32f7 stm32g0 stm32g4 stm32l4'
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workspace
|
- name: Clean workspace
|
||||||
run: |
|
run: |
|
||||||
|
35
.github/workflows/cmake_arm.yml
vendored
35
.github/workflows/cmake_arm.yml
vendored
@ -86,34 +86,28 @@ jobs:
|
|||||||
# for rp2040, there is no harm if defined for other families
|
# for rp2040, there is no harm if defined for other families
|
||||||
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
||||||
|
|
||||||
# Upload binaries for hardware test with self-hosted
|
- name: Upload Artifacts for Hardware Testing
|
||||||
- name: Prepare rp2040 Artifacts
|
|
||||||
if: contains(matrix.family, 'rp2040') && github.repository_owner == 'hathach'
|
|
||||||
working-directory: ${{github.workspace}}/cmake-build/cmake-build-raspberry_pi_pico
|
|
||||||
run: |
|
|
||||||
find device/ -name "*.elf" -exec mv {} ../../ \;
|
|
||||||
# find host/ -name "*.elf" -exec mv {} ../../ \;
|
|
||||||
# find dual/ -name "*.elf" -exec mv {} ../../ \;
|
|
||||||
|
|
||||||
- name: Upload Artifacts for rp2040
|
|
||||||
if: contains(matrix.family,'rp2040') && github.repository_owner == 'hathach'
|
if: contains(matrix.family,'rp2040') && github.repository_owner == 'hathach'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: rp2040
|
name: raspberry_pi_pico
|
||||||
path: |
|
path: |
|
||||||
*.elf
|
cmake-build/cmake-build-raspberry_pi_pico/*/*/*.elf
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Hardware in the loop (HIL)
|
# Hardware in the loop (HIL)
|
||||||
# Current self-hosted instance is running on an RPI4.
|
# Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json
|
||||||
# For attached hardware checkout hil_pi4.json
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
hw-rp2040-test:
|
hil-test:
|
||||||
# run only with hathach's commit due to limited resource on RPI4
|
# run only with hathach's commit due to limited resource on RPI4
|
||||||
if: github.repository_owner == 'hathach'
|
if: github.repository_owner == 'hathach'
|
||||||
needs: build-arm
|
needs: build-arm
|
||||||
runs-on: [self-hosted, rp2040, hardware-in-the-loop]
|
runs-on: [self-hosted, rp2040, hardware-in-the-loop]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
board:
|
||||||
|
- 'raspberry_pi_pico'
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workspace
|
- name: Clean workspace
|
||||||
run: |
|
run: |
|
||||||
@ -126,11 +120,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
sparse-checkout: test/hil
|
sparse-checkout: test/hil
|
||||||
|
|
||||||
- name: Download rp2040 Artifacts
|
- name: Download Artifacts
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: rp2040
|
name: ${{ matrix.board }}
|
||||||
|
path: cmake-build/cmake-build-${{ matrix.board }}
|
||||||
|
|
||||||
- name: Test on actual hardware (hardware in the loop)
|
- name: Test on actual hardware
|
||||||
run: |
|
run: |
|
||||||
python3 test/hil/hil_test.py hil_pi4.json
|
python3 test/hil/hil_test.py --board ${{ matrix.board }} hil_pi4.json
|
||||||
|
@ -158,7 +158,7 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) {
|
|||||||
|
|
||||||
void board_led_write(bool state) {
|
void board_led_write(bool state) {
|
||||||
#ifdef NEOPIXEL_PIN
|
#ifdef NEOPIXEL_PIN
|
||||||
strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00);
|
strip->set_pixel(strip, 0, state ? 0x08 : 0x00, 0x00, 0x00);
|
||||||
strip->refresh(strip, 100);
|
strip->refresh(strip, 100);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3,23 +3,23 @@
|
|||||||
{
|
{
|
||||||
"name": "stm32l412nucleo",
|
"name": "stm32l412nucleo",
|
||||||
"uid": "41003B000E504E5457323020",
|
"uid": "41003B000E504E5457323020",
|
||||||
"debugger": "jlink",
|
"flasher": "jlink",
|
||||||
"debugger_sn": "774470029",
|
"flasher_sn": "774470029",
|
||||||
"cpu": "STM32L412KB"
|
"flasher_args": "-device STM32L412KB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "stm32f746disco",
|
"name": "stm32f746disco",
|
||||||
"uid": "210041000C51343237303334",
|
"uid": "210041000C51343237303334",
|
||||||
"debugger": "jlink",
|
"flasher": "jlink",
|
||||||
"debugger_sn": "770935966",
|
"flasher_sn": "770935966",
|
||||||
"cpu": "STM32F746NG"
|
"flasher_args": "-device STM32F746NG"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lpcxpresso43s67",
|
"name": "lpcxpresso43s67",
|
||||||
"uid": "08F000044528BAAA8D858F58C50700F5",
|
"uid": "08F000044528BAAA8D858F58C50700F5",
|
||||||
"debugger": "jlink",
|
"flasher": "jlink",
|
||||||
"debugger_sn": "728973776",
|
"flasher_sn": "728973776",
|
||||||
"cpu": "LPC43S67_M4"
|
"flasher_args": "-device LPC43S67_M4"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,19 @@
|
|||||||
{
|
{
|
||||||
"name": "raspberry_pi_pico",
|
"name": "raspberry_pi_pico",
|
||||||
"uid": "E6614C311B764A37",
|
"uid": "E6614C311B764A37",
|
||||||
"debugger": "openocd",
|
"flasher": "openocd",
|
||||||
"debugger_sn": "E6614103E72C1D2F",
|
"flasher_sn": "E6614103E72C1D2F",
|
||||||
"debugger_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\""
|
"flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "espressif_s3_devkitc",
|
||||||
|
"uid": "7CDFA1E073CC",
|
||||||
|
"tests": [
|
||||||
|
"cdc_msc_freertos", "hid_composite_freertos"
|
||||||
|
],
|
||||||
|
"flasher": "esptool",
|
||||||
|
"flasher_sn": "461cb8d7decdeb119be9b506e93fd3f1",
|
||||||
|
"flasher_args": "-b 1500000"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import click
|
||||||
import serial
|
import serial
|
||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
@ -42,7 +43,7 @@ def get_serial_dev(id, vendor_str, product_str, ifnum):
|
|||||||
# known vendor and product
|
# known vendor and product
|
||||||
return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}'
|
return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}'
|
||||||
else:
|
else:
|
||||||
# just use id: mostly for cp210x/ftdi debugger
|
# just use id: mostly for cp210x/ftdi flasher
|
||||||
pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*'
|
pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*'
|
||||||
port_list = glob.glob(pattern)
|
port_list = glob.glob(pattern)
|
||||||
return port_list[0]
|
return port_list[0]
|
||||||
@ -99,14 +100,14 @@ def read_disk_file(id, fname):
|
|||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# Flash with debugger
|
# Flashing firmware
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
def flash_jlink(board, firmware):
|
def flash_jlink(board, firmware):
|
||||||
script = ['halt', 'r', f'loadfile {firmware}', 'r', 'go', 'exit']
|
script = ['halt', 'r', f'loadfile {firmware}', 'r', 'go', 'exit']
|
||||||
with open('flash.jlink', 'w') as f:
|
with open('flash.jlink', 'w') as f:
|
||||||
f.writelines(f'{s}\n' for s in script)
|
f.writelines(f'{s}\n' for s in script)
|
||||||
ret = subprocess.run(
|
ret = subprocess.run(
|
||||||
f'JLinkExe -USB {board["debugger_sn"]} -device {board["cpu"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink',
|
f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink',
|
||||||
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
os.remove('flash.jlink')
|
os.remove('flash.jlink')
|
||||||
return ret
|
return ret
|
||||||
@ -114,19 +115,19 @@ def flash_jlink(board, firmware):
|
|||||||
|
|
||||||
def flash_openocd(board, firmware):
|
def flash_openocd(board, firmware):
|
||||||
ret = subprocess.run(
|
ret = subprocess.run(
|
||||||
f'openocd -c "adapter serial {board["debugger_sn"]}" {board["debugger_args"]} -c "program {firmware} reset exit"',
|
f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware} reset exit"',
|
||||||
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def flash_esptool(board, firmware):
|
def flash_esptool(board, firmware):
|
||||||
port = get_serial_dev(board["debugger_sn"], None, None, 0)
|
port = get_serial_dev(board["flasher_sn"], None, None, 0)
|
||||||
dir = os.path.dirname(firmware)
|
dir = os.path.dirname(firmware)
|
||||||
with open(f'{dir}/config.env') as f:
|
with open(f'{dir}/config.env') as f:
|
||||||
IDF_TARGET = json.load(f)['IDF_TARGET']
|
IDF_TARGET = json.load(f)['IDF_TARGET']
|
||||||
with open(f'{dir}/flash_args') as f:
|
with open(f'{dir}/flash_args') as f:
|
||||||
flash_args = f.read().strip().replace('\n', ' ')
|
flash_args = f.read().strip().replace('\n', ' ')
|
||||||
command = (f'esptool.py --chip {IDF_TARGET} -p {port} {board["debugger_args"]} '
|
command = (f'esptool.py --chip {IDF_TARGET} -p {port} {board["flasher_args"]} '
|
||||||
f'--before=default_reset --after=hard_reset write_flash {flash_args}')
|
f'--before=default_reset --after=hard_reset write_flash {flash_args}')
|
||||||
ret = subprocess.run(command, shell=True, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
ret = subprocess.run(command, shell=True, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
return ret
|
return ret
|
||||||
@ -262,13 +263,15 @@ def test_hid_composite_freertos(id):
|
|||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# Main
|
# Main
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
if __name__ == '__main__':
|
@click.command()
|
||||||
if len(sys.argv) != 2:
|
@click.argument('config_file')
|
||||||
print('Usage:')
|
@click.option('-b', '--board', multiple=True, default=None, help='Boards to test, all if not specified')
|
||||||
print('python hitl_test.py config.json')
|
def main(config_file, board):
|
||||||
sys.exit(-1)
|
"""
|
||||||
|
Hardware test on specified boards
|
||||||
with open(f'{os.path.dirname(__file__)}/{sys.argv[1]}') as f:
|
"""
|
||||||
|
config_file = os.path.join(os.path.dirname(__file__), config_file)
|
||||||
|
with open(config_file) as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|
||||||
# all possible tests
|
# all possible tests
|
||||||
@ -276,13 +279,18 @@ if __name__ == '__main__':
|
|||||||
'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface',
|
'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface',
|
||||||
]
|
]
|
||||||
|
|
||||||
for board in config['boards']:
|
if len(board) == 0:
|
||||||
print(f'Testing board:{board["name"]}')
|
config_boards = config['boards']
|
||||||
debugger = board['debugger'].lower()
|
else:
|
||||||
|
config_boards = [e for e in config['boards'] if e['name'] in board]
|
||||||
|
|
||||||
|
for item in config_boards:
|
||||||
|
print(f'Testing board:{item["name"]}')
|
||||||
|
flasher = item['flasher'].lower()
|
||||||
|
|
||||||
# default to all tests
|
# default to all tests
|
||||||
if 'tests' in board:
|
if 'tests' in item:
|
||||||
test_list = board['tests']
|
test_list = item['tests']
|
||||||
else:
|
else:
|
||||||
test_list = all_tests
|
test_list = all_tests
|
||||||
|
|
||||||
@ -290,36 +298,41 @@ if __name__ == '__main__':
|
|||||||
test_list.append('board_test')
|
test_list.append('board_test')
|
||||||
|
|
||||||
# remove skip_tests
|
# remove skip_tests
|
||||||
if 'tests_skip' in board:
|
if 'tests_skip' in item:
|
||||||
for skip in board['tests_skip']:
|
for skip in item['tests_skip']:
|
||||||
if skip in test_list:
|
if skip in test_list:
|
||||||
test_list.remove(skip)
|
test_list.remove(skip)
|
||||||
|
|
||||||
for test in test_list:
|
for test in test_list:
|
||||||
# cmake, make, download from artifacts
|
fw_list = [
|
||||||
elf_list = [
|
# cmake: esp32 use .bin file
|
||||||
f'cmake-build/cmake-build-{board["name"]}/device/{test}/{test}.elf',
|
f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.elf',
|
||||||
f'examples/device/{test}/_build/{board["name"]}/{test}.elf',
|
f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.bin',
|
||||||
f'{test}.elf'
|
# make
|
||||||
|
f'examples/device/{test}/_build/{item["name"]}/{test}.elf'
|
||||||
]
|
]
|
||||||
|
|
||||||
elf = None
|
fw = None
|
||||||
for e in elf_list:
|
for f in fw_list:
|
||||||
if os.path.isfile(e):
|
if os.path.isfile(f):
|
||||||
elf = e
|
fw = f
|
||||||
break
|
break
|
||||||
|
|
||||||
if elf is None:
|
if fw is None:
|
||||||
print(f'Cannot find firmware file for {test}')
|
print(f'Cannot find binary file for {test}')
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
print(f' {test} ...', end='')
|
print(f' {test} ...', end='')
|
||||||
|
|
||||||
# flash firmware
|
# flash firmware
|
||||||
ret = locals()[f'flash_{debugger}'](board, elf)
|
ret = globals()[f'flash_{flasher}'](item, fw)
|
||||||
assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode()
|
assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode()
|
||||||
|
|
||||||
# run test
|
# run test
|
||||||
locals()[f'test_{test}'](board['uid'])
|
globals()[f'test_{test}'](item['uid'])
|
||||||
|
|
||||||
print('OK')
|
print('OK')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user