summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-02-13 01:10:55 +0700
committerhathach <[email protected]>2026-02-13 01:10:55 +0700
commit35a90f213d75a4630adf576f50d2b5bc8f03456c (patch)
tree42ab3bc2b3816d14bc93d5abb2c84e9286b70f08
parentbe24a38a65d8e22fed461b4058e3deb97d5a2907 (diff)
parentd13284d02da552c843e3ccbda4472083f25b0b16 (diff)
Merge branch 'refs/heads/master' into dwc2_vbus
-rw-r--r--.circleci/config2.yml8
-rw-r--r--.github/actions/get_deps/action.yml1
-rw-r--r--.github/membrowse-targets.json494
-rw-r--r--.github/pull_request_template.md5
-rw-r--r--.github/workflows/build.yml104
-rw-r--r--.github/workflows/build_util.yml58
-rwxr-xr-x.github/workflows/ci_set_matrix.py72
-rw-r--r--.github/workflows/membrowse-report.yml101
-rw-r--r--.idea/cmake.xml2
-rw-r--r--README.rst5
-rw-r--r--docs/getting_started.rst5
-rw-r--r--examples/device/cdc_dual_ports/src/tusb_config.h2
-rw-r--r--examples/device/cdc_msc/src/tusb_config.h2
-rw-r--r--examples/device/cdc_msc_freertos/src/tusb_config.h2
-rw-r--r--examples/device/cdc_uac2/src/tusb_config.h2
-rw-r--r--hw/bsp/family_support.cmake116
-rw-r--r--hw/bsp/rp2040/family.cmake3
-rw-r--r--src/class/msc/msc_device.c6
-rw-r--r--src/class/mtp/mtp_device.h2
-rw-r--r--src/class/video/video_device.h3
-rw-r--r--src/common/tusb_verify.h7
-rw-r--r--src/device/usbd.c10
-rw-r--r--src/device/usbd.h4
-rw-r--r--src/host/usbh.c10
-rw-r--r--src/portable/mentor/musb/dcd_musb.c21
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.h22
-rw-r--r--src/tusb_option.h18
-rwxr-xr-xtools/build.py60
-rw-r--r--tools/codespell/ignore-words.txt21
-rwxr-xr-xtools/get_deps.py30
30 files changed, 369 insertions, 827 deletions
diff --git a/.circleci/config2.yml b/.circleci/config2.yml
index 352d0f4fa..a31b0a818 100644
--- a/.circleci/config2.yml
+++ b/.circleci/config2.yml
@@ -110,7 +110,7 @@ commands:
no_output_timeout: 20m
command: |
if [ << parameters.toolchain >> == esp-idf ]; then
- docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> << parameters.family >>
+ docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> --target all << parameters.family >>
else
# Toolchain option default is gcc
if [ << parameters.toolchain >> == arm-clang ]; then
@@ -124,7 +124,11 @@ commands:
# circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large)
# Required for IAR, also prevent crashed/killed by docker
- python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >>
+ BUILD_PY_ARGS="-s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> --target all"
+ if [ << parameters.build-system >> == "cmake" ]; then
+ BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics"
+ fi
+ python tools/build.py $BUILD_PY_ARGS << parameters.family >>
fi
# Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random)
diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml
index a84db893b..bbe94f0fa 100644
--- a/.github/actions/get_deps/action.yml
+++ b/.github/actions/get_deps/action.yml
@@ -22,6 +22,7 @@ runs:
NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip
wget $NINJA_URL -O ninja-linux.zip
unzip ninja-linux.zip -d ninja-bin
+ pip install membrowse
echo >> $GITHUB_PATH "${{ github.workspace }}/ninja-bin"
shell: bash
diff --git a/.github/membrowse-targets.json b/.github/membrowse-targets.json
deleted file mode 100644
index 05c90c74e..000000000
--- a/.github/membrowse-targets.json
+++ /dev/null
@@ -1,494 +0,0 @@
-{
- "templates": {
- "build_cmd": "python3 tools/build.py -s cmake -b ${board}",
- "elf": "cmake-build/cmake-build-${board}/device/${example}/${example}.elf",
- "setup_cmd": "${toolchain.setup_cmd} && python3 tools/get_deps.py ${get_deps}",
- "get_deps": "${port}"
- },
- "toolchains": {
- "arm-none-eabi-gcc-14": {
- "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH"
- },
- "aarch64-none-elf-gcc-10": {
- "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.xz && tar -C $HOME/toolchain -xf toolchain.tar.xz && echo \"$HOME/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin\" >> $GITHUB_PATH"
- },
- "riscv-none-elf-gcc-13": {
- "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH"
- },
- "msp430-gcc-9": {
- "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.bz2 && tar -C $HOME/toolchain -xf toolchain.tar.bz2 && echo \"$HOME/toolchain/msp430-gcc-9.2.0.50_linux64/bin\" >> $GITHUB_PATH"
- }
- },
- "targets": [
- {
- "port": "at32f402_405",
- "board": "at_start_f402",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f402_405/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F402xC_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f403a_407",
- "board": "at32f403a_weact_blackpill",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f403a_407/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F403AxC_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f413",
- "board": "at_start_f413",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f413/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F413xC_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f415",
- "board": "at_start_f415",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f415/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F415xC_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f423",
- "board": "at_start_f423",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f423/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F423xC_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f425",
- "board": "at_start_f425",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f425/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "at32f435_437",
- "board": "at_start_f435",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/artery/at32f435_437/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F435xM_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "broadcom_32bit",
- "board": "raspberrypi_zero",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/broadcom/broadcom/link.ld",
- "example": "cdc_msc"
- },
- {
- "port": "broadcom_64bit",
- "board": "raspberrypi_cm4",
- "toolchain": "aarch64-none-elf-gcc-10",
- "ld": "hw/mcu/broadcom/broadcom/link8.ld",
- "example": "cdc_msc"
- },
- {
- "port": "ch32v10x",
- "board": "ch32v103r_r1_1v0",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/bsp/ch32v10x/linker/ch32v10x.ld",
- "linker_vars": "__FLASH_SIZE=64K __RAM_SIZE=20K",
- "example": "cdc_msc"
- },
- {
- "port": "ch32v20x",
- "board": "ch32v203c_r0_1v0",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/bsp/ch32v20x/linker/ch32v20x.ld",
- "linker_vars": "__flash_size=64K __ram_size=20K",
- "example": "cdc_msc"
- },
- {
- "port": "ch32v30x",
- "board": "ch32v307v_r1_1v0",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/bsp/ch32v30x/linker/ch32v30x.ld",
- "linker_vars": "__flash_size=128K __ram_size=32K",
- "example": "cdc_msc"
- },
- {
- "port": "da1469x",
- "board": "da14695_dk_usb",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/da1469x/linker/da1469x.ld",
- "example": "cdc_msc"
- },
- {
- "port": "fomu",
- "board": "fomu",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/bsp/fomu/fomu.ld",
- "example": "cdc_msc"
- },
- {
- "port": "gd32vf103",
- "board": "sipeed_longan_nano",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/mcu/gd/nuclei-sdk/SoC/gd32vf103/Board/gd32vf103c_longan_nano/Source/GCC/gcc_gd32vf103xb_flashxip.ld",
- "linker_vars": "__ROM_BASE=0x08000000 __ROM_SIZE=0x00020000 __RAM_BASE=0x20000000 __RAM_SIZE=0x00008000",
- "example": "cdc_msc"
- },
- {
- "port": "hpmicro",
- "board": "hpm6750evk2",
- "toolchain": "riscv-none-elf-gcc-13",
- "ld": "hw/mcu/hpmicro/hpm_sdk/soc/HPM6700/HPM6750/toolchains/gcc/flash_xip.ld",
- "linker_vars": "_flash_size=16M _stack_size=16K _heap_size=16K",
- "example": "cdc_msc"
- },
- {
- "port": "imxrt",
- "board": "metro_m7_1011",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/MIMXRT1011/gcc/MIMXRT1011xxxxx_flexspi_nor.ld",
- "example": "cdc_msc"
- },
- {
- "port": "kinetis_k",
- "board": "frdm_k64f",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/MK64F12/gcc/MK64FN1M0xxx12_flash.ld",
- "get_deps": "kinetis_k kinetis_kl",
- "example": "cdc_msc"
- },
- {
- "port": "kinetis_k32l2",
- "board": "frdm_k32l2a4s",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/K32L2A41A/gcc/K32L2A41xxxxA_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "kinetis_kl",
- "board": "frdm_kl25z",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc11",
- "board": "lpcxpresso11u37",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc11/boards/lpcxpresso11u37/lpc11u37.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc13",
- "board": "lpcxpresso1347",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc13/boards/lpcxpresso1347/lpc1347.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc15",
- "board": "lpcxpresso1549",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc17",
- "board": "lpcxpresso1769",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc18",
- "board": "lpcxpresso18s37",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc40",
- "board": "ea4088_quickstart",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc43",
- "board": "ea4357",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc43/boards/ea4357/lpc4357.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc51",
- "board": "lpcxpresso51u68",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC51U68/gcc/LPC51U68_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc54",
- "board": "lpcxpresso54114",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC54114/gcc/LPC54114J256_cm4_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "lpc55",
- "board": "double_m33_express",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld",
- "example": "cdc_msc"
- },
- {
- "port": "maxim",
- "board": "apard32690",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/maxim/linker/max32690.ld",
- "example": "cdc_msc"
- },
- {
- "port": "mcx",
- "board": "frdm_mcxa153",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/MCXA153/gcc/MCXA153_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "mm32",
- "board": "mm32f327x_mb39",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "msp430",
- "board": "msp_exp430f5529lp",
- "toolchain": "msp430-gcc-9",
- "ld": "hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld",
- "example": "cdc_msc"
- },
- {
- "port": "msp432e4",
- "board": "msp_exp432e401y",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/ti/msp432e4/Source/msp432e411y.ld",
- "example": "cdc_msc"
- },
- {
- "port": "nrf",
- "board": "adafruit_clue",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/nrf/linker/nrf52840_xxaa.ld",
- "example": "cdc_msc"
- },
- {
- "port": "nuc100_120",
- "board": "nutiny_sdk_nuc120",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/nuc100_120/boards/nutiny_sdk_nuc120/nuc120_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "nuc121_125",
- "board": "nutiny_sdk_nuc121",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/nuc121_125/boards/nutiny_sdk_nuc121/nuc121_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "nuc126",
- "board": "nutiny_nuc126v",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/nuc126/boards/nutiny_nuc126v/nuc126_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "nuc505",
- "board": "nutiny_sdk_nuc505",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/nuc505/boards/nutiny_sdk_nuc505/nuc505_flashtoram.ld",
- "example": "cdc_msc"
- },
- {
- "port": "ra",
- "board": "portenta_c33",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld hw/bsp/ra/boards/portenta_c33/script/fsp.ld",
- "example": "cdc_msc"
- },
- {
- "port": "rw61x",
- "board": "frdm_rw612",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/nxp/mcux-sdk/devices/RW612/gcc/RW612_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "samd11",
- "board": "cynthion_d11",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld",
- "linker_vars": "BOOTLOADER_SIZE=0x800",
- "example": "cdc_dual_ports"
- },
- {
- "port": "samd5x_e5x",
- "board": "metro_m4_express",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld",
- "example": "cdc_msc"
- },
- {
- "port": "samg",
- "board": "samg55_xplained",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32c0",
- "board": "stm32c071nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f0",
- "board": "stm32f070rbnucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f1",
- "board": "stm32f103_bluepill",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f2",
- "board": "stm32f207nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f2/boards/stm32f207nucleo/STM32F207ZGTx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f3",
- "board": "stm32f303disco",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f3/boards/stm32f303disco/STM32F303VCTx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f4",
- "board": "feather_stm32f405",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32f7",
- "board": "stlinkv3mini",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32g0",
- "board": "stm32g0b1nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32g4",
- "board": "b_g474e_dpow1",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32h5",
- "board": "stm32h503nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32h7",
- "board": "stm32h743eval",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32h7/linker/stm32h743xx_flash.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32h7rs",
- "board": "stm32h7s3nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld",
- "linker_vars": "__FLASH_BEGIN=0x08000000 __FLASH_SIZE=0x00010000 __RAM_BEGIN=0x24000000 __RAM_SIZE=0x4FC00 __RAM_NONCACHEABLEBUFFER_SIZE=0x400",
- "example": "cdc_msc"
- },
- {
- "port": "stm32l0",
- "board": "stm32l052dap52",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32l4",
- "board": "stm32l412nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32n6",
- "board": "stm32n6570dk",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32n6/boards/stm32n6570dk/STM32N657XX_AXISRAM2_fsbl.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32u0",
- "board": "stm32u083cdk",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32u5",
- "board": "b_u585i_iot2a",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32wb",
- "board": "stm32wb55nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld",
- "example": "cdc_msc"
- },
- {
- "port": "stm32wba",
- "board": "stm32wba_nucleo",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld",
- "example": "cdc_msc"
- },
- {
- "port": "tm4c",
- "board": "ek_tm4c123gxl",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld",
- "example": "cdc_msc"
- },
- {
- "port": "xmc4000",
- "board": "xmc4500_relax",
- "toolchain": "arm-none-eabi-gcc-14",
- "ld": "hw/mcu/infineon/mtb-xmclib-cat3/CMSIS/Infineon/COMPONENT_XMC4500/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld",
- "example": "cdc_msc"
- }
- ]
-}
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
deleted file mode 100644
index aa148eb79..000000000
--- a/.github/pull_request_template.md
+++ /dev/null
@@ -1,5 +0,0 @@
-**Describe the PR**
-A clear and concise description of what this PR solve.
-
-**Additional context**
-If applicable, add any other context about the PR and/or screenshots here.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e0c1d0a14..9d8b90f5a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,6 +7,7 @@ on:
pull_request:
release:
types: [ published ]
+
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
@@ -15,9 +16,9 @@ env:
HIL_JSON: test/hil/tinyusb.json
jobs:
- # Check if code paths changed (skip builds if doc-only)
+ # Check if the code changes and we need to run ci build
+ # Cannot use paths filter in the on-event since we want this workflow to run even when there are no code changes, to register the commit chain
check-paths:
- if: github.event_name == 'pull_request' || github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: read
@@ -46,13 +47,6 @@ jobs:
- '.github/workflows/ci_set_matrix.py'
set-matrix:
- needs: [check-paths]
- if: |
- always() && (
- github.event_name == 'release' ||
- github.event_name == 'workflow_dispatch' ||
- needs.check-paths.outputs.code_changed == 'true'
- )
runs-on: ubuntu-latest
outputs:
json: ${{ steps.set-matrix-json.outputs.matrix }}
@@ -79,7 +73,7 @@ jobs:
# For Make and IAR build: will be done on CircleCI only (one random per family as well)
# ------------------------------------------------------------------------------
cmake:
- needs: set-matrix
+ needs: [ check-paths, set-matrix ]
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
@@ -97,10 +91,14 @@ jobs:
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
build-options: '--one-first'
upload-metrics: true
- upload-artifacts: true
+ upload-artifacts: false
+ upload-membrowse: true
+ code-changed: ${{ needs.check-paths.outputs.code_changed == 'true' }}
+ secrets: inherit
code-metrics:
- needs: cmake
+ needs: [ check-paths, cmake ]
+ if: needs.check-paths.outputs.code_changed == 'true'
runs-on: ubuntu-latest
permissions:
pull-requests: write
@@ -197,26 +195,29 @@ jobs:
# Build Make/CMake on Windows/MacOS
# ---------------------------------------
build-os:
- needs: [check-paths]
+ needs: [ check-paths ]
if: needs.check-paths.outputs.code_changed == 'true'
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
matrix:
os: [ windows-latest, macos-latest ]
+ build-system: [ 'make', 'cmake' ]
with:
os: ${{ matrix.os }}
- build-system: 'cmake-make'
+ build-system: ${{ matrix.build-system }}
toolchain: 'arm-gcc-${{ matrix.os }}'
- build-args: '["stm32h7"]'
+ build-args: '["stm32h7rs"]'
build-options: '--one-random'
# ---------------------------------------
# Zephyr
# ---------------------------------------
zephyr:
- needs: [check-paths]
- if: needs.check-paths.outputs.code_changed == 'true'
+ needs: [ check-paths ]
+ # skip zephyr build due to failed build, fix later
+ if: false
+ #if: needs.check-paths.outputs.code_changed == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout TinyUSB
@@ -238,10 +239,8 @@ jobs:
# Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR
# ---------------------------------------
hil-build:
- needs: [check-paths, set-matrix]
- if: |
- github.repository_owner == 'hathach' &&
- (github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true')
+ needs: [ check-paths, set-matrix ]
+ if: needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach'
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
@@ -260,10 +259,7 @@ jobs:
# self-hosted on local VM, for attached hardware checkout HIL_JSON
# ---------------------------------------
hil-tinyusb:
- needs: [check-paths, hil-build]
- if: |
- github.repository_owner == 'hathach' &&
- (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true')
+ needs: hil-build
runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ]
steps:
- name: Get Skip Boards from previous run
@@ -303,11 +299,11 @@ jobs:
# Since IAR Token secret is not passed to forked PR, only build non-forked PR
# ---------------------------------------
hil-hfp:
- needs: [check-paths]
+ needs: [ check-paths ]
if: |
+ needs.check-paths.outputs.code_changed == 'true' &&
github.repository_owner == 'hathach' &&
- github.event.pull_request.head.repo.fork == false &&
- (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true')
+ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true)
runs-on: [ self-hosted, Linux, X64, hifiphile ]
env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
@@ -340,55 +336,3 @@ jobs:
- name: Test on actual hardware (hardware in the loop)
run: python3 test/hil/hil_test.py hfp.json
-
- # ---------------------------------------
- # Membrowse Memory Analysis
- # Push: always runs (uses identical for doc-only to maintain commit chain)
- # PR: only runs if code changed (doc-only PRs skip entirely)
- # ---------------------------------------
- membrowse:
- needs: [check-paths, cmake]
- if: |
- always() && !cancelled() && (
- github.event_name == 'push' ||
- github.event_name == 'release' ||
- github.event_name == 'workflow_dispatch' ||
- (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true')
- )
- permissions:
- contents: read
- actions: read
- uses: ./.github/workflows/membrowse-report.yml
- with:
- code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }}
- secrets: inherit
-
- membrowse-comment:
- needs: [check-paths, membrowse]
- if: >
- always() &&
- github.event_name == 'pull_request' &&
- needs.check-paths.outputs.code_changed == 'true'
- runs-on: ubuntu-latest
- permissions:
- contents: read
- actions: read
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
-
- - name: Download report artifacts
- id: download
- uses: actions/download-artifact@v5
- with:
- pattern: membrowse-report-*
- path: reports
- merge-multiple: true
- continue-on-error: true
-
- - name: Upload Membrowse Comment Artifact
- if: steps.download.outcome == 'success'
- uses: actions/upload-artifact@v5
- with:
- name: membrowse-comment
- path: reports/
diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml
index e62c10ca1..d03c9af81 100644
--- a/.github/workflows/build_util.yml
+++ b/.github/workflows/build_util.yml
@@ -3,6 +3,10 @@ name: Reusable build util
on:
workflow_call:
inputs:
+ os:
+ required: false
+ type: string
+ default: 'ubuntu-latest'
build-system:
required: true
type: string
@@ -24,10 +28,14 @@ on:
required: false
default: false
type: boolean
- os:
+ upload-membrowse:
required: false
- type: string
- default: 'ubuntu-latest'
+ default: false
+ type: boolean
+ code-changed:
+ required: false
+ default: true
+ type: boolean
jobs:
family:
@@ -39,6 +47,8 @@ jobs:
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ !inputs.upload-membrowse && 1 || 0 }}
- name: Setup Toolchain
id: setup-toolchain
@@ -52,42 +62,40 @@ jobs:
arg: ${{ matrix.arg }}
- name: Build
+ if: ${{ inputs.code-changed }}
env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
- TOOLCHAIN: ${{ inputs.toolchain }}
run: |
- if [ "$TOOLCHAIN" == "esp-idf" ]; then
- docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }}
- elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then
- python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }}
- python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }}
+ if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then
+ docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }}
else
- python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }}
+ BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} --target all"
+ if [ "${{ inputs.upload-metrics }}" = "true" ]; then
+ BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics"
+ fi
+ python tools/build.py $BUILD_PY_ARGS ${{ matrix.arg }}
fi
shell: bash
+ - name: Membrowse Upload
+ if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true
+ env:
+ MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }}
+ run: |
+ # if code-changed is false --> there is no elf -> membrowse target upload with --identical flag
+ BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}"
+ python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }}
+ shell: bash
+
- name: Upload Artifacts for Metrics
- if: ${{ inputs.upload-metrics }}
+ if: inputs.upload-metrics == true && inputs.code-changed == true
uses: actions/upload-artifact@v5
with:
name: metrics-${{ matrix.arg }}
path: cmake-build/cmake-build-*/metrics.json
- - name: Copy linker scripts for artifacts
- if: ${{ inputs.upload-artifacts }}
- run: |
- for dir in cmake-build/cmake-build-*; do
- board=$(basename "$dir" | sed 's/cmake-build-//')
- ld_path=$(jq -r --arg b "$board" '.targets[] | select(.board == $b) | .ld // empty' .github/membrowse-targets.json)
- if [ -n "$ld_path" ] && [ -f "$ld_path" ]; then
- mkdir -p "cmake-build/$(dirname "$ld_path")"
- cp "$ld_path" "cmake-build/$ld_path"
- fi
- done
- shell: bash
-
- name: Upload Artifacts for Hardware Testing
- if: ${{ inputs.upload-artifacts }}
+ if: inputs.upload-artifacts == true && inputs.code-changed == true
uses: actions/upload-artifact@v5
with:
name: binaries-${{ matrix.arg }}
diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py
index 9ab08601d..cd7dfa76b 100755
--- a/.github/workflows/ci_set_matrix.py
+++ b/.github/workflows/ci_set_matrix.py
@@ -15,32 +15,76 @@ toolchain_list = [
# family: [supported toolchain]
family_list = {
- "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": [
- "arm-gcc"],
+ "at32f402_405": ["arm-gcc"],
+ "at32f403a_407": ["arm-gcc"],
+ "at32f413": ["arm-gcc"],
+ "at32f415": ["arm-gcc"],
+ "at32f423": ["arm-gcc"],
+ "at32f425": ["arm-gcc"],
+ "at32f435_437": ["arm-gcc"],
+ "at32f45x": ["arm-gcc"],
+ "broadcom_32bit": ["arm-gcc"],
"broadcom_64bit": ["aarch64-gcc"],
- "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"],
+ "ch32v10x": ["riscv-gcc"],
+ "ch32v20x": ["riscv-gcc"],
+ "ch32v30x": ["riscv-gcc"],
+ "da1469x": ["arm-gcc"],
+ "fomu": ["riscv-gcc"],
+ "gd32vf103": ["riscv-gcc"],
+ "hpmicro": ["riscv-gcc"],
"imxrt": ["arm-gcc", "arm-clang"],
- "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"],
- "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"],
- "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"],
- "maxim mcx mm32 msp432e4 rw61x tm4c": ["arm-gcc"],
+ "kinetis_k": ["arm-gcc", "arm-clang"],
+ "kinetis_k32l2": ["arm-gcc", "arm-clang"],
+ "kinetis_kl": ["arm-gcc", "arm-clang"],
+ "lpc11": ["arm-gcc", "arm-clang"],
+ "lpc13": ["arm-gcc", "arm-clang"],
+ "lpc15": ["arm-gcc", "arm-clang"],
+ "lpc17": ["arm-gcc", "arm-clang"],
+ "lpc18": ["arm-gcc", "arm-clang"],
+ "lpc40": ["arm-gcc", "arm-clang"],
+ "lpc43": ["arm-gcc", "arm-clang"],
+ "lpc51": ["arm-gcc", "arm-clang"],
+ "lpc54": ["arm-gcc", "arm-clang"],
+ "lpc55": ["arm-gcc", "arm-clang"],
+ "maxim": ["arm-gcc"],
+ "mcx": ["arm-gcc"],
+ "mm32": ["arm-gcc"],
"msp430": ["msp430-gcc"],
+ "msp432e4": ["arm-gcc"],
"nrf": ["arm-gcc", "arm-clang"],
- "nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"],
+ "nuc100_120": ["arm-gcc"],
+ "nuc121_125": ["arm-gcc"],
+ "nuc126": ["arm-gcc"],
+ "nuc505": ["arm-gcc"],
"ra": ["arm-gcc"],
"rp2040": ["arm-gcc"],
+ "rw61x": ["arm-gcc"],
"rx": ["rx-gcc"],
- "samd11 samd2x_l2x samd5x_e5x samg": ["arm-gcc", "arm-clang"],
- "stm32c0 stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"],
+ "samd11": ["arm-gcc", "arm-clang"],
+ "samd2x_l2x": ["arm-gcc", "arm-clang"],
+ "samd5x_e5x": ["arm-gcc", "arm-clang"],
+ "samg": ["arm-gcc", "arm-clang"],
+ "stm32c0": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32f0": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32f1": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32f2": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32f3": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32f4": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32f7": ["arm-gcc", "arm-clang", "arm-iar"],
- "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32g0": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32g4": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32h5": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32h7": ["arm-gcc", "arm-clang", "arm-iar"],
- "stm32h7rs stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32l0": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32l4": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32n6": ["arm-gcc"],
- "stm32u0 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32u0": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32u5": ["arm-gcc", "arm-clang", "arm-iar"],
- "-bespressif_s2_devkitc": ["esp-idf"],
+ "stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
+ "stm32wba": ["arm-gcc", "arm-clang", "arm-iar"],
+ "tm4c": ["arm-gcc"],
+ "xmc4000": ["arm-gcc"],
# S3, P4 will be built by hil test
# "-bespressif_s3_devkitm": ["esp-idf"],
# "-bespressif_p4_function_ev": ["esp-idf"],
diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml
deleted file mode 100644
index 0667418e6..000000000
--- a/.github/workflows/membrowse-report.yml
+++ /dev/null
@@ -1,101 +0,0 @@
-name: Membrowse Memory Report
-
-on:
- workflow_call:
- inputs:
- code_changed:
- description: 'Whether code paths changed (true) or doc-only (false)'
- type: boolean
- required: true
-
-permissions:
- contents: read
- actions: read
-
-jobs:
- load-targets:
- runs-on: ubuntu-latest
- outputs:
- targets: ${{ steps.load.outputs.targets }}
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
-
- - name: Load target matrix
- id: load
- run: echo "targets=$(jq -c '.targets' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT
-
- analyze:
- needs: [load-targets]
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- include: ${{ fromJson(needs.load-targets.outputs.targets) }}
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
- with:
- fetch-depth: 0
- submodules: recursive
-
- # Download artifacts when code changed (build artifacts available)
- - name: Download build artifacts
- if: inputs.code_changed
- id: download
- uses: actions/download-artifact@v5
- with:
- pattern: binaries-*
- path: cmake-build
- merge-multiple: true
- continue-on-error: true
-
- - name: Restore linker scripts
- if: inputs.code_changed
- run: cp -r cmake-build/hw . 2>/dev/null || true
-
- - name: Check if ELF exists
- id: check-elf
- run: |
- if [ -f "cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf" ]; then
- echo "exists=true" >> $GITHUB_OUTPUT
- else
- echo "exists=false" >> $GITHUB_OUTPUT
- fi
-
- # Run with actual ELF analysis when build artifacts available
- - name: Run Membrowse Analysis
- if: steps.check-elf.outputs.exists == 'true'
- id: membrowse
- continue-on-error: true
- uses: membrowse/membrowse-action@v1
- with:
- target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }}
- elf: cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf
- ld: ${{ matrix.ld }}
- linker_vars: ${{ matrix.linker_vars || '' }}
- api_key: ${{ secrets.MEMBROWSE_API_KEY }}
- api_url: ${{ vars.MEMBROWSE_API_URL }}
- verbose: INFO
-
- # Run with identical=true when no ELF (doc-only push)
- # Preserves the chain of commits in membrowse tracking
- - name: Run Membrowse Identical Report
- if: steps.check-elf.outputs.exists == 'false'
- id: membrowse-identical
- continue-on-error: true
- uses: membrowse/membrowse-action@v1
- with:
- target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }}
- identical: true
- api_key: ${{ secrets.MEMBROWSE_API_KEY }}
- api_url: ${{ vars.MEMBROWSE_API_URL }}
- verbose: INFO
-
- - name: Upload report artifact
- if: steps.membrowse.outcome == 'success' || steps.membrowse-identical.outcome == 'success'
- uses: actions/upload-artifact@v5
- with:
- name: membrowse-report-${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }}
- path: ${{ steps.membrowse.outputs.report_path || steps.membrowse-identical.outputs.report_path }}
diff --git a/.idea/cmake.xml b/.idea/cmake.xml
index cc73ca8fc..822a70236 100644
--- a/.idea/cmake.xml
+++ b/.idea/cmake.xml
@@ -131,6 +131,7 @@
<configuration PROFILE_NAME="stm32h7s3nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h7s3nucleo -DLOG=1" />
<configuration PROFILE_NAME="stm32l0538disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l0538disco -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32l476disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l476disco -DLOG=1 -DLOGGER=RTT" />
+ <configuration PROFILE_NAME="stm32u083cdk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u083cdk -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32u575nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u575nucleo -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32u5a5nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u5a5nucleo -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
@@ -170,6 +171,7 @@
<configuration PROFILE_NAME="mm32f327x_mb39" ENABLED="false" GENERATION_OPTIONS="-DBOARD=mm32f327x_mb39" />
<configuration PROFILE_NAME="fomu" ENABLED="false" GENERATION_OPTIONS="-DBOARD=fomu" />
<configuration PROFILE_NAME="sipeed_longan_nano" ENABLED="false" GENERATION_OPTIONS="-DBOARD=sipeed_longan_nano" />
+ <configuration PROFILE_NAME="ch32v103r_r1_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v103r_r1_1v0" />
<configuration PROFILE_NAME="nanoch32v203" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DLOG=0" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0 USBFS" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DPORT=1" />
diff --git a/README.rst b/README.rst
index 0eb1e84b9..a3863c375 100644
--- a/README.rst
+++ b/README.rst
@@ -101,10 +101,11 @@ If you have a special requirement, ``usbd_app_driver_get_cb()`` can be used to w
Host Stack
----------
-- Human Interface Device (HID): Keyboard, Mouse, Generic
-- Mass Storage Class (MSC)
- Communication Device Class: CDC-ACM
- Vendor serial over USB: FTDI, CP210x, CH34x, PL2303
+- Human Interface Device (HID): Keyboard, Mouse, Generic
+- Mass Storage Class (MSC)
+- Musical Instrument Digital Interface (MIDI)
- Hub with multiple-level support
Similar to the Device Stack, if you have a special requirement, ``usbh_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 0c3fcec80..8442305d4 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -34,7 +34,10 @@ Get the Code
$ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7
.. note::
- For rp2040 `pico-sdk <https://github.com/raspberrypi/pico-sdk>`_ or `esp-idf <https://github.com/espressif/esp-idf>`_ for Espressif targets are required; install them per vendor instructions.
+ Some MCU families require additional SDKs, please follow their instructions to install and set it up
+
+ * **rp2040**: Requires `pico-sdk <https://github.com/raspberrypi/pico-sdk>`_
+ * **Espressif (esp32)**: Requires `esp-idf <https://github.com/espressif/esp-idf>`_. Only a few examples support the ESP-IDF build system. Look for ones with `src/CMakeLists.txt` that contain `idf_component_register()`, such as `cdc_msc_freertos`.
Simple Device Example
---------------------
diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h
index 0da4032a7..710c01ee2 100644
--- a/examples/device/cdc_dual_ports/src/tusb_config.h
+++ b/examples/device/cdc_dual_ports/src/tusb_config.h
@@ -104,6 +104,8 @@
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// CDC Endpoint transfer buffer size, more is faster
+// Leave it as default size (512 for HS, 64 for FS) unless your host application
+// is able to send ZLP (Zero Length Packet) to terminate transfer !
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#ifdef __cplusplus
diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h
index fdb2ddf18..3f2f05f20 100644
--- a/examples/device/cdc_msc/src/tusb_config.h
+++ b/examples/device/cdc_msc/src/tusb_config.h
@@ -104,6 +104,8 @@
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// CDC Endpoint transfer buffer size, more is faster
+// Leave it as default size (512 for HS, 64 for FS) unless your host application
+// is able to send ZLP (Zero Length Packet) to terminate transfer !
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// MSC Buffer size of Device Mass storage
diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h
index 6b1937a8d..8277b1604 100644
--- a/examples/device/cdc_msc_freertos/src/tusb_config.h
+++ b/examples/device/cdc_msc_freertos/src/tusb_config.h
@@ -111,6 +111,8 @@
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// CDC Endpoint transfer buffer size, more is faster
+// Leave it as default size (512 for HS, 64 for FS) unless your host application
+// is able to send ZLP (Zero Length Packet) to terminate transfer !
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// MSC Buffer size of Device Mass storage
diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h
index b7ece8b7c..5eb2e8f74 100644
--- a/examples/device/cdc_uac2/src/tusb_config.h
+++ b/examples/device/cdc_uac2/src/tusb_config.h
@@ -160,6 +160,8 @@ extern "C" {
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// CDC Endpoint transfer buffer size, more is faster
+// Leave it as default size (512 for HS, 64 for FS) unless your host application
+// is able to send ZLP (Zero Length Packet) to terminate transfer !
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#ifdef __cplusplus
diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake
index baa8422fe..699afda92 100644
--- a/hw/bsp/family_support.cmake
+++ b/hw/bsp/family_support.cmake
@@ -238,6 +238,7 @@ function(family_add_bloaty TARGET)
COMMAND ${BLOATY_EXE} ${OPTION_LIST} $<TARGET_FILE:${TARGET}>
VERBATIM)
+ set_property(TARGET ${TARGET}-bloaty PROPERTY FOLDER ${TARGET})
# post build
# add_custom_command(TARGET ${TARGET} POST_BUILD
# COMMAND ${BLOATY_EXE} --csv ${OPTION_LIST} $<TARGET_FILE:${TARGET}> > ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_bloaty.csv
@@ -258,12 +259,103 @@ function(family_add_linkermap TARGET)
VERBATIM
)
+ set_property(TARGET ${TARGET}-linkermap PROPERTY FOLDER ${TARGET})
+
# post build
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $<TARGET_FILE:${TARGET}>.map
VERBATIM)
endfunction()
+# Add membrowse target (installed with pip install membrowse)
+function(family_add_membrowse TARGET)
+ find_program(MEMBROWSE_EXE membrowse)
+ if (MEMBROWSE_EXE STREQUAL MEMBROWSE_EXE-NOTFOUND)
+ # force anyway, bash login shell will find it from pip install path
+ set(MEMBROWSE_EXE membrowse)
+ endif ()
+
+ set(OPTION "")
+ if (DEFINED MEMBROWSE_OPTION)
+ string(APPEND OPTION " ${MEMBROWSE_OPTION}")
+ endif ()
+
+ # For Ninja generator, extract all linker scripts from Ninja commands (with INCLUDE) and pass them to membrowse.
+ if (CMAKE_GENERATOR MATCHES "Ninja")
+ set(TARGET_ELF_PATH "$<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_NAME:${TARGET}>")
+ set(MEMBROWSE_LD_SCRIPTS_CMD
+ "ld_scripts=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?:-Wl,--script=|-T\\s*)\\K[A-Za-z0-9_./-]+\\.ld' | xargs)\"; \
+all_ld_scripts=\"\"; \
+pending_ld_scripts=\"$ld_scripts\"; \
+while [ -n \"$pending_ld_scripts\" ]; do \
+ next_pending=\"\"; \
+ for script in $pending_ld_scripts; do \
+ case \" $all_ld_scripts \" in *\" $script \"*) continue ;; esac; \
+ all_ld_scripts=\"$all_ld_scripts $script\"; \
+ script_dir=$(dirname \"$script\"); \
+ include_scripts=$(grep -hoP '^\\s*INCLUDE\\s+[<\"]?\\K[^\">[:space:]]+\\.ld' \"$script\" 2>/dev/null | xargs); \
+ for include_script in $include_scripts; do \
+ resolved_script=\"\"; \
+ if [ -f \"$include_script\" ]; then \
+ resolved_script=\"$include_script\"; \
+ elif [ -f \"$script_dir/$include_script\" ]; then \
+ resolved_script=\"$script_dir/$include_script\"; \
+ fi; \
+ if [ -n \"$resolved_script\" ]; then \
+ case \" $all_ld_scripts $next_pending \" in *\" $resolved_script \"*) ;; *) next_pending=\"$next_pending $resolved_script\" ;; esac; \
+ fi; \
+ done; \
+ done; \
+ pending_ld_scripts=\"$(echo \"$next_pending\" | xargs)\"; \
+done; \
+ld_scripts=\"$(echo \"$all_ld_scripts\" | xargs)\"")
+ set(MEMBROWSE_LD_DEFS_CMD
+ "ld_symbols=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?<=--defsym[=,])[^[:space:]]+' | xargs)\"; \
+ld_defs=\"\"; \
+for symbol in $ld_symbols; do \
+ ld_defs=\"$ld_defs --def $symbol\"; \
+done; \
+ld_defs=\"$(echo \"$ld_defs\" | xargs)\"")
+ set(MEMBROWSE_PREPARE_CMD
+ "if [ -f \"${TARGET_ELF_PATH}\" ]; then \
+ ${MEMBROWSE_LD_SCRIPTS_CMD}; \
+ ${MEMBROWSE_LD_DEFS_CMD}; \
+ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \
+ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \
+ else \
+ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs\"; \
+ fi; \
+else \
+ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \
+ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \
+ else \
+ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical\"; \
+ fi; \
+fi; \
+echo \"$MEMBROWSE_CMD\"")
+
+ add_custom_target(${TARGET}-membrowse
+ DEPENDS ${TARGET}
+ COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=0 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\""
+ VERBATIM
+ )
+ set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET})
+
+ add_custom_target(${TARGET}-membrowse-upload
+ COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=1 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\""
+ VERBATIM
+ )
+
+ if (NOT TARGET examples-membrowse-upload)
+ add_custom_target(examples-membrowse-upload)
+ endif ()
+ add_dependencies(examples-membrowse-upload ${TARGET}-membrowse-upload)
+
+ set_property(TARGET ${TARGET}-membrowse-upload PROPERTY FOLDER ${TARGET})
+ endif ()
+endfunction()
+
+
#-------------------------------------------------------------
# Common Target Configure
# Most families use these settings except rp2040 and espressif
@@ -377,6 +469,7 @@ function(family_configure_common TARGET RTOS)
# Analyze size with bloaty and linkermap
family_add_bloaty(${TARGET})
family_add_linkermap(${TARGET})
+ family_add_membrowse(${TARGET})
endif ()
# run size after build
@@ -508,6 +601,8 @@ exit"
COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $<TARGET_FILE_DIR:${BINARY_TARGET}>/${BINARY_TARGET}.jlink
VERBATIM
)
+
+ set_property(TARGET ${NAME_TARGET}-jlink PROPERTY FOLDER ${TARGET})
endfunction()
@@ -521,6 +616,8 @@ function(family_flash_stlink TARGET)
DEPENDS ${TARGET}
COMMAND ${STM32_PROGRAMMER_CLI} --connect port=swd --write $<TARGET_FILE:${TARGET}> --go
)
+
+ set_property(TARGET ${TARGET}-stlink PROPERTY FOLDER ${TARGET})
endfunction()
@@ -534,6 +631,8 @@ function(family_flash_stflash TARGET)
DEPENDS ${TARGET}
COMMAND ${ST_FLASH} write $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin 0x8000000
)
+
+ set_property(TARGET ${TARGET}-stflash PROPERTY FOLDER ${TARGET})
endfunction()
@@ -560,6 +659,8 @@ function(family_flash_openocd TARGET)
COMMAND ${OPENOCD} -c "tcl_port disabled; gdb_port disabled" ${OPTION_LIST} -c "init; halt; program $<TARGET_FILE:${TARGET}>" -c reset ${OPTION_LIST2} -c exit
VERBATIM
)
+
+ set_property(TARGET ${TARGET}-openocd PROPERTY FOLDER ${TARGET})
endfunction()
@@ -621,6 +722,8 @@ function(family_flash_wlink_rs TARGET)
DEPENDS ${TARGET}
COMMAND ${WLINK_RS} flash $<TARGET_FILE:${TARGET}>
)
+
+ set_property(TARGET ${TARGET}-wlink-rs PROPERTY FOLDER ${TARGET})
endfunction()
@@ -634,6 +737,8 @@ function(family_flash_pyocd TARGET)
DEPENDS ${TARGET}
COMMAND ${PYOCD} flash -t ${PYOCD_TARGET} $<TARGET_FILE:${TARGET}>
)
+
+ set_property(TARGET ${TARGET}-pyocd PROPERTY FOLDER ${TARGET})
endfunction()
@@ -643,6 +748,7 @@ function(family_flash_uf2 TARGET FAMILY_ID)
DEPENDS ${TARGET}
COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} --deploy $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.uf2
)
+ set_property(TARGET ${TARGET}-uf2 PROPERTY FOLDER ${TARGET})
endfunction()
@@ -657,6 +763,8 @@ function(family_flash_teensy TARGET)
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex
COMMAND ${TEENSY_CLI} --mcu=${TEENSY_MCU} -w -s $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex
)
+
+ set_property(TARGET ${TARGET}-teensy PROPERTY FOLDER ${TARGET})
endfunction()
@@ -675,6 +783,8 @@ function(family_flash_nxplink TARGET)
DEPENDS ${TARGET}
COMMAND ${LINKSERVER_PATH} flash ${NXPLINK_DEVICE} load $<TARGET_FILE:${TARGET}>
)
+
+ set_property(TARGET ${TARGET}-nxplink PROPERTY FOLDER ${TARGET})
endfunction()
@@ -688,6 +798,8 @@ function(family_flash_dfu_util TARGET OPTION)
COMMAND ${DFU_UTIL} -R -d ${DFU_UTIL_VID_PID} -a 0 -D $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin
VERBATIM
)
+
+ set_property(TARGET ${TARGET}-dfu-util PROPERTY FOLDER ${TARGET})
endfunction()
function(family_flash_msp430flasher TARGET)
@@ -703,6 +815,8 @@ function(family_flash_msp430flasher TARGET)
COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR}
${MSP430FLASHER} -w $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex -z [VCC]
)
+
+ set_property(TARGET ${TARGET}-msp430flasher PROPERTY FOLDER ${TARGET})
endfunction()
function(family_flash_uniflash TARGET)
@@ -717,6 +831,8 @@ function(family_flash_uniflash TARGET)
COMMAND ${DSLITE} ${UNIFLASH_OPTION} -f $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex
VERBATIM
)
+
+ set_property(TARGET ${TARGET}-uniflash PROPERTY FOLDER ${TARGET})
endfunction()
#----------------------------------
diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake
index e617ab3ca..82d0034a1 100644
--- a/hw/bsp/rp2040/family.cmake
+++ b/hw/bsp/rp2040/family.cmake
@@ -250,9 +250,10 @@ function(family_configure_target TARGET RTOS)
family_flash_openocd(${TARGET})
family_flash_jlink(${TARGET})
- # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options
+ # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options
family_add_bloaty(${TARGET})
family_add_linkermap(${TARGET})
+ family_add_membrowse(${TARGET})
endfunction()
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 15bfafc35..3766e3a25 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -646,7 +646,11 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
break;
}
- TU_ASSERT(prepare_cbw(p_msc));
+ if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) {
+ TU_ASSERT(prepare_cbw(p_msc));
+ } else {
+ p_msc->stage = MSC_STAGE_CMD;
+ }
} else {
// Any xfer ended here is considered unknown error, ignore it
TU_LOG1(" Warning expect SCSI Status but received unknown data\r\n");
diff --git a/src/class/mtp/mtp_device.h b/src/class/mtp/mtp_device.h
index a33f1dc08..6cce7efbb 100644
--- a/src/class/mtp/mtp_device.h
+++ b/src/class/mtp/mtp_device.h
@@ -18,7 +18,7 @@
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN0
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h
index f14555e4f..2750bb2fb 100644
--- a/src/class/video/video_device.h
+++ b/src/class/video/video_device.h
@@ -99,8 +99,7 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
* @param[in] stm_idx Destination streaming interface index
* @param[out] payload_buf Payload storage buffer (target buffer for requested data)
* @param[in] payload_size Size of payload_buf (requested data size)
- * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize)
- * @return video_error_code_t */
+ * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize) */
void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request);
//--------------------------------------------------------------------+
diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h
index c9e06361c..bd00b9d11 100644
--- a/src/common/tusb_verify.h
+++ b/src/common/tusb_verify.h
@@ -73,8 +73,13 @@
#define TU_MESS_FAILED() do {} while (0)
#endif
+// Custom defined application function
+#ifdef CFG_TUSB_DEBUG_BREAKPOINT
+ extern void CFG_TUSB_DEBUG_BREAKPOINT(void);
+ #define TU_BREAKPOINT() CFG_TUSB_DEBUG_BREAKPOINT()
+
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55
-#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \
+#elif defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \
defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define TU_BREAKPOINT() do { \
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 1e21c667a..cca4169d7 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -666,8 +666,14 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
return;
}
- // Loop until there is no more events in the queue
- while (1) {
+ // Loop until there are no more events in the queue or CFG_TUD_TASK_EVENTS_PER_RUN is reached
+ for (unsigned epr = 0;; epr++) {
+#if CFG_TUD_TASK_EVENTS_PER_RUN > 0
+ if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) {
+ TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n");
+ break;
+ }
+#endif
dcd_event_t event;
if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) {
return;
diff --git a/src/device/usbd.h b/src/device/usbd.h
index f923b1c56..7d7604c81 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -820,7 +820,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
/* Interface */ \
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \
/* Function */ \
- 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
+ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110)
//--------------------------------------------------------------------+
// DFU Descriptor Templates
@@ -834,7 +834,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
#define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \
TU_XSTRCAT(TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \
/* Function */ \
- 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
+ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110)
#define TUD_DFU_ALT(_itfnum, _alt, _stridx) \
/* Interface */ \
diff --git a/src/host/usbh.c b/src/host/usbh.c
index a725b7c8b..41f41dcfb 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -599,8 +599,14 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
return;
}
- // Loop until there is no more events in the queue
- while (1) {
+ // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached
+ for (unsigned epr = 0;; epr++) {
+#if CFG_TUH_TASK_EVENTS_PER_RUN > 0
+ if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) {
+ TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n");
+ break;
+ }
+#endif
hcd_event_t event;
if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { return; }
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index f0c5aa722..d329285e9 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -32,12 +32,6 @@
#define MUSB_DEBUG 2
#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport])
-#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED)
-/* GCC warns that an address may be unaligned, even though
- * the target CPU has the capability for unaligned memory access. */
-_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"");
-#endif
-
#include "musb_type.h"
#include "device/dcd.h"
@@ -73,7 +67,10 @@ typedef struct TU_ATTR_PACKED
typedef struct
{
- tusb_control_request_t setup_packet;
+ union {
+ tusb_control_request_t setup_packet;
+ uint32_t setup_buffer[2];
+ };
uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */
int8_t status_out;
pipe_state_t pipe0;
@@ -174,9 +171,8 @@ static void process_setup_packet(uint8_t rhport) {
musb_regs_t* musb_regs = MUSB_REGS(rhport);
// Read setup packet
- uint32_t *p = (void*)&_dcd.setup_packet;
- p[0] = musb_regs->fifo[0];
- p[1] = musb_regs->fifo[0];
+ _dcd.setup_buffer[0] = musb_regs->fifo[0];
+ _dcd.setup_buffer[1] = musb_regs->fifo[0];
_dcd.pipe0.buf = NULL;
_dcd.pipe0.length = 0;
@@ -193,14 +189,13 @@ static void process_setup_packet(uint8_t rhport) {
}
}
-static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
-{
+static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) {
unsigned epnum = tu_edpt_number(ep_addr);
unsigned epnum_minus1 = epnum - 1;
pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1];
const unsigned rem = pipe->remaining;
- if (!rem) {
+ if (rem == 0 && pipe->length > 0) {
pipe->buf = NULL;
return true;
}
diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h
index c53e345b0..b749a92ff 100644
--- a/src/portable/st/stm32_fsdev/fsdev_common.h
+++ b/src/portable/st/stm32_fsdev/fsdev_common.h
@@ -63,23 +63,21 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b
// CFG_TUSB_FSDEV_PMA_SIZE is PMA buffer size in bytes.
// - 512-byte devices, access with a stride of two words (use every other 16-bit address)
-// - 1024-byte devices, access with a stride of one word (use every 16-bit address)
+// - 1024-byte devices, access with a stride of one word (use every 16-bit address) or 32-bit address
// - 2048-byte devices, access with 32-bit address
-
-// For purposes of accessing the packet
-#if CFG_TUSB_FSDEV_PMA_SIZE == 512
- // 1x16 bit / word access scheme
- #define FSDEV_PMA_STRIDE 2
- #define pma_access_scheme TU_ATTR_ALIGNED(4)
-#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
- // 2x16 bit / word access scheme
- #define FSDEV_PMA_STRIDE 1
- #define pma_access_scheme
-#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048
+#if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0)
// 32 bit access scheme
#define FSDEV_BUS_32BIT
#define FSDEV_PMA_STRIDE 1
#define pma_access_scheme
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
+ // 2x16 bit / word access scheme
+ #define FSDEV_PMA_STRIDE 1
+ #define pma_access_scheme
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 512
+ // 1x16 bit / word access scheme
+ #define FSDEV_PMA_STRIDE 2
+ #define pma_access_scheme TU_ATTR_ALIGNED(4)
#endif
// The fsdev_bus_t type can be used for both register and PMA access necessities
diff --git a/src/tusb_option.h b/src/tusb_option.h
index abf5e0608..8e270e5f2 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -340,14 +340,14 @@
#if defined(TUP_USBIP_FSDEV)
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
- #if CFG_TUSB_FSDEV_PMA_SIZE == 512
- #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data
+ #if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0)
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data
#define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase
#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
#define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data
#define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase
- #elif CFG_TUSB_FSDEV_PMA_SIZE == 2048
- #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data
+ #elif CFG_TUSB_FSDEV_PMA_SIZE == 512
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data
#define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase
#endif
#endif
@@ -560,6 +560,11 @@
#define CFG_TUD_INTERFACE_MAX 16
#endif
+// max events processed in one tud_task_ext() call, 0 for unlimited
+#ifndef CFG_TUD_TASK_EVENTS_PER_RUN
+ #define CFG_TUD_TASK_EVENTS_PER_RUN 16
+#endif
+
// default to max hardware endpoint, but can be smaller to save RAM
#ifndef CFG_TUD_ENDPPOINT_MAX
#define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX
@@ -679,6 +684,11 @@
#define CFG_TUH_MEM_DCACHE_LINE_SIZE CFG_TUSB_MEM_DCACHE_LINE_SIZE
#endif
+// max events processed in one tuh_task_ext() call, 0 for unlimited
+#ifndef CFG_TUH_TASK_EVENTS_PER_RUN
+ #define CFG_TUH_TASK_EVENTS_PER_RUN 16
+#endif
+
//------------- CLASS -------------//
#ifndef CFG_TUH_HUB
diff --git a/tools/build.py b/tools/build.py
index d22d06a0b..3c5c3c077 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -24,7 +24,6 @@ build_separator = '-' * 95
build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED]
verbose = False
-clean_build = False
parallel_jobs = os.cpu_count()
# CI board control lists (used when running under CI)
@@ -98,15 +97,15 @@ def get_examples(family):
return all_examples
-def print_build_result(board, example, status, duration):
+def print_build_result(board, build_target, status, duration):
if isinstance(duration, (int, float)):
duration = "{:.2f}s".format(duration)
- print(build_format.format(board, example, build_status[status], duration))
+ print(build_format.format(board, build_target, build_status[status], duration))
# -----------------------------
# CMake
# -----------------------------
-def cmake_board(board, build_args, build_flags_on):
+def cmake_board(board, build_args, build_flags_on, build_targets):
ret = [0, 0, 0]
start_time = time.monotonic()
@@ -135,39 +134,36 @@ def cmake_board(board, build_args, build_flags_on):
f'-DBOARD={board}', '-DCMAKE_BUILD_TYPE=MinSizeRel', '-DLINKERMAP_OPTION=-q -f tinyusb/src',
*build_args, *build_flags])
if rcmd.returncode == 0:
- if clean_build:
- run_cmd(["cmake", "--build", build_dir, '--target', 'clean'])
cmd = ["cmake", "--build", build_dir, '--parallel', str(parallel_jobs)]
- rcmd = run_cmd(cmd)
- if rcmd.returncode == 0:
- ret[0] += 1
- run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_metrics'])
- # print(rcmd.stdout.decode("utf-8"))
- else:
- ret[1] += 1
+ for target in build_targets:
+ rcmd = run_cmd(cmd + ['--target', target])
+ if rcmd.returncode != 0:
+ break
+ ret[0 if rcmd.returncode == 0 else 1] += 1
- example = 'all'
- print_build_result(board, example, 0 if ret[1] == 0 else 1, time.monotonic() - start_time)
+ print_build_result(board, ','.join(build_targets), 0 if ret[1] == 0 else 1, time.monotonic() - start_time)
return ret
# -----------------------------
# Make
# -----------------------------
-def make_one_example(example, board, make_option):
+def make_one_example(example, board, make_option, build_targets):
# Check if board is skipped
if build_utils.skip_example(example, board):
print_build_result(board, example, 2, '-')
r = 2
else:
start_time = time.monotonic()
- make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)]
+ make_cmd = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)]
if make_option:
- make_args += shlex.split(make_option)
- if clean_build:
- run_cmd(make_args + ["clean"])
- build_result = run_cmd(make_args + ['all'])
- r = 0 if build_result.returncode == 0 else 1
+ make_cmd += shlex.split(make_option)
+ r = 0
+ for target in build_targets:
+ build_result = run_cmd(make_cmd + [target])
+ if build_result.returncode != 0:
+ r = 1
+ break
print_build_result(board, example, r, time.monotonic() - start_time)
ret = [0, 0, 0]
@@ -175,7 +171,7 @@ def make_one_example(example, board, make_option):
return ret
-def make_board(board, build_args):
+def make_board(board, build_args, build_targets):
print(build_separator)
family = find_family(board);
all_examples = get_examples(family)
@@ -186,7 +182,7 @@ def make_board(board, build_args):
final_status = 2
else:
with Pool(processes=os.cpu_count()) as pool:
- pool_args = list((map(lambda e, b=board, o=f"{build_args}": [e, b, o], all_examples)))
+ pool_args = list((map(lambda e, b=board, o=f"{build_args}", t=build_targets: [e, b, o, t], all_examples)))
r = pool.starmap(make_one_example, pool_args)
# sum all element of same index (column sum)
ret = list(map(sum, list(zip(*r))))
@@ -198,16 +194,16 @@ def make_board(board, build_args):
# -----------------------------
# Build Family
# -----------------------------
-def build_boards_list(boards, build_defines, build_system, build_flags_on):
+def build_boards_list(boards, build_defines, build_system, build_flags_on, build_targets):
ret = [0, 0, 0]
for b in boards:
r = [0, 0, 0]
if build_system == 'cmake':
build_args = [f'-D{d}' for d in build_defines]
- r = cmake_board(b, build_args, build_flags_on)
+ r = cmake_board(b, build_args, build_flags_on, build_targets)
elif build_system == 'make':
build_args = ' '.join(f'{d}' for d in build_defines)
- r = make_board(b, build_args)
+ r = make_board(b, build_args, build_targets)
ret[0] += r[0]
ret[1] += r[1]
ret[2] += r[2]
@@ -257,13 +253,11 @@ def get_family_boards(family, one_random, one_first):
# -----------------------------
def main():
global verbose
- global clean_build
global parallel_jobs
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('-c', '--clean', action='store_true', default=False, help='Clean before 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('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system')
@@ -273,6 +267,8 @@ def main():
parser.add_argument('--one-first', action='store_true', default=False,
help='Build only the first board (alphabetical) of each specified family')
parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel')
+ parser.add_argument('-T', '--target', action='append', default=[],
+ help='Build target to use, may be specified multiple times (default: all)')
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
args = parser.parse_args()
@@ -284,8 +280,8 @@ def main():
build_flags_on = args.build_flags_on
one_random = args.one_random
one_first = args.one_first
+ build_targets = args.target if args.target else ['all']
verbose = args.verbose
- clean_build = args.clean
parallel_jobs = args.jobs
build_defines.append(f'TOOLCHAIN={toolchain}')
@@ -295,7 +291,7 @@ def main():
return 1
print(build_separator)
- print(build_format.format('Board', 'Example', '\033[39mResult\033[0m', 'Time'))
+ print(build_format.format('Board', 'Target', '\033[39mResult\033[0m', 'Time'))
total_time = time.monotonic()
# get all families
@@ -314,7 +310,7 @@ def main():
all_boards.extend(get_family_boards(f, one_random, one_first))
# build all boards
- result = build_boards_list(all_boards, build_defines, build_system, build_flags_on)
+ result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_targets)
total_time = time.monotonic() - total_time
print(build_separator)
diff --git a/tools/codespell/ignore-words.txt b/tools/codespell/ignore-words.txt
index 957cbd86b..5b6e2e98b 100644
--- a/tools/codespell/ignore-words.txt
+++ b/tools/codespell/ignore-words.txt
@@ -1,14 +1,15 @@
-synopsys
-sie
-tre
-thre
-hsi
-fro
-dout
-mot
-te
attch
+busses
+dout
endianess
+fro
+hsi
+inout
+mot
pris
-busses
ser
+sie
+synopsys
+te
+thre
+tre
diff --git a/tools/get_deps.py b/tools/get_deps.py
index a75f0c169..1d596469b 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -45,7 +45,7 @@ deps_optional = {
'xmc4000'],
'hw/mcu/microchip': ['https://github.com/hathach/microchip_driver.git',
'9e8b37e307d8404033bb881623a113931e1edf27',
- 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg'],
+ 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg'],
'hw/mcu/mindmotion/mm32sdk': ['https://github.com/hathach/mm32sdk.git',
'b93e856211060ae825216c6a1d6aa347ec758843',
'mm32'],
@@ -252,11 +252,11 @@ deps_optional = {
'hpmicro'],
'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git',
'2b7495b8535bdcb306dac29b9ded4cfb679d7e5c',
- 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx rw61x mm32 msp432e4 nrf saml2x '
+ 'imxrt kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx rw61x mm32 msp432e4 nrf samd2x_l2x '
'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 '
'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 '
'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba '
- 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg '
+ 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg '
'tm4c '],
'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git',
'6f0a58d01aa9bd2feba212097f9afe7acd991d52',
@@ -330,18 +330,16 @@ def main():
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch')
parser.add_argument('-D', '--define', action='append', default=[], help='Have no effect')
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()
families = args.families
boards = args.board
- print_only = args.print
status = 0
- deps = list(deps_mandatory.keys())
+ deps = []
if 'all' in families:
- deps += deps_optional.keys()
+ deps.extend(deps_optional.keys())
else:
families = list(families)
if boards is not None:
@@ -349,24 +347,16 @@ def main():
f = find_family(b)
if f is not None:
families.append(f)
-
for f in families:
for d in deps_optional:
if d not in deps and f in deps_optional[d][2].split():
deps.append(d)
+ if len(deps) == 0:
+ print('WARN: no additional dependencies found for given boards or families')
- if print_only:
- pvalue = {}
- # print only without arguments, always add CMSIS_5
- if len(families) == 0 and len(boards) == 0:
- deps.append('lib/CMSIS_5')
- for d in deps:
- commit = deps_all[d][1]
- pvalue[d] = commit
- print(pvalue)
- else:
- with Pool() as pool:
- status = sum(pool.map(get_a_dep, deps))
+ deps.extend(deps_mandatory.keys())
+ with Pool() as pool:
+ status = sum(pool.map(get_a_dep, deps))
return status