initial commit

This commit is contained in:
shell committed 2026-10-11 21:48:59 +08:00
commit b44ce7bd77
2716 files changed
+559005

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
version: 2.1
setup: true
orbs:
continuation: circleci/continuation@1
jobs:
set-matrix:
executor: continuation/default
docker:
- image: cimg/base:current
resource_class: large
steps:
- checkout
- run:
name: Set matrix
command: |
MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)
echo "MATRIX_JSON=$MATRIX_JSON"
BUILDSYSTEM_LIST=(
"cmake"
"make"
)
TOOLCHAIN_LIST=(
"aarch64-gcc"
"arm-clang"
"arm-gcc"
"esp-idf"
"ft9xx-gcc"
"msp430-gcc"
"riscv-gcc"
)
# only build IAR if not forked PR, since IAR token is not shared
if [ -z $CIRCLE_PR_USERNAME ]; then
TOOLCHAIN_LIST+=("arm-iar")
fi
gen_build_entry() {
local build_system="$1"
local toolchain="$2"
local family="$3"
local build_args=""
if [[ "$toolchain" == "arm-iar" || "$build_system" == "make" ]]; then
build_args="--one-random"
fi
if [[ "$toolchain" == "esp-idf" ]]; then
echo " - build-vm:" >> .circleci/config2.yml
else
echo " - build:" >> .circleci/config2.yml
fi
echo " matrix:" >> .circleci/config2.yml
echo " alias: build-${build_system}-${toolchain}" >> .circleci/config2.yml
echo " parameters:" >> .circleci/config2.yml
echo " build-system: ['$build_system']" >> .circleci/config2.yml
echo " toolchain: ['$toolchain']" >> .circleci/config2.yml
echo " family: $family" >> .circleci/config2.yml
echo " resource_class: ['large']" >> .circleci/config2.yml
echo " build-args: ['$build_args']" >> .circleci/config2.yml
}
# Collect all build aliases for code-metrics requires (cmake only, exclude esp-idf)
BUILD_ALIASES=()
for build_system in "${BUILDSYSTEM_LIST[@]}"; do
for toolchain in "${TOOLCHAIN_LIST[@]}"; do
# make does not support these toolchains
if [ "$build_system" == "make" ] && { [ "$toolchain" == "arm-clang" ] || [ "$toolchain" == "arm-iar" ] || [ "$toolchain" == "esp-idf" ]; }; then
continue
fi
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"")
echo "FAMILY_${toolchain}=$FAMILY"
gen_build_entry "$build_system" "$toolchain" "$FAMILY"
# Only add cmake builds: excluding esp-idf or build_args="--one-random" to metrics requirements
if [ "$build_system" == "cmake" ] && [ "$toolchain" != "esp-idf" ] && [ "$toolchain" != "arm-iar" ]; then
BUILD_ALIASES+=("build-${build_system}-${toolchain}")
fi
done
done
# Add code-metrics job that requires all build jobs
echo " - code-metrics:" >> .circleci/config2.yml
echo " requires:" >> .circleci/config2.yml
for alias in "${BUILD_ALIASES[@]}"; do
echo " - $alias" >> .circleci/config2.yml
done
- continuation/continue:
configuration_path: .circleci/config2.yml
workflows:
set-matrix:
jobs:
- set-matrix
+299
View File
@@ -0,0 +1,299 @@
version: 2.1
commands:
setup-toolchain:
parameters:
toolchain:
type: string
steps:
- run:
name: Set toolchain url and key
command: |
toolchain_url=$(jq -r '."<< parameters.toolchain >>"' .github/actions/setup_toolchain/toolchain.json)
# only cache if not a github link
if [[ $toolchain_url != "https://github.com"* ]]; then
echo "<< parameters.toolchain >>-$toolchain_url" > toolchain_key
fi
echo "export toolchain_url=$toolchain_url" >> $BASH_ENV
- restore_cache:
name: Restore Toolchain Cache
key: deps-{{ checksum "toolchain_key" }}
paths:
- ~/cache/<< parameters.toolchain >>
- run:
name: Install Toolchain
command: |
# download if folder does not exist (not cached)
if [ ! -d ~/cache/<< parameters.toolchain >> ]; then
mkdir -p ~/cache/<< parameters.toolchain >>
if [[ << parameters.toolchain >> == rx-gcc ]]; then
wget --progress=dot:giga $toolchain_url -O toolchain.run
chmod +x toolchain.run
./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y
elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then
wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb
elif [[ << parameters.toolchain >> == arm-iar ]]; then
wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb
wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/toolchain.deb
else
wget --progress=dot:giga $toolchain_url -O toolchain.tar.gz
tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz
fi
fi
# Add toolchain to PATH
if [[ << parameters.toolchain >> == arm-iar ]]; then
# Install IAR since we only cache deb file
sudo dpkg -i ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb
sudo dpkg --ignore-depends=libusb-1.0-0 -i ~/cache/<< parameters.toolchain >>/toolchain.deb
echo "export PATH=$PATH:/opt/iar/cxarm/arm/bin" >> $BASH_ENV
elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then
sudo apt install -y ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb
echo "export PATH=$PATH:/opt/ft32/bin" >> $BASH_ENV
else
echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV
fi
- save_cache:
name: Save Toolchain Cache
key: deps-{{ checksum "toolchain_key" }}
paths:
- ~/cache/<< parameters.toolchain >>
build:
parameters:
build-system:
type: string
toolchain:
type: string
family:
type: string
build-args:
type: string
default: ""
steps:
- checkout
- run:
name: Get Dependencies
command: |
python tools/get_deps.py << parameters.family >>
# Install ninja if cmake build system
if [ << parameters.build-system >> == "cmake" ]; then
NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip
wget $NINJA_URL -O ninja-linux.zip
unzip ninja-linux.zip -d ~/bin
fi
# rx-gcc is 32-bit binary
if [[ << parameters.toolchain >> == rx-gcc ]]; then
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386 libstdc++6:i386 zlib1g:i386
fi
# Install Pico SDK
if [ << parameters.family >> == "rp2040" ]; then
git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk
echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV
fi
- when:
condition:
not:
equal: [esp-idf, << parameters.toolchain >>]
steps:
- setup-toolchain:
toolchain: << parameters.toolchain >>
- run:
name: Build
no_output_timeout: 20m
command: |
if [ << parameters.toolchain >> == esp-idf ]; then
docker run --rm -v $PWD:/project -w /project espressif/idf:v5.5.3 python tools/build.py << parameters.build-args >> --target all << parameters.family >>
else
# Toolchain option default is gcc
if [ << parameters.toolchain >> == arm-clang ]; then
TOOLCHAIN_OPTION="--toolchain clang"
elif [ << parameters.toolchain >> == arm-iar ]; then
TOOLCHAIN_OPTION="--toolchain iar"
iccarm --version
elif [ << parameters.toolchain >> == arm-gcc ]; then
TOOLCHAIN_OPTION="--toolchain gcc"
fi
# circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large)
# Required for IAR, also prevent crashed/killed by docker
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)
- when:
condition:
and:
- equal: [ cmake, << parameters.build-system >> ]
- not:
equal: [ esp-idf, << parameters.toolchain >> ]
- not:
equal: [ arm-iar, << parameters.toolchain >> ]
steps:
- run:
name: Collect Metrics
command: |
# Create unique directory per toolchain to avoid workspace conflicts
METRICS_DIR="/tmp/metrics/<< parameters.toolchain >>"
mkdir -p "${METRICS_DIR}"
# Copy all metrics.json files
for f in cmake-build/cmake-build-*/metrics.json; do
if [ -f "$f" ]; then
BOARD_DIR=$(dirname "$f" | xargs basename)
cp "$f" "${METRICS_DIR}/${BOARD_DIR}.json"
fi
done
- persist_to_workspace:
root: /tmp
paths:
- metrics/<< parameters.toolchain >>
jobs:
# Build using docker
build:
parameters:
resource_class:
type: string
default: large
build-system:
type: string
toolchain:
type: string
family:
type: string
build-args:
type: string
default: ""
docker:
- image: cimg/base:current
working_directory: ~/project/tinyusb
resource_class: << parameters.resource_class >>
steps:
- build:
build-system: << parameters.build-system >>
toolchain: << parameters.toolchain >>
family: << parameters.family >>
build-args: << parameters.build-args >>
# Build using VM
build-vm:
parameters:
resource_class:
type: string
default: large
build-system:
type: string
toolchain:
type: string
family:
type: string
build-args:
type: string
default: ""
machine:
image: ubuntu-2404:current
working_directory: ~/project/tinyusb
resource_class: << parameters.resource_class >>
steps:
- build:
build-system: << parameters.build-system >>
toolchain: << parameters.toolchain >>
family: << parameters.family >>
build-args: << parameters.build-args >>
# Aggregate code metrics from all builds
code-metrics:
docker:
- image: cimg/python:3.12
resource_class: large
steps:
- checkout
- attach_workspace:
at: /tmp
- run:
name: Aggregate Code Metrics
command: |
python tools/get_deps.py
# Combine all metrics files from all toolchain subdirectories
ls -R /tmp/metrics
if ls /tmp/metrics/*/*.json 1> /dev/null 2>&1; then
python tools/metrics.py combine -j -m -f tinyusb/src /tmp/metrics/*/*.json
else
echo "No metrics files found"
exit 1
fi
- store_artifacts:
path: metrics.json
destination: metrics.json
# Compare with base master metrics on PR branches
- when:
condition:
not:
equal: [ master, << pipeline.git.branch >> ]
steps:
- run:
name: Download Base Branch Metrics
command: |
# Download metrics.json artifact from the latest successful build on master branch
mkdir -p base-metrics
# Use CircleCI API to get the latest artifact
curl -s -L "https://dl.circleci.com/api/v2/project/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/latest/artifacts?branch=master&filter=successful" \
-H "Circle-Token: ${CIRCLE_TOKEN:-}" | \
jq -r '.items[] | select(.path == "metrics.json") | .url' | \
head -1 | xargs -I {} curl -s -L -o base-metrics/metrics.json {} || true
- run:
name: Compare with Base Branch
command: |
if [ -f base-metrics/metrics.json ]; then
python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json
cat metrics_compare.md
else
echo "No base metrics found, skipping comparison"
cp metrics.md metrics_compare.md
fi
- store_artifacts:
path: metrics_compare.md
destination: metrics_compare.md
workflows:
build:
jobs:
# The jobs below are populated dynamically by config.yml set-matrix job
# Example entries that will be generated:
# - build:
# matrix:
# alias: build-cmake-arm-gcc
# parameters:
# toolchain: [ 'arm-gcc' ]
# build-system: [ 'cmake' ]
# family: [ 'nrf' ]
# resource_class: ['large']
# - code-metrics:
# requires:
# - build-cmake-arm-gcc
+99
View File
@@ -0,0 +1,99 @@
---
Language: Cpp
BasedOnStyle: LLVM
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignConsecutiveShortCaseStatements:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCaseColons: false
AlignEscapedNewlines: LeftWithLastLine
AlignOperands: true
AlignTrailingComments:
Kind: Always
OverEmptyLines: 2
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BracedInitializerIndentWidth: 2
BreakBeforeBinaryOperators: None
BreakConstructorInitializers: AfterColon
BreakConstructorInitializersBeforeComma: false
ContinuationIndentWidth: 2
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: false
Cpp11BracedListStyle: true
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^<.*'
Priority: 1
- Regex: '^".*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentPPDirectives: BeforeHash
InsertBraces: true
IndentCaseLabels: true
InsertNewlineAtEOF: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
PenaltyBreakBeforeFirstCallParameter: 1000000
PenaltyBreakOpenParenthesis: 1000000
PPIndentWidth: 2
QualifierAlignment: Custom
QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type']
SpaceAfterTemplateKeyword: false
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SortIncludes: false
TabWidth: 2
...
+32
View File
@@ -0,0 +1,32 @@
---
name: build-doc
description: Use when building, previewing, or testing the TinyUSB Sphinx docs locally (docs/ → HTML), chasing Sphinx warnings, understanding how example READMEs get into the docs, or regenerating the auto-generated reference files after adding a board or dependency (boards.rst, dependencies.rst, BoardPresets.json, CMakePresets.json).
---
# Build TinyUSB Docs
## Build & preview
```bash
pip install -r docs/requirements.txt # one-time
python3 tools/build_doc.py -o # build docs/_build/ and open it
```
`tools/build_doc.py` wraps `sphinx-build`: `-c` clean, `-W` fail on warnings, `-o` open. Raw form: `sphinx-build -b html docs docs/_build`.
- Pages can be `.rst` or `.md` (MyST). Example `README.md`s under `examples/{device,host,dual}/*/` are **auto-collected** at build time into `docs/examples/` (per-group `index` pages, git-ignored) — add/rename an example and just rebuild; edit the source README, never the generated copies.
- Watch the output for `WARNING:` (broken refs, missing toctree entries).
## Regenerate after adding a board or dependency
Run from the repo root; `docs/reference/*.rst` and the preset JSONs are **generated** — don't hand-edit.
| Added | Run |
|---|---|
| Board (`hw/bsp/FAMILY/boards/`) | `python3 tools/gen_doc.py` + `python3 tools/gen_presets.py` |
| Dependency (edited `tools/get_deps.py`) | `python3 tools/gen_doc.py` |
- `gen_doc.py` → `docs/reference/boards.rst` + `dependencies.rst`. Needs `pandas` + `tabulate` (not in `requirements.txt`) — `pip install pandas tabulate` if it errors.
- `gen_presets.py` → `hw/bsp/BoardPresets.json` + per-example `CMakePresets.json`.
Then rebuild and `git diff` the regenerated files; commit them with the board/dep change.
+76
View File
@@ -0,0 +1,76 @@
---
name: code-size
description: Use when comparing TinyUSB code size between a base ref (master by default) and the current branch to evaluate the size impact of changes. Three granularities — single example on one board (with optional bloaty), all examples on one board, or all examples across CI families combined.
---
# Code Size Comparison
Compare TinyUSB code size between a base ref (default `master`) and the current branch using `tools/metrics_compare_base.py`. Three granularities — pick the narrowest one that exercises your change:
| Granularity | When to use | Command |
|---|---|---|
| **single example, one board** | Focused change touching one feature | `-b BOARD -e device/cdc_msc` |
| **all examples, one board** | Per-board regression sweep | `-b BOARD` |
| **all examples, all CI families (combined)** | Pre-merge full check | `--ci` |
The script handles the full base-vs-branch dance:
1. Creates a temporary git worktree of the base ref under `cmake-metrics/_worktree/`.
2. Builds the base in `cmake-metrics/<board>/base/`.
3. Builds the current tree in `cmake-metrics/<board>/build/`.
4. Runs `tools/metrics.py compare` and writes `cmake-metrics/<board>/metrics_compare.md`.
5. Removes the worktree on exit.
`--combined` (auto-set by `--ci`) also produces `cmake-metrics/_combined/metrics_compare.md` aggregating across all boards.
## Choosing arguments
Infer from the user's request:
- **Board(s):** named board → `-b BOARD` (repeatable). "All boards" / "CI" / "full sweep" → `--ci` (first board of each arm-gcc family). Default to a fast board (`raspberry_pi_pico`) if unspecified for an iterative check.
- **Example:** named example → `-e <group>/<name>` (e.g. `-e device/cdc_msc`). "All examples" → omit `-e`.
- **Bloaty:** only with `-e`. Use when the user wants a section/symbol-level breakdown for a single binary.
- **Base ref:** default `master`. Override with `--base-branch <ref>` (tag or commit also works).
- **Filter:** default is the absolute path of each side's `<checkout>/src/` directory, which uniquely identifies TinyUSB stack code without matching vendored deps that also have a `src/` (e.g. `pico-sdk/src/`). Override with one or more `-f SUBSTRING` flags to use repo-relative substrings instead. Change only if asked.
## Common invocations
```bash
# Single example, one board (linkermap, fastest):
python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc
# Same with bloaty for section/symbol breakdown:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc --bloaty
# All examples for one board:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico
# Multiple boards, one combined report:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico -b raspberry_pi_pico2 --combined
# Full CI sweep (first board per arm-gcc family, combined):
python3 tools/metrics_compare_base.py --ci
# Compare against a tag/commit instead of master:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico --base-branch v0.18.0
```
## Outputs
- **Per-board:** `cmake-metrics/<board>/metrics_compare.md` (and `_<example>.md` when `-e` is set)
- **Combined (with `--combined`/`--ci`):** `cmake-metrics/_combined/metrics_compare.md`
- **Bloaty:** printed to stdout as section + symbol diffs
## Timing
- Single example, single board: ~30 s
- All examples, single board: ~60-90 s
- `--ci` (all arm-gcc families, first board each): 4-8 minutes — sequential sweep across boards (Ninja parallelizes within each board, not across)
Use timeouts ≥ 10 minutes (600000 ms) for `--ci`.
## Reporting results
After running:
- Show the markdown report's summary table to the user.
- Highlight any rows with non-zero `% diff` — under the default filter every row is a TinyUSB stack source file (e.g. `usbd.c`, `cdc_device.c`, `dcd_<port>.c`), so any non-zero delta is a real stack-size impact.
- If the diff is unexpected, follow up with a single-example `--bloaty` run to localize.
+64
View File
@@ -0,0 +1,64 @@
---
name: hil
description: Use when running TinyUSB Hardware-in-the-Loop (HIL) tests on physical boards, debugging HIL failures, or copying firmware to the ci.lan test rig. Covers per-host config selection (htpc uses local.json, ci uses tinyusb.json), local execution on either htpc or ci, remote execution over SSH from htpc, and debugging tips.
---
# Hardware-in-the-Loop (HIL) Testing
Run TinyUSB HIL tests on real boards. **Run `hostname` first** — it tells you which host you are on, which determines the default config and whether remote mode is possible.
| Host | Local config | Remote (SSH → ci.lan)? |
|------|--------------|------------------------|
| `htpc` (dev PC) | `test/hil/local.json` | yes (large pool, `test/hil/tinyusb.json`) |
| `ci` (the rig) | `test/hil/tinyusb.json` (large pool) | no — can't SSH to htpc, and boards are already local |
Default to **local**. Use **remote** only when on `htpc` and the user says `remote`/`ci.lan`. Never attempt remote on `ci`.
## Prerequisites
Examples must be built for the target board(s) — see AGENTS.md "Build" → "All examples for a board" (produces `examples/cmake-build-<board>/`). `-B examples` points `hil_test.py` at that parent folder.
## Arguments
- **Board:** `-b BOARD_NAME` for one board; omit to run all boards in the config.
- **Pass-through:** `-v`, `-r N`, etc. forwarded unchanged.
If `local.json` is missing on `htpc`, ask the user to supply one (only fall back to `tinyusb.json` if told to).
## Local execution
Set `CONFIG` from `hostname` first (`test/hil/local.json` on htpc, `test/hil/tinyusb.json` on ci):
```bash
CONFIG=test/hil/local.json # on ci use: CONFIG=test/hil/tinyusb.json
# All boards in the config:
python3 test/hil/hil_test.py -B examples "$CONFIG"
# A single board (replace stm32f723disco):
python3 test/hil/hil_test.py -b stm32f723disco -B examples "$CONFIG"
```
Append pass-through flags (`-v`, `-r 1`, …) to either command as needed.
## Remote execution (htpc → ci.lan only)
`test/hil/hil_ci.sh` handles dir setup, scp of test scripts, rsync of firmware (`.elf`/`.bin`/`.hex`), and runs `hil_test.py` on `ci.lan` with `tinyusb.json`:
```bash
# All boards:
bash test/hil/hil_ci.sh
# A single board, with pass-through flags:
bash test/hil/hil_ci.sh -b raspberry_pi_pico2 -t host/cdc_msc_hid -r 1
```
Env overrides: `REMOTE`, `REMOTE_DIR`, `CONFIG`. Fails fast if the build dir/repo layout is missing.
## Timing
Runs take 2-5 min. Use a timeout ≥ 20 min (1200000 ms). NEVER cancel early.
## Reporting
Show the output, summarize pass/fail per board. On failure, retry with `-v`; if that's not enough, add temporary debug prints to `hil_test.py`.
@@ -0,0 +1,71 @@
---
name: make-release
description: Use when cutting a new TinyUSB release — version bump, regenerated files, the per-release changelog, and validation before the maintainer commits and tags.
---
# Cut a TinyUSB Release
**Don't commit or tag during prep** — leave changes unstaged for the maintainer (step 4). Work in a worktree. Agree the version `X.Y.Z` with the maintainer first (their call, not derivable from the diff).
## 1. Bump + regenerate
```bash
# set version = 'X.Y.Z' in tools/make_release.py, then FROM REPO ROOT:
python3 tools/make_release.py
```
Refreshes `tusb_option.h`, `repository.yml`, `library.json`, `sonar-project.properties`, and (via gen_doc/gen_presets) `docs/reference/{boards,dependencies}.rst` + preset JSONs (presets/docs change only if boards/deps changed).
Gotchas: `gen_doc` needs `pandas`+`tabulate` (not in requirements) → `pip install pandas tabulate`; `boards.rst` lands with no trailing newline → let pre-commit fix it (step 3).
## 2. Changelog — `docs/changelog/` (the hard part)
New file `docs/changelog/X.Y.Z.md`, listed **first** in `docs/changelog/index.rst`. Get the PR set by **commit reachability, not merge date** (a date query wrongly pulls in the prior release's changelog PR at the boundary):
```bash
PREV=0.20.0
git merge-base --is-ancestor $PREV HEAD && echo OK # else stop: range invalid
git log --first-parent $PREV..HEAD --pretty=%s > /tmp/fp.txt
{ sed -nE 's/^Merge pull request #([0-9]+).*/\1/p' /tmp/fp.txt # merge-button
sed -nE 's/.*\(#([0-9]+)\)$/\1/p' /tmp/fp.txt ; } | sort -un > /tmp/prs.txt # squash
grep -vE '^Merge pull request #[0-9]+|\(#[0-9]+\)$' /tmp/fp.txt # guard: must be empty (direct pushes)
xargs -P8 -I{} gh pr view {} --json number,title,labels \
--jq '"#\(.number)\t\(.title)\t[\(.labels|map(.name)|join(","))]"' < /tmp/prs.txt # categorize
```
`--first-parent` skips dev-merges; the two `sed`s catch merge-button + squash. A PR merged into a *feature branch* folds into its parent (won't appear alone) — reflect its final state in the parent's bullet.
**Curate** into the prior file's exact Markdown (MyST) style:
- Title = version (`# X.Y.Z`), then italic date (ask if unknown). Add to top of `index.rst`.
- Section order: **General** (New MCUs and Boards / Code Quality and Build / Documentation) → **API Changes** → **Device Stack** (per class) → **Host Stack** → **Controller Driver (DCD & HCD)** (per driver) → **Testing** → **Contributors**. Sections are `##`; each class/driver group is a `###` sub-heading, not a bullet.
- Single backticks for symbols; group related PRs into one bullet (don't dump). `Port *`/driver labels help bucket DCD/HCD.
- **Contributors**: unique non-bot PR authors, alphabetical (the only contributor credit — no separate page):
```bash
xargs -P8 -I{} gh pr view {} --json author --jq '.author.login' < /tmp/prs.txt \
| grep -viE '\[bot\]$|^(copilot|claude|dependabot|github-actions)$' | sort -uf | sed 's/^/@/' | paste -sd, - | sed 's/,/, /g' # drop any CI/service accounts
```
## 3. Validate (leave unstaged)
```bash
pre-commit run --files docs/changelog/X.Y.Z.md docs/changelog/index.rst \
docs/reference/boards.rst docs/reference/dependencies.rst \
library.json repository.yml sonar-project.properties src/tusb_option.h tools/make_release.py
python3 tools/build_doc.py -c # docs build clean (see build-doc skill)
( cd test/unit-test && ceedling test:all )
( cd examples/device/cdc_msc && rm -rf build && mkdir build && cd build && \
cmake -DBOARD=stm32f407disco -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. && cmake --build . )
git diff --stat -- ':!.idea' # .idea/* is IDE noise
```
Confirm the version matches across `tusb_option.h` / `library.json` / `repository.yml` / `sonar-project.properties`.
## 4. Finalize (maintainer)
```bash
git add -A -- ':!.idea' && git commit -m "Bump version to X.Y.Z"
git tag -a X.Y.Z -m "Release X.Y.Z" # tags are unprefixed (0.20.0, not v0.20.0)
git push origin <branch> X.Y.Z
```
Then create the GitHub release from the tag.
## 5. Code size (automatic)
On the release event, CI's `code-metrics` job diffs against the previous tag's `metrics.json` and uploads `metrics.json` + a compare to the release — **only if the previous release has a `metrics.json` asset**. Confirm both appeared.
+36
View File
@@ -0,0 +1,36 @@
---
name: pvs
description: Use when running PVS-Studio static analysis (SAST + MISRA C:2023 / C++:2008) on TinyUSB for a given board. Builds the examples with an exported compile_commands.json, runs pvs-studio-analyzer against .PVS-Studio/.pvsconfig, and emits readable + SARIF output.
---
# PVS-Studio Static Analysis
`run_pvs.sh <BOARD>` builds all examples for the board (with
`compile_commands.json` exported), runs `pvs-studio-analyzer` against
`.PVS-Studio/.pvsconfig`, then writes `pvs-<board>.log` and `pvs-<board>.sarif`
plus printed errorfile findings. Needs a license file or `$PVS_STUDIO_CREDENTIALS`.
```bash
.claude/skills/pvs/run_pvs.sh raspberry_pi_pico # whole project for a board
# Scope to specific files — -S takes a plaintext list (one path per line),
# NOT a source file directly. Extra args pass through to the analyzer.
printf 'src/tusb.c\nsrc/class/cdc/cdc_device.c\n' > /tmp/files.txt
.claude/skills/pvs/run_pvs.sh stm32f407disco -S /tmp/files.txt
```
## Notes
- **Board:** `raspberry_pi_pico` mirrors CI (needs Pico SDK deps);
`stm32f407disco` is fastest (no external SDK). Any board works once its deps
are fetched (`python3 tools/get_deps.py -b <board>`).
- `.pvsconfig` already excludes vendored code and suppresses accepted MISRA
deviations — don't re-add those on the command line. Surviving `src/` findings
are genuinely new.
- Timing is dominated by the build (deps may push it past a minute); the analysis
pass is ~10-30 s. Use a timeout ≥ 10 min when deps must be fetched first.
- `--dump-files` is intentionally omitted — it scatters `.PVS-Studio.i/.cfg`
dumps across the tree (FP-debugging only); add it back via the passthrough args.
After a run, summarize findings by rule/severity from the errorfile output and
point the user at `pvs-<board>.sarif`.
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Run PVS-Studio static analysis on TinyUSB for a given BOARD.
#
# Mirrors the "Static Analysis (PVS-Studio)" section in AGENTS.md / CLAUDE.md:
# - build all examples for BOARD with compile_commands.json exported
# - run pvs-studio-analyzer against that compile DB using .PVS-Studio/.pvsconfig
# - convert the log to human-readable (errorfile) and SARIF output
#
# Usage:
# .claude/skills/pvs/run_pvs.sh <BOARD> [extra pvs-studio-analyzer args...]
#
# Examples:
# .claude/skills/pvs/run_pvs.sh raspberry_pi_pico
# # Scope to specific files via a plaintext list (one path per line):
# printf 'src/tusb.c\nsrc/class/cdc/cdc_device.c\n' > /tmp/files.txt
# .claude/skills/pvs/run_pvs.sh stm32f407disco -S /tmp/files.txt
set -euo pipefail
BOARD="${1:-}"
if [ -z "$BOARD" ]; then
echo "Usage: $0 <BOARD> [extra pvs-studio-analyzer args...]" >&2
echo "Example: $0 raspberry_pi_pico" >&2
exit 2
fi
shift
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
cd "$REPO_ROOT"
BUILD_DIR="examples/cmake-build-${BOARD}"
COMPILE_DB="${BUILD_DIR}/compile_commands.json"
REPORT_LOG="pvs-${BOARD}.log"
SARIF_OUT="pvs-${BOARD}.sarif"
JOBS="$(nproc 2>/dev/null || echo 4)"
# --- License ---------------------------------------------------------------
# Use an existing license file, else materialize one from PVS_STUDIO_CREDENTIALS
# (format: "<name> <key>", as supplied by the CI secret of the same name).
if ! pvs-studio-analyzer lic-info >/dev/null 2>&1; then
if [ -n "${PVS_STUDIO_CREDENTIALS:-}" ]; then
echo ">>> Registering PVS-Studio license from PVS_STUDIO_CREDENTIALS"
# Split "<name> <key>" into exactly two fields, quoted, so a key containing
# glob chars or extra spaces can't be word-split/expanded.
read -r _pvs_name _pvs_key <<< "$PVS_STUDIO_CREDENTIALS"
pvs-studio-analyzer credentials "$_pvs_name" "$_pvs_key"
else
echo "ERROR: no PVS-Studio license found and PVS_STUDIO_CREDENTIALS is unset." >&2
exit 1
fi
fi
# --- Build (exports compile_commands.json) ---------------------------------
echo ">>> Building all examples for ${BOARD} (this also fetches the compile DB)"
cmake examples -B "${BUILD_DIR}" -G Ninja \
-DBOARD="${BOARD}" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build "${BUILD_DIR}"
if [ ! -f "${COMPILE_DB}" ]; then
echo "ERROR: ${COMPILE_DB} was not produced by the build." >&2
exit 1
fi
# --- Analyze ---------------------------------------------------------------
echo ">>> Running PVS-Studio analyzer (-j${JOBS})"
# Note: AGENTS.md shows --dump-files, but that scatters .PVS-Studio.i/.cfg dump
# files across the source tree (only useful for debugging false positives). It is
# omitted here to keep the working tree clean; add it back via "$@" if needed.
pvs-studio-analyzer analyze \
-f "${COMPILE_DB}" \
-R .PVS-Studio/.pvsconfig \
-o "${REPORT_LOG}" -j"${JOBS}" \
--security-related-issues \
--misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser \
"$@"
# --- Report ----------------------------------------------------------------
echo ">>> General-analysis + MISRA findings (errorfile):"
plog-converter -a GA:1,2 -t errorfile "${REPORT_LOG}" || true
plog-converter -t sarif -o "${SARIF_OUT}" "${REPORT_LOG}" >/dev/null
echo ">>> Done."
echo " Raw log : ${REPORT_LOG}"
echo " SARIF : ${SARIF_OUT}"
+80
View File
@@ -0,0 +1,80 @@
---
name: usbmon
description: Use when capturing, analyzing, or debugging USB bus traffic for TinyUSB device development on Linux — enumeration failures, STALLed control transfers, missing/short bulk or interrupt transfers, isochronous/audio dropouts, or descriptor problems. Captures host-side URBs with usbmon + tshark into a Wireshark pcapng and decodes them. Use whenever you need to see what the host actually exchanged with a device on real hardware, even if the user just says "sniff USB", "capture the enumeration", or "why won't my device enumerate".
---
# usbmon — capture & debug USB traffic
`usbmon` records host-side **URBs** — control / bulk / interrupt / isochronous transfers, descriptors, class requests, STALLs, short packets — i.e. exactly what the host exchanged with a device. Use it to debug a TinyUSB device on real hardware. (It's host/URB-level, not wire-level; for SOF/ACK/electrical use a hardware analyzer.)
**Setup (assumed in place):** `usbmon` loaded and a udev rule `SUBSYSTEM=="usbmon", GROUP="wireshark", MODE="0640"` with your user in the `wireshark` group — so `tshark` captures with no `sudo`.
If you were just added to `wireshark` (e.g. `usermod -aG`), the running shell/agent still has the old group set (group adds only apply to a fresh login). Don't restart — wrap each capture in `sg wireshark -c '…'`, which re-reads `/etc/group` immediately: `sg wireshark -c 'tshark -i usbmon3 -s 128 -a duration:30 -w /tmp/cap.pcapng'`. (Reading a finished `.pcapng` with `tshark -r` needs no special group.) For long/high-throughput captures add `-s 128` (snaplen) to keep only URB headers/status, not payloads.
## Capture
```bash
.claude/skills/usbmon/scripts/usbcap.sh <bus|VID:PID|auto> [seconds] [outfile]
# examples
.claude/skills/usbmon/scripts/usbcap.sh cafe: 10 # auto-find a TinyUSB (VID 0xcafe) device
.claude/skills/usbmon/scripts/usbcap.sh 3 8 /tmp/enum.pcapng # bus 3, 8 s
```
`lsusb` shows `Bus 00N` → interface `usbmonN`; `usbmon0` = all buses. Capture the device's own bus. To catch enumeration, start the capture, then replug the device.
## Analyze
```bash
tshark -r cap.pcapng # one line per URB
tshark -r cap.pcapng -V | less # full dissection (descriptors decoded)
tshark -r cap.pcapng -Y 'usb.device_address==26' # filter to one device
```
## Filter (`-Y '<expr>'`)
| Goal | Expression |
|---|---|
| One device / endpoint | `usb.device_address==26` / `usb.endpoint_address==0x81` |
| IN (to host) / OUT (from host) | `usb.endpoint_address.direction==1` / `==0` |
| Submit / Complete event | `usb.urb_type=='S'` / `=='C'` (char literal: single quotes) |
| Control / bulk / interrupt / iso | `usb.transfer_type==2` / `3` / `1` / `0` |
| Only transfers carrying data | `usb.data_len>0` |
| GET_DESCRIPTOR / SET_ADDRESS / SET_CONFIGURATION | `usb.setup.bRequest==6` / `5` / `9` |
| SET_INTERFACE / CLEAR_FEATURE (clear-halt) | `usb.setup.bRequest==11` / `1` |
| Descriptor type DEVICE/CONFIG/STRING/HID-report | `usb.bDescriptorType==1` / `2` / `3` / `0x22` |
| Class / vendor requests | `usb.bmRequestType.type!=0` |
| STALLs / errors | `usb.urb_status!=0 && usb.urb_status!=-115` |
Combine with `&&` — e.g. one endpoint's data: `usb.endpoint_address==0x02 && usb.data_len>0`.
**`usb.urb_status` codes** (errno): `0` success · `-115` `-EINPROGRESS` (every Submit) · `-71` `-EPROTO` (transaction error — device answered wrong or didn't service in time, after the HC's retries) · `-32` `-EPIPE` (STALL) · `-110` `-ETIMEDOUT` · `-75` `-EOVERFLOW` (babble). A **control** transfer completing `-71` ≠ a STALL: the device mis-/under-served it (e.g. EP0 starved under load), not a `tud_*_control_xfer_cb` returning false.
**Decoding class requests:** the plain `-e usb.setup.bRequest` field is often blank for class requests (CDC `SET_LINE_CODING` 0x20 / `SET_CONTROL_LINE_STATE` 0x22, `bmRequestType==0x21`) — Wireshark routes them to class fields. Use `-V` on the Submit frame to get the request name + `wValue` (for `SET_CONTROL_LINE_STATE`, `wValue` bit0=DTR, bit1=RTS).
**Hard limit — usbmon is URB-level, not wire-level.** It cannot show data toggle (DATA0/DATA1) or NAKs. A device-side stall and a toggle desync both look identical: Submits on an endpoint with no Completes. To tell them apart, pair usbmon with **on-device GDB** (e.g. `openocd` + `gdb`): read the EP control register (response/toggle bits) and the DCD/USBD/class structs (`data.xfer[ep][dir]`, `_usbd_dev.ep_status`, `_cdcd_itf[].line_state`) at the moment of the hang. Build `MinSizeRel` still ships DWARF, so `p`/struct access works.
## Host-side kernel logs (dynamic debug)
usbmon shows the URBs; the kernel's **dynamic debug** shows the host driver's *reasoning* that usbmon can't — port resets, enumeration retries, address (re)assignment, EP halts, xHCI ring/command errors. Turn it on, reproduce, read `dmesg`:
```bash
# pick the module from `lsusb -t` Driver= : xhci_hcd (USB3 / most modern HCs), ehci_hcd (USB2),
# plus usbcore for enumeration / hub / descriptor logic (controller-independent).
echo 'module usbcore +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
echo 'module xhci_hcd +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
dmesg -w # follow live; replug to catch enumeration
echo 'module xhci_hcd -p' | sudo tee /sys/kernel/debug/dynamic_debug/control # OFF when done — very noisy
```
`+p` enables the print flag at every call-site in that module (`+pfl` also tags func+line); `grep <module> /sys/kernel/debug/dynamic_debug/control` lists active sites. The control file is debugfs (`/sys/kernel/debug`), root-only → use `sudo tee` (a plain `sudo echo >` redirects as your user, not root). Needs `CONFIG_DYNAMIC_DEBUG` (standard on distro kernels). Best for **re-enumerates / enumeration stalls / port-reset storms**, where usbmon shows the resets but not the host's reason.
## Troubleshoot — symptom → what to check
| Symptom | Look for |
|---|---|
| Not recognized / re-enumerates | Is `GET DESCRIPTOR (DEVICE)` answered, `bMaxPacketSize0` sane? Repeated SET_ADDRESS / resets = device too slow to respond. Enable `usbcore`/`xhci_hcd` dynamic debug (above) for the host's reset reason. |
| Enumeration stalls | Find the last good control transfer; the next request (often CONFIG, a string, or the first class request) is what your `tud_descriptor_*` / control callback mishandled. |
| Control STALL | `usb.urb_status!=0` on a control URB = a `tud_*_control_xfer_cb` returned `false` or didn't handle that `bRequest` (decode it with `-V`). |
| Bulk / interrupt missing or short | On the endpoint, do Submits get Completes? an unexpected short (`usb.data_len < wMaxPacketSize`) = FIFO/length bug; no completions = the class never wrote. |
| CDC read (`dd`/cat) hangs, IN endpoint idle | Don't assume a bulk-IN bug. Check EP0: did `SET_CONTROL_LINE_STATE` (`bmRequestType==0x21`) complete `0` or fail `-71`? If it failed, the device never saw DTR → `tud_cdc_connected()` is false → the app stops sourcing TX. A device that streams fine in isolation but stalls right after a bulk **write** phase points here (control transfer starved by concurrent bulk). Confirm device-side with GDB: `_cdcd_itf[0].line_state` bit0 (DTR). |
| ISO / audio dropouts | ISO URB cadence (~1/ms at full-speed) and payload lengths; zero-length frames = device starved the endpoint. |
| Wrong descriptors | `-V` decodes them; check `bLength` / `wTotalLength` against your `tud_descriptor_configuration_cb`. |
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# usbcap.sh - capture a USB bus via usbmon into a Wireshark-readable pcapng.
# Usage: usbcap.sh <bus|VID:PID|auto> [seconds] [outfile]
# <bus> numeric USB bus (lsusb "Bus 00N" -> N); 0 or "auto" = all buses.
# <VID:PID> resolve the bus from a plugged-in device, e.g. cafe: or 1a86:8010.
# Assumes usbmon is loaded and /dev/usbmon* is readable by your wireshark group
# (see SKILL.md), so tshark captures with no sudo.
set -euo pipefail
target="${1:?usage: usbcap.sh <bus|VID:PID|auto> [seconds] [outfile]}"
dur="${2:-10}"
out="${3:-/tmp/usbcap-$$.pcapng}"
[[ "$dur" =~ ^[0-9]+$ ]] || { echo "seconds must be an integer" >&2; exit 2; }
case "$target" in
auto) bus=0 ;;
*:*) line=$(lsusb | grep -iF "ID ${target}" | head -1) || true
bus=$(printf '%s' "$line" | sed -E 's/^Bus 0*([0-9]+).*/\1/')
[ -n "$bus" ] || { echo "no device matching '$target' (plugged in?)" >&2; exit 1; } ;;
*) bus="$target" ;;
esac
[[ "$bus" =~ ^[0-9]+$ ]] || { echo "bad bus '$target'" >&2; exit 2; }
echo "capturing usbmon${bus} for ${dur}s -> $out"
tshark -i "usbmon${bus}" -a "duration:${dur}" -w "$out"
echo "saved $out ($(tshark -r "$out" 2>/dev/null | wc -l | tr -d ' ') packets)"
echo "analyze: tshark -r $out | tshark -r $out -V"
+10
View File
@@ -0,0 +1,10 @@
# See: https://github.com/codespell-project/codespell#using-a-config-file
[codespell]
# In the event of a false positive, add the problematic word, in all lowercase, to 'ignore-words.txt' (one word per line).
# Or copy & paste the whole problematic line to 'exclude-file.txt'
ignore-words = tools/codespell/ignore-words.txt
exclude-file = tools/codespell/exclude-file.txt
check-filenames =
check-hidden =
count =
skip = *.rb,.cproject,.git,./lib,./examples/*/*/_build,./examples/*/*/ses,./examples/*/*/ozone,./hw/mcu,./tests_obsolete
+28
View File
@@ -0,0 +1,28 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
*.c text
*.cpp text
*.h text
*.icf text
*.js text
*.json text
*.ld text
*.md text
*.mk text
*.py text
*.rst text
*.s text
*.txt text
*.xml text
*.yml text
Makefile text
# Shell scripts must stay LF even when core.autocrlf=true (CRLF breaks bash)
*.sh text eol=lf
# Windows-only Visual Studio things
*.sln text eol=crlf
*.csproj text eol=crlf
+1
View File
@@ -0,0 +1 @@
github: hathach
@@ -0,0 +1,93 @@
name: Bug Report
description: Report a problem with TinyUSB
labels: 'Bug 🐞'
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
It's okay to leave some blank if it doesn't apply to your problem.
- type: dropdown
attributes:
label: Operating System
options:
- Linux
- MacOS
- RaspberryPi OS
- Windows 7
- Windows 10
- Windows 11
- Others
validations:
required: true
- type: input
attributes:
label: Commit SHA
placeholder: e.g 3a042b37da28d0ba1e5593eb1068ca5645d77b56 or version bundled by esp-idf or pico-sdk
validations:
required: true
- type: input
attributes:
label: Board
placeholder: e.g Adafruit Feather nRF52840 Express
validations:
required: true
- type: textarea
attributes:
label: Firmware
placeholder: |
e.g examples/device/cdc_msc. If it is custom firmware, it is preferably compiled like one in example folder and reviewable for people to comment on. The easiest way is
- Fork this repo, checkout a new branch
- Add your-own-example based on stock one
- Push and post it here.
validations:
required: true
- type: textarea
attributes:
label: What happened ?
placeholder: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: How to reproduce ?
placeholder: |
Exact steps in chronological order, details should be specific e.g if you use a command/script to test with, please post it as well.
1. Go to '...'
2. Click on '....'
3. See error
validations:
required: true
- type: textarea
attributes:
label: Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)
placeholder: |
Attach your debug log txt file here, where the issue occurred, best with comments to explain the actual events.
Note1: Please DO NOT paste your lengthy log contents here since it hurts the readability.
Note2: To enable logging, add `LOG=2` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=2` in your tusb_config.h.
More information can be found at [example's readme](https://github.com/hathach/tinyusb/blob/master/docs/getting_started.md)
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
validations:
required: false
- type: checkboxes
attributes:
label: I have checked existing issues, discussion and documentation
description: You agree to check all the resources above before opening a new issue.
options:
- label: I confirm I have checked existing issues, discussion and documentation.
required: true
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: TinyUSB Discussion
url: https://github.com/hathach/tinyusb/discussions
about: If you have other questions or need help, post it here.
- name: TinyUSB Docs
url: https://docs.tinyusb.org/
about: Online documentation
@@ -0,0 +1,49 @@
name: Feature Request
description: Suggest an idea for this project
labels: 'Feature 💡'
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this request!
It's okay to leave some blank if it doesn't apply to your request.
- type: input
attributes:
label: Related area
description: Please briefly explain the area of your Feature Request.
placeholder: eg. new port support, device stack, class driver ...
validations:
required: true
- type: input
attributes:
label: Hardware specification
description: Please provide if your proposal depends on specific Hardware.
placeholder: eg. rp2040, samd51 ...
validations:
required: true
- type: textarea
attributes:
label: Is your feature request related to a problem?
description: Please provide a clear and concise description of what the problem is. Add relevant issue link.
placeholder: ex. I'm facing the issue/missing function...
validations:
required: true
- type: textarea
attributes:
label: Describe the solution you'd like
description: Please provide a clear and concise description of what you want to happen.
placeholder: ex. When using this function...
validations:
required: true
- type: checkboxes
attributes:
label: I have checked existing issues, dicussion and documentation
description: You agree to check all the resources above before opening a new issue.
options:
- label: I confirm I have checked existing issues, dicussion and documentation.
required: true
+39
View File
@@ -0,0 +1,39 @@
name: Get dependencies
inputs:
arg:
description: 'Arguments to get_deps.py'
required: true
runs:
using: "composite"
steps:
- name: Checkout pico-sdk for rp2040
if: >-
contains(inputs.arg, 'rp2040') ||
contains(inputs.arg, 'rp2350') ||
contains(inputs.arg, 'raspberry_pi_pico') ||
contains(inputs.arg, 'adafruit_fruit_jam')
uses: actions/checkout@v6
with:
repository: raspberrypi/pico-sdk
ref: master
path: pico-sdk
- name: Linux dependencies
if: runner.os == 'Linux'
run: |
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
- name: Get Dependencies
env:
ARG: ${{ inputs.arg }}
run: |
python3 tools/get_deps.py ${ARG}
echo "PICO_SDK_PATH=${{ github.workspace }}/pico-sdk" >> $GITHUB_ENV
shell: bash
@@ -0,0 +1,53 @@
name: Setup Toolchain
inputs:
toolchain:
description: 'Toolchain name'
required: true
outputs:
build_option:
description: 'Build option for the toolchain e.g --toolchain clang'
value: ${{ steps.set-toolchain-option.outputs.build_option }}
runs:
using: "composite"
steps:
- name: Pull ESP-IDF docker
if: inputs.toolchain == 'esp-idf'
uses: ./.github/actions/setup_toolchain/espressif
with:
toolchain: ${{ inputs.toolchain }}
- name: Get Toolchain URL
if: inputs.toolchain != 'esp-idf'
id: set-toolchain-url
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
TOOLCHAIN_URL=$(jq -r --arg tc "$TOOLCHAIN" '.[$tc]' .github/actions/setup_toolchain/toolchain.json)
echo "toolchain_url=$TOOLCHAIN_URL"
echo "toolchain_url=$TOOLCHAIN_URL" >> $GITHUB_OUTPUT
shell: bash
- name: Download Toolchain
if: inputs.toolchain != 'esp-idf'
uses: ./.github/actions/setup_toolchain/download
with:
toolchain: ${{ inputs.toolchain }}
toolchain_url: ${{ steps.set-toolchain-url.outputs.toolchain_url }}
- name: Set toolchain option
id: set-toolchain-option
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
BUILD_OPTION=""
if [[ "$TOOLCHAIN" == *"clang"* ]]; then
BUILD_OPTION="--toolchain clang"
elif [[ "$TOOLCHAIN" == "arm-iar" ]]; then
BUILD_OPTION="--toolchain iar"
fi
echo "build_option=$BUILD_OPTION"
echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT
shell: bash
@@ -0,0 +1,78 @@
name: Download Toolchain
inputs:
toolchain:
description: 'Toolchain name'
required: true
toolchain_url:
description: 'Toolchain URL'
required: true
runs:
using: "composite"
steps:
- name: Cache Toolchain
if: ${{ !startsWith(inputs.toolchain_url, 'https://github.com') }}
uses: actions/cache@v5
id: cache-toolchain-download
with:
path: ~/cache/${{ inputs.toolchain }}
key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }}
- name: Install Toolchain
if: steps.cache-toolchain-download.outputs.cache-hit != 'true'
env:
TOOLCHAIN: ${{ inputs.toolchain }}
TOOLCHAIN_URL: ${{ inputs.toolchain_url }}
run: |
mkdir -p ~/cache/${TOOLCHAIN}
FILE_EXT="${TOOLCHAIN_URL##*.}"
if [[ ${TOOLCHAIN} == rx-gcc ]]; then
wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.run
chmod +x toolchain.run
./toolchain.run -p ~/cache/${TOOLCHAIN}/gnurx -y
elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then
wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb
elif [[ ${TOOLCHAIN} == arm-iar ]]; then
wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb
wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/cxarm.deb
elif [[ ${FILE_EXT} == zip ]]; then
curl -L "$TOOLCHAIN_URL" -o toolchain.zip
unzip -q toolchain.zip -d ~/cache/${TOOLCHAIN}
~/cache/${TOOLCHAIN}/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin/arm-none-eabi-gcc.exe --version
elif [[ ${FILE_EXT} == gz ]]; then
wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.tar.gz
tar -C ~/cache/${TOOLCHAIN} -xaf toolchain.tar.gz
else
echo "Unsupported toolchain file extension: ${FILE_EXT}"
exit 1
fi
shell: bash
- name: Setup Toolchain
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
if [[ ${TOOLCHAIN} == arm-iar ]]; then
sudo dpkg -i ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb
sudo apt install -y ~/cache/${TOOLCHAIN}/cxarm.deb
TOOLCHAIN_PATH="/opt/iar/cxarm/arm/bin"
elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then
sudo apt install -y ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb
TOOLCHAIN_PATH="/opt/ft32/bin"
else
# Find the single toolchain bin directory
TOOLCHAIN_BIN_DIRS=(~/cache/${TOOLCHAIN}/*/bin)
if [[ ${#TOOLCHAIN_BIN_DIRS[@]} -ne 1 ]]; then
echo "Error: Expected exactly one toolchain bin directory, found ${#TOOLCHAIN_BIN_DIRS[@]}"
exit 1
fi
TOOLCHAIN_PATH="${TOOLCHAIN_BIN_DIRS[0]}"
fi
# Convert to native path for Windows compatibility
if [[ "$RUNNER_OS" == "Windows" ]]; then
TOOLCHAIN_PATH=$(cygpath -w "$TOOLCHAIN_PATH")
fi
echo "$TOOLCHAIN_PATH" >> $GITHUB_PATH
shell: bash
@@ -0,0 +1,54 @@
name: Setup ESP-IDF Toolchain
inputs:
toolchain:
description: 'Toolchain name'
required: true
toolchain_version:
description: 'Toolchain version'
required: false
default: 'v5.5.3'
runs:
using: "composite"
steps:
- name: Set DOCKER_ESP_IDF
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
DOCKER_ESP_IDF=$HOME/cache/${TOOLCHAIN}/docker_image.tar
echo "DOCKER_ESP_IDF=$DOCKER_ESP_IDF" >> $GITHUB_ENV
shell: bash
- name: Cache Docker Image
uses: actions/cache@v5
id: cache-toolchain-espressif
with:
path: ${{ env.DOCKER_ESP_IDF }}
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_version }}
- name: Pull and Save Docker Image
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
env:
TOOLCHAIN_VERSION: ${{ inputs.toolchain_version }}
run: |
docker pull espressif/idf:${TOOLCHAIN_VERSION}
mkdir -p $(dirname $DOCKER_ESP_IDF)
docker save -o $DOCKER_ESP_IDF espressif/idf:${TOOLCHAIN_VERSION}
du -sh $DOCKER_ESP_IDF
shell: bash
- name: Load Docker Image
if: steps.cache-toolchain-espressif.outputs.cache-hit == 'true'
run: |
du -sh $DOCKER_ESP_IDF
docker load --input $DOCKER_ESP_IDF
shell: bash
- name: Tag Local Image
env:
TOOLCHAIN_VERSION: ${{ inputs.toolchain_version }}
run: |
docker tag espressif/idf:${TOOLCHAIN_VERSION} espressif/idf:tinyusb
docker images
shell: bash
@@ -0,0 +1,12 @@
{
"aarch64-gcc": "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",
"arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-19.1.1/LLVM-ET-Arm-19.1.1-Linux-x86_64.tar.xz",
"arm-gcc": "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",
"ft9xx-gcc": "https://github.com/Bridgetek/ft32-toolchain-linux/releases/download/v2.7.6/ft9xxtoolchain_2.7.6_amd64.deb",
"arm-gcc-macos-latest": "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-darwin-arm64.tar.gz",
"arm-gcc-windows-latest": "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-win32-x64.zip",
"msp430-gcc": "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",
"riscv-gcc": "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",
"rx-gcc": "https://github.com/hathach/rx_device/releases/download/0.0.1/gcc-8.3.0.202411-GNURX-ELF.run",
"arm-iar": "https://netstorage.iar.com/FileStore/STANDARD/001/003/723/cxarm-9.70.1.deb"
}
+77
View File
@@ -0,0 +1,77 @@
# Path-based auto-labeling for USB IP / port drivers.
# Maps changed dcd/hcd files under src/portable/ to their "Port <ip>" label.
# Consumed by actions/labeler (see .github/workflows/labeler.yml -> label-port job).
"Port DWC2":
- changed-files:
- any-glob-to-any-file: 'src/portable/synopsys/dwc2/**'
"Port EHCI":
- changed-files:
- any-glob-to-any-file: 'src/portable/ehci/**'
"Port OHCI":
- changed-files:
- any-glob-to-any-file: 'src/portable/ohci/**'
"Port FSDev":
- changed-files:
- any-glob-to-any-file: 'src/portable/st/stm32_fsdev/**'
"Port ChipIdea":
- changed-files:
- any-glob-to-any-file: 'src/portable/chipidea/**'
"Port NXP IP3511":
- changed-files:
- any-glob-to-any-file: 'src/portable/nxp/lpc_ip3511/**'
"Port NXP IP3516":
- changed-files:
- any-glob-to-any-file: 'src/portable/nxp/lpc_ip3516/**'
"Port MUSB":
- changed-files:
- any-glob-to-any-file:
- 'src/portable/mentor/musb/**'
- 'src/portable/sunxi/**'
"Port RUSB2":
- changed-files:
- any-glob-to-any-file: 'src/portable/renesas/rusb2/**'
"Port WCH USBFS":
- changed-files:
- any-glob-to-any-file: 'src/portable/wch/*usbfs*'
"Port WCH USBHS":
- changed-files:
- any-glob-to-any-file: 'src/portable/wch/*usbhs*'
"Port MAX3421":
- changed-files:
- any-glob-to-any-file: 'src/portable/analog/max3421/**'
"Port SAMD":
- changed-files:
- any-glob-to-any-file: 'src/portable/microchip/samd/**'
"Port SAMG":
- changed-files:
- any-glob-to-any-file: 'src/portable/microchip/samg/**'
"Port nRF":
- changed-files:
- any-glob-to-any-file: 'src/portable/nordic/nrf5x/**'
"Port Nuvoton":
- changed-files:
- any-glob-to-any-file: 'src/portable/nuvoton/**'
"Port RP2":
- changed-files:
- any-glob-to-any-file: 'src/portable/raspberrypi/**'
"Port MSP430":
- changed-files:
- any-glob-to-any-file: 'src/portable/ti/msp430x5xx/**'
+38
View File
@@ -0,0 +1,38 @@
{#- Top 10 targets with biggest memory changes + project dashboard link -#}
{% set section_columns = ['.text', '.rodata', '.data', '.bss'] -%}
{#- --- Compute per-target total absolute delta and collect changed targets --- -#}
{% set changed = [] -%}
{% for target in targets -%}
{% if target.has_changes -%}
{% set ns = namespace(total_delta=0, total_current=0) -%}
{% for region in target.regions -%}
{% set ns.total_delta = ns.total_delta + region.delta -%}
{% set ns.total_current = ns.total_current + region.used_size -%}
{% endfor -%}
{% set total_old = ns.total_current - ns.total_delta -%}
{% set pct = (ns.total_delta / total_old * 100) if total_old > 0 else 0 -%}
{% set abs_pct = (ns.total_delta | abs) if total_old == 0 else (pct | abs) -%}
{% set _ = changed.append({'target': target, 'total_current': ns.total_current, 'total_old': total_old, 'total_delta': ns.total_delta, 'pct': pct, 'abs_pct': abs_pct}) -%}
{% endif -%}
{% endfor -%}
{#- --- Sort by absolute percentage change descending and take top 10 --- -#}
{% set sorted_changed = changed | sort(attribute='abs_pct', reverse=true) -%}
{% set top10 = sorted_changed[:10] -%}
{#- --- Render --- -#}
{% if top10 %}
### Top {{ top10 | length }} targets by memory change (%) (out of {{ targets | length }} targets) {% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %}
| target | .text | .rodata | .data | .bss | total | % diff |
|--------|-------|---------|-------|------|-------|--------|
{% for info in top10 -%}
{% set target = info.target -%}
{% set section_map = {} -%}
{% for section in target.sections -%}
{% set _ = section_map.update({section.name: section}) -%}
{% endfor -%}
| {% if target.comparison_url %}[{{ target.name }}]({{ target.comparison_url }}){% else %}{{ target.name }}{% endif %} |
{%- for col in section_columns %} {% if col in section_map %}{{ "{:,}".format(section_map[col].old.size) }} → {{ "{:,}".format(section_map[col].size) }} ({{ section_map[col].delta_str }}){% else %}—{% endif %} |{% endfor %} {{ "{:,}".format(info.total_old) }} → {{ "{:,}".format(info.total_current) }} ({% if info.total_delta >= 0 %}+{{ "{:,}".format(info.total_delta) }}{% else %}{{ "{:,}".format(info.total_delta) }}{% endif %}) | {% if info.total_old > 0 %}{% if info.pct >= 0 %}+{% endif %}{{ "%.1f" | format(info.pct) }}%{% else %}N/A{% endif %} |
{% endfor %}
{% else %}
No memory changes detected across {{ targets | length }} target{{ 's' if targets | length != 1 else '' }}.{% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %}
{% endif -%}
+417
View File
@@ -0,0 +1,417 @@
name: Build
on:
workflow_dispatch:
push:
branches: [master]
pull_request:
release:
types: [ published ]
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
# 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:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
code_changed: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 2 # Needed for push commit comparison
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
code:
- 'src/**'
- 'examples/**'
- 'lib/**'
- 'hw/**'
- 'test/hil/**'
- 'tools/build.py'
- 'tools/get_deps.py'
- '.github/actions/**'
- '.github/workflows/build.yml'
- '.github/workflows/build_util.yml'
- '.github/workflows/ci_set_matrix.py'
set-matrix:
runs-on: ubuntu-latest
outputs:
json: ${{ steps.set-matrix-json.outputs.matrix }}
hil_json: ${{ steps.set-matrix-json.outputs.hil_matrix }}
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Generate matrix json
id: set-matrix-json
run: |
# build matrix
MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)
echo "matrix=$MATRIX_JSON"
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
# HIL matrix (merged from tinyusb + hifiphile configs)
HIL_MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/tinyusb.json test/hil/hfp.json)
echo "hil_matrix=$HIL_MATRIX_JSON"
echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT
# ------------------------------------------------------------------------------
# CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR
# Note:
# For Make and IAR build: will be done on CircleCI only (one random per family as well)
# ------------------------------------------------------------------------------
cmake:
needs: [ check-paths, set-matrix ]
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
matrix:
toolchain:
- 'aarch64-gcc'
#- 'arm-clang'
- 'arm-gcc'
#- 'esp-idf'
- 'ft9xx-gcc'
- 'msp430-gcc'
- 'riscv-gcc'
with:
build-system: 'cmake'
toolchain: ${{ matrix.toolchain }}
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
build-options: '--one-first'
upload-metrics: true
upload-artifacts: false
upload-membrowse: true
code-changed: ${{ needs.check-paths.outputs.code_changed == 'true' }}
secrets: inherit
code-metrics:
needs: [ check-paths, cmake ]
if: needs.check-paths.outputs.code_changed == 'true'
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
with:
fetch-tags: ${{ github.event_name == 'release' }}
- name: Download Artifacts
uses: actions/download-artifact@v5
with:
pattern: metrics-*
path: cmake-build
merge-multiple: true
- name: Aggregate Code Metrics
run: |
python tools/get_deps.py
python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json
- name: Upload Metrics Artifact
if: github.event_name == 'push' || github.event_name == 'release'
uses: actions/upload-artifact@v7
with:
name: metrics-tinyusb
path: metrics.json
- name: Download Base Branch Metrics
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
uses: dawidd6/action-download-artifact@v11
with:
workflow: build.yml
workflow_conclusion: ''
branch: ${{ github.base_ref }}
name: metrics-tinyusb
path: base-metrics
continue-on-error: true
- name: Download Previous Release Asset
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
run: |
PREV_TAG=$(git tag --sort=-creatordate | head -n 2 | tail -n 1)
echo "Previous Release: $PREV_TAG"
echo "PREV_TAG=$PREV_TAG" >> $GITHUB_ENV
mkdir -p base-metrics
gh release download $PREV_TAG -p metrics.json -D base-metrics || echo "No metrics.json found in $PREV_TAG release"
- name: Compare with Base Branch
if: github.event_name != 'push'
run: |
if [ -f base-metrics/metrics.json ]; then
python tools/metrics.py compare -m -f tinyusb/src base-metrics/metrics.json metrics.json
cat metrics_compare.md
else
echo "No base metrics found, skipping comparison"
cp metrics.md metrics_compare.md
fi
- name: Upload Release Assets
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
run: |
CURR_TAG=${{ github.event.release.tag_name }}
COMPARE_FILE="metrics_compare_${CURR_TAG}-${PREV_TAG}.md"
mv metrics_compare.md $COMPARE_FILE
gh release upload $CURR_TAG metrics.json $COMPARE_FILE
- name: Upload Metrics Comment Artifact
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v7
with:
name: metrics-comment
path: |
metrics_compare.md
metrics.json
- name: Post Code Metrics as PR Comment
if: (github.event_name == 'workflow_dispatch') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)
uses: marocchino/sticky-pull-request-comment@v2
with:
header: code-metrics
path: metrics_compare.md
# ---------------------------------------
# Keep the metrics baseline available on no-code-change pushes
# The code-metrics job only runs (and uploads metrics-tinyusb) when code changed, so a
# workflow/docs-only push to master would leave the latest run without a baseline for PRs
# to compare against. Carry the previous artifact forward so the baseline is never missing.
# ---------------------------------------
metrics-carry-forward:
needs: [ check-paths ]
if: github.event_name == 'push' && needs.check-paths.outputs.code_changed != 'true'
runs-on: ubuntu-latest
steps:
- name: Download previous metrics baseline from this branch
uses: dawidd6/action-download-artifact@v11
with:
workflow: build.yml
workflow_conclusion: '' # any conclusion, matching the PR-side baseline download
search_artifacts: true # scan back past runs that lack the artifact (e.g. earlier no-code pushes)
branch: ${{ github.ref_name }}
name: metrics-tinyusb
path: .
if_no_artifact_found: warn
continue-on-error: true # best-effort: never make a no-code push red
- name: Re-publish baseline so the latest run keeps it
if: hashFiles('metrics.json') != ''
uses: actions/upload-artifact@v7
with:
name: metrics-tinyusb
path: metrics.json
# ---------------------------------------
# Build Make/CMake on Windows/MacOS
# ---------------------------------------
build-os:
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: ${{ matrix.build-system }}
toolchain: 'arm-gcc-${{ matrix.os }}'
build-args: '["stm32h7rs"]'
build-options: '--one-random'
# ---------------------------------------
# Zephyr
# ---------------------------------------
zephyr:
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
uses: actions/checkout@v6
- name: Setup Zephyr project
uses: zephyrproject-rtos/action-zephyr-setup@v1
with:
app-path: examples
toolchains: arm-zephyr-eabi
- name: Build
run: |
west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr
west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr
# ---------------------------------------
# Hardware in the loop (HIL)
# Run on PR only (hil-tinyusb), hil-hfp-iar only run on non-forked PR
# ---------------------------------------
hil-build:
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
matrix:
toolchain:
- 'arm-gcc'
- 'riscv-gcc'
- 'esp-idf'
with:
build-system: 'cmake'
toolchain: ${{ matrix.toolchain }}
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }}
upload-artifacts: true
# ---------------------------------------
# Hardware in the loop (HIL)
# self-hosted on local VM, for attached hardware checkout HIL_JSON
# ---------------------------------------
hil-tinyusb:
needs: hil-build
name: hil-tinyusb (${{ matrix.display }})
strategy:
fail-fast: false
matrix:
include:
- display: tinyusb.json
runner: [ self-hosted, X64, hathach, hardware-in-the-loop ]
hil_json: test/hil/tinyusb.json
- display: hfp.json
runner: [ self-hosted, Linux, X64, hifiphile ]
hil_json: test/hil/hfp.json
runs-on: ${{ matrix.runner }}
env:
HIL_JSON: ${{ matrix.hil_json }}
steps:
- name: Set HIL report dir (sibling of workspace; persists across run attempts)
run: echo "HIL_REPORT_DIR=$(dirname "$GITHUB_WORKSPACE")/hil-report" >> "$GITHUB_ENV"
- name: Get Skip Boards from previous run
if: github.run_attempt != '1'
run: |
if [ -f "${{ env.HIL_JSON }}.skip" ]; then
SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip")
else
SKIP_BOARDS=""
fi
echo "SKIP_BOARDS=$SKIP_BOARDS"
echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV
- name: Clean workspace
run: |
echo "Cleaning up for the first run"
rm -rf "${{ github.workspace }}"
mkdir -p "${{ github.workspace }}"
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Download Artifacts
uses: actions/download-artifact@v5
with:
pattern: binaries-*
path: cmake-build
merge-multiple: true
- name: Test on actual hardware
run: |
python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS || \
(if [ -f "${{ env.HIL_JSON }}.skip" ]; then
SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip")
echo "Re-running with SKIP_BOARDS=$SKIP_BOARDS"
python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS
else
exit 1
fi)
- name: Upload HIL report
if: always() && github.event_name == 'pull_request'
uses: actions/upload-artifact@v7
with:
name: hil-report-${{ matrix.display }}
path: ${{ env.HIL_REPORT_DIR }}/hil_report.md
if-no-files-found: ignore
overwrite: true
# ---------------------------------------
# Hardware in the loop (HIL)
# self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json
# Since IAR Token secret is not passed to forked PR, only build non-forked PR
# ---------------------------------------
hil-hfp-iar:
needs: [ check-paths ]
if: |
needs.check-paths.outputs.code_changed == 'true' &&
github.repository_owner == 'hathach' &&
!(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true)
runs-on: [ self-hosted, Linux, X64, hifiphile ]
timeout-minutes: 30
env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
PYTHONUNBUFFERED: '1'
steps:
- name: Clean workspace
run: |
echo "Cleaning up previous run"
rm -rf "${{ github.workspace }}"
mkdir -p "${{ github.workspace }}"
- name: Toolchain version
run: |
iccarm --version
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Get build boards
run: |
MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json)
BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")')
echo "BUILD_ARGS=$BUILD_ARGS"
echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV
- name: Get Dependencies
run: python3 tools/get_deps.py $BUILD_ARGS
- name: Build
run: |
# Each variant carries its own --build-name/--cflag, which are global to a
# single build.py invocation — so build one matrix entry at a time rather
# than joining them (joining would leak a variant's flags onto every board).
readarray -t ENTRIES < <(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json | jq -r '.["arm-gcc"][]')
for entry in "${ENTRIES[@]}"; do
echo "+ tools/build.py --toolchain iar $entry"
python3 tools/build.py --toolchain iar $entry
done
- name: Test on actual hardware (hardware in the loop)
run: |
python3 test/hil/hil_test.py hfp.json
- name: Upload HIL report
if: always() && github.event_name == 'pull_request'
uses: actions/upload-artifact@v7
with:
name: hil-report-hfp-iar
path: hil_report.md
if-no-files-found: ignore
overwrite: true
+111
View File
@@ -0,0 +1,111 @@
name: Reusable build util
on:
workflow_call:
inputs:
os:
required: false
type: string
default: 'ubuntu-latest'
build-system:
required: true
type: string
toolchain:
required: true
type: string
build-args:
required: true
type: string
build-options:
required: false
default: ''
type: string
upload-artifacts:
required: false
default: false
type: boolean
upload-metrics:
required: false
default: false
type: boolean
upload-membrowse:
required: false
default: false
type: boolean
code-changed:
required: false
default: true
type: boolean
jobs:
family:
runs-on: ${{ inputs.os }}
strategy:
fail-fast: false
matrix:
arg: ${{ fromJSON(inputs.build-args) }}
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
with:
fetch-depth: ${{ !inputs.upload-membrowse && 1 || 0 }}
- name: Setup Toolchain
id: setup-toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: ${{ inputs.toolchain }}
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
arg: ${{ matrix.arg }}
- name: Build
if: ${{ inputs.code-changed }}
env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
run: |
if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then
docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -e CI="$CI" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }}
else
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
continue-on-error: 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 == true && inputs.code-changed == true
uses: actions/upload-artifact@v7
with:
name: metrics-${{ matrix.arg }}
path: cmake-build/cmake-build-*/metrics.json
- name: Upload Artifacts for Hardware Testing
if: inputs.upload-artifacts == true && inputs.code-changed == true
uses: actions/upload-artifact@v7
with:
name: binaries-${{ matrix.arg }}
path: |
cmake-build/cmake-build-*/*/*/*.elf
cmake-build/cmake-build-*/*/*/*.bin
cmake-build/cmake-build-*/*/*/*.bin
cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin
cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin
cmake-build/cmake-build-*/*/*/config.env
cmake-build/cmake-build-*/*/*/flash_args
cmake-build/hw/mcu/**/*.ld
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env python3
import json
# toolchain, url
toolchain_list = [
"aarch64-gcc",
"arm-clang",
"arm-iar",
"arm-gcc",
"esp-idf",
"ft9xx-gcc",
"msp430-gcc",
"riscv-gcc",
"rx-gcc"
]
# family: [supported toolchain]
family_list = {
"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"],
"ch32f20x": ["arm-gcc"],
"ch32v10x": ["riscv-gcc"],
"ch32v20x": ["riscv-gcc"],
"ch32v30x": ["riscv-gcc"],
"ch583": ["riscv-gcc"],
"da1469x": ["arm-gcc"],
"fomu": ["riscv-gcc"],
"ft9xx": ["ft9xx-gcc"],
"gd32vf103": ["riscv-gcc"],
"hpmicro": ["riscv-gcc"],
"imxrt": ["arm-gcc", "arm-clang"],
"kinetis_k": ["arm-gcc"],
"kinetis_k32l": ["arm-gcc"],
"kinetis_kl": ["arm-gcc"],
"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": ["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": ["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"],
"stm32c5": ["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": ["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": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32l0": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32l4": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32n6": ["arm-gcc"],
"stm32u0": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32u5": ["arm-gcc", "arm-clang", "arm-iar"],
"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"],
}
def set_matrix_json():
matrix = {}
for toolchain in toolchain_list:
filtered_families = [family for family, supported_toolchain in family_list.items() if
toolchain in supported_toolchain]
matrix[toolchain] = filtered_families
print(json.dumps(matrix))
if __name__ == '__main__':
set_matrix_json()
+36
View File
@@ -0,0 +1,36 @@
name: CIFuzz
on:
workflow_dispatch:
pull_request:
branches:
- master
paths:
- '**.c'
- '**.cc'
- '**.cpp'
- '**.cxx'
- '**.h'
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'tinyusb'
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'tinyusb'
language: c++
fuzz-seconds: 400
- name: Upload Crash
uses: actions/upload-artifact@v7
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
@@ -0,0 +1,67 @@
name: Claude Code Review
on:
pull_request:
# opened/reopened/ready_for_review -> first auto review
# synchronize -> auto re-review on new pushes
#
# NOTE: pull_request (not _target) means fork PRs get a read-only GITHUB_TOKEN
# and NO repository secrets (CLAUDE_CODE_OAUTH_TOKEN), so they cannot be
# auto-reviewed. The job condition below skips them cleanly -> use @claude on
# those. Same-repo branches (yours or write-access contributors) auto-review.
types: [opened, synchronize, reopened, ready_for_review]
jobs:
claude-review:
# Skip drafts, and skip fork PRs (no secrets -> would only fail noisily)
if: >
github.event.pull_request.draft == false &&
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write # Claude posts the review comment via the issues API
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Allow claude[bot]'s own pushes to be handled gracefully (skip) instead
# of erroring out the workflow
allowed_bots: 'claude'
# Pairs with the actions: read permission so Claude can read CI results
additional_permissions: |
actions: read
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
# Post/update a single summary comment every run, so a clean review
# ("no issues found") is still visible instead of posting nothing.
use_sticky_comment: true
# --comment makes the code-review command post its findings to the PR.
# Without it the command only prints the review to the Actions log.
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }} --comment'
# TEMPORARY: expose the full Claude transcript in the Actions log for
# debugging. Revert to remove once done.
show_full_output: true
# The headless review was blocked on two tools: compound Bash pipelines
# (sed/python/grep) and Write (it dropped a check_headings.py helper to
# inspect the diff). Default permission mode gates both; Read/Grep/Glob/
# Task already run un-prompted. Allowlist them. Safe here (unlike
# claude.yml's fork-exposed @claude job): same-repo-only + contents:read
# token, so any write is ephemeral and nothing can be pushed.
claude_args: |
--max-turns 50
--model claude-opus-4-8
--effort max
--allowedTools Bash,Write
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
+68
View File
@@ -0,0 +1,68 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
# only "opened" — an issue's author_association gates the summon below;
# "assigned" would gate on the issue author, not the assigner, so a
# maintainer assigning an outsider's issue would be wrongly skipped.
types: [opened]
pull_request_review:
types: [submitted]
jobs:
claude:
# Only trusted actors (repo owner/member/collaborator) may summon @claude, so the
# write-scoped token and OAuth secret are never issued for an outside contributor's
# comment on this public repo. Defense-in-depth on top of the action's own check.
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
runs-on: ubuntu-latest
permissions:
contents: write # allow Claude to push commits/branches when asked
pull-requests: write # allow Claude to comment on / update PRs
issues: write # allow Claude to comment on / update issues
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Sign the bot's commits so they show as "Verified". The action commits
# automatically — on a PR comment it pushes to that PR's branch; on an
# issue comment it opens a new claude/* branch + PR with the fix.
use_commit_signing: true
# No custom prompt: Claude performs the instructions in the @claude comment.
# Deliberately NO Bash in the tool allowlist. @claude can be summoned on a
# fork PR (claude-code-review.yml even directs fork PRs here), and this job
# holds the OAuth secret + a write token. Any build/interpreter command
# (python -c, cmake/make custom targets, etc.) run against attacker-
# controlled PR content is arbitrary code + network execution, so no
# command allowlist can safely contain it. Claude still edits files and
# the action commits/opens the PR; the resulting commit is verified by the
# repo's CircleCI matrix. --max-turns gives room to investigate + fix.
claude_args: '--max-turns 30'
+182
View File
@@ -0,0 +1,182 @@
name: Labeler
on:
issues:
types: [opened]
pull_request_target:
types: [opened, synchronize, reopened]
discussion:
types: [created]
jobs:
label-priority:
# Author-based priority labels: only on issue/PR/discussion creation, not on PR updates.
if: github.event_name != 'pull_request_target' || github.event.action == 'opened'
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
discussions: write
steps:
- name: Label New Issue, PR or Discussion
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let labels = [];
let username = '';
let issueOrPrNumber = 0;
let discussionNodeId = '';
if (context.eventName === 'issues') {
username = context.payload.issue.user.login;
issueOrPrNumber = context.payload.issue.number;
} else if (context.eventName === 'pull_request_target') {
username = context.payload.pull_request.user.login;
issueOrPrNumber = context.payload.pull_request.number;
} else if (context.eventName === 'discussion') {
username = context.payload.discussion.user.login;
discussionNodeId = context.payload.discussion.node_id;
}
// Maintainer is an Adafruit member; skip the Adafruit perks for their own
// issues/PRs and treat them as a plain contributor (Prio only).
const isOwner = username.toLowerCase() === 'hathach';
// Check if an Adafruit member: Adafruit + Sponsor + top priority
if (!isOwner) {
try {
const adafruitResponse = await github.rest.orgs.checkMembershipForUser({
org: 'adafruit',
username: username
});
if (adafruitResponse.status === 204) {
console.log('Adafruit Member');
labels = ['Adafruit 🌸', 'Sponsor 💖', 'Prio Top 🚨'];
}
} catch (error) {
console.log('Not an Adafruit member');
}
}
// Check if a public GitHub Sponsor of the repo owner.
// Word ($32) tier and up get triage priority; DWORD/QWORD ($128+) go to the top.
// Private sponsorships are not visible to GITHUB_TOKEN, so only public sponsors are detected.
if (labels.length === 0) {
try {
const result = await github.graphql(`
query($sponsorable: String!, $sponsor: String!) {
user(login: $sponsorable) {
isSponsoredBy(accountLogin: $sponsor)
sponsorshipsAsMaintainer(includePrivate: false, first: 100) {
nodes {
sponsorEntity {
... on User { login }
... on Organization { login }
}
tier { monthlyPriceInDollars }
}
}
}
}`, { sponsorable: context.repo.owner, sponsor: username });
const owner = result.user;
if (owner && owner.isSponsoredBy) {
let monthly = 0;
const nodes = (owner.sponsorshipsAsMaintainer && owner.sponsorshipsAsMaintainer.nodes) || [];
for (const node of nodes) {
const login = node.sponsorEntity && node.sponsorEntity.login;
if (login && login.toLowerCase() === username.toLowerCase()) {
monthly = (node.tier && node.tier.monthlyPriceInDollars) || 0;
break;
}
}
if (monthly >= 128) {
console.log('Sponsor (DWORD/QWORD tier)');
labels = ['Sponsor 💖', 'Prio Top 🚨'];
} else if (monthly >= 32) {
console.log('Sponsor (Word tier)');
labels = ['Sponsor 💖', 'Prio 📌'];
} else {
console.log('Sponsor (below Word tier or tier not visible)');
labels = ['Sponsor 💖'];
}
} else {
console.log('Not a public sponsor');
}
} catch (error) {
console.log('Sponsor lookup failed: ' + error.message);
}
}
// Check if a contributor: prioritized in triage queue
if (labels.length === 0) {
try {
const collaboratorResponse = await github.rest.repos.checkCollaborator({
owner: context.repo.owner,
repo: context.repo.repo,
username: username
});
if (collaboratorResponse.status === 204) {
console.log('Contributor');
labels = ['Prio 📌'];
}
} catch (error) {
console.log('Not a contributor');
}
}
if (labels.length !== 0) {
if (context.eventName === 'discussion') {
// Discussions are not covered by the REST issues API; resolve the label
// names to node IDs and attach them with the GraphQL labelable mutation.
const labelIds = [];
for (const name of labels) {
const res = await github.graphql(`
query($owner: String!, $repo: String!, $name: String!) {
repository(owner: $owner, name: $repo) {
label(name: $name) { id }
}
}`, { owner: context.repo.owner, repo: context.repo.repo, name: name });
if (res.repository.label) {
labelIds.push(res.repository.label.id);
}
}
if (labelIds.length !== 0) {
await github.graphql(`
mutation($labelableId: ID!, $labelIds: [ID!]!) {
addLabelsToLabelable(input: { labelableId: $labelableId, labelIds: $labelIds }) {
clientMutationId
}
}`, { labelableId: discussionNodeId, labelIds: labelIds });
}
} else {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
labels: labels
});
}
}
# Path-based Port labels: attach "Port <ip>" when a PR touches the matching
# dcd/hcd driver under src/portable/. Mapping lives in .github/labeler.yml.
label-port:
if: github.event_name == 'pull_request_target'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write # allow auto-creating a Port label that doesn't exist yet
steps:
- uses: actions/labeler@v5
with:
configuration-path: .github/labeler.yml
# sync-labels so a Port label is removed once a PR no longer touches
# that driver (job reruns on synchronize). Only labels listed in
# labeler.yml are managed, so author-based Prio/Sponsor labels are untouched.
sync-labels: true
@@ -0,0 +1,33 @@
name: Membrowse Comment
on:
workflow_run:
workflows: ["Build"]
types:
- completed
jobs:
post-comment:
runs-on: ubuntu-latest
# Run the comment job even if some of the builds fail
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion != 'cancelled'
permissions:
contents: read
actions: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Post Membrowse PR comment
if: ${{ env.MEMBROWSE_API_KEY != '' }}
uses: membrowse/membrowse-action/comment-action@v1
with:
api_key: ${{ secrets.MEMBROWSE_API_KEY }}
commit: ${{ github.event.workflow_run.head_sha }}
comment_template: .github/membrowse_pr_message.j2
env:
MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,62 @@
name: Onboard to Membrowse
on:
workflow_dispatch:
inputs:
num_commits:
description: 'Number of commits to process'
required: true
default: '10'
type: string
jobs:
load-targets:
runs-on: ubuntu-22.04
outputs:
targets: ${{ steps.load.outputs.targets }}
toolchains: ${{ steps.load.outputs.toolchains }}
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
echo "toolchains=$(jq -c '.toolchains' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT
onboard:
needs: load-targets
runs-on: ubuntu-22.04
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
- name: Install packages
run: |
${{ fromJson(needs.load-targets.outputs.toolchains)[matrix.toolchain].setup_cmd }} && python3 tools/get_deps.py ${{ matrix.get_deps || matrix.port }}
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ matrix.port }}-${{ matrix.board }}
- name: Run Membrowse Onboard Action
uses: membrowse/membrowse-action/onboard-action@v1
with:
target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }}
num_commits: ${{ github.event.inputs.num_commits }}
build_script: python3 tools/build.py -s cmake -b ${{ matrix.board }}
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 }}
+131
View File
@@ -0,0 +1,131 @@
name: PR Comment
on:
workflow_run:
workflows: ["Build"]
types:
- completed
jobs:
# Resolve the PR number from trusted workflow_run metadata, NOT from build artifacts: a forked PR
# controls its own Build run and could plant any number, which the privileged jobs below would
# then post to. Same-repo PRs populate workflow_run.pull_requests; for forks it is empty, so look
# the PR up by the trusted head SHA.
pr_number:
if: github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
number: ${{ steps.resolve.outputs.number }}
steps:
- name: Resolve PR number
id: resolve
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
PRS_JSON: ${{ toJSON(github.event.workflow_run.pull_requests) }}
run: |
# Every lookup is best-effort: on any miss the number stays empty and the comment jobs
# below simply skip (never a failed check).
# Same-repo PRs: workflow_run.pull_requests is populated.
num=$(printf '%s' "$PRS_JSON" | jq -r '.[0].number // empty')
# Fork PRs: pull_requests is empty. Find the open PR by its trusted head ref and confirm
# its head SHA matches the built commit.
if [ -z "$num" ] && [ -n "$HEAD_BRANCH" ] && [ -n "$HEAD_REPO" ]; then
num=$(gh api --method GET "repos/$REPO/pulls" \
-f state=open -f head="${HEAD_REPO%%/*}:$HEAD_BRANCH" \
--jq '[.[] | select(.head.sha == env.HEAD_SHA)][0].number // empty' 2>/dev/null || true)
fi
echo "number=$num" >> "$GITHUB_OUTPUT"
metrics-comment:
needs: pr_number
if: >
github.event.workflow_run.conclusion == 'success' &&
needs.pr_number.outputs.number != ''
runs-on: ubuntu-latest
permissions:
actions: read
pull-requests: write
steps:
- name: Download Artifacts
uses: actions/download-artifact@v5
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
name: metrics-comment
# Best-effort: docs-only PRs skip code-metrics, so the artifact may be absent.
continue-on-error: true
- name: Post Code Metrics as PR Comment
if: hashFiles('metrics_compare.md') != ''
uses: marocchino/sticky-pull-request-comment@v2
with:
header: code-metrics
path: metrics_compare.md
number: ${{ needs.pr_number.outputs.number }}
# ---------------------------------------
# Combine the rigs' HIL reports into one sticky PR comment (one table per rig).
# Runs here (workflow_run / base-repo context) rather than in build.yml so it also works on
# forked PRs, whose build-side GITHUB_TOKEN is read-only and cannot post comments. Posts even
# on build/HIL failure (when the report matters most); skips only on cancellation.
# ---------------------------------------
hil-comment:
needs: pr_number
if: >
github.event.workflow_run.conclusion != 'cancelled' &&
needs.pr_number.outputs.number != ''
runs-on: ubuntu-latest
permissions:
actions: read
pull-requests: write
steps:
- name: Download HIL reports
uses: actions/download-artifact@v5
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pattern: hil-report-*
path: hil-reports
continue-on-error: true
- name: Combine rig reports (one table per rig)
id: combine
run: |
shopt -s nullglob
dirs=(hil-reports/hil-report-*)
if [ ${#dirs[@]} -eq 0 ]; then
echo "No HIL reports found"
exit 0
fi
{
echo "## Hardware-in-the-loop (HIL) Test Report"
echo
for d in "${dirs[@]}"; do
[ -d "$d" ] || continue
echo "### ${d#hil-reports/hil-report-}"
echo
cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_"
echo
done
} > hil_combined.md
# Fork PRs can influence report content and this job posts in base-repo context, so
# neutralize @-mentions (insert a zero-width space) to prevent notification abuse.
zwsp=$(printf '\342\200\213')
sed -i -E "s/@([A-Za-z0-9_-])/@${zwsp}\1/g" hil_combined.md
cat hil_combined.md
echo "found=true" >> "$GITHUB_OUTPUT"
- name: Post HIL report as sticky PR comment
if: steps.combine.outputs.found == 'true'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: hil-report
path: hil_combined.md
number: ${{ needs.pr_number.outputs.number }}
+45
View File
@@ -0,0 +1,45 @@
name: pre-commit
on:
workflow_dispatch:
push:
pull_request:
branches: [ master ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Get Dependencies
run: |
gem install ceedling
#cd test/unit-test
#ceedling test:all
- name: Run pre-commit
uses: pre-commit/action@v3.0.1
- name: Build Fuzzer
run: |
sudo apt install libc++-dev libc++abi-dev
clang --version
export CC=clang
export CXX=clang++
fuzz_harness=$(ls -d test/fuzz/device/*/)
for h in $fuzz_harness
do
make -C $h get-deps
make -C $h all
done
@@ -0,0 +1,242 @@
name: Static Analysis
on:
workflow_dispatch:
push:
branches: [ master ]
paths:
- 'src/**'
- 'examples/**'
- 'hw/bsp/**'
- '.github/workflows/static_analysis.yml'
pull_request:
branches: [ master ]
paths:
- 'src/**'
- 'examples/**'
- 'hw/bsp/**'
- '.github/workflows/static_analysis.yml'
permissions:
actions: read
contents: read
security-events: write
# pull-requests: write
# checks: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
CodeQL:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
board:
- 'metro_m4_express'
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
arg: -b${{ matrix.board }}
- name: Setup Toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-gcc'
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: 'c-cpp'
queries: security-and-quality
- name: Build
run: |
mkdir -p build
cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: CodeQL
upload: false
id: analyze
- name: Filter SARIF report
uses: advanced-security/filter-sarif@v1
with:
patterns: |
-hw/mcu/**
-lib/**
input: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif
output: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ steps.analyze.outputs.sarif-output }}
category: CodeQL
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: codeql-${{ matrix.board }}
path: ${{ steps.analyze.outputs.sarif-output }}
PVS-Studio:
# Only run on non-forked PR since secrets token is required
if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
board:
- 'raspberry_pi_pico'
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
arg: -b${{ matrix.board }}
- name: Setup Toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-gcc'
- name: Install Tools
run: |
wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list
sudo apt update
sudo apt install pvs-studio
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
pvs-studio-analyzer --version
- name: Analyze
run: |
mkdir -p build
cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build build
pvs-studio-analyzer analyze -f build/compile_commands.json -R .PVS-Studio/.pvsconfig -j4 --security-related-issues --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser -e lib/ -e hw/mcu/ -e */iar/cxarm/ -e pico-sdk/
plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: pvs-studio-${{ matrix.board }}.sarif
category: PVS-Studio
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: pvs-studio-${{ matrix.board }}
path: pvs-studio-${{ matrix.board }}.sarif
SonarQube:
# Only run on non-forked PR since secrets token is required
if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false
runs-on: ubuntu-latest
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory
strategy:
fail-fast: false
matrix:
board:
- 'stm32h743eval'
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
arg: -b${{ matrix.board }}
- name: Setup Toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-gcc'
- name: Install Build Wrapper
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6
- name: Run Build Wrapper
run: |
cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
args: >
--define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json
IAR-CStat:
# Only run on non-forked PR since secrets token is required
#if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false
if: false
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
board:
- 'b_g474e_dpow1'
steps:
- name: Checkout TinyUSB
uses: actions/checkout@v6
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
arg: -b${{ matrix.board }}
- name: Setup Toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-iar'
- name: Install CMake 4.2
run: |
# IAR CSTAT requires CMake >= 4.1
wget -q https://github.com/Kitware/CMake/releases/download/v4.2.0-rc1/cmake-4.2.0-rc1-linux-x86_64.tar.gz
tar -xzf cmake-4.2.0-rc1-linux-x86_64.tar.gz
echo "${{ github.workspace }}/cmake-4.2.0-rc1-linux-x86_64/bin" >> $GITHUB_PATH
- name: Build and run IAR C-STAT Analysis
env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
run: |
# CMake run post build to generate C-STAT SARIF report
cmake --version
mkdir -p build
cmake examples/device/cdc_msc -B build -G Ninja -DBOARD=${{ matrix.board }} -DTOOLCHAIN=iar -DIAR_CSTAT=1 -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build build
# Merge sarif files for codeql upload
npm i -g @microsoft/sarif-multitool
npx @microsoft/sarif-multitool merge --merge-runs --output-file iar-cstat-${{ matrix.board }}.sarif build/cstat_sarif/*.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: iar-cstat-${{ matrix.board }}.sarif
category: IAR-CStat
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: iar-cstat-${{ matrix.board }}
path: iar-cstat-${{ matrix.board }}.sarif
+60
View File
@@ -0,0 +1,60 @@
name: Trigger Repos
on:
workflow_dispatch:
push:
branches: master
release:
types:
- created
jobs:
trigger-mynewt:
if: github.repository == 'hathach/tinyusb'
runs-on: ubuntu-latest
steps:
- name: Trigger mynewt-tinyusb-example
shell: bash
run: |
curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" --data '{"event_type": "rebuild"}' https://api.github.com/repos/hathach/mynewt-tinyusb-example/dispatches
mirror-tinyusb-src:
if: github.repository == 'hathach/tinyusb'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Push to tinyusb_src
run: |
# clone tinyusb_src with PAT
git config --global user.email "thach@tinyusb.org"
git config --global user.name "hathach"
git clone --depth 1 --single-branch --branch main "https://${{ secrets.API_TOKEN_GITHUB }}@github.com/hathach/tinyusb_src.git" tinyusb_src
# Remove all files
rm -rf tinyusb_src/*
# Copy src and other files
cp -r src tinyusb_src/
cp LICENSE tinyusb_src/
cd tinyusb_src
# Commit if there is changes
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit --message "Update from https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA"
git push
fi
- name: Create tinyusb_src Release
if: ${{ github.event_name == 'release' }}
run: |
# Push tag
cd tinyusb_src
git tag ${{ github.event.release.tag_name }}
git push origin ${{ github.event.release.tag_name }}
# Send POST reqwuest to release https://docs.github.com/en/rest/reference/repos#create-a-release
bb="For release note, please checkout https://github.com/hathach/tinyusb/releases/tag/${{ github.event.release.tag_name }}"
curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "$bb", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases
+93
View File
@@ -0,0 +1,93 @@
html
latex
hil_report.md
hil_report.json
*.a
*.d
*.o
*.P
*.axf
*.bin
*.elf
*.env
*.ind
*.log
*.sarif
*.map
*.obj
*.jlink
*.emSession
*.ninja*
*.eww
*.ewp
*.ewt
*.ewd
*.hex
.venv/
cmake_install.cmake
CMakeCache.txt
settings/
.settings/
.vscode/
.gdb_history
/examples/*/*/build*
test_old/
tests_obsolete/
_build/
build/
/examples/*/*/ses
/examples/*/*/ozone
/examples/obsolete
hw/bsp/**/cubemx/*/
.mxproject
# coverity intermediate files
cov-int
# cppcheck build directories
*-build-dir
/_bin/
__pycache__
cmake-build/
cmake-build-*
sdkconfig
.PVS-Studio
.vscode/
CMakeFiles
Debug
RelWithDebInfo
Release
BrowseInfo
.cmake_build
README_processed.rst
docs/examples/
.worktrees
cmake-metrics/
# Directories fetched by tools/get_deps.py - not to be committed
lib/CMSIS_5/
lib/CMSIS_6/
lib/FreeRTOS-Kernel/
lib/fatfs/
lib/lwip/
lib/sct_neopixel/
lib/threadx/
tools/linkermap/
tools/uf2/
hw/mcu/allwinner/
hw/mcu/analog/
hw/mcu/artery/
hw/mcu/broadcom/
hw/mcu/bridgetek/ft9xx/ft90x-sdk/
hw/mcu/gd/
hw/mcu/hpmicro/
hw/mcu/infineon/
hw/mcu/microchip/
hw/mcu/mindmotion/
hw/mcu/nordic/nrfx/
hw/mcu/nuvoton/
hw/mcu/nxp/
hw/mcu/raspberry_pi/
hw/mcu/renesas/
hw/mcu/silabs/
hw/mcu/sony/cxd56/spresense-exported-sdk/
hw/mcu/st/
hw/mcu/ti/
hw/mcu/wch/
+10
View File
@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
# GitHub Copilot persisted chat sessions
/copilot/chatSessions
+193
View File
@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="raspberrypi_zero" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero -DLOG=1" />
<configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=1" />
<configuration PROFILE_NAME="raspberrypi_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=1" />
<configuration PROFILE_NAME="raspberry_pi_pico" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1" />
<configuration PROFILE_NAME="raspberry_pi_pico-pio_host" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUH_RPI_PIO_USB=1&quot;" />
<configuration PROFILE_NAME="raspberry_pi_pico2" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico2 -DLOG=1" />
<configuration PROFILE_NAME="raspberry_pi_pico2-pio_host" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico2 -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUH_RPI_PIO_USB=1&quot;" />
<configuration PROFILE_NAME="feather_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_feather_rp2040 -DLOG=1" />
<configuration PROFILE_NAME="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=1" />
<configuration PROFILE_NAME="metro_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_metro_rp2040 -DLOG=1 -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="adafruit_metro_rp2350" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=adafruit_metro_rp2350 -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUH_RPI_PIO_USB=1&quot;" />
<configuration PROFILE_NAME="adafruit_fruit_jam" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=adafruit_fruit_jam -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUH_RPI_PIO_USB=1&quot;" />
<configuration PROFILE_NAME="adafruit_feather_esp32_v2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32_v2 -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="adafruit_feather_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="adafruit_feather_esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s3 -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="adafruit_metro_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_kaluga_1" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_s3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_s3_devkitc-DMA" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1&quot;">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_p4_function_ev" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_p4_function_ev -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_p4_function_ev-DMA" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_p4_function_ev -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1&quot;">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="espressif_c3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_c3_devkitc -DMAX3421_HOST=1 -DLOG=1">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</configuration>
<configuration PROFILE_NAME="feather_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="metro_m0_express-max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="samd11_xplained" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=samd11_xplained" />
<configuration PROFILE_NAME="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
<configuration PROFILE_NAME="feather_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="metro_m4_express-max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="feather_m4_express-zephyr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=1 -DMAX3421_HOST=1 -DRTOS=zephyr" />
<configuration PROFILE_NAME="itsybitsy_m4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=itsybitsy_m4" />
<configuration PROFILE_NAME="same54_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same54_xplained -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="samg55_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
<configuration PROFILE_NAME="same70_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same70_xplained -DLOG=1" />
<configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
<configuration PROFILE_NAME="nrf52840dk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nrf52840dk -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="nrf52840dk-zephyr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nrf52840dk -DLOG=1 -DTRACE_ETM=1 -DRTOS=zephyr" BUILD_OPTIONS="-v" />
<configuration PROFILE_NAME="nrf5340dk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nrf5340dk -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="nrf54h20dk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nrf54h20dk -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="nrf54lm20dk" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=nrf54lm20dk -DLOG=0 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="metro m7 1011 sd" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011_sd -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="metro_m7_1011" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="rt1010 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1010_evk -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="rt1024 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1024_evk -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="rt1050 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1050_evkb -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="mimxrt1060_evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1060_evk -DLOG=1" />
<configuration PROFILE_NAME="mimxrt1064_evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1064_evk" />
<configuration PROFILE_NAME="rt1170 evkb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1170_evkb -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="stm32f072disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f072disco -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2 -DLOG=1 -DLOGGGER=RTT" />
<configuration PROFILE_NAME="stm32f103ze_iar" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103ze_iar -DLOG=1 -DLOGGGER=RTT" />
<configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f411disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f412disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f412disco -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f723disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f723disco -DLOG=0" />
<configuration PROFILE_NAME="stm32f723disco-DMA" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f723disco -DLOG=1 -DLOGGER=RTT -DCFLAGS_CLI=&quot;-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1&quot;" />
<configuration PROFILE_NAME="stm32f723disco_device1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f723disco -DLOG=0 -DRHPORT_DEVICE=1" />
<configuration PROFILE_NAME="stm32f769disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32g0b1nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g0b1nucleo" />
<configuration PROFILE_NAME="stm32g474nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g474nucleo" />
<configuration PROFILE_NAME="b_g474e_dpow1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=b_g474e_dpow1 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32h563nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32h563nucleo -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="stm32h743eval" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="stm32h743eval-DMA" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1 -DCFLAGS_CLI=&quot;-DCFG_TUD_DWC2_DMA_ENABLE=1&quot;" />
<configuration PROFILE_NAME="stm32h743eval_host1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DRHPORT_HOST=1 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="stm32h743eval IAR" ENABLED="false" CONFIG_NAME="Debug" TOOLCHAIN_NAME="iccarm" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1 -DIAR_CSTAT=1" />
<configuration PROFILE_NAME="stm32h743nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743nucleo -DLOG=1" />
<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" />
<configuration PROFILE_NAME="ra2a1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra2a1_ek -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra4m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra4m1_ek -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra4m3_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra4m3_ek -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra6m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m1_ek -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra6m5_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="ra6m5_ek PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1 -DRHPORT_DEVICE=0" />
<configuration PROFILE_NAME="ra8m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra8m1_ek -DLOG=2 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="ra8m1_ek PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra8m1_ek -DLOG=2 -DLOGGER=RTT -DTRACE_ETM=1 -DRHPORT_DEVICE=0" />
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=1" />
<configuration PROFILE_NAME="lpcxpresso11u37" ENABLED="false" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u37" />
<configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="mcb1800" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcb1800 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="ea4357" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4357 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="lpcxpresso51u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso51u68 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpc5414" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54114 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="frdm_mcxa153" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_mcxa153 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="frdm_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="frdm_k32l2a4s" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k32l2a4s" />
<configuration PROFILE_NAME="frdm_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
<configuration PROFILE_NAME="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=1" />
<configuration PROFILE_NAME="ek_tm4c123gxl" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ek_tm4c123gxl -DLOG=1" />
<configuration PROFILE_NAME="xmc4500_relax" ENABLED="false" GENERATION_OPTIONS="-DBOARD=xmc4500_relax -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="xmc4500_relax_dma" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=xmc4500_relax -DLOG=1 -DLOGGER=RTT -DCFLAGS_CLI=&quot;-DCFG_TUD_DWC2_DMA=1&quot;" />
<configuration PROFILE_NAME="f1c100s" ENABLED="false" GENERATION_OPTIONS="-DBOARD=f1c100s" />
<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" />
<configuration PROFILE_NAME="ch32v203g_r0_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203g_r0_1v0" />
<configuration PROFILE_NAME="nanoch32v305" ENABLED="false" GENERATION_OPTIONS="-DBOARD=nanoch32v305 -DLOG=1" />
<configuration PROFILE_NAME="ch32v307v_r1_1v0" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DLOG=1" />
<configuration PROFILE_NAME="ch32v307v_r1_1v0 USBFS" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DSPEED=full" />
<configuration PROFILE_NAME="da14695_dk_usb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=da14695_dk_usb" />
<configuration PROFILE_NAME="max32650fthr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32650fthr -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="max32666fthr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32666fthr -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="max32690evkit" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32690evkit -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="at_start_f403a" ENABLED="false" GENERATION_OPTIONS="-DBOARD=at_start_f403a -DLOG=1" />
<configuration PROFILE_NAME="at_start_f423" ENABLED="false" GENERATION_OPTIONS="-DBOARD=at_start_f423 -DLOG=1" />
</configurations>
</component>
</project>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="AT32F423VCT7" uniqueID="de4ea1de-6dcf-413e-a21f-aaeaeb0f3dbc">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="AT32F423VCT7" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<stlink-debug-target name="ST-LINK" uniqueID="cf98f5f4-9c5b-4340-ab06-16ddd7f07062">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/opt/st/stm32cubeclt_1.20.0/STLink-gdb-server/bin/ST-LINK_gdbserver" programmer="/opt/st/stm32cubeclt_1.20.0/STM32CubeProgrammer/bin" />
<st-link />
<device interface="SWD" />
<connection port="61234" warmup-ms="500" />
<swo enabled="false" port="61235" />
</stlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="at32f403acgu7" uniqueID="13a1c815-97d7-4b16-8fcc-564bddfe2270">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="AT32F403ACGU7" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+14
View File
@@ -0,0 +1,14 @@
<component name="DebugServers">
<generic-debug-target name="esp32s2" uniqueID="254eff00-2acf-48fe-b255-1d0c0c9c4a7a">
<debugger version="1">
<debugger kind="GDB">$USER_HOME$/.espressif/tools/xtensa-esp-elf-gdb/14.2_20240403/xtensa-esp-elf-gdb/bin/xtensa-esp32s2-elf-gdb</debugger>
<env />
</debugger>
<gdbserver exe="$USER_HOME$/.espressif/tools/openocd-esp32/v0.12.0-esp32-20241016/openocd-esp32/bin/openocd" args="-f board/esp32s2-kaluga-1.cfg">
<env />
</gdbserver>
<console port="4444" />
<target download-type="NONE" reset-command="monitor reset halt" reset-before="false" />
<connection extended-remote="false" remote-string="tcp::3333" warmup-ms="500" />
</generic-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="lpc1769" uniqueID="8f746157-a0c3-435f-b417-10f26c3b2699">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="LPC1769" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="lpc55s69" uniqueID="7de47452-94f1-4f1d-b03c-0f4ad3556d01">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="LPC55S69_M33_0" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="max32690" uniqueID="cb5e7c25-cbda-4c6d-94e9-28a85a81ba66">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MAX32690" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="mcxa153" uniqueID="6a023429-69e6-4f8c-a592-4995cdf255db">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MCXA153" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="nrf52833" uniqueID="19eede9f-2096-4b30-9390-14d415964264">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="nRF52833_xxAA" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="nrf5340" uniqueID="d82e668b-1307-4266-8a5c-3752be6795c9" selected="true">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="nRF5340_xxAA_APP" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="ra6m1" uniqueID="c8cdc79a-939b-4342-92b1-d24da72d12fe">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="R7FA6M1AD" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="ra6m5" uniqueID="19100d9f-7329-47da-b566-f9faf297f47c">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="R7FA6M5BH" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+14
View File
@@ -0,0 +1,14 @@
<component name="DebugServers">
<generic-debug-target name="rp2040" uniqueID="006ce655-8571-401e-a94b-6a4f6d519724">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/local/bin/openocd" args="-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c &quot;adapter speed 5000&quot;">
<env />
</gdbserver>
<console enabled="true" port="4444" />
<target download-type="UPDATED_ONLY" reset-before="false" />
<connection extended-remote="false" remote-string="tcp::3333" warmup-ms="500" />
</generic-debug-target>
</component>
+14
View File
@@ -0,0 +1,14 @@
<component name="DebugServers">
<generic-debug-target name="rp2350" uniqueID="939fdf16-9c30-4261-8435-3e8df7fd5800">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/local/bin/openocd" args="-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c &quot;adapter speed 5000&quot;">
<env />
</gdbserver>
<console enabled="true" port="4444" />
<target download-type="UPDATED_ONLY" reset-before="false" />
<connection extended-remote="false" remote-string="tcp::3333" warmup-ms="500" />
</generic-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="rt1011" uniqueID="e10c53c4-acf5-4a6f-a05d-32b7b042d70a">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MIMXRT1011xxx5A" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="rt1060" uniqueID="851396c6-2030-4694-b86d-21ba9547ddcb">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MIMXRT1062xxx6A" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="rt1064" uniqueID="9602472b-6ce8-4a2d-9636-1c03b5fcd6da">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MIMXRT1064xxx6A" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="rt1170" uniqueID="cfc772e4-782e-49a3-99fb-b6f726e14f9d">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="MIMXRT1176xxxA_M7" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+6
View File
@@ -0,0 +1,6 @@
<component name="DebugServers">
<esp-idf-debug-target name="s3" uniqueID="e096f0d4-5923-482d-bcc3-169a2cfd7cdc">
<console enabled="false" />
<target />
</esp-idf-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="sam21" uniqueID="b22537b6-0924-4a2b-8721-48a8952239de">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="ATSAMD21G18A" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="sam51" uniqueID="481ff0d4-6501-4394-8b6b-f7a2ca4c2675">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="ATSAMD51J19A" reset-before="false" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32f072" uniqueID="f5c65701-0f8d-4923-a7ea-3ee2547147ae">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32F072RB" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32f303" uniqueID="1cdd63e5-1736-42be-bff3-4c48e1f169fa">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32F303VC" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32f411" uniqueID="c48950a7-634c-49b6-b136-204ed0b71718">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32F411VE" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32f769" uniqueID="7a47302f-f7e5-434b-b20b-78e95318dd0c">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32F769NI" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32h563" uniqueID="a3e9293d-113b-48b3-b83d-dd4249984abe">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32H562ZI" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32h743" uniqueID="6d6a3ed6-f66d-4f6a-9e70-6aafe5c971d0">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32H743XI" reset-before="false" frequency="16000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+13
View File
@@ -0,0 +1,13 @@
<component name="DebugServers">
<jlink-debug-target name="stm32l053" uniqueID="51d156d7-86a6-4006-814a-ed14981d7b49">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver exe="/usr/bin/JLinkGDBServerCLExe" />
<console port="19021" />
<target device="STM32L053R8" reset-before="false" frequency="12000" />
<connection extended-remote="false" port="4444" warmup-ms="500" />
<swo />
</jlink-debug-target>
</component>
+14
View File
@@ -0,0 +1,14 @@
<component name="DebugServers">
<generic-debug-target name="wch-riscv" uniqueID="c471e2d0-3cb4-4e7e-aeb7-a33d0c8fdc08">
<debugger version="1">
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver dir="$CMakeProjectDir$" exe="$USER_HOME$/app/riscv-openocd-wch/src/openocd" args="-f hw/bsp/ch32v20x/wch-riscv.cfg">
<env />
</gdbserver>
<console enabled="true" port="4444" />
<target download-type="UPDATED_ONLY" reset-command="monitor reset init; resume 0x08000000" reset-before="false" />
<connection extended-remote="false" remote-string="tcp::3333" warmup-ms="500" />
</generic-debug-target>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="k64f" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;MK64FN1M0xxx12&quot; -if swd -speed 10000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="kl25" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;MKL25Z128xxx4&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lpc1857" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;lpc1857&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="device_info" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="device_info">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lpc4088" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;lpc4088&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lpc54628" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;LPC54628J512&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lpc55s69" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;lpc55s69&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="mcx947" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;MCXN947_M33_0&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun -jlinkscriptfile $ProjectFileDir$/hw/bsp/mcx/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="nrf52840" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nrf" PROGRAM_PARAMS="-select usb=752001685 -device &quot;nrf52840_xxaa&quot; -if swd -speed 8000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="nrf5340" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nrf" PROGRAM_PARAMS="-select usb=752001685 -device &quot;nrf5340_xxaa_app&quot; -if swd -speed 16000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ra2a1" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="renesas" PROGRAM_PARAMS="-device &quot;R7FA2A1AB&quot; -if swd -speed 20000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ra4m1" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="renesas" PROGRAM_PARAMS="-device &quot;R7FA4M1AB&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun -jlinkscriptfile $PROJECT_DIR$/hw/bsp/ra/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ra6m1" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="renesas" PROGRAM_PARAMS="-device &quot;R7FA6M1AD&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun -jlinkscriptfile $PROJECT_DIR$/hw/bsp/ra/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ra6m5" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="renesas" PROGRAM_PARAMS="-device &quot;R7FA6M5BH&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun -jlinkscriptfile $PROJECT_DIR$/hw/bsp/ra/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+10
View File
@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rp2040" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="$PROJECT_DIR$/hw/bsp/rp2040/rp2040-openocd.cfg" reset-type="INIT" download-type="UPDATED_ONLY">
<debugger kind="GDB" isBundled="true" />
</openocd>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rt1010" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;MIMXRT1011xxx5A&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun -jlinkscriptfile $ProjectFileDir$/hw/bsp/imxrt/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rt1060" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="nxp" PROGRAM_PARAMS="-device &quot;MIMXRT1062xxx5A&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="device_info" TARGET_NAME="device_info" version="1" RUN_TARGET_PROJECT_NAME="device_info" RUN_TARGET_NAME="device_info">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="samd21g18" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="microchip" PROGRAM_PARAMS="-device &quot;ATSAMD21G18&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="samd51j19" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="microchip" PROGRAM_PARAMS="-device &quot;ATSAMD51J19A&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+10
View File
@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="stlink" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-p 49578 -cp &quot;$USER_HOME$/st/stm32cubeide_1.16.1/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.linux64_2.1.400.202404281720/tools/bin&quot; --frequency 8000 --swd" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" CONFIG_NAME="raspberry_pi_pico" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::49578" executable="$USER_HOME$/st/stm32cubeide_1.16.1/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.1.400.202404281720/tools/bin/ST-LINK_gdbserver" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD">
<debugger kind="GDB" isBundled="true" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="stm32g474" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="stm32" PROGRAM_PARAMS="-device &quot;stm32g474re&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="stm32h563" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="stm32" PROGRAM_PARAMS="-device &quot;stm32h563zi&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="stm32h743" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="stm32" PROGRAM_PARAMS="-device &quot;stm32h743xi&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc_hid" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc_hid">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="stm32u5a5" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="stm32" PROGRAM_PARAMS="-device &quot;stm32u5a5zj&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+11
View File
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="uno_r4" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" folderName="renesas" PROGRAM_PARAMS="-device &quot;R7FA4M1AB&quot; -if swd -speed 20000 -port 25321 -nogui -singlerun -jlinkscriptfile $PROJECT_DIR$/hw/bsp/ra/debug.jlinkscript" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD" connection-mode="REMOTE" gdbserver-enable="false" console-enabled="false" console-port="0">
<debugger kind="GDB" isBundled="true" />
<extra-debugger-params debugger-working-dir="" debugger-env-pass-parent="true" custom-script="" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/Pico-PIO-USB" vcs="Git" />
</component>
</project>
+57
View File
@@ -0,0 +1,57 @@
# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
#
# SPDX-License-Identifier: Unlicense
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-yaml
- id: trailing-whitespace
exclude: |
(?x)^(
hw/bsp/mcx/sdk/
)
- id: end-of-file-fixer
exclude: |
(?x)^(
.idea/|
hw/bsp/mcx/sdk/
)
- id: forbid-submodules
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
- id: codespell
args: [-w]
exclude: |
(?x)^(
lib/|
hw/bsp/mcx/sdk/
)
- repo: local
hooks:
- id: unit-test
name: unit-test
files: ^(src/|test/unit-test/)
entry: sh -c "cd test/unit-test && ceedling test:all"
pass_filenames: false
types_or: [c, header]
language: system
# - id: build-fuzzer
# name: build-fuzzer
# files: ^(src/|test/fuzz/)
# language: system
# types_or: [c, header]
# entry: |
# bash -c 'export CC=clang
# export CXX=clang++
# fuzz_harness=$(ls -d test/fuzz/device/*/)
# for h in $fuzz_harness
# do
# make -C $h get-deps
# make -C $h all
# done'
+24
View File
@@ -0,0 +1,24 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
submodules:
include: []
recursive: false
+212
View File
@@ -0,0 +1,212 @@
# TinyUSB Agent Instructions
TinyUSB is a cross-platform USB Host/Device stack for embedded systems: memory-safe (no dynamic allocation) and thread-safe (ISR events deferred to task context).
Reference these instructions first; fall back to search/bash only when reality diverges.
## Behavioral Guidelines
Bias toward caution over speed. For trivial tasks, use judgment.
- **Think first** — state assumptions; ask if unclear; present alternatives instead of picking silently.
- **Simplicity** — no features, abstractions, flexibility, or error handling beyond what was asked. If 200 lines could be 50, rewrite.
- **Surgical changes** — touch only what the task requires; match existing style; don't refactor working code; mention unrelated dead code rather than deleting it. Remove only orphans *your* changes created.
- **Goal-driven** — turn tasks into verifiable goals ("write failing test, make it pass"). For multi-step work, state a brief `step → verify` plan.
## Ground Rules
- **Language/style:** C99, 2-space indent (no tabs), snake_case helpers, `UPPER_CASE` macros. Public APIs use `tud_`/`tuh_`; macros use `TU_`. Headers self-contained with `#if CFG_TUSB_MCU` guards.
- **Safety:** no dynamic allocation; defer ISR work to task context; use `TU_ASSERT()` for error checks; always check return values; include order: C stdlib → tusb common → drivers → classes.
- **Layout:** `src/` core, `hw/{mcu,bsp}/` MCU+BSP, `examples/{device,host,dual}/`, `test/{unit-test,fuzz,hil}/`, `docs/`, `tools/`.
- **Commits/PRs:** imperative mood, scoped changes, link issues, include test/build evidence. After opening a PR, monitor it and drive it to green: address automated review comments (Copilot/Codex/Claude) and fix any failing CI builds, pushing follow-up commits until checks pass and review threads are resolved. Useful: `gh pr checks <num> --watch`, `gh pr view <num> --comments`.
- **Formatting/lint:** `clang-format` (`.clang-format`), `codespell` (`.codespellrc`), run `pre-commit run --all-files` before submitting.
## Bootstrap
```bash
sudo apt-get install -y gcc-arm-none-eabi # ARM toolchain (2-5 min, one-time)
python3 tools/get_deps.py [FAMILY|-b BOARD] # fetch deps into lib/, hw/mcu/ (<1 s)
. $HOME/code/esp-idf/export.sh # Espressif only: before any build/flash/monitor
```
## Build
Single example (CMake+Ninja, recommended, 1-3 s):
```bash
cd examples/device/cdc_msc && mkdir -p build && cd build
cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel ..
cmake --build .
```
All examples for a board (15-20 s; some objcopy failures are non-critical). Use `cmake-build-<board>` as the build dir — HIL tests expect that exact name:
```bash
cd examples
cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .
cmake --build cmake-build-raspberry_pi_pico
```
Single example with Make:
```bash
cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all
```
Espressif (only ESP-IDF examples like `cdc_msc_freertos`):
```bash
. $HOME/code/esp-idf/export.sh
cd examples/device/cdc_msc_freertos
idf.py -DBOARD=espressif_s3_devkitc build
```
**Build options** (CMake `-D…` / Make `…=…`):
- Debug: `CMAKE_BUILD_TYPE=Debug` / `DEBUG=1`
- Logging: `LOG=2` (add `LOGGER=rtt` for RTT)
- Root hub port: `RHPORT_DEVICE=1`
- Speed: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED`
## Flash
```bash
# JLink
ninja cdc_msc-jlink # CMake
make BOARD=<board> flash-jlink # Make
# OpenOCD
ninja cdc_msc-openocd # CMake
make BOARD=<board> flash-openocd # Make
# UF2
ninja cdc_msc-uf2 # CMake
make BOARD=<board> all uf2 # Make
ninja -t targets # list CMake targets
# Espressif (after . $HOME/code/esp-idf/export.sh)
idf.py -DBOARD=<board> flash
idf.py -DBOARD=<board> monitor
```
## GDB Debugging
Look up `JLINK_DEVICE` / `OPENOCD_OPTION` in `hw/bsp/*/boards/*/board.cmake` (CMake builds) or `board.mk` (Make builds).
**JLink — Terminal 1:**
```bash
JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -nogui
```
**OpenOCD — Terminal 1:**
```bash
openocd -f interface/stlink.cfg -f target/stm32h7x.cfg
# or with a J-Link interface:
openocd -f interface/jlink.cfg -f target/stm32h7x.cfg
# rp2040/rp2350 via CMSIS-DAP:
openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"
```
**Terminal 2 — connect GDB** (replace `<port>` with `2331` for JLinkGDBServer or `3333` for OpenOCD):
```bash
arm-none-eabi-gdb /tmp/build/firmware.elf
(gdb) target remote :<port>
(gdb) monitor reset halt
(gdb) load
(gdb) break main # optional, to stop at entry
(gdb) continue
```
**RTT logging:** build with `LOG=2 LOGGER=rtt`, flash, then run JLinkGDBServer with `-RTTTelnetPort 19021`, and in another terminal `JLinkRTTClient` (pipe to `tee rtt.log` or use `timeout 20s JLinkRTTClient > rtt.log` for non-interactive capture).
## Testing
**Unit (Ceedling, Unity+CMock, ~4 s):**
```bash
sudo gem install ceedling
cd test/unit-test && ceedling test:all # or ceedling test:test_fifo
```
**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) for the full procedure (local vs remote mode, config selection, SSH copy steps, debugging tips). Requires pre-built examples — see Build → "All examples for a board".
## Documentation
Sphinx docs in `docs/` (reStructuredText `.rst` or Markdown `.md` via MyST). Use the `build-doc` skill (`.claude/skills/build-doc/SKILL.md`) to build/preview locally (`sphinx-build`) and to regenerate auto-generated files (`tools/gen_doc.py` + `tools/gen_presets.py`) after adding a board or dependency.
## Code Size Metrics
Verify size impact before committing. Invoke the `code-size` skill (`.claude/skills/code-size/SKILL.md`) — it wraps `tools/metrics_compare_base.py` to handle the base-vs-branch worktree + build + compare flow.
Quick reference:
```bash
# Single example, one board:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc
# Add --bloaty for section/symbol breakdown.
# All examples, one board:
python3 tools/metrics_compare_base.py -b raspberry_pi_pico
# All arm-gcc CI families combined (pre-merge sweep, 4-8 min):
python3 tools/metrics_compare_base.py --ci
```
Reports land in `cmake-metrics/<board>/metrics_compare.md` (per-board) and `cmake-metrics/_combined/metrics_compare.md` (with `--combined`/`--ci`).
## Static Analysis (PVS-Studio)
Requires `compile_commands.json`, which the examples build exports by default
(`hw/bsp/family_support.cmake` sets `CMAKE_EXPORT_COMPILE_COMMANDS ON`). The
`pvs` skill (`.claude/skills/pvs/SKILL.md`) wraps the build + analyze flow for a
board; the commands below are the underlying steps.
```bash
# Whole project:
pvs-studio-analyzer analyze \
-f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
-R .PVS-Studio/.pvsconfig \
-o pvs-report.log -j12 \
--security-related-issues \
--misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
# Specific files: -S takes a plaintext list (one path per line), not paths directly:
printf 'src/foo.c\nsrc/bar.c\n' > files.txt
pvs-studio-analyzer analyze \
-f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
-R .PVS-Studio/.pvsconfig \
-S files.txt \
-o pvs-report.log -j12 \
--security-related-issues \
--misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
plog-converter -a GA:1,2 -t errorfile pvs-report.log # view results
```
Takes ~10-30 s. (`--dump-files` adds preprocessed `.PVS-Studio.i/.cfg` dumps next
to every source for false-positive debugging — omit it for normal runs.)
## Validation After Changes
1. `pre-commit run --all-files` — format, spell, unit tests (10-15 s).
2. Build at least one board's full example set (Build → "All examples for a board") for modules you touched.
3. Run relevant unit tests; add fuzz/HIL coverage for parsers or protocol state machines.
**Boards good for local testing:**
- `stm32f407disco` — no external SDK
- `raspberry_pi_pico` — Pico SDK required
- Others: see `hw/bsp/FAMILY/boards/`
Device examples need real hardware to validate runtime behavior; must at least build.
## Release
Cutting a release — version bump, regenerated files, the per-release changelog, validation, and the maintainer's commit/tag/GitHub-release — is handled by the `make-release` skill (`.claude/skills/make-release/SKILL.md`).
## References
- MCU reference manuals, datasheets, schematics: `$HOME/Documents/calibre-library`.
- Supported MCUs/boards: `hw/bsp/` and `docs/reference/boards.rst`.
- USB classes: `src/class/{cdc,hid,msc,audio,…}/` — each has `*_device.c` and `*_host.c`.
- Key files: `src/tusb.h`, `src/tusb_config.h`, `tools/get_deps.py`, `tools/build.py`, `test/unit-test/project.yml`.
## Common Build Issues
- Missing compiler → install `gcc-arm-none-eabi`.
- Missing deps → `python3 tools/get_deps.py FAMILY`.
- Unknown board → check `hw/bsp/FAMILY/boards/`.
- `objcopy` errors in full builds are often non-critical; retry the single example.
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+163
View File
@@ -0,0 +1,163 @@
***************
Code of Conduct
***************
Our Pledge
----------
We pledge to make our community welcoming, safe, and equitable for all.
We are committed to fostering an environment that respects and promotes the dignity,
rights, and contributions of all individuals, regardless of characteristics including
race, ethnicity, caste, color, age, physical characteristics, neurodiversity,
disability, sex or gender, gender identity or expression, sexual orientation, language,
philosophy or religion, national or social origin, socio-economic position, level of
education, or other status. The same privileges of participation are extended to
everyone who participates in good faith and in accordance with this Covenant.
Encouraged Behaviors
--------------------
While acknowledging differences in social norms, we all strive to meet our community's
expectations for positive behavior. We also understand that our words and actions may be
interpreted differently than we intend based on culture, background, or native language.
With these considerations in mind, we agree to behave mindfully toward each other and act
in ways that center our shared values, including:
1. Respecting the **purpose of our community**, our activities, and our ways of gathering.
2. Engaging **kindly and honestly** with others.
3. Respecting **different viewpoints** and experiences.
4. **Taking responsibility** for our actions and contributions.
5. Gracefully giving and accepting **constructive feedback**.
6. Committing to **repairing harm** when it occurs.
7. Behaving in other ways that promote and sustain the **well-being of our community**.
Restricted Behaviors
--------------------
We agree to restrict the following behaviors in our community. Instances, threats, and
promotion of these behaviors are violations of this Code of Conduct.
1. **Harassment.** Violating explicitly expressed boundaries or engaging in unnecessary
personal attention after any clear request to stop.
2. **Character attacks.** Making insulting, demeaning, or pejorative comments directed at
a community member or group of people.
3. **Stereotyping or discrimination.** Characterizing anyone's personality or behavior on
the basis of immutable identities or traits.
4. **Sexualization.** Behaving in a way that would generally be considered inappropriately
intimate in the context or purpose of the community.
5. **Violating confidentiality.** Sharing or acting on someone's personal or private
information without their permission.
6. **Endangerment.** Causing, encouraging, or threatening violence or other harm toward
any person or group.
7. Behaving in other ways that **threaten the well-being** of our community.
Other Restrictions
~~~~~~~~~~~~~~~~~~
1. **Misleading identity.** Impersonating someone else for any reason, or pretending to be
someone else to evade enforcement actions.
2. **Failing to credit sources.** Not properly crediting the sources of content you
contribute.
3. **Promotional materials.** Sharing marketing or other commercial content in a way that
is outside the norms of the community.
4. **Irresponsible communication.** Failing to responsibly present content which includes,
links or describes any other restricted behaviors.
Reporting an Issue
------------------
Tensions can occur between community members even when they are trying their best to
collaborate. Not every conflict represents a code of conduct violation, and this Code of
Conduct reinforces encouraged behaviors and norms that can help avoid conflicts and
minimize harm.
When an incident does occur, it is important to report it promptly. To report a possible
violation, contact the project team at thach@tinyusb.org.
Community Moderators take reports of violations seriously and will make every effort to
respond in a timely manner. They will investigate all reports of code of conduct
violations, reviewing messages, logs, and recordings, or interviewing witnesses and other
participants. Community Moderators will keep investigation and enforcement actions as
transparent as possible while prioritizing safety and confidentiality. In order to honor
these values, enforcement actions are carried out in private with the involved parties,
but communicating to the whole community may be part of a mutually agreed upon resolution.
Addressing and Repairing Harm
-----------------------------
If an investigation by the Community Moderators finds that this Code of Conduct has been
violated, the following enforcement ladder may be used to determine how best to repair
harm, based on the incident's impact on the individuals involved and the community as a
whole. Depending on the severity of a violation, lower rungs on the ladder may be skipped.
1. **Warning**
- **Event:** A violation involving a single incident or series of incidents.
- **Consequence:** A private, written warning from the Community Moderators.
- **Repair:** Examples of repair include a private written apology, acknowledgement of
responsibility, and seeking clarification on expectations.
2. **Temporarily Limited Activities**
- **Event:** A repeated incidence of a violation that previously resulted in a warning,
or the first incidence of a more serious violation.
- **Consequence:** A private, written warning with a time-limited cooldown period
designed to underscore the seriousness of the situation and give the community members
involved time to process the incident. The cooldown period may be limited to particular
communication channels or interactions with particular community members.
- **Repair:** Examples of repair may include making an apology, using the cooldown period
to reflect on actions and impact, and being thoughtful about re-entering community
spaces after the period is over.
3. **Temporary Suspension**
- **Event:** A pattern of repeated violation which the Community Moderators have tried to
address with warnings, or a single serious violation.
- **Consequence:** A private written warning with conditions for return from suspension.
In general, temporary suspensions give the person being suspended time to reflect upon
their behavior and possible corrective actions.
- **Repair:** Examples of repair include respecting the spirit of the suspension, meeting
the specified conditions for return, and being thoughtful about how to reintegrate with
the community when the suspension is lifted.
4. **Permanent Ban**
- **Event:** A pattern of repeated code of conduct violations that other steps on the
ladder have failed to resolve, or a violation so serious that the Community Moderators
determine there is no way to keep the community safe with this person as a member.
- **Consequence:** Access to all community spaces, tools, and communication channels is
removed. In general, permanent bans should be rarely used, should have strong reasoning
behind them, and should only be resorted to if working through other remedies has failed
to change the behavior.
- **Repair:** There is no possible repair in cases of this severity.
This enforcement ladder is intended as a guideline. It does not limit the ability of
Community Managers to use their discretion and judgment, in keeping with the best interests
of our community.
Scope
-----
This Code of Conduct applies within all community spaces, and also applies when an
individual is officially representing the community in public or other spaces. Examples of
representing our community include using an official email address, posting via an official
social media account, or acting as an appointed representative at an online or offline event.
Attribution
-----------
This Code of Conduct is adapted from the Contributor Covenant, version 3.0, permanently
available at https://www.contributor-covenant.org/version/3/0/.
Contributor Covenant is stewarded by the Organization for Ethical Source and licensed under
CC BY-SA 4.0. To view a copy of this license, visit
https://creativecommons.org/licenses/by-sa/4.0/.
For answers to common questions about Contributor Covenant, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are provided at
https://www.contributor-covenant.org/translations. Additional enforcement and community
guideline resources can be found at https://www.contributor-covenant.org/resources. The
enforcement ladder was inspired by the work of
`Mozilla's code of conduct team <https://github.com/mozilla/inclusion>`__.
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2012-2026, hathach (tinyusb.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
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 IN
THE SOFTWARE.
Loaded 100 of 2716 files, more files were not shown because too many files have changed in this diff. Show more