diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..ed4f36657 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,29 @@ +# Autogenerated by extra/ci_dependabot_config.sh - DO NOT EDIT" + +version: 2 +updates: + + - package-ecosystem: "gomod" + directory: "/tools/bin2uf2" + schedule: + interval: "weekly" + + - package-ecosystem: "gomod" + directory: "/tools/gen-rodata-ld" + schedule: + interval: "weekly" + + - package-ecosystem: "gomod" + directory: "/tools/sync-zephyr-artifacts" + schedule: + interval: "weekly" + + - package-ecosystem: "gomod" + directory: "/tools/zephyr-check-size" + schedule: + interval: "weekly" + + - package-ecosystem: "gomod" + directory: "/tools/zephyr-sketch-tool" + schedule: + interval: "weekly" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe0f5cd67..c14216629 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,14 +54,18 @@ jobs: run: | echo EXTRA_ZEPHYR_MODULES="$(pwd)/$MODULE_PATH" >> $GITHUB_ENV - - name: Build fade + - name: Apply Zephyr patches run: | - west build -p -b arduino_nano_33_ble//sense $MODULE_PATH/samples/fade + bash $MODULE_PATH/extra/apply_zephyr_patches.sh - - name: Build i2cdemo + - name: Build blinky run: | - west build -p -b ek_ra8d1 $MODULE_PATH/samples/i2cdemo + west build -p -b kit_pse84_ai/pse846gps2dbzc4a/m33 $MODULE_PATH/samples/blinky_arduino - - name: Build adc + - name: Build hello run: | - west build -p -b arduino_nano_33_ble/nrf52840/sense $MODULE_PATH/samples/analog_input + west build -p -b kit_pse84_ai/pse846gps2dbzc4a/m33 $MODULE_PATH/samples/hello_arduino + + - name: Build threads + run: | + west build -p -b kit_pse84_ai/pse846gps2dbzc4a/m33 $MODULE_PATH/samples/threads_arduino diff --git a/.github/workflows/package_core.yml b/.github/workflows/package_core.yml index ef6972935..3da8adce3 100644 --- a/.github/workflows/package_core.yml +++ b/.github/workflows/package_core.yml @@ -40,6 +40,9 @@ jobs: # Tag (if found) or hash identifying this core build, should be used for # user-friendly strings and file names CORE_TAG: ${{ env.CORE_TAG }} + # Target branch referred to by this workflow (HEAD_REF for branch pushes, + # or closest branch that contains the tag), used for ci-builds tracking + CORE_BRANCH: ${{ env.CORE_BRANCH }} # Hash identifying this core build, should be used for exact version match CORE_HASH: ${{ env.CORE_HASH }} # JSON describing all boards to build, collected by get_board_details.sh @@ -80,6 +83,13 @@ jobs: run: | echo "## Building \`$CORE_VER\`" >> "$GITHUB_STEP_SUMMARY" echo "CORE_TAG=$(git describe --tags --exact-match --exclude '*/*' 2>/dev/null || echo $CORE_HASH)" >> "$GITHUB_ENV" + if [[ "${{ github.ref_type }}" == "tag" ]]; then + BRANCH=$(git branch -r --contains HEAD --sort=-committerdate --format='%(refname:short)' | sed 's|origin/||' | grep -v HEAD | head -1) + [[ -n "$BRANCH" ]] || { echo "::error::No branch found containing tag ${{ github.ref_name }}"; exit 1; } + echo "CORE_BRANCH=${BRANCH}" >> "$GITHUB_ENV" + else + echo "CORE_BRANCH=${{ github.head_ref || github.ref_name }}" >> "$GITHUB_ENV" + fi echo "ALL_BOARD_FQBNS=$(jq -c 'map((. + {link_mode: "static"}), (. + {link_mode: "dynamic"}))' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV" echo "ARTIFACTS=$(jq -c '["zephyr"] + (map(.artifact) | unique)' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV" echo "SUB_ARCHES=$(jq -c 'map(.subarch) | unique' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV" @@ -111,7 +121,7 @@ jobs: # for later jobs. build-board: - # NOTE: this name is hardcoded in ci_inspect_logs.py + # NOTE: this name is hardcoded in ci_collect_data.py name: Build for ${{ matrix.board }} runs-on: ubuntu-latest needs: @@ -197,9 +207,11 @@ jobs: # Preprare an archive of the built binaries (and build dir on failure) [ "${{ job.status }}" == "failure" ] && FULL_BUILD_DIR="build/${{ matrix.variant }}/" + sed -e '/^#/d' boards.local.txt > boards.local_${{ matrix.variant }}.txt tar chf - \ firmwares/*${{ matrix.variant }}* \ variants/${{ matrix.variant }}/ \ + boards.local_${{ matrix.variant }}.txt \ ${FULL_BUILD_DIR} \ | zstd > binaries-${ARTIFACT_TAG}.tar.zstd @@ -273,6 +285,7 @@ jobs: for f in binaries-*.tar.zstd ; do tar --use-compress-program=unzstd -xpf $f done + cat $(ls boards.local_*.txt | sort) >> boards.local.txt # Create the core artifact for this set of boards ./extra/package_core.sh ${{ matrix.artifact }} ${CORE_TAG} distrib/${CORE_ARTIFACT} @@ -310,7 +323,7 @@ jobs: # This step never fails, so that expected errors do not block the CI run. test-core: - # NOTE: this name is hardcoded in ci_inspect_logs.py + # NOTE: this name is hardcoded in ci_collect_data.py name: Test ${{ matrix.board }}:${{ matrix.link_mode }} runs-on: ubuntu-latest needs: @@ -347,6 +360,21 @@ jobs: tar xf ${CORE_ARTIFACT} # will create ArduinoCore-zephyr/ echo "REPORT_FILE=$(echo ${FQBN} | tr ':' '-').json" >> $GITHUB_ENV + - name: Install arm-zephyr-eabi 1.0.1 for zephyr_contrib boards + # zephyr_contrib boards (e.g. kit_pse84_ai) use Zephyr 4.4.0 + SDK 1.0.1. + # The Board Manager only ships arm-zephyr-eabi-0.16.8 (for SDK 0.16.8/Zephyr 4.2.0). + # We install 1.0.1 manually into the arduino-cli packages path so that + # {runtime.tools.arm-zephyr-eabi-1.0.1.path} resolves correctly during compilation. + if: ${{ matrix.subarch == 'zephyr_contrib' }} + run: | + TOOL_DIR=~/.arduino15/packages/zephyr/tools/arm-zephyr-eabi/1.0.1 + if [ ! -d "$TOOL_DIR/bin" ]; then + mkdir -p "$TOOL_DIR" + wget -q https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v1.0.1/toolchain_gnu_linux-x86_64_arm-zephyr-eabi.tar.xz -O /tmp/arm-zephyr-eabi.tar.xz + tar -xf /tmp/arm-zephyr-eabi.tar.xz -C "$TOOL_DIR" --strip-components=1 + rm /tmp/arm-zephyr-eabi.tar.xz + fi + - name: Get test sketches run: | # sets ALL_TESTS and ALL_LIBRARIES env vars in GITHUB_ENV @@ -395,7 +423,7 @@ jobs: # Collect all build and test reports, analyze them and produce a summary. - # See ci_inspect_logs.py for details. + # See ci_collect_data.py and ci_generate_report.py for details. verify-core: runs-on: ubuntu-latest @@ -429,8 +457,9 @@ jobs: export WORKFLOW_JOBS=$(gh run view ${{ github.run_id }} --attempt ${{ github.run_attempt }} --json jobs --jq '.jobs') # Archive the input set of reports for later inspection tar jchf build-reports-${{ needs.build-env.outputs.CORE_HASH }}.tar.bz2 zephyr-* arduino-*.json - # Run the log inspection script - extra/ci_inspect_logs.py result summary full_log + # Collect all CI data into a JSON file, then generate the report + extra/ci_collect_data.py build_info.json + extra/ci_generate_report.py build_info.json result summary full_log cat result # Display the summary and full log in the step summary @@ -458,6 +487,14 @@ jobs: # errors due to race conditions with parallel branch runs should not fail the job extra/ci_calc_size_reports.py ${GITHUB_BASE_SHA} sketches-reports/ || true + # upload build metadata artifact, for upload to ci-builds + - name: Archive build metadata information + uses: actions/upload-artifact@v7 + with: + name: build-metadata + path: build_info.json + retention-days: 1 + # upload comment request artifact (will be retrieved by leave_pr_comment.yml) - name: Archive comment information uses: actions/upload-artifact@v7 @@ -589,22 +626,48 @@ jobs: - uses: actions/download-artifact@v8 with: + pattern: ArduinoCore-*.tar.bz2 path: . - pattern: ArduinoCore-* merge-multiple: true + - uses: actions/download-artifact@v8 + with: + name: build-metadata + path: snippets/metadata/ + - name: Prepare package index snippets run: | + mkdir -p snippets/platforms/ jq -cr '.[]' <<< ${ARTIFACTS} | while read -r artifact; do # note: the archive names are always hash-based so they use a # predictable pattern. JSON files can use the tag for user-friendliness. ARTIFACT_FILE=ArduinoCore-${artifact}-${CORE_HASH}.tar.bz2 - PACKAGE_JSON=ArduinoCore-${artifact}-${CORE_TAG}.json + PACKAGE_JSON=snippets/platforms/ArduinoCore-${artifact}-${CORE_TAG}.json ./extra/gen_package_index_json.sh ${artifact} ${ARTIFACT_FILE} ${PACKAGE_JSON} done - name: Archive package index snippets uses: actions/upload-artifact@v7 with: - name: ArduinoCore-zephyr-${{ env.CORE_TAG }}-jsons - path: ArduinoCore-*-${{ env.CORE_TAG }}.json + name: snippets-${{ env.CORE_TAG }} + path: snippets/ + + ci-builds-upload: + name: Upload to ci-builds + if: ${{ github.event_name == 'push' && github.repository == 'arduino/ArduinoCore-zephyr' }} + runs-on: ubuntu-latest + needs: + - build-env + - verify-core + - prepare-json + permissions: + id-token: write # required to obtain the OIDC token + steps: + # Run the composite action in this context to create a proper OIDC token + # for this repo and start the internal workflows. + - uses: arduino/core-ci-builds@main + with: + token: ${{ secrets.CI_BUILDS_TOKEN }} + version: ${{ needs.build-env.outputs.CORE_VER }} + artifact: snippets-${{ needs.build-env.outputs.CORE_TAG }} + base-branch: ${{ needs.build-env.outputs.CORE_BRANCH }} diff --git a/.github/workflows/package_tool.yml b/.github/workflows/package_tool.yml index c2793768c..bacd2afbd 100644 --- a/.github/workflows/package_tool.yml +++ b/.github/workflows/package_tool.yml @@ -40,10 +40,13 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} is_release: ${{ steps.set-matrix.outputs.is_release }} tool_artifact: ${{ steps.set-matrix.outputs.tool_artifact }} + CORE_BRANCH: ${{ steps.set-matrix.outputs.CORE_BRANCH }} + CORE_VER: ${{ steps.set-matrix.outputs.CORE_VER }} steps: - uses: actions/checkout@v6 with: fetch-depth: 0 + fetch-tags: true # for get_core_version persist-credentials: false submodules: 'ignore' @@ -59,6 +62,10 @@ jobs: '{include: [{tool: $tool, version: $version}]}') echo "tool_artifact=$TOOL-$VERSION" >> "$GITHUB_OUTPUT" echo "is_release=${{ github.repository == 'arduino/ArduinoCore-zephyr' }}" >> "$GITHUB_OUTPUT" + + BRANCH=$(git branch -r --contains HEAD --sort=-committerdate --format='%(refname:short)' | sed 's|origin/||' | grep -v HEAD | head -1) + [[ -n "$BRANCH" ]] || { echo "::error::No branch found containing tag ${{ github.ref_name }}"; exit 1; } + echo "CORE_BRANCH=${BRANCH}" >> "$GITHUB_OUTPUT" else # build all tools using commit SHA as version VERSION=$(git rev-parse --short ${{ github.event.pull_request.head.sha || 'HEAD' }}) @@ -66,9 +73,24 @@ jobs: | jq -Rnc --arg version "$VERSION" '{include: [inputs | {tool: ., version: $version}]}') echo "tool_artifact=" >> "$GITHUB_OUTPUT" echo "is_release=false" >> "$GITHUB_OUTPUT" + + echo "CORE_BRANCH=${{ github.head_ref || github.ref_name }}" >> "$GITHUB_OUTPUT" fi echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" + echo "CORE_VER=$(extra/get_core_version.sh)" >> "$GITHUB_OUTPUT" + + - name: Verify dependabot config + if: ${{ github.event_name == 'pull_request' }} + run: | + # Check that the dependabot config is exactly as generated by extra/ci_dependabot_config.sh, to avoid + # accidentally breaking it and leaving the tools unmaintained. + extra/ci_dependabot_config.sh /tmp/expected_dependabot.yml + if ! cmp -s /tmp/expected_dependabot.yml .github/dependabot.yml; then + echo "::error::Dependabot config is not up to date. Please run extra/ci_dependabot_config.sh and commit the changes." + exit 1 + fi + # Build and package the tools in parallel according to the matrix, uploading # the resulting packages and metadata as artifacts for later use. @@ -91,7 +113,12 @@ jobs: cache: false - name: Build and package tool - run: extra/package_tool.sh tools/${{ matrix.tool }} ${{ matrix.version }} + run: | + mkdir -p snippets/tools snippets/metadata + extra/package_tool.sh tools/${{ matrix.tool }} ${{ matrix.version }} + mv distrib/*.json snippets/tools/ + # metadata dir is empty, but is still required to preserve the + # directory structure in the generated artifacts - name: Upload tool artifact uses: actions/upload-artifact@v7 @@ -102,12 +129,11 @@ jobs: distrib/*.zip retention-days: 7 - - name: Upload JSON artifact + - name: Upload JSON snippet uses: actions/upload-artifact@v7 with: - name: ${{ matrix.tool }}-${{ matrix.version }}.json - path: distrib/*.json - archive: false + name: snippet-${{ matrix.tool }}-${{ matrix.version }} + path: snippets/ # Upload the built tool packages to the S3 bucket for public distribution. @@ -156,3 +182,24 @@ jobs: # A failure here means either the build or publish step failed when it was expected to run. [ ${{ needs.build-tool.result }} == "success" ] && \ ( [ ${{ needs.publish-tool.result }} == "success" ] || [ ${{ needs.publish-tool.result }} == "skipped" ] ) + + ci-builds-upload: + name: Upload to ci-builds + if: fromJSON(needs.setup.outputs.is_release) + runs-on: ubuntu-latest + needs: + - setup + - build-tool + - publish-tool + - verify-tool + permissions: + id-token: write # required to obtain the OIDC token + steps: + # Run the composite action in this context to create a proper OIDC token + # for this repo and start the internal workflows. + - uses: arduino/core-ci-builds@main + with: + token: ${{ secrets.CI_BUILDS_TOKEN }} + version: ${{ needs.setup.outputs.CORE_VER }} + artifact: snippet-${{ needs.setup.outputs.tool_artifact }} + base-branch: ${{ needs.setup.outputs.CORE_BRANCH }} diff --git a/.github/workflows/release_pse84.yml b/.github/workflows/release_pse84.yml new file mode 100644 index 000000000..8785290bd --- /dev/null +++ b/.github/workflows/release_pse84.yml @@ -0,0 +1,171 @@ +# Copyright (c) Arduino s.r.l. and/or its affiliated companies +# SPDX-License-Identifier: Apache-2.0 + +# PSE84-specific release workflow: triggered automatically when package_core.yml +# completes successfully on main. Bumps the version, tags the commit, and +# publishes the ArduinoCore-zephyr_contrib package as a GitHub Release. + +name: Release PSE84 + +on: + workflow_run: + workflows: ["Package, test and upload core"] + types: [completed] + branches: [main] + +jobs: + + bump-version-and-tag: + name: Bump version, tag, and create release + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository == 'michal-gora/ArduinoCore-zephyr' && github.triggering_actor != 'github-actions[bot]' }} + permissions: + contents: write + outputs: + release_tag: ${{ steps.release_tag.outputs.release_tag }} + steps: + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Compute next release tag + id: release_tag + env: + RELEASE_BUMP: patch + run: | + git fetch --tags + + EXISTING_TAG=$(git tag --points-at "${{ github.event.workflow_run.head_sha }}" --list '[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n1) + if [ -n "${EXISTING_TAG}" ]; then + echo "Using existing tag on HEAD: ${EXISTING_TAG}" + echo "release_tag=${EXISTING_TAG}" >> "$GITHUB_OUTPUT" + exit 0 + fi + + LAST_TAG=$(git tag --list '[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n1) + if [ -z "${LAST_TAG}" ]; then + LAST_TAG="0.0.0" + fi + + IFS='.' read -r MAJOR MINOR PATCH <<< "${LAST_TAG}" + case "${RELEASE_BUMP}" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + *) + PATCH=$((PATCH + 1)) + ;; + esac + + NEW_TAG="${MAJOR}.${MINOR}.${PATCH}" + echo "release_tag=${NEW_TAG}" >> "$GITHUB_OUTPUT" + + - name: Create release (and tag if missing) + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.release_tag.outputs.release_tag }} + run: | + if gh release view "${TAG}" >/dev/null 2>&1; then + echo "Release ${TAG} already exists" + else + gh release create "${TAG}" \ + --target "${{ github.event.workflow_run.head_sha }}" \ + --title "ArduinoCore-zephyr-pse84 ${TAG}" \ + --notes "Automated release for ${{ github.event.workflow_run.head_sha }}." + fi + + + publish-pse84-release: + name: Publish PSE84 release assets + runs-on: ubuntu-latest + needs: + - bump-version-and-tag + if: ${{ needs.bump-version-and-tag.result == 'success' }} + permissions: + contents: write + actions: read + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + TAG: ${{ needs.bump-version-and-tag.outputs.release_tag }} + steps: + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: false + fetch-tags: true + + - name: Download zephyr_contrib artifact from triggering workflow run + uses: actions/download-artifact@v8 + with: + pattern: ArduinoCore-zephyr_contrib-* + path: release-assets + merge-multiple: true + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Normalize artifact filename for release tag + run: | + if [ -z "${TAG}" ]; then + echo "Release tag is empty" >&2 + exit 1 + fi + + TAR_FILE=$(ls release-assets/ArduinoCore-zephyr_contrib-*.tar.bz2 | head -n1) + if [ -z "${TAR_FILE}" ]; then + echo "Downloaded artifact does not contain expected tarball" >&2 + exit 1 + fi + + OLD_BASENAME=$(basename "${TAR_FILE}") + NEW_BASENAME="ArduinoCore-zephyr_contrib-${TAG}.tar.bz2" + + if [ "${OLD_BASENAME}" != "${NEW_BASENAME}" ]; then + mv "${TAR_FILE}" "release-assets/${NEW_BASENAME}" + echo "Renamed ${OLD_BASENAME} -> ${NEW_BASENAME}" + fi + + echo "TAR_BASENAME=${NEW_BASENAME}" >> "$GITHUB_ENV" + + - name: Generate package index JSON + run: | + ARTIFACT_PATH="release-assets/${TAR_BASENAME}" + SIZE=$(wc -c < "${ARTIFACT_PATH}") + SHA256=$(sha256sum "${ARTIFACT_PATH}" | cut -d' ' -f1) + URL="https://github.com/${GH_REPO}/releases/download/${TAG}/${TAR_BASENAME}" + + python3 - <> $env:GITHUB_ENV + + - name: Compute SHA-256 and size + run: | + $hash = (Get-FileHash -Algorithm SHA256 $env:TAR_NAME).Hash.ToLower() + $size = (Get-Item $env:TAR_NAME).Length + echo "TAR_SHA256=$hash" >> $env:GITHUB_ENV + echo "TAR_SIZE=$size" >> $env:GITHUB_ENV + + - name: Upload to GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.event.inputs.release_tag }} + files: ${{ env.TAR_NAME }} + + - name: Print package index values + run: | + Write-Host "" + Write-Host "=== Paste these into the Windows entry of the package index template ===" + Write-Host "archiveFileName : $env:TAR_NAME" + Write-Host "url : https://github.com/${{ github.repository }}/releases/download/${{ github.event.inputs.release_tag }}/$env:TAR_NAME" + Write-Host "checksum : SHA-256:$env:TAR_SHA256" + Write-Host "size : $env:TAR_SIZE" diff --git a/.github/workflows/upload_json.yml b/.github/workflows/upload_json.yml deleted file mode 100644 index 508d66cde..000000000 --- a/.github/workflows/upload_json.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) Arduino s.r.l. and/or its affiliated companies -# SPDX-License-Identifier: Apache-2.0 - -# CI workflow to upload the zephyr_ci package index to GitHub Pages. - -name: Deploy CI JSON to GitHub Pages - -on: - workflow_run: - workflows: ["Package, test and upload core"] - types: - - completed - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - submit-json-to-gh-pages: - name: Update git JSON on Github Pages - runs-on: ubuntu-latest - if: ${{ github.repository == 'arduino/ArduinoCore-zephyr' - && github.event.workflow_run.event == 'push' - && github.event.workflow_run.head_branch == 'main' - && github.event.workflow_run.conclusion == 'success' }} - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }}/package_zephyr_ci_index.json - steps: - - name: Download artifact - id: download-artifact - uses: dawidd6/action-download-artifact@v20 - with: - workflow: package-core.yml - run_id: ${{ github.event.workflow_run.id }} - name: ArduinoCore-zephyr-.*-jsons - name_is_regexp: true - - - name: Setup private SSH key - uses: webfactory/ssh-agent@v0.10.0 - with: - ssh-private-key: ${{ secrets.PACKAGE_INDEX_DEPLOY_KEY }} - - - name: Create zephyr_ci package index - run: | - git clone ${{ secrets.PACKAGE_INDEX_REPO }} package_index - mkdir -p package_index/zephyr_ci/arduino/platforms pages - cd package_index - cp ../ArduinoCore-*/*.json zephyr_ci/arduino/platforms/ - (cd zephyr_staging && for dir in */tools ; do mkdir -p ../zephyr_ci/$dir && cp $dir/*.json ../zephyr_ci/$dir/ ; done) - python3 -m venv venv - . venv/bin/activate - pip install -r scripts/requirements.txt - scripts/meld.py prod.json prod/ - scripts/meld.py --ref-index prod.json ../pages/package_zephyr_ci_index.json zephyr_ci/ - - - name: Setup Pages - uses: actions/configure-pages@v6 - - name: Upload artifact - uses: actions/upload-pages-artifact@v5 - with: - path: 'pages/' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v5 diff --git a/.gitignore b/.gitignore index 5c3ff0e6e..53a2144bc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,13 @@ /distrib/ /firmwares/* /venv/ +/boards.local.txt + llext-edk/ cflags.txt cxxflags.txt +machine_flags.txt includes.txt syms-dynamic.ld syms-static.ld +tls-syms.S diff --git a/README.md b/README.md index e64cbdfb4..9082befc0 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ > This core is in **BETA**. πŸ§ͺ > Features may change, and bugs may be present. Use for testing only and provide feedback to help us improve. > -> [![Default branch status](https://github.com/arduino/ArduinoCore-zephyr/actions/workflows/package_core.yml/badge.svg?branch=arduino&event=push)](https://github.com/arduino/ArduinoCore-zephyr/actions/workflows/package_core.yml) +> [![Default branch status](https://github.com/arduino/ArduinoCore-zephyr/actions/workflows/package_core.yml/badge.svg?branch=arduino&event=push)](https://github.com/arduino/ArduinoCore-zephyr/actions/workflows/package_core.yml) (TODO correct repo link) # 🚧 Arduino Core for Zephyr This repository is a downstream fork of the [Arduino Core for Zephyr RTOS-based -boards](https://github.com/zephyrproject-rtos/arduino-core-zephyr) that -includes support for Arduino software tools, allowing it to be seamlessly used +boards](https://github.com/arduino/ArduinoCore-zephyr) that +includes support for Infineon PSOC Edge boards, allowing it to be seamlessly used by the [Arduino IDE](https://docs.arduino.cc/software/ide/), -[Arduino CLI](https://docs.arduino.cc/arduino-cli/) and -[Arduino App Lab](https://docs.arduino.cc/software/app-lab/). +[Arduino CLI](https://docs.arduino.cc/arduino-cli/) (untested) and +[Arduino App Lab](https://docs.arduino.cc/software/app-lab/) (untested). ## 🧐 What is Zephyr? @@ -23,24 +23,25 @@ by the [Arduino IDE](https://docs.arduino.cc/software/ide/), Install the core and its toolchains via Board Manager: * Download and install the latest [Arduino IDE](https://www.arduino.cc/en/software) (only versions `2.x.x` are supported). -* Open the *'Settings / Preferences'* window. -* Open the *'Boards Manager'* from the side menu and search for *'Zephyr'*. - * If it doesn’t appear, add the following URL to the *'Additional Boards Manager URLs'* field: `https://downloads.arduino.cc/packages/package_zephyr_index.json` (if you have multiple URLs, separate them with a comma). -* Install the `Arduino Zephyr Boards` platform. +* Navigate to *'File > Preferences'*. Look for the text field called 'Additional boards manager URLs'. +* Copy the link of the released `.json`-file and paste it into the text field (if you have multiple URLs, separate them with a comma). Examples of a link: + * [version 0.1.81](https://github.com/michal-gora/ArduinoCore-zephyr/releases/tag/0.1.81): `https://github.com/michal-gora/ArduinoCore-zephyr/releases/download/0.1.81/package_infineon_pse84_index.json`, + * [latest version](https://github.com/michal-gora/ArduinoCore-zephyr/releases/latest): `https://github.com/michal-gora/ArduinoCore-zephyr/releases/latest/download/package_infineon_pse84_index.json` +* In the *'Boards Manager'* (left side menu), search for *'PSOC Edge'* and install `Infineon PSOC Edge Boards`. This may take a while. Alternatively, to install the core using the command line, run the following command with the Arduino CLI: ```bash -arduino-cli core install arduino:zephyr --additional-urls https://downloads.arduino.cc/packages/package_zephyr_index.json +arduino-cli core install infineon:zephyr_pse84 --additional-urls https://github.com/michal-gora/ArduinoCore-zephyr/releases/latest/download/package_infineon_pse84_index.json ``` +(TODO correct repo link, untested) ## πŸ—οΈ First Use To get started with your board: -* Put the board in bootloader mode by double-clicking the RESET button. -* Run the `Burn Bootloader` option from the IDE/CLI. - * Note that due to limitations in the Arduino IDE, you may need to select any programmer from the `Programmers` menu. -* Once the bootloader is installed, you can load your first sketch by placing the board into bootloader mode again. +* Select the correct platform and port (e.g. `Tools > Board: ... > Infineon PSOC Edge Boards > Infineon KIT-PSE84-AI (PSOC Edge E84)` and `Tools > COM`). +* Run the `Tools > Burn Bootloader` option from the IDE/CLI. +* Once the bootloader is installed, you can load your first sketch. > [!NOTE] > After the initial setup, future sketches will be loaded automatically without needing to reset the board. @@ -103,7 +104,7 @@ The most important components of this project are: * [LLEXT](https://docs.zephyrproject.org/latest/services/llext/index.html) * [Actual core](/cores/arduino) with [variants](/variants) and the usual [platform](/platform.txt) and [boards](/boards) files * [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API) -* [zephyr-sketch-tool](/extra/zephyr-sketch-tool) +* [zephyr-sketch-tool](/tools/zephyr-sketch-tool) ## πŸƒ Shortcut: using the Core in Arduino IDE/CLI without installing Zephyr diff --git a/boards.txt b/boards.txt index e12045a8c..6360b8b76 100644 --- a/boards.txt +++ b/boards.txt @@ -1,759 +1,711 @@ -menu.debug=Debug -menu.link_mode=Link mode -menu.wait_linux_boot=Startup mode ########################################################################################## -giga.name=Arduino Giga R1 -giga.build.core=arduino -giga.build.crossprefix=arm-zephyr-eabi- -giga.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -giga.menu.debug.false=Standard -giga.menu.debug.true=Debug -giga.menu.debug.true.build.zsk_args.debug=-debug - -giga.menu.link_mode.dynamic=Dynamic -giga.menu.link_mode.static=Static -giga.menu.link_mode.static.build.link_mode=static -giga.menu.link_mode.static.upload.extension=bin-zsk.bin - -giga.build.zephyr_target=arduino_giga_r1//m7 -giga.build.zephyr_args=--shield arduino_giga_display_shield -giga.build.zephyr_hals=hal_stm32 hal_infineon -giga.build.variant=arduino_giga_r1_stm32h747xx_m7 -giga.build.artifact=zephyr_main -giga.build.mcu=cortex-m7 -giga.build.fpu=-mfpu=fpv5-d16 -giga.build.architecture=cortex-m7 - -giga.build.float-abi=-mfloat-abi=softfp -giga.build.extra_flags= -giga.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -giga.build.architecture=cortex-m7 -giga.build.board=GIGA -giga.vid.0=0x2341 -giga.pid.0=0x0066 -giga.upload_port.0.vid=0x2341 -giga.upload_port.0.pid=0x0066 - -giga.upload.tool=dfu-util -giga.upload.tool.default=dfu-util -giga.upload.protocol= -giga.upload.transport= -giga.upload.vid=0x2341 -giga.upload.pid=0x0366 -giga.upload.interface=0 -giga.upload.use_1200bps_touch=true -giga.upload.wait_for_upload_port=true -giga.upload.native_usb=true -giga.upload.maximum_size=1966080 -giga.upload.maximum_data_size=523624 - -giga.upload.address=0x080E0000 - -giga.upload.maximum_size=786432 -giga.upload.maximum_data_size=523624 - -giga.bootloader.tool=dfu-util -giga.bootloader.tool.default=dfu-util -giga.bootloader.vid=0x2341 -giga.bootloader.pid=0x0366 -giga.bootloader.interface=0 -giga.bootloader.file=zephyr-{build.variant}.bin -giga.bootloader.address=0x08040000 - -giga.debug.tool=gdb -giga.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -giga.debug.server.openocd.scripts.1={programmer.transport_script} -giga.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg -giga.debug.cortex-debug.custom.request=attach -giga.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +# NOTE: +# +# The following board-specific properties are auto-generated by 'build.sh' +# and saved in 'boards.local.txt'. VALUES IN THIS FILE WILL HAVE NO EFFECT. +# +# - build.architecture +# - build.float-abi +# - build.fpu +# - build.mcu +# - upload.address +# - upload.maximum_data_size +# - upload.maximum_size ########################################################################################## -nano33ble.name=Arduino Nano 33 BLE -nano33ble.build.core=arduino -nano33ble.build.crossprefix=arm-zephyr-eabi- -nano33ble.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -nano33ble.menu.debug.false=Standard -nano33ble.menu.debug.true=Debug -nano33ble.menu.debug.true.build.zsk_args.debug=-debug - -nano33ble.menu.link_mode.dynamic=Dynamic -nano33ble.menu.link_mode.static=Static -nano33ble.menu.link_mode.static.build.link_mode=static -nano33ble.menu.link_mode.static.upload.extension=bin-zsk.bin - -nano33ble.build.zephyr_target=arduino_nano_33_ble//sense -nano33ble.build.zephyr_args= -nano33ble.build.zephyr_hals=hal_nordic -nano33ble.build.artifact=zephyr_main -nano33ble.build.variant=arduino_nano_33_ble_nrf52840_sense -nano33ble.build.mcu=cortex-m4 -nano33ble.build.fpu=-mfpu=fpv4-sp-d16 -nano33ble.build.architecture=cortex-m4 - -nano33ble.build.float-abi=-mfloat-abi=hard -nano33ble.build.extra_flags= -nano33ble.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -nano33ble.build.architecture=cortex-m4 -nano33ble.build.board=NANO33BLE -nano33ble.vid.0=0x2341 -nano33ble.pid.0=0x035a -nano33ble.upload_port.0.vid=0x2341 -nano33ble.upload_port.0.pid=0x005a - -nano33ble.upload.tool=bossac -nano33ble.upload.tool.default=bossac -nano33ble.upload.protocol= -nano33ble.upload.transport= -nano33ble.upload.vid=0x2341 -nano33ble.upload.pid=0x005a -nano33ble.upload.interface=0 -nano33ble.upload.use_1200bps_touch=true -nano33ble.upload.wait_for_upload_port=true -nano33ble.upload.native_usb=true -nano33ble.upload.maximum_size=1966080 -nano33ble.upload.maximum_data_size=523624 -nano33ble.upload.address=0x60000 - -nano33ble.upload.maximum_size=786432 -nano33ble.upload.maximum_data_size=523624 - -nano33ble.bootloader.tool=bossac -nano33ble.bootloader.tool.default=bossac -nano33ble.bootloader.vid=0x2341 -nano33ble.bootloader.pid=0x035b -nano33ble.bootloader.interface=0 -nano33ble.bootloader.file=zephyr-{build.variant}.bin -nano33ble.bootloader.address=0x0000 - -nano33ble.debug.tool=gdb -nano33ble.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -nano33ble.debug.server.openocd.scripts.1={programmer.transport_script} -nano33ble.debug.server.openocd.scripts.2=target/nrf52.cfg -nano33ble.debug.cortex-debug.custom.request=attach - -############################################################################################################## - -ek_ra8d1.name=Renesas RA8D1 EK -ek_ra8d1.build.core=arduino -ek_ra8d1.build.crossprefix=arm-zephyr-eabi- -ek_ra8d1.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -ek_ra8d1.menu.debug.false=Standard -ek_ra8d1.menu.debug.true=Debug -ek_ra8d1.menu.debug.true.build.zsk_args.debug=-debug - -ek_ra8d1.menu.link_mode.dynamic=Dynamic -ek_ra8d1.menu.link_mode.static=Static -ek_ra8d1.menu.link_mode.static.build.link_mode=static -ek_ra8d1.menu.link_mode.static.upload.extension=bin-zsk.bin - -ek_ra8d1.build.zephyr_target=ek_ra8d1 -ek_ra8d1.build.zephyr_args= -ek_ra8d1.build.zephyr_hals=hal_renesas -ek_ra8d1.build.variant=ek_ra8d1_r7fa8d1bhecbd -ek_ra8d1.build.mcu=cortex-m85+nomve -ek_ra8d1.build.fpu=-mfpu=fpv5-d16 -ek_ra8d1.build.architecture=cortex-m85+nomve - -ek_ra8d1.build.float-abi=-mfloat-abi=hard -ek_ra8d1.build.extra_flags= -ek_ra8d1.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -ek_ra8d1.build.architecture=cortex-m85+nomve -ek_ra8d1.build.board=EK_RA8D1 - -#ek_ra8d1.recipe.hooks.objcopy.postobjcopy.4.pattern=cp {build.variant.path}/flasher.jlink "{build.path}/flasher.jlink" -#ek_ra8d1.recipe.hooks.objcopy.postobjcopy.5.pattern=sed -i 's|SKETCH|"{build.path}/{build.project_name}.llext.dfu.bin"|g' "{build.path}/flasher.jlink" - -ek_ra8d1.vid.0=0x2341 -ek_ra8d1.pid.0=0x0077 -ek_ra8d1.upload_port.0.vid=0x2341 -ek_ra8d1.upload_port.0.pid=0x0077 - -ek_ra8d1.upload.tool=pyocd -ek_ra8d1.upload.tool.default=pyocd -ek_ra8d1.upload.protocol= -ek_ra8d1.upload.transport= -ek_ra8d1.upload.vid=0x2341 -ek_ra8d1.upload.pid=0x0366 -ek_ra8d1.upload.interface=0 -ek_ra8d1.upload.use_1200bps_touch=false -ek_ra8d1.upload.wait_for_upload_port=false -ek_ra8d1.upload.native_usb=true -ek_ra8d1.upload.maximum_size=1966080 -ek_ra8d1.upload.maximum_data_size=523624 -ek_ra8d1.upload.address=0x2032000 -ek_ra8d1.upload.target=R7FA8D1AH - -ek_ra8d1.bootloader.tool=pyocd -ek_ra8d1.bootloader.tool.default=pyocd -ek_ra8d1.bootloader.file=zephyr-{build.variant}.elf -ek_ra8d1.bootloader.target=R7FA8D1AH - - -############################################################################################################## - -frdm_mcxn947.name=NXP FRDM MCXN947 -frdm_mcxn947.build.core=arduino -frdm_mcxn947.build.crossprefix=arm-zephyr-eabi- -frdm_mcxn947.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -frdm_mcxn947.menu.debug.false=Standard -frdm_mcxn947.menu.debug.true=Debug -frdm_mcxn947.menu.debug.true.build.zsk_args.debug=-debug - -frdm_mcxn947.menu.link_mode.dynamic=Dynamic -frdm_mcxn947.menu.link_mode.static=Static -frdm_mcxn947.menu.link_mode.static.build.link_mode=static -frdm_mcxn947.menu.link_mode.static.upload.extension=bin-zsk.bin - -frdm_mcxn947.build.zephyr_target=frdm_mcxn947//cpu0 -frdm_mcxn947.build.zephyr_args= -frdm_mcxn947.build.zephyr_hals=hal_nxp -frdm_mcxn947.build.variant=frdm_mcxn947_mcxn947_cpu0 -frdm_mcxn947.build.mcu=cortex-m33 -frdm_mcxn947.build.fpu=-mfpu=fpv5-sp-d16 -frdm_mcxn947.build.architecture=cortex-m33 - -frdm_mcxn947.build.float-abi=-mfloat-abi=hard -frdm_mcxn947.build.extra_flags= -frdm_mcxn947.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -frdm_mcxn947.build.board=FRDM_MCXN947 -frdm_mcxn947.vid.0=0x1fc9 -frdm_mcxn947.pid.0=0x0143 -frdm_mcxn947.upload_port.0.vid=0x1fc9 -frdm_mcxn947.upload_port.0.pid=0x0143 -frdm_mcxn947.upload.address=0x100F0000 -frdm_mcxn947.upload.target=mcxn947vdf - -frdm_mcxn947.upload.tool=pyocd -frdm_mcxn947.upload.tool.default=pyocd -frdm_mcxn947.upload.protocol= -frdm_mcxn947.upload.transport= -frdm_mcxn947.upload.vid=0x1fc9 -frdm_mcxn947.upload.pid=0x0143 -frdm_mcxn947.upload.interface=0 -frdm_mcxn947.upload.use_1200bps_touch=false -frdm_mcxn947.upload.wait_for_upload_port=false -frdm_mcxn947.upload.native_usb=true -frdm_mcxn947.upload.maximum_size=1966080 -frdm_mcxn947.upload.maximum_data_size=523624 - -frdm_mcxn947.bootloader.tool=pyocd -frdm_mcxn947.bootloader.tool.default=pyocd -frdm_mcxn947.bootloader.file=zephyr-{build.variant}.elf -frdm_mcxn947.bootloader.target=mcxn947vdf - - -########################################################################################## - -portentah7.name=Arduino Portenta H7 -portentah7.build.core=arduino -portentah7.build.crossprefix=arm-zephyr-eabi- -portentah7.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -portentah7.menu.debug.false=Standard -portentah7.menu.debug.true=Debug -portentah7.menu.debug.true.build.zsk_args.debug=-debug - -portentah7.menu.link_mode.dynamic=Dynamic -portentah7.menu.link_mode.static=Static -portentah7.menu.link_mode.static.build.link_mode=static -portentah7.menu.link_mode.static.upload.extension=bin-zsk.bin - -portentah7.build.zephyr_target=arduino_portenta_h7@1.0.0//m7 -portentah7.build.zephyr_args= -portentah7.build.zephyr_hals=hal_stm32 hal_infineon -portentah7.build.artifact=zephyr_main -portentah7.build.variant=arduino_portenta_h7_stm32h747xx_m7 -portentah7.build.mcu=cortex-m7 -portentah7.build.fpu=-mfpu=fpv5-d16 -portentah7.build.architecture=cortex-m7 - -portentah7.build.float-abi=-mfloat-abi=softfp -portentah7.build.extra_flags= -portentah7.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -portentah7.build.architecture=cortex-m7 -portentah7.build.board=PORTENTA_H7_M7 -portentah7.vid.0=0x2341 -portentah7.pid.0=0x005b -portentah7.upload_port.0.vid=0x2341 -portentah7.upload_port.0.pid=0x035b - -portentah7.upload.tool=dfu-util -portentah7.upload.tool.default=dfu-util -portentah7.upload.protocol= -portentah7.upload.transport= -portentah7.upload.vid=0x2341 -portentah7.upload.pid=0x035b -portentah7.upload.interface=0 -portentah7.upload.use_1200bps_touch=true -portentah7.upload.wait_for_upload_port=true -portentah7.upload.native_usb=true -portentah7.upload.maximum_size=1966080 -portentah7.upload.maximum_data_size=523624 - -portentah7.upload.address=0x080E0000 - -portentah7.upload.maximum_size=786432 -portentah7.upload.maximum_data_size=523624 - -portentah7.bootloader.tool=dfu-util -portentah7.bootloader.tool.default=dfu-util -portentah7.bootloader.vid=0x2341 -portentah7.bootloader.pid=0x035b -portentah7.bootloader.interface=0 -portentah7.bootloader.file=zephyr-{build.variant}.bin -portentah7.bootloader.address=0x08040000 - -portentah7.debug.tool=gdb -portentah7.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -portentah7.debug.server.openocd.scripts.1={programmer.transport_script} -portentah7.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg -portentah7.debug.cortex-debug.custom.request=attach -portentah7.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd - -############################################################################################################## - -nicla_vision.name=Arduino Nicla Vision -nicla_vision.build.core=arduino -nicla_vision.build.crossprefix=arm-zephyr-eabi- -nicla_vision.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -nicla_vision.menu.debug.false=Standard -nicla_vision.menu.debug.true=Debug -nicla_vision.menu.debug.true.build.zsk_args.debug=-debug - -nicla_vision.menu.link_mode.dynamic=Dynamic -nicla_vision.menu.link_mode.static=Static -nicla_vision.menu.link_mode.static.build.link_mode=static -nicla_vision.menu.link_mode.static.upload.extension=bin-zsk.bin - -nicla_vision.build.zephyr_target=arduino_nicla_vision//m7 -nicla_vision.build.zephyr_args= -nicla_vision.build.zephyr_hals=hal_stm32 hal_infineon -nicla_vision.build.artifact=zephyr_main -nicla_vision.build.variant=arduino_nicla_vision_stm32h747xx_m7 -nicla_vision.build.mcu=cortex-m7 -nicla_vision.build.fpu=-mfpu=fpv5-d16 -nicla_vision.build.architecture=cortex-m7 - -nicla_vision.build.float-abi=-mfloat-abi=softfp -nicla_vision.build.extra_flags= -nicla_vision.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -nicla_vision.build.architecture=cortex-m7 -nicla_vision.build.board=NICLA_VISION -nicla_vision.vid.0=0x2341 -nicla_vision.pid.0=0x005b -nicla_vision.upload_port.0.vid=0x2341 -nicla_vision.upload_port.0.pid=0x025f - -nicla_vision.upload.tool=dfu-util -nicla_vision.upload.tool.default=dfu-util -nicla_vision.upload.protocol= -nicla_vision.upload.transport= -nicla_vision.upload.vid=0x2341 -nicla_vision.upload.pid=0x035f -nicla_vision.upload.interface=0 -nicla_vision.upload.use_1200bps_touch=true -nicla_vision.upload.wait_for_upload_port=true -nicla_vision.upload.native_usb=true -nicla_vision.upload.maximum_size=1966080 -nicla_vision.upload.maximum_data_size=523624 - -nicla_vision.upload.address=0x080E0000 - -nicla_vision.upload.maximum_size=786432 -nicla_vision.upload.maximum_data_size=523624 - -nicla_vision.bootloader.tool=dfu-util -nicla_vision.bootloader.tool.default=dfu-util -nicla_vision.bootloader.vid=0x2341 -nicla_vision.bootloader.pid=0x035f -nicla_vision.bootloader.interface=0 -nicla_vision.bootloader.file=zephyr-{build.variant}.bin -nicla_vision.bootloader.address=0x08040000 - -nicla_vision.debug.tool=gdb -nicla_vision.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -nicla_vision.debug.server.openocd.scripts.1={programmer.transport_script} -nicla_vision.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg -nicla_vision.debug.cortex-debug.custom.request=attach -nicla_vision.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd - -############################################################################################################## - -frdm_rw612.name=NXP FRDM RW612 -frdm_rw612.build.core=arduino -frdm_rw612.build.crossprefix=arm-zephyr-eabi- -frdm_rw612.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -frdm_rw612.menu.debug.false=Standard -frdm_rw612.menu.debug.true=Debug -frdm_rw612.menu.debug.true.build.zsk_args.debug=-debug - -frdm_rw612.menu.link_mode.dynamic=Dynamic -frdm_rw612.menu.link_mode.static=Static -frdm_rw612.menu.link_mode.static.build.link_mode=static -frdm_rw612.menu.link_mode.static.upload.extension=bin-zsk.bin - -frdm_rw612.build.zephyr_target=frdm_rw612 -frdm_rw612.build.zephyr_args= -frdm_rw612.build.zephyr_hals=hal_stm32 -frdm_rw612.build.variant=frdm_rw612_rw612 -frdm_rw612.build.mcu=cortex-m33+nodsp -frdm_rw612.build.fpu=-mfpu=fpv5-sp-d16 -frdm_rw612.build.architecture=cortex-m33+nodsp - -frdm_rw612.build.float-abi=-mfloat-abi=hard -frdm_rw612.build.extra_flags= -frdm_rw612.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -frdm_rw612.build.board=FRDM_RW612 -frdm_rw612.vid.0=0x1fc9 -frdm_rw612.pid.0=0x0143 -frdm_rw612.upload_port.0.vid=0x1fc9 -frdm_rw612.upload_port.0.pid=0x0143 -frdm_rw612.upload.address=0x18323000 -frdm_rw612.upload.target=rw612 - -frdm_rw612.upload.tool=pyocd -frdm_rw612.upload.tool.default=pyocd -frdm_rw612.upload.protocol= -frdm_rw612.upload.transport= -frdm_rw612.upload.vid=0x1fc9 -frdm_rw612.upload.pid=0x0143 -frdm_rw612.upload.interface=0 -frdm_rw612.upload.use_1200bps_touch=false -frdm_rw612.upload.wait_for_upload_port=false -frdm_rw612.upload.native_usb=true -frdm_rw612.upload.maximum_size=1966080 -frdm_rw612.upload.maximum_data_size=523624 - -frdm_rw612.bootloader.tool=pyocd -frdm_rw612.bootloader.tool.default=pyocd -frdm_rw612.bootloader.file=zephyr-{build.variant}.elf -frdm_rw612.bootloader.target=rw612 - -########################################################################################## - -niclasense.name=Arduino Nicla Sense ME -niclasense.build.core=arduino -niclasense.build.crossprefix=arm-zephyr-eabi- -niclasense.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -niclasense.menu.link_mode.dynamic=Dynamic -niclasense.menu.link_mode.static=Static -niclasense.menu.link_mode.static.build.link_mode=static -niclasense.menu.link_mode.static.upload.extension=bin-zsk.bin - -niclasense.build.zephyr_target=arduino_nicla_sense_me -niclasense.build.zephyr_args= -niclasense.build.zephyr_hals=hal_nordic -niclasense.build.artifact=zephyr_main -niclasense.build.variant=arduino_nicla_sense_me_nrf52832 -niclasense.build.mcu=cortex-m4 -niclasense.build.fpu=-mfpu=fpv4-sp-d16 -niclasense.build.architecture=cortex-m4 - -niclasense.build.float-abi=-mfloat-abi=hard -niclasense.build.extra_flags= -niclasense.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -niclasense.build.architecture=cortex-m4 -niclasense.build.board=NICLA_SENSE_ME -niclasense.vid.0=0x2341 -niclasense.pid.0=0x0360 -niclasense.upload_port.0.vid=0x2341 -niclasense.upload_port.0.pid=0x0060 - -niclasense.upload.tool=openocd -niclasense.upload.tool.default=openocd -niclasense.upload.protocol= -niclasense.upload.config=-f target/nrf52.cfg -niclasense.upload.programmer=-f interface/cmsis-dap.cfg -niclasense.upload.vid=0x2341 -niclasense.upload.pid=0x0060 -niclasense.upload.interface=0 -niclasense.upload.use_1200bps_touch=false -niclasense.upload.wait_for_upload_port=false -niclasense.upload.native_usb=false -niclasense.upload.maximum_size=1966080 -niclasense.upload.maximum_data_size=523624 -niclasense.upload.address=0x70000 -niclasense.upload.target=nrf52 - -niclasense.upload.maximum_size=786432 -niclasense.upload.maximum_data_size=523624 - -niclasense.bootloader.tool=openocd -niclasense.bootloader.tool.default=openocd -niclasense.bootloader.vid=0x2341 -niclasense.bootloader.pid=0x0360 -niclasense.bootloader.interface=0 -niclasense.bootloader.file=zephyr-{build.variant}.hex -niclasense.bootloader.target=nrf52 - -niclasense.debug.tool=gdb -niclasense.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -niclasense.debug.server.openocd.scripts.1={programmer.transport_script} -niclasense.debug.server.openocd.scripts.2=target/nrf52.cfg -niclasense.debug.cortex-debug.custom.request=attach - - -########################################################################################## - -portentac33.name=Arduino Portenta C33 -portentac33.build.core=arduino -portentac33.build.crossprefix=arm-zephyr-eabi- -portentac33.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -portentac33.menu.debug.false=Standard -portentac33.menu.debug.true=Debug -portentac33.menu.debug.true.build.zsk_args.debug=-debug - -portentac33.menu.link_mode.dynamic=Dynamic -portentac33.menu.link_mode.static=Static -portentac33.menu.link_mode.static.build.link_mode=static -portentac33.menu.link_mode.static.upload.extension=bin-zsk.bin - -portentac33.build.zephyr_target=arduino_portenta_c33 -portentac33.build.zephyr_args= -portentac33.build.zephyr_hals=hal_renesas nanopb -portentac33.build.artifact=zephyr_main -portentac33.build.variant=arduino_portenta_c33_r7fa6m5bh3cfc -portentac33.build.mcu=cortex-m33 -portentac33.build.fpu=-mfpu=fpv5-sp-d16 -portentac33.build.architecture=cortex-m33 - -portentac33.build.float-abi=-mfloat-abi=hard -portentac33.build.extra_flags= -portentac33.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -portentac33.build.board=PORTENTA_C33 -portentac33.vid.0=0x2341 -portentac33.pid.0=0x0068 -portentac33.upload_port.0.vid=0x2341 -portentac33.upload_port.0.pid=0x0068 -portentac33.upload.target=portentac33 - -portentac33.upload.tool=dfu-util -portentac33.upload.tool.default=dfu-util -portentac33.upload.protocol= -portentac33.upload.transport= -portentac33.upload.vid=0x2341 -portentac33.upload.pid=0x0368 -portentac33.upload.interface=1 -portentac33.upload.use_1200bps_touch=true -portentac33.upload.wait_for_upload_port=false -portentac33.upload.native_usb=true -portentac33.upload.maximum_size=1966080 -portentac33.upload.maximum_data_size=523624 -portentac33.upload.address=0x100000 -portentac33.upload.dfuse=-Q -w - -portentac33.bootloader.tool=dfu-util -portentac33.bootloader.tool.default=dfu-util -portentac33.bootloader.file=zephyr-{build.variant}.bin -portentac33.bootloader.interface=0 -portentac33.bootloader.address=0x10000 -portentac33.bootloader.dfuse=-Q - -########################################################################################## - -opta.name=Arduino Opta -opta.build.core=arduino -opta.build.crossprefix=arm-zephyr-eabi- -opta.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -opta.menu.debug.false=Standard -opta.menu.debug.true=Debug -opta.menu.debug.true.build.zsk_args.debug=-debug - -opta.menu.link_mode.dynamic=Dynamic -opta.menu.link_mode.static=Static -opta.menu.link_mode.static.build.link_mode=static -opta.menu.link_mode.static.upload.extension=bin-zsk.bin - -opta.build.zephyr_target=arduino_opta//m7 -opta.build.zephyr_args= -opta.build.zephyr_hals=hal_stm32 hal_infineon -opta.build.artifact=zephyr_main -opta.build.variant=arduino_opta_stm32h747xx_m7 -opta.build.mcu=cortex-m7 -opta.build.fpu=-mfpu=fpv5-d16 -opta.build.architecture=cortex-m7 - -opta.build.float-abi=-mfloat-abi=softfp -opta.build.extra_flags= -opta.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -opta.build.architecture=cortex-m7 -opta.build.board=OPTA -opta.vid.0=0x2341 -opta.pid.0=0x0064 -opta.upload_port.0.vid=0x2341 -opta.upload_port.0.pid=0x0364 - -opta.upload.tool=dfu-util -opta.upload.tool.default=dfu-util -opta.upload.protocol= -opta.upload.transport= -opta.upload.vid=0x2341 -opta.upload.pid=0x0364 -opta.upload.interface=0 -opta.upload.use_1200bps_touch=true -opta.upload.wait_for_upload_port=true -opta.upload.native_usb=true -opta.upload.maximum_size=1966080 -opta.upload.maximum_data_size=523624 - -opta.upload.address=0x080E0000 - -opta.upload.maximum_size=786432 -opta.upload.maximum_data_size=523624 - -opta.bootloader.tool=dfu-util -opta.bootloader.tool.default=dfu-util -opta.bootloader.vid=0x2341 -opta.bootloader.pid=0x0364 -opta.bootloader.interface=0 -opta.bootloader.file=zephyr-{build.variant}.bin -opta.bootloader.address=0x08040000 - -opta.debug.tool=gdb -opta.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg -opta.debug.server.openocd.scripts.1={programmer.transport_script} -opta.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg -opta.debug.cortex-debug.custom.request=attach -opta.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +menu.debug=Debug +menu.link_mode=Link mode +menu.wait_linux_boot=Startup mode ########################################################################################## -nano_matter.name=Arduino Nano Matter -nano_matter.build.core=arduino -nano_matter.build.crossprefix=arm-zephyr-eabi- -nano_matter.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -nano_matter.menu.link_mode.dynamic=Dynamic -nano_matter.menu.link_mode.static=Static -nano_matter.menu.link_mode.static.build.link_mode=static -nano_matter.menu.link_mode.static.upload.extension=bin-zsk.bin - -nano_matter.build.zephyr_target=arduino_nano_matter -nano_matter.build.zephyr_args= -nano_matter.build.zephyr_hals=hal_silabs -nano_matter.build.artifact=zephyr_main -nano_matter.build.variant=arduino_nano_matter_mgm240sd22vna -nano_matter.build.mcu=cortex-m33 -nano_matter.build.fpu=-mfpu=fpv4-sp-d16 -nano_matter.build.architecture=cortex-m33 - -nano_matter.build.float-abi=-mfloat-abi=hard -nano_matter.build.extra_flags= -nano_matter.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -nano_matter.build.architecture=cortex-m33 -nano_matter.build.board=ARDUINO_NANO_MATTER -nano_matter.vid.0=0x2341 -nano_matter.pid.0=0x0072 -nano_matter.upload_port.0.vid=0x2341 -nano_matter.upload_port.0.pid=0x0072 - -nano_matter.upload.tool=openocd -nano_matter.upload.tool.default=openocd -nano_matter.upload.config=-f target/efm32s2_g23.cfg -nano_matter.upload.programmer=-f interface/cmsis-dap.cfg -nano_matter.upload.maximum_data_size=262144 -nano_matter.upload.maximum_size=1572864 -nano_matter.upload.address=0x080C4000 -nano_matter.upload.protocol=SWD -nano_matter.upload.setup_command= -nano_matter.upload.use_1200bps_touch=false -nano_matter.upload.wait_for_upload_port=false -nano_matter.upload.native_usb=false - -nano_matter.bootloader.tool=openocd -nano_matter.bootloader.tool.default=openocd -nano_matter.bootloader.vid=0x2341 -nano_matter.bootloader.pid=0x0072 -nano_matter.bootloader.interface=0 -nano_matter.bootloader.file=zephyr-{build.variant}.hex -nano_matter.bootloader.target=arduino_nano_matter - -nano_matter.debug.server=openocd -nano_matter.debug.server.openocd.scripts.0=interface/cmsis-dap.cfg -nano_matter.debug.server.openocd.scripts.1=target/efm32s2_g23.cfg -nano_matter.debug.cortex-debug.custom.postAttachCommands.0=monitor reset halt -#nano_matter.debug.cortex-debug.custom.postAttachCommands.1=monitor reset_config srst_nogate -#nano_matter.debug.cortex-debug.custom.postAttachCommands.2=monitor gdb_breakpoint_override hard -nano_matter.debug.cortex-debug.custom.postAttachCommands.3=monitor gdb_sync -nano_matter.debug.cortex-debug.custom.postAttachCommands.4=c -nano_matter.debug.cortex-debug.custom.overrideRestartCommands.0=monitor reset halt -nano_matter.debug.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync -nano_matter.debug.cortex-debug.custom.overrideRestartCommands.2=c -nano_matter.debug.cortex-debug.custom.request=attach - -############################################################################################################## - -unoq.name=Arduino UNO Q -unoq.build.core=arduino -unoq.build.crossprefix=arm-zephyr-eabi- -unoq.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ - -unoq.menu.link_mode.dynamic=Dynamic -unoq.menu.link_mode.static=Static -unoq.menu.link_mode.static.build.link_mode=static -unoq.menu.link_mode.static.upload.extension=bin-zsk.bin - -unoq.menu.wait_linux_boot.yes=Wait for Linux -unoq.menu.wait_linux_boot.no=Immediate -unoq.menu.wait_linux_boot.no.build.boot_mode=immediate -unoq.menu.wait_linux_boot.app=Wait for App -unoq.menu.wait_linux_boot.app.build.boot_mode=app - -unoq.build.zephyr_target=arduino_uno_q -unoq.build.zephyr_args= -unoq.build.variant=arduino_uno_q_stm32u585xx -unoq.build.artifact=zephyr_unoq -unoq.build.subarch=zephyr -unoq.build.mcu=cortex-m33 -unoq.build.fpu=-mfpu=fpv5-sp-d16 -unoq.build.architecture=cortex-m33 -unoq.compiler.zephyr.arch.define= - -unoq.openocd_cfg=flash_sketch.cfg - -unoq.build.float-abi=-mfloat-abi=hard -unoq.build.extra_flags= -unoq.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit -unoq.build.board=UNO_Q -unoq.build.zephyr_hals=hal_stm32 -unoq.compiler.zephyr.arch.define= -unoq.compiler.zephyr= -unoq.vid.0=0x2341 -unoq.pid.0=0x0078 -unoq.upload_port.0.vid=0x2341 -unoq.upload_port.0.pid=0x0078 -unoq.upload.address=0x8100000 -unoq.upload.target=stm32u585zitxq - -unoq.upload.tool=remoteocd -unoq.upload.tool.default=remoteocd -unoq.upload.tool.network=remoteocd_network -unoq.upload.protocol= -unoq.upload.transport= -unoq.upload.vid=0x2341 -unoq.upload.pid=0x0078 -unoq.upload.interface=0 -unoq.upload.use_1200bps_touch=false -unoq.upload.wait_for_upload_port=false -unoq.upload.native_usb=true -unoq.upload.maximum_size=1966080 -unoq.upload.maximum_data_size=523624 - -unoq.bootloader.tool=remoteocd -unoq.bootloader.tool.default=remoteocd -unoq.bootloader.file=zephyr-{build.variant}.elf -unoq.bootloader.target=stm32u585zitxq +# giga.name=Arduino Giga R1 +# giga.build.core=arduino +# giga.build.crossprefix=arm-zephyr-eabi- +# giga.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# giga.menu.debug.false=Standard +# giga.menu.debug.true=Debug +# giga.menu.debug.true.build.zsk_args.debug=-debug +# +# giga.menu.link_mode.dynamic=Dynamic +# giga.menu.link_mode.static=Static +# giga.menu.link_mode.static.build.link_mode=static +# giga.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# giga.build.zephyr_target=arduino_giga_r1//m7 +# giga.build.zephyr_args=--shield arduino_giga_display_shield +# giga.build.zephyr_hals=hal_stm32 hal_infineon +# giga.build.variant=arduino_giga_r1_stm32h747xx_m7 +# giga.build.artifact=zephyr_main +# +# giga.build.extra_flags= +# giga.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# giga.build.board=GIGA +# giga.vid.0=0x2341 +# giga.pid.0=0x0066 +# giga.upload_port.0.vid=0x2341 +# giga.upload_port.0.pid=0x0066 +# +# giga.upload.tool=dfu-util +# giga.upload.tool.default=dfu-util +# giga.upload.protocol= +# giga.upload.transport= +# giga.upload.vid=0x2341 +# giga.upload.pid=0x0366 +# giga.upload.interface=0 +# giga.upload.use_1200bps_touch=true +# giga.upload.wait_for_upload_port=true +# giga.upload.native_usb=true +# +# giga.bootloader.tool=dfu-util +# giga.bootloader.tool.default=dfu-util +# giga.bootloader.vid=0x2341 +# giga.bootloader.pid=0x0366 +# giga.bootloader.interface=0 +# giga.bootloader.file=zephyr-{build.variant}.bin +# giga.bootloader.address=0x08040000 +# +# giga.debug.tool=gdb +# giga.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# giga.debug.server.openocd.scripts.1={programmer.transport_script} +# giga.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg +# giga.debug.cortex-debug.custom.request=attach +# giga.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +# +# ########################################################################################## +# +# nano33ble.name=Arduino Nano 33 BLE +# nano33ble.build.core=arduino +# nano33ble.build.crossprefix=arm-zephyr-eabi- +# nano33ble.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# nano33ble.menu.debug.false=Standard +# nano33ble.menu.debug.true=Debug +# nano33ble.menu.debug.true.build.zsk_args.debug=-debug +# +# nano33ble.menu.link_mode.dynamic=Dynamic +# nano33ble.menu.link_mode.static=Static +# nano33ble.menu.link_mode.static.build.link_mode=static +# nano33ble.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# nano33ble.build.zephyr_target=arduino_nano_33_ble//sense +# nano33ble.build.zephyr_args= +# nano33ble.build.zephyr_hals=hal_nordic +# nano33ble.build.artifact=zephyr_main +# nano33ble.build.variant=arduino_nano_33_ble_nrf52840_sense +# +# nano33ble.build.extra_flags= +# nano33ble.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# nano33ble.build.board=NANO33BLE +# nano33ble.vid.0=0x2341 +# nano33ble.pid.0=0x035a +# nano33ble.upload_port.0.vid=0x2341 +# nano33ble.upload_port.0.pid=0x005a +# +# nano33ble.upload.tool=bossac +# nano33ble.upload.tool.default=bossac +# nano33ble.upload.protocol= +# nano33ble.upload.transport= +# nano33ble.upload.vid=0x2341 +# nano33ble.upload.pid=0x005a +# nano33ble.upload.interface=0 +# nano33ble.upload.use_1200bps_touch=true +# nano33ble.upload.wait_for_upload_port=true +# nano33ble.upload.native_usb=true +# +# nano33ble.bootloader.tool=bossac +# nano33ble.bootloader.tool.default=bossac +# nano33ble.bootloader.vid=0x2341 +# nano33ble.bootloader.pid=0x035b +# nano33ble.bootloader.interface=0 +# nano33ble.bootloader.file=zephyr-{build.variant}.bin +# nano33ble.bootloader.address=0x0000 +# +# nano33ble.debug.tool=gdb +# nano33ble.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# nano33ble.debug.server.openocd.scripts.1={programmer.transport_script} +# nano33ble.debug.server.openocd.scripts.2=target/nrf52.cfg +# nano33ble.debug.cortex-debug.custom.request=attach +# +# ############################################################################################################## +# +# ek_ra8d1.name=Renesas RA8D1 EK +# ek_ra8d1.build.core=arduino +# ek_ra8d1.build.crossprefix=arm-zephyr-eabi- +# ek_ra8d1.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# ek_ra8d1.menu.debug.false=Standard +# ek_ra8d1.menu.debug.true=Debug +# ek_ra8d1.menu.debug.true.build.zsk_args.debug=-debug +# +# ek_ra8d1.menu.link_mode.dynamic=Dynamic +# ek_ra8d1.menu.link_mode.static=Static +# ek_ra8d1.menu.link_mode.static.build.link_mode=static +# ek_ra8d1.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# ek_ra8d1.build.zephyr_target=ek_ra8d1 +# ek_ra8d1.build.zephyr_args= +# ek_ra8d1.build.zephyr_hals=hal_renesas +# ek_ra8d1.build.variant=ek_ra8d1_r7fa8d1bhecbd +# +# ek_ra8d1.build.extra_flags= +# ek_ra8d1.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# ek_ra8d1.build.board=EK_RA8D1 +# +# #ek_ra8d1.recipe.hooks.objcopy.postobjcopy.4.pattern=cp {build.variant.path}/flasher.jlink "{build.path}/flasher.jlink" +# #ek_ra8d1.recipe.hooks.objcopy.postobjcopy.5.pattern=sed -i 's|SKETCH|"{build.path}/{build.project_name}.llext.dfu.bin"|g' "{build.path}/flasher.jlink" +# +# ek_ra8d1.vid.0=0x2341 +# ek_ra8d1.pid.0=0x0077 +# ek_ra8d1.upload_port.0.vid=0x2341 +# ek_ra8d1.upload_port.0.pid=0x0077 +# +# ek_ra8d1.upload.tool=pyocd +# ek_ra8d1.upload.tool.default=pyocd +# ek_ra8d1.upload.protocol= +# ek_ra8d1.upload.transport= +# ek_ra8d1.upload.vid=0x2341 +# ek_ra8d1.upload.pid=0x0366 +# ek_ra8d1.upload.interface=0 +# ek_ra8d1.upload.use_1200bps_touch=false +# ek_ra8d1.upload.wait_for_upload_port=false +# ek_ra8d1.upload.native_usb=true +# ek_ra8d1.upload.target=R7FA8D1AH +# +# ek_ra8d1.bootloader.tool=pyocd +# ek_ra8d1.bootloader.tool.default=pyocd +# ek_ra8d1.bootloader.file=zephyr-{build.variant}.elf +# ek_ra8d1.bootloader.target=R7FA8D1AH +# +# +# ############################################################################################################## +# +# frdm_mcxn947.name=NXP FRDM MCXN947 +# frdm_mcxn947.build.core=arduino +# frdm_mcxn947.build.crossprefix=arm-zephyr-eabi- +# frdm_mcxn947.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# frdm_mcxn947.menu.debug.false=Standard +# frdm_mcxn947.menu.debug.true=Debug +# frdm_mcxn947.menu.debug.true.build.zsk_args.debug=-debug +# +# frdm_mcxn947.menu.link_mode.dynamic=Dynamic +# frdm_mcxn947.menu.link_mode.static=Static +# frdm_mcxn947.menu.link_mode.static.build.link_mode=static +# frdm_mcxn947.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# frdm_mcxn947.build.zephyr_target=frdm_mcxn947//cpu0 +# frdm_mcxn947.build.zephyr_args= +# frdm_mcxn947.build.zephyr_hals=hal_nxp +# frdm_mcxn947.build.variant=frdm_mcxn947_mcxn947_cpu0 +# frdm_mcxn947.build.extra_flags= +# frdm_mcxn947.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# frdm_mcxn947.build.board=FRDM_MCXN947 +# frdm_mcxn947.vid.0=0x1fc9 +# frdm_mcxn947.pid.0=0x0143 +# frdm_mcxn947.upload_port.0.vid=0x1fc9 +# frdm_mcxn947.upload_port.0.pid=0x0143 +# frdm_mcxn947.upload.target=mcxn947vdf +# +# frdm_mcxn947.upload.tool=pyocd +# frdm_mcxn947.upload.tool.default=pyocd +# frdm_mcxn947.upload.protocol= +# frdm_mcxn947.upload.transport= +# frdm_mcxn947.upload.vid=0x1fc9 +# frdm_mcxn947.upload.pid=0x0143 +# frdm_mcxn947.upload.interface=0 +# frdm_mcxn947.upload.use_1200bps_touch=false +# frdm_mcxn947.upload.wait_for_upload_port=false +# frdm_mcxn947.upload.native_usb=true +# +# frdm_mcxn947.bootloader.tool=pyocd +# frdm_mcxn947.bootloader.tool.default=pyocd +# frdm_mcxn947.bootloader.file=zephyr-{build.variant}.elf +# frdm_mcxn947.bootloader.target=mcxn947vdf +# +# +# ########################################################################################## +# +# portentah7.name=Arduino Portenta H7 +# portentah7.build.core=arduino +# portentah7.build.crossprefix=arm-zephyr-eabi- +# portentah7.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# portentah7.menu.debug.false=Standard +# portentah7.menu.debug.true=Debug +# portentah7.menu.debug.true.build.zsk_args.debug=-debug +# +# portentah7.menu.link_mode.dynamic=Dynamic +# portentah7.menu.link_mode.static=Static +# portentah7.menu.link_mode.static.build.link_mode=static +# portentah7.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# portentah7.build.zephyr_target=arduino_portenta_h7@1.0.0//m7 +# portentah7.build.zephyr_args= +# portentah7.build.zephyr_hals=hal_stm32 hal_infineon +# portentah7.build.artifact=zephyr_main +# portentah7.build.variant=arduino_portenta_h7_stm32h747xx_m7 +# +# portentah7.build.extra_flags= +# portentah7.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# portentah7.build.board=PORTENTA_H7_M7 +# portentah7.vid.0=0x2341 +# portentah7.pid.0=0x005b +# portentah7.upload_port.0.vid=0x2341 +# portentah7.upload_port.0.pid=0x035b +# +# portentah7.upload.tool=dfu-util +# portentah7.upload.tool.default=dfu-util +# portentah7.upload.protocol= +# portentah7.upload.transport= +# portentah7.upload.vid=0x2341 +# portentah7.upload.pid=0x035b +# portentah7.upload.interface=0 +# portentah7.upload.use_1200bps_touch=true +# portentah7.upload.wait_for_upload_port=true +# portentah7.upload.native_usb=true +# +# portentah7.bootloader.tool=dfu-util +# portentah7.bootloader.tool.default=dfu-util +# portentah7.bootloader.vid=0x2341 +# portentah7.bootloader.pid=0x035b +# portentah7.bootloader.interface=0 +# portentah7.bootloader.file=zephyr-{build.variant}.bin +# portentah7.bootloader.address=0x08040000 +# +# portentah7.debug.tool=gdb +# portentah7.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# portentah7.debug.server.openocd.scripts.1={programmer.transport_script} +# portentah7.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg +# portentah7.debug.cortex-debug.custom.request=attach +# portentah7.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +# +# ############################################################################################################## +# +# nicla_vision.name=Arduino Nicla Vision +# nicla_vision.build.core=arduino +# nicla_vision.build.crossprefix=arm-zephyr-eabi- +# nicla_vision.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# nicla_vision.menu.debug.false=Standard +# nicla_vision.menu.debug.true=Debug +# nicla_vision.menu.debug.true.build.zsk_args.debug=-debug +# +# nicla_vision.menu.link_mode.dynamic=Dynamic +# nicla_vision.menu.link_mode.static=Static +# nicla_vision.menu.link_mode.static.build.link_mode=static +# nicla_vision.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# nicla_vision.build.zephyr_target=arduino_nicla_vision//m7 +# nicla_vision.build.zephyr_args= +# nicla_vision.build.zephyr_hals=hal_stm32 hal_infineon +# nicla_vision.build.artifact=zephyr_main +# nicla_vision.build.variant=arduino_nicla_vision_stm32h747xx_m7 +# +# nicla_vision.build.extra_flags= +# nicla_vision.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# nicla_vision.build.board=NICLA_VISION +# nicla_vision.vid.0=0x2341 +# nicla_vision.pid.0=0x005b +# nicla_vision.upload_port.0.vid=0x2341 +# nicla_vision.upload_port.0.pid=0x025f +# +# nicla_vision.upload.tool=dfu-util +# nicla_vision.upload.tool.default=dfu-util +# nicla_vision.upload.protocol= +# nicla_vision.upload.transport= +# nicla_vision.upload.vid=0x2341 +# nicla_vision.upload.pid=0x035f +# nicla_vision.upload.interface=0 +# nicla_vision.upload.use_1200bps_touch=true +# nicla_vision.upload.wait_for_upload_port=true +# nicla_vision.upload.native_usb=true +# +# nicla_vision.bootloader.tool=dfu-util +# nicla_vision.bootloader.tool.default=dfu-util +# nicla_vision.bootloader.vid=0x2341 +# nicla_vision.bootloader.pid=0x035f +# nicla_vision.bootloader.interface=0 +# nicla_vision.bootloader.file=zephyr-{build.variant}.bin +# nicla_vision.bootloader.address=0x08040000 +# +# nicla_vision.debug.tool=gdb +# nicla_vision.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# nicla_vision.debug.server.openocd.scripts.1={programmer.transport_script} +# nicla_vision.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg +# nicla_vision.debug.cortex-debug.custom.request=attach +# nicla_vision.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +# +# ############################################################################################################## +# +# frdm_rw612.name=NXP FRDM RW612 +# frdm_rw612.build.core=arduino +# frdm_rw612.build.crossprefix=arm-zephyr-eabi- +# frdm_rw612.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# frdm_rw612.menu.debug.false=Standard +# frdm_rw612.menu.debug.true=Debug +# frdm_rw612.menu.debug.true.build.zsk_args.debug=-debug +# +# frdm_rw612.menu.link_mode.dynamic=Dynamic +# frdm_rw612.menu.link_mode.static=Static +# frdm_rw612.menu.link_mode.static.build.link_mode=static +# frdm_rw612.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# frdm_rw612.build.zephyr_target=frdm_rw612 +# frdm_rw612.build.zephyr_args= +# frdm_rw612.build.zephyr_hals=hal_stm32 +# frdm_rw612.build.variant=frdm_rw612_rw612 +# frdm_rw612.build.extra_flags= +# frdm_rw612.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# frdm_rw612.build.board=FRDM_RW612 +# frdm_rw612.vid.0=0x1fc9 +# frdm_rw612.pid.0=0x0143 +# frdm_rw612.upload_port.0.vid=0x1fc9 +# frdm_rw612.upload_port.0.pid=0x0143 +# frdm_rw612.upload.target=rw612 +# +# frdm_rw612.upload.tool=pyocd +# frdm_rw612.upload.tool.default=pyocd +# frdm_rw612.upload.protocol= +# frdm_rw612.upload.transport= +# frdm_rw612.upload.vid=0x1fc9 +# frdm_rw612.upload.pid=0x0143 +# frdm_rw612.upload.interface=0 +# frdm_rw612.upload.use_1200bps_touch=false +# frdm_rw612.upload.wait_for_upload_port=false +# frdm_rw612.upload.native_usb=true +# +# frdm_rw612.bootloader.tool=pyocd +# frdm_rw612.bootloader.tool.default=pyocd +# frdm_rw612.bootloader.file=zephyr-{build.variant}.elf +# frdm_rw612.bootloader.target=rw612 +# +# ########################################################################################## +# +# nicla_sense.name=Arduino Nicla Sense ME +# nicla_sense.build.core=arduino +# nicla_sense.build.crossprefix=arm-zephyr-eabi- +# nicla_sense.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# nicla_sense.menu.link_mode.dynamic=Dynamic +# nicla_sense.menu.link_mode.static=Static +# nicla_sense.menu.link_mode.static.build.link_mode=static +# nicla_sense.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# nicla_sense.build.zephyr_target=arduino_nicla_sense_me +# nicla_sense.build.zephyr_args= +# nicla_sense.build.zephyr_hals=hal_nordic +# nicla_sense.build.artifact=zephyr_main +# nicla_sense.build.variant=arduino_nicla_sense_me_nrf52832 +# +# nicla_sense.build.extra_flags= +# nicla_sense.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# nicla_sense.build.board=NICLA_SENSE_ME +# nicla_sense.vid.0=0x2341 +# nicla_sense.pid.0=0x0360 +# nicla_sense.upload_port.0.vid=0x2341 +# nicla_sense.upload_port.0.pid=0x0060 +# +# nicla_sense.upload.tool=openocd +# nicla_sense.upload.tool.default=openocd +# nicla_sense.upload.protocol= +# nicla_sense.upload.config=-f target/nrf52.cfg +# nicla_sense.upload.programmer=-f interface/cmsis-dap.cfg +# nicla_sense.upload.vid=0x2341 +# nicla_sense.upload.pid=0x0060 +# nicla_sense.upload.interface=0 +# nicla_sense.upload.use_1200bps_touch=false +# nicla_sense.upload.wait_for_upload_port=false +# nicla_sense.upload.native_usb=false +# nicla_sense.upload.target=nrf52 +# +# nicla_sense.bootloader.tool=openocd +# nicla_sense.bootloader.tool.default=openocd +# nicla_sense.bootloader.vid=0x2341 +# nicla_sense.bootloader.pid=0x0360 +# nicla_sense.bootloader.interface=0 +# nicla_sense.bootloader.file=zephyr-{build.variant}.hex +# nicla_sense.bootloader.target=nrf52 +# +# nicla_sense.debug.tool=gdb +# nicla_sense.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# nicla_sense.debug.server.openocd.scripts.1={programmer.transport_script} +# nicla_sense.debug.server.openocd.scripts.2=target/nrf52.cfg +# nicla_sense.debug.cortex-debug.custom.request=attach +# +# +# ########################################################################################## +# +# portentac33.name=Arduino Portenta C33 +# portentac33.build.core=arduino +# portentac33.build.crossprefix=arm-zephyr-eabi- +# portentac33.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# portentac33.menu.debug.false=Standard +# portentac33.menu.debug.true=Debug +# portentac33.menu.debug.true.build.zsk_args.debug=-debug +# +# portentac33.menu.link_mode.dynamic=Dynamic +# portentac33.menu.link_mode.static=Static +# portentac33.menu.link_mode.static.build.link_mode=static +# portentac33.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# portentac33.build.zephyr_target=arduino_portenta_c33 +# portentac33.build.zephyr_args= +# portentac33.build.zephyr_hals=hal_renesas nanopb +# portentac33.build.artifact=zephyr_main +# portentac33.build.variant=arduino_portenta_c33_r7fa6m5bh3cfc +# portentac33.build.extra_flags= +# portentac33.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# portentac33.build.board=PORTENTA_C33 +# portentac33.vid.0=0x2341 +# portentac33.pid.0=0x0068 +# portentac33.upload_port.0.vid=0x2341 +# portentac33.upload_port.0.pid=0x0068 +# portentac33.upload.target=portentac33 +# +# portentac33.upload.tool=dfu-util +# portentac33.upload.tool.default=dfu-util +# portentac33.upload.protocol= +# portentac33.upload.transport= +# portentac33.upload.vid=0x2341 +# portentac33.upload.pid=0x0368 +# portentac33.upload.interface=1 +# portentac33.upload.use_1200bps_touch=true +# portentac33.upload.wait_for_upload_port=false +# portentac33.upload.native_usb=true +# portentac33.upload.dfuse=-Q -w +# +# portentac33.bootloader.tool=dfu-util +# portentac33.bootloader.tool.default=dfu-util +# portentac33.bootloader.file=zephyr-{build.variant}.bin +# portentac33.bootloader.interface=0 +# portentac33.bootloader.address=0x10000 +# portentac33.bootloader.dfuse=-Q +# +# ########################################################################################## +# +# opta.name=Arduino Opta +# opta.build.core=arduino +# opta.build.crossprefix=arm-zephyr-eabi- +# opta.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# opta.menu.debug.false=Standard +# opta.menu.debug.true=Debug +# opta.menu.debug.true.build.zsk_args.debug=-debug +# +# opta.menu.link_mode.dynamic=Dynamic +# opta.menu.link_mode.static=Static +# opta.menu.link_mode.static.build.link_mode=static +# opta.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# opta.build.zephyr_target=arduino_opta//m7 +# opta.build.zephyr_args= +# opta.build.zephyr_hals=hal_stm32 hal_infineon +# opta.build.artifact=zephyr_main +# opta.build.variant=arduino_opta_stm32h747xx_m7 +# +# opta.build.extra_flags= +# opta.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# opta.build.board=OPTA +# opta.vid.0=0x2341 +# opta.pid.0=0x0064 +# opta.upload_port.0.vid=0x2341 +# opta.upload_port.0.pid=0x0364 +# +# opta.upload.tool=dfu-util +# opta.upload.tool.default=dfu-util +# opta.upload.protocol= +# opta.upload.transport= +# opta.upload.vid=0x2341 +# opta.upload.pid=0x0364 +# opta.upload.interface=0 +# opta.upload.use_1200bps_touch=true +# opta.upload.wait_for_upload_port=true +# opta.upload.native_usb=true +# +# opta.bootloader.tool=dfu-util +# opta.bootloader.tool.default=dfu-util +# opta.bootloader.vid=0x2341 +# opta.bootloader.pid=0x0364 +# opta.bootloader.interface=0 +# opta.bootloader.file=zephyr-{build.variant}.bin +# opta.bootloader.address=0x08040000 +# +# opta.debug.tool=gdb +# opta.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg +# opta.debug.server.openocd.scripts.1={programmer.transport_script} +# opta.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg +# opta.debug.cortex-debug.custom.request=attach +# opta.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd +# +# ########################################################################################## +# +# nano_matter.name=Arduino Nano Matter +# nano_matter.build.core=arduino +# nano_matter.build.crossprefix=arm-zephyr-eabi- +# nano_matter.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# nano_matter.menu.link_mode.dynamic=Dynamic +# nano_matter.menu.link_mode.static=Static +# nano_matter.menu.link_mode.static.build.link_mode=static +# nano_matter.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# nano_matter.build.zephyr_target=arduino_nano_matter +# nano_matter.build.zephyr_args= +# nano_matter.build.zephyr_hals=hal_silabs +# nano_matter.build.artifact=zephyr_main +# nano_matter.build.variant=arduino_nano_matter_mgm240sd22vna +# +# nano_matter.build.extra_flags= +# nano_matter.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# nano_matter.build.board=ARDUINO_NANO_MATTER +# nano_matter.vid.0=0x2341 +# nano_matter.pid.0=0x0072 +# nano_matter.upload_port.0.vid=0x2341 +# nano_matter.upload_port.0.pid=0x0072 +# +# nano_matter.upload.tool=openocd +# nano_matter.upload.tool.default=openocd +# nano_matter.upload.config=-f target/efm32s2_g23.cfg +# nano_matter.upload.programmer=-f interface/cmsis-dap.cfg +# nano_matter.upload.protocol=SWD +# nano_matter.upload.setup_command= +# nano_matter.upload.use_1200bps_touch=false +# nano_matter.upload.wait_for_upload_port=false +# nano_matter.upload.native_usb=false +# +# nano_matter.bootloader.tool=openocd +# nano_matter.bootloader.tool.default=openocd +# nano_matter.bootloader.vid=0x2341 +# nano_matter.bootloader.pid=0x0072 +# nano_matter.bootloader.interface=0 +# nano_matter.bootloader.file=zephyr-{build.variant}.hex +# nano_matter.bootloader.target=arduino_nano_matter +# +# nano_matter.debug.server=openocd +# nano_matter.debug.server.openocd.scripts.0=interface/cmsis-dap.cfg +# nano_matter.debug.server.openocd.scripts.1=target/efm32s2_g23.cfg +# nano_matter.debug.cortex-debug.custom.postAttachCommands.0=monitor reset halt +# #nano_matter.debug.cortex-debug.custom.postAttachCommands.1=monitor reset_config srst_nogate +# #nano_matter.debug.cortex-debug.custom.postAttachCommands.2=monitor gdb_breakpoint_override hard +# nano_matter.debug.cortex-debug.custom.postAttachCommands.3=monitor gdb_sync +# nano_matter.debug.cortex-debug.custom.postAttachCommands.4=c +# nano_matter.debug.cortex-debug.custom.overrideRestartCommands.0=monitor reset halt +# nano_matter.debug.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync +# nano_matter.debug.cortex-debug.custom.overrideRestartCommands.2=c +# nano_matter.debug.cortex-debug.custom.request=attach +# +# ############################################################################################################## +# +# unoq.name=Arduino UNO Q +# unoq.build.core=arduino +# unoq.build.crossprefix=arm-zephyr-eabi- +# unoq.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ +# +# unoq.menu.link_mode.dynamic=Dynamic +# unoq.menu.link_mode.static=Static +# unoq.menu.link_mode.static.build.link_mode=static +# unoq.menu.link_mode.static.upload.extension=bin-zsk.bin +# +# unoq.menu.wait_linux_boot.yes=Wait for Linux +# unoq.menu.wait_linux_boot.no=Immediate +# unoq.menu.wait_linux_boot.no.build.boot_mode=immediate +# unoq.menu.wait_linux_boot.app=Wait for App +# unoq.menu.wait_linux_boot.app.build.boot_mode=app +# +# unoq.build.zephyr_target=arduino_uno_q +# unoq.build.zephyr_args= +# unoq.build.variant=arduino_uno_q_stm32u585xx +# unoq.build.artifact=zephyr_unoq +# unoq.build.subarch=zephyr +# +# unoq.openocd_cfg=flash_sketch.cfg +# unoq.build.extra_flags= +# unoq.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit +# unoq.build.board=UNO_Q +# unoq.build.zephyr_hals=hal_stm32 +# unoq.build.zephyr_toolchain=arm-zephyr-eabi +# unoq.vid.0=0x2341 +# unoq.pid.0=0x0078 +# unoq.upload_port.0.vid=0x2341 +# unoq.upload_port.0.pid=0x0078 +# unoq.upload.target=stm32u585zitxq +# +# unoq.upload.tool=remoteocd +# unoq.upload.tool.default=remoteocd +# unoq.upload.tool.network=remoteocd_network +# unoq.upload.protocol= +# unoq.upload.transport= +# unoq.upload.vid=0x2341 +# unoq.upload.pid=0x0078 +# unoq.upload.interface=0 +# unoq.upload.use_1200bps_touch=false +# unoq.upload.wait_for_upload_port=false +# unoq.upload.native_usb=true +# +# unoq.bootloader.tool=remoteocd +# unoq.bootloader.tool.default=remoteocd +# unoq.bootloader.file=zephyr-{build.variant}.elf +# unoq.bootloader.target=stm32u585zitxq +# +# ########################################################################################## + + +kit_pse84_ai.name=Infineon KIT-PSE84-AI (PSOC Edge E84) +kit_pse84_ai.build.core=arduino +kit_pse84_ai.build.crossprefix=arm-zephyr-eabi- +kit_pse84_ai.build.compiler_path={runtime.tools.arm-zephyr-eabi-1.0.1.path}/bin/ +kit_pse84_ai.menu.debug.false=Standard +kit_pse84_ai.menu.debug.true=Debug +kit_pse84_ai.menu.debug.true.build.zsk_args.debug=-debug +kit_pse84_ai.menu.link_mode.dynamic=Dynamic +kit_pse84_ai.menu.link_mode.static=Static +kit_pse84_ai.menu.link_mode.static.build.link_mode=static +kit_pse84_ai.menu.link_mode.static.upload.extension=bin-zsk.bin +kit_pse84_ai.build.zephyr_target=kit_pse84_ai/pse846gps2dbzc4a/m33 +kit_pse84_ai.build.zephyr_args= +kit_pse84_ai.build.zephyr_hals=hal_infineon +kit_pse84_ai.build.variant=kit_pse84_ai_pse846gps2dbzc4a_m33 +kit_pse84_ai.build.mcu=cortex-m33 +kit_pse84_ai.build.fpu=-mfpu=fpv5-sp-d16 +kit_pse84_ai.build.architecture=cortex-m33 +kit_pse84_ai.build.float-abi=-mfloat-abi=hard +kit_pse84_ai.compiler.zephyr.specs= +kit_pse84_ai.build.extra_flags= +kit_pse84_ai.build.specs= +kit_pse84_ai.build.link_command="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" "-L{build.variant.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {build.extra_flags} {build.extra_ldflags} {compiler.zephyr.common_ldflags} {compiler.ldflags} {object_files} -Wl,--start-group "{build.path}/{archive_file}" {compiler.zephyr.extra_ldflags} {compiler.libraries.ldflags} -Wl,--end-group {build.link_args.{build.link_mode}} +kit_pse84_ai.build.postbuild.cmd="{tools.openocd.path}/{tools.openocd.cmd}" exit +kit_pse84_ai.build.board=KIT_PSE84_AI +kit_pse84_ai.upload.address=0x60200000 +kit_pse84_ai.upload.target=pse84 +kit_pse84_ai.upload.tool=openocd +kit_pse84_ai.upload.tool.default=openocd +kit_pse84_ai.tools.openocd.path={runtime.tools.openocd.path} +kit_pse84_ai.tools.openocd.cmd=bin/openocd +kit_pse84_ai.tools.openocd.cmd.windows=bin/openocd.exe +kit_pse84_ai.programmer.default=cmsis-dap +kit_pse84_ai.tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "telnet_port disabled; init; reset init; halt; adapter speed 10000; flash write_image erase {{build.path}/{build.project_name}.{upload.extension}} {upload.address} bin; reset run; shutdown" +kit_pse84_ai.tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "telnet_port disabled; init; reset init; halt; adapter speed 10000; flash write_image erase {{build.path}/{build.project_name}.{upload.extension}} {upload.address} bin; reset run; shutdown" +kit_pse84_ai.tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "telnet_port disabled; init; reset init; halt; adapter speed 10000; program {{runtime.platform.path}/firmwares/zephyr-{build.variant}.hex}; reset run; shutdown" +kit_pse84_ai.tools.openocd.upload.pattern.windows=cmd /C cd /D "{build.path}" && "{path}/{cmd}" {upload.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "set sketch_file [list {build.project_name}.{upload.extension}]; telnet_port disabled; init; reset init; halt; adapter speed 10000; flash write_image erase $sketch_file {upload.address} bin; reset run; shutdown" +kit_pse84_ai.tools.openocd.program.pattern.windows=cmd /C cd /D "{build.path}" && "{path}/{cmd}" {program.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "set sketch_file [list {build.project_name}.{upload.extension}]; telnet_port disabled; init; reset init; halt; adapter speed 10000; flash write_image erase $sketch_file {upload.address} bin; reset run; shutdown" +kit_pse84_ai.upload.protocol= +kit_pse84_ai.upload.transport= +kit_pse84_ai.upload.interface=0 +kit_pse84_ai.upload.use_1200bps_touch=false +kit_pse84_ai.upload.wait_for_upload_port=false +kit_pse84_ai.upload.native_usb=false +kit_pse84_ai.upload.maximum_size=1047552 +kit_pse84_ai.upload.maximum_data_size=135168 +kit_pse84_ai.bootloader.tool=openocd +kit_pse84_ai.bootloader.tool.default=openocd +kit_pse84_ai.tools.openocd.bootloader.pattern.windows=cmd /C cd /D "{runtime.platform.path}/firmwares" && "{path}/{cmd}" {bootloader.verbose} -s "{path}/scripts/" -s "{path}/share/openocd/scripts/" -s "{runtime.platform.path}/variants/{build.variant}/" -f "{runtime.platform.path}/variants/{build.variant}/openocd.cfg" -c "set bootloader_file [list zephyr-{build.variant}.hex]; telnet_port disabled; init; reset init; halt; adapter speed 10000; program $bootloader_file; reset run; shutdown" +kit_pse84_ai.bootloader.target=pse84 ########################################################################################## diff --git a/cores/arduino/llext_wrappers.c b/cores/arduino/llext_wrappers.c index 97b502827..afba3d196 100644 --- a/cores/arduino/llext_wrappers.c +++ b/cores/arduino/llext_wrappers.c @@ -62,6 +62,7 @@ __real_##name(a); \ } +#ifdef CONFIG_ARM /* * Naked trampoline for compiler ABI helpers (__aeabi_*). * @@ -79,6 +80,7 @@ "movt r12, #:upper16:__real_" #name "\n\t" \ "bx r12"); \ } +#endif /* string.h */ W3(void *, memcpy, void *, const void *, size_t) @@ -162,7 +164,10 @@ W1(float, sinf, float) W1(float, sqrtf, float) W1(float, tanf, float) -/* compiler ABI helpers: need to preserve all RTABI argument registers */ +#ifdef CONFIG_ARM +/* ARM compiler ABI helpers: need to preserve all RTABI argument registers */ +/* thread pointer access */ +VN(__aeabi_read_tp) /* double arithmetic */ VN(__aeabi_dadd) VN(__aeabi_dsub) @@ -198,6 +203,7 @@ VN(__aeabi_idivmod) VN(__aeabi_uidivmod) VN(__aeabi_ldivmod) VN(__aeabi_uldivmod) +#endif /* stdio.h */ W1(int, puts, const char *) diff --git a/cores/arduino/zephyrClockInit.hpp b/cores/arduino/zephyrClockInit.hpp new file mode 100644 index 000000000..108daf93d --- /dev/null +++ b/cores/arduino/zephyrClockInit.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) Arduino s.r.l. and/or its affiliated companies + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include + +namespace zephyr { +namespace arduino { + +inline int init_pwm_ref_clock(const struct device *clock_dev, const struct pwm_dt_spec &clock_pwm, + size_t state_pin_idx = PINCTRL_STATE_DEFAULT) { + + int ret = init_dev_apply_channel_pinctrl(clock_pwm.dev, state_pin_idx); + if (ret < 0) { + return ret; + } + + if (clock_control_get_status(clock_dev, (clock_control_subsys_t)0) != CLOCK_CONTROL_STATUS_ON) { + return clock_control_on(clock_dev, (clock_control_subsys_t)0); + } + + return 0; +} + +} // namespace arduino +} // namespace zephyr diff --git a/cores/arduino/zephyrPinctrl.cpp b/cores/arduino/zephyrPinctrl.cpp index 4c8f16146..31a42880a 100644 --- a/cores/arduino/zephyrPinctrl.cpp +++ b/cores/arduino/zephyrPinctrl.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace zephyr { @@ -66,6 +67,48 @@ static const struct pinctrl_dev_config *get_known_pcfg(const struct device *dev) return nullptr; } +static int init_device_with_dependencies(const struct device *dev) { +#if defined(CONFIG_DEVICE_DEPS) + // Recurse on all dependencies + size_t handle_count = 0; + const device_handle_t *handles = device_required_handles_get(dev, &handle_count); + if (handles != nullptr) { + for (size_t i = 0; i < handle_count; i++) { + const struct device *dep_dev = device_from_handle(handles[i]); + if (dep_dev == nullptr) { + continue; + } + int ret = init_device_with_dependencies(dep_dev); + if (ret < 0) { + return ret; + } + } + } +#endif + + // Initialize the device + if (!device_is_ready(dev)) { + int ret = device_init(dev); + if (ret != 0 && ret != -EALREADY) { + return ret; + } + } + + /* + * If the device is without pinctrl or pinctrl_apply_state returns -ENOENT because no pins where + * defined in PINCTRL_STATE_DEFAULT this should not be treated as an error, so just continue. + */ + const struct pinctrl_dev_config *pcfg = get_known_pcfg(dev); + if (pcfg != nullptr) { + int ret = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0 && ret != -ENOENT) { + return ret; + } + } + + return 0; +} + /** * @brief Initialize the peripheral and acquire a single pin to ARDUINO state. * @@ -94,8 +137,9 @@ int init_dev_apply_channel_pinctrl(const struct device *dev, size_t state_pin_id const struct pinctrl_dev_config *pcfg = get_known_pcfg(dev); if (pcfg == nullptr) { - /* Device not in DT mapping - add to pinctrl_map if needed */ - return -ENOTSUP; + /* Device not in DT mapping, add to pinctrl_map if needed. Don't return an error because + * the device has been initialized successfully. */ + return 0; } int err = pinctrl_lookup_state(pcfg, PINCTRL_STATE_ARDUINO, &state); @@ -123,29 +167,17 @@ int init_dev_apply_channel_pinctrl(const struct device *dev, size_t state_pin_id /** * @brief Optimize peripheral transitions applying pinctrl state PINCTRL_STATE_DEFAULT. + * Before initializing the device itself, also ensure its dependencies are initialized and apply the + * pinctrl state to them as well if required. * * @param dev Target peripheral device to acquire pin for */ int init_dev_apply_pinctrl(const struct device *dev) { - if (dev == nullptr) { return -EINVAL; } - if (!device_is_ready(dev)) { - int ret = device_init(dev); - if (ret != 0 && ret != -EALREADY) { - return ret; - } - } - - const struct pinctrl_dev_config *pcfg = get_known_pcfg(dev); - if (pcfg == nullptr) { - /* Device not in DT mapping - add to pinctrl_map if needed */ - return -ENOTSUP; - } - - return pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); + return init_device_with_dependencies(dev); } } // namespace arduino diff --git a/documentation/dynamic_pinmux.md b/documentation/dynamic_pinmux.md index 545aa6ca5..350d80ec8 100644 --- a/documentation/dynamic_pinmux.md +++ b/documentation/dynamic_pinmux.md @@ -37,7 +37,7 @@ Typical mapping: - sleep: optional low-power/disconnected state (not used) - arduino: custom channel list used for per-pin restore (mainly ADC/PWM/DAC) -## Runtime Infrastructure in zephyrCommon.cpp +## Runtime Infrastructure in zephyrPinctrl.cpp The core builds a runtime map between devices and pinctrl configs. @@ -49,13 +49,18 @@ The map is then used by APIs: - init_dev_apply_pinctrl(dev) - init_dev_apply_channel_pinctrl(dev, state_pin_idx) -If a device has no known pinctrl config in the map, APIs return -ENOTSUP. +If a device has no known pinctrl config in the map: + +- init_dev_apply_channel_pinctrl(...) returns -ENOTSUP, +- init_dev_apply_pinctrl(...) still initializes the device/dependencies but skips pinctrl apply for entries + not present in the map. ## Dynamic Pinmux APIs and Runtime Flow ### init_dev_apply_pinctrl(dev) -Purpose: apply the whole pinctrl PINCTRL_STATE_DEFAULT state to a device. +Purpose: initialize the target device and its dependencies, then apply the whole pinctrl +PINCTRL_STATE_DEFAULT state where pinctrl configuration is known. Used for full peripheral remux, to restore the default state. @@ -63,8 +68,10 @@ SPI (SPI.begin), I2C (Wire.begin) and UART (ZephyrSerial::begin) calls init_dev_ Behavior details: -- initializes the device on first use if needed, -- applies PINCTRL_STATE_DEFAULT from the device pinctrl config. +- recursively initializes required dependencies first, +- initializes each device on first use if needed, +- applies PINCTRL_STATE_DEFAULT from known device pinctrl configs, +- treats -ENOENT from pinctrl_apply_state as non-fatal (for empty/default-less states). ### init_dev_apply_channel_pinctrl(dev, state_pin_idx) @@ -153,8 +160,11 @@ Use deferred init and provide usual default/sleep states. Same pattern applies to i2cX and uartX. -Recommendation: keep the UART selected as `zephyr,log-uart` out of deferred-init. -If it is marked as deferred-init, early error logs generated during system startup or sketch load may not be visible. +Note: the runtime map explicitly includes the node selected as `zephyr,console` even when it is +not deferred-init. + +Recommendation: keep the UART used for early logs available from boot; if it is deferred-init, +early error logs generated during system startup or sketch load may not be visible. ### For channel-based ADC/PWM/DAC nodes diff --git a/extra/apply_zephyr_patches.sh b/extra/apply_zephyr_patches.sh new file mode 100644 index 000000000..12d1c5b43 --- /dev/null +++ b/extra/apply_zephyr_patches.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Copyright (c) Arduino s.r.l. and/or its affiliated companies +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PATCH_DIR="$SCRIPT_DIR/patches/zephyr" + +if [ ! -d "$PATCH_DIR" ]; then + # No patch set is configured. + exit 0 +fi + +if ! command -v west >/dev/null 2>&1; then + echo "[ERROR] west is not available; cannot resolve Zephyr workspace" + exit 1 +fi + +ZEPHYR_BASE="$(west list -f '{abspath}' zephyr 2>/dev/null || true)" +if [ -z "$ZEPHYR_BASE" ]; then + echo "[ERROR] Unable to locate Zephyr module with 'west list zephyr'" + exit 1 +fi + +if [ ! -d "$ZEPHYR_BASE/.git" ]; then + echo "[ERROR] Zephyr repository not found at '$ZEPHYR_BASE'" + exit 1 +fi + +applied_any=false +for patch in "$PATCH_DIR"/*.patch; do + [ -e "$patch" ] || continue + patch_name="$(basename "$patch")" + + if git -C "$ZEPHYR_BASE" apply --check "$patch" >/dev/null 2>&1; then + echo "[INFO] Applying Zephyr patch: $patch_name" + git -C "$ZEPHYR_BASE" apply "$patch" + applied_any=true + elif git -C "$ZEPHYR_BASE" apply --reverse --check "$patch" >/dev/null 2>&1; then + echo "[INFO] Zephyr patch already applied: $patch_name" + else + echo "[ERROR] Cannot apply Zephyr patch cleanly: $patch_name" + echo "[ERROR] Patch file: $patch" + exit 1 + fi +done + +if [ "$applied_any" = true ]; then + echo "[INFO] Zephyr patch set applied" +fi diff --git a/extra/artifacts/_common.json b/extra/artifacts/_common.json index 952eaa3a4..f8fc37d8b 100644 --- a/extra/artifacts/_common.json +++ b/extra/artifacts/_common.json @@ -16,7 +16,7 @@ { "packager": "zephyr", "name": "arm-zephyr-eabi", - "version": "0.16.8" + "version": "1.0.1" }, { "packager": "arduino", @@ -31,7 +31,7 @@ { "packager": "arduino", "name": "zephyr-sketch-tool", - "version": "0.3.0" + "version": "0.4.0" }, { "packager": "arduino", @@ -62,6 +62,11 @@ "packager": "arduino", "name": "zephyr-check-size", "version": "0.1.0" + }, + { + "packager": "arduino", + "name": "bin2uf2", + "version": "0.1.0" } ] } diff --git a/extra/artifacts/zephyr_unoq.json b/extra/artifacts/zephyr_unoq.json index ae4e79da0..53a3537c5 100644 --- a/extra/artifacts/zephyr_unoq.json +++ b/extra/artifacts/zephyr_unoq.json @@ -3,8 +3,8 @@ "architecture": "zephyr", "category": "Arduino", "libraryDependencies": [ - { "name":"Arduino_RouterBridge", "version":"0.4.1" }, - { "name":"Arduino_RPClite", "version":"0.2.1" }, + { "name":"Arduino_RouterBridge", "version":"0.4.2" }, + { "name":"Arduino_RPClite", "version":"0.3.0" }, { "name":"MsgPack", "version":"0.4.2" }, { "name":"DebugLog", "version":"0.8.4" }, { "name":"ArxTypeTraits", "version":"0.3.2" }, diff --git a/extra/bootstrap.sh b/extra/bootstrap.sh index ef3d48929..c60e6dc6d 100755 --- a/extra/bootstrap.sh +++ b/extra/bootstrap.sh @@ -35,12 +35,13 @@ log_msg "group" "Initializing Zephyr workspace and modules: $HAL_FILTER" west init -l . west config manifest.project-filter -- "$HAL_FILTER" west update "$@" +bash ./extra/apply_zephyr_patches.sh west zephyr-export pip install -r ../zephyr/scripts/requirements-base.txt log_msg "endgroup" -log_msg "group" "Installing Zephyr SDK 0.16.8" -west sdk install --version 0.16.8 -t arm-zephyr-eabi +log_msg "group" "Installing Zephyr SDK 1.0.1" +west sdk install --version 1.0.1 -t arm-zephyr-eabi log_msg "endgroup" log_msg "group" "Fetching blobs for: $NEEDED_HALS" diff --git a/extra/build.sh b/extra/build.sh index e490e1c3f..58cdc7b8f 100755 --- a/extra/build.sh +++ b/extra/build.sh @@ -9,6 +9,10 @@ source venv/bin/activate ZEPHYR_BASE=$(west topdir)/zephyr +# Ensure Zephyr patch set is applied even for incremental builds where +# bootstrap.sh was not re-run. +bash ./extra/apply_zephyr_patches.sh + if [ x$ZEPHYR_SDK_INSTALL_DIR == x"" ]; then SDK_PATH=$(west sdk list | grep path | tail -n 1 | cut -d ':' -f 2 | tr -d ' ') if [ x$SDK_PATH == x ]; then @@ -45,18 +49,25 @@ fi chosen_board=$(extra/get_board_details.sh | jq -cr ".[] | select(.board == \"$1\") // empty") if ! [ -z "$chosen_board" ]; then # found, use the target and args from there + board=$(jq -cr '.board' <<< "$chosen_board") target=$(jq -cr '.target' <<< "$chosen_board") args=$(jq -cr '.args' <<< "$chosen_board") + + # Check for debug flag and append + if [ x$2 == x"--debug" ]; then + args="$args -- -DEXTRA_CONF_FILE=../extra/debug.conf" + fi else # expect Zephyr-compatible target and args target=$1 shift args="$*" -fi - -# Check for debug flag and append -if [ x$2 == x"--debug" ]; then - args="$args -- -DEXTRA_CONF_FILE=../extra/debug.conf" + chosen_board=$(extra/get_board_details.sh | jq -cr ".[] | select(.target == \"$target\") // empty") + if [ ! -z "$chosen_board" ]; then + board=$(jq -cr '.board' <<< "$chosen_board") + else + log_msg warning "No board for '$target' defined in 'boards.txt'. A proper definition is required to use the core." + fi fi echo @@ -93,15 +104,19 @@ perl -i -pe "s/${c_comment}//gs unless /${line_preproc_ok}/ || (/${line_comment_ for ext in elf bin hex; do rm -f firmwares/zephyr-$variant.$ext - if [ -f ${BUILD_DIR}/zephyr/zephyr.$ext ]; then - cp ${BUILD_DIR}/zephyr/zephyr.$ext firmwares/zephyr-$variant.$ext - fi + if [ "$ext" = "hex" ] && [ -f ${BUILD_DIR}/zephyr/zephyr.signed.hex ]; then + # Prefer signed HEX when available (for PSE84) for bootloader programming. + cp ${BUILD_DIR}/zephyr/zephyr.signed.hex firmwares/zephyr-$variant.hex + elif [ -f ${BUILD_DIR}/zephyr/zephyr.$ext ]; then + cp ${BUILD_DIR}/zephyr/zephyr.$ext firmwares/zephyr-$variant.$ext + fi done cp ${BUILD_DIR}/zephyr/zephyr.dts firmwares/zephyr-$variant.dts cp ${BUILD_DIR}/zephyr/.config firmwares/zephyr-$variant.config # Generate the provides.ld file for linked builds echo "Generating exported symbol scripts" +extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -T > ${VARIANT_DIR}/tls-syms.S extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -L > ${VARIANT_DIR}/syms-dynamic.ld extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -LF \ "+kheap_llext_heap" \ @@ -116,3 +131,63 @@ extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -LF \ "random=__wrap_random" > ${VARIANT_DIR}/syms-static.ld cmake -P extra/gen_arduino_files.cmake $variant + +get_value_from_text_file() { + local file=$1 + local field=$2 + + grep -E "\<${field//./\\./}\>\s*=" $file | tail -n 1 | cut -d '=' -f 2- | tr -d '); ' +} + +update_local_field() { + local field=$1 + local value=$2 + local full_field_name="${board}.${field}" + local match_regexp="^${full_field_name//./\\.}" # escape dots, match start of line + + if grep -qE "${match_regexp}" boards.local.txt; then + sed -i -e "s/${match_regexp}=.*/${full_field_name}=${value}/" boards.local.txt + else + echo "${full_field_name}=${value}" >> boards.local.txt + fi +} + +# update properties on boards.local.txt from the generated files +if [ ! -z "$board" ]; then + + if [ ! -f boards.local.txt ] ; then + cat << EOF > boards.local.txt +######################################################################################### +# +# AUTO GENERATED FILE - DO NOT EDIT +# This file is manipulated by extra/build.sh; manual changes may be overwritten. +# +######################################################################################### + +EOF + fi + + # sketch load address: start of sketch partition, hex (exact) + CODE_ADDR=$(get_value_from_text_file variants/${variant}/syms-static.ld '_sketch_start') + update_local_field "upload.address" $CODE_ADDR + + # maximum sketch size: size of sketch partition, decimal (exact limit) + CODE_SIZE=$(( $(get_value_from_text_file variants/${variant}/syms-static.ld '_sketch_max_size') )) + update_local_field "upload.maximum_size" $CODE_SIZE + + # maximum data size: configured LLEXT heap size, decimal (larger bound, real limit is smaller) + DATA_SIZE=$(( 1024*$(get_value_from_text_file firmwares/zephyr-${variant}.config 'CONFIG_LLEXT_HEAP_SIZE') )) + update_local_field "upload.maximum_data_size" $DATA_SIZE + + # machine fields + MACH_CPU=$(get_value_from_text_file variants/${variant}/machine_flags.txt 'mcpu') + [ -z "$MACH_CPU" ] && MACH_CPU=$(get_value_from_text_file variants/${variant}/machine_flags.txt 'march') + [ -z "$MACH_CPU" ] || update_local_field "build.architecture" $MACH_CPU + [ -z "$MACH_CPU" ] || update_local_field "build.mcu" $MACH_CPU + + MACH_FPU=$(get_value_from_text_file variants/${variant}/machine_flags.txt 'mfpu') + [ -z "$MACH_FPU" ] || update_local_field "build.fpu" $MACH_FPU + + MACH_FABI=$(get_value_from_text_file variants/${variant}/machine_flags.txt 'mfloat-abi') + [ -z "$MACH_FABI" ] || update_local_field "build.float-abi" $MACH_FABI +fi diff --git a/extra/build_all.sh b/extra/build_all.sh index edd9cbb56..38c4174e1 100755 --- a/extra/build_all.sh +++ b/extra/build_all.sh @@ -43,7 +43,7 @@ while read -r item; do echo "::group::=== ${subarch}:${board} (${variant}) ===" fi - ./extra/build.sh "$target" $args + ./extra/build.sh $board result=$? final_result=$((final_result | result)) diff --git a/extra/ci_collect_data.py b/extra/ci_collect_data.py new file mode 100755 index 000000000..9d52799fb --- /dev/null +++ b/extra/ci_collect_data.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 + +# Copyright (c) Arduino s.r.l. and/or its affiliated companies +# SPDX-License-Identifier: Apache-2.0 + +# Script to analyze CI build and test logs and collect results into a JSON file. +# +# The script reads build artifacts and test reports generated during a GitHub +# Actions CI run for Arduino Zephyr cores. It aggregates results by board, +# artifact, and sketch, and serializes all data to a JSON file for further +# processing by ci_generate_report.py. +# +# This script expects the following inputs: +# +# - Environment variables: +# - ALL_BOARD_DATA: JSON array of all board metadata, generated by get_board_details.sh +# - WORKFLOW_JOBS: JSON array of job names and URLs, generated by workflow YAML +# - GITHUB_REPOSITORY, GITHUB_RUN_ID: workflow context variables for writing links +# +# - Files in the current directory: +# - zephyr-.config: Kconfig settings, generated at loader build time +# - zephyr-.warnings: Loader compilation warnings +# - zephyr-.meminfo: Loader memory usage report +# - arduino---link_mode=.json: Compilation test report files +# - variants//known_example_issues.txt: Expected errors for that variant +# +# This script produces one output file: +# +# - : JSON file with all collected data, to be consumed by ci_generate_report.py +# +# Usage: ci_collect_data.py [] +# If no argument is given, output is written to /dev/stdout. + +from collections import defaultdict +import json +import os +import re +import sys + +import ci_shared +from ci_shared import ( + TestStatus, SKIP, PASS, WARNING, EXPECTED_ERROR, INVALID_EXCEPTION, ERROR, FAILURE, + LoaderEntry, TestEntry, TestGroup, +) + +# Global Data Structures +# ---------------------- + +# Loader build results, one per board +BOARD_LOADERS = {} # { board: LoaderEntry() } + +ALL_TESTS = [] # [ TestEntry() ] + +# Test results grouped by artifact, board, and artifact/sketch +# (grouping sketch results across different artifacts is really confusing) +ARTIFACT_TESTS = defaultdict(TestGroup) # { artifact: TestGroup() } +BOARD_TESTS = defaultdict(TestGroup) # { board: TestGroup() } +SKETCH_TESTS = defaultdict(lambda: defaultdict(TestGroup)) # { artifact: { sketch: TestGroup() } } + +def log_test(artifact, board, sketch, link_mode, exceptions, status, issues, job_link=None): + """ + Logs individual test results into the global test tracking structures. + """ + + # Ensure issues is a list + if isinstance(issues, str): + issues = [ issues ] + + # Create the test entry + excepted = any(pattern.match(sketch) for pattern in exceptions) + status = EXPECTED_ERROR if excepted and status == ERROR else status + test_entry = TestEntry(artifact, board, sketch, link_mode, excepted, status, issues, job_link) + + # Track in global structures + ARTIFACT_TESTS[artifact].track(test_entry) + BOARD_TESTS[board].track(test_entry) + SKETCH_TESTS[artifact][sketch].track(test_entry) + ALL_TESTS.append(test_entry) + +# --------------------------------------------------------------------------- +# Main Logic +# --------------------------------------------------------------------------- + +# Environment Variable Checks +ALL_BOARD_DATA_STR = os.environ.get('ALL_BOARD_DATA') +WORKFLOW_JOBS_STR = os.environ.get('WORKFLOW_JOBS') +GITHUB_REPOSITORY = os.environ.get('GITHUB_REPOSITORY') +GITHUB_RUN_ID = os.environ.get('GITHUB_RUN_ID') +JOB_LINK_STEM = f"https://github.com/{GITHUB_REPOSITORY}/actions/runs/{GITHUB_RUN_ID}" + +if not ALL_BOARD_DATA_STR or not GITHUB_REPOSITORY or not GITHUB_RUN_ID: + print("Not in a Github CI run, cannot proceed.") + sys.exit(0) + +if not len(sys.argv) in (1, 2): + print("Usage: ci_collect_data.py []") + sys.exit(1) + +json_file = sys.argv[1] if len(sys.argv) == 2 else "/dev/stdout" + +# Load board data and job URLs from environment variables +ALL_BOARD_DATA = json.loads(ALL_BOARD_DATA_STR) +ALL_BOARD_DATA = { b['board']: b for b in ALL_BOARD_DATA } + +JOB_URLS = json.loads(WORKFLOW_JOBS_STR) +JOB_URLS = { j['name']: j['url'] for j in JOB_URLS } + +REGIONS_BY_SOC = defaultdict(set) # { soc: set(regions) } + +# Import and process data for each board +for board_data in ALL_BOARD_DATA.values(): + # Extract common fields from board data + artifact = board_data['artifact'] + board = board_data['board'] + variant = board_data['variant'] + subarch = board_data['subarch'] + + # Get job link for this build + # NOTE: This must match the name used in the workflow YAML + job_link = JOB_URLS.get(f"Build for {board}") + if job_link: + job_link += "#step:5:1" + + # Read loader build data + BOARD_LOADERS[board] = LoaderEntry(artifact, board, variant, job_link) + if BOARD_LOADERS[board].status == FAILURE: + log_test(artifact, board, 'CI test', '', [], FAILURE, "Core data could not be read.") + continue + + # Get SoC-specific info from loader config + soc = BOARD_LOADERS[board].config['CONFIG_SOC'] + board_data['soc'] = soc + REGIONS_BY_SOC[soc].update(BOARD_LOADERS[board].meminfo.keys()) + + # Get list of expected errors for this board + exceptions = [] + if os.path.exists(f"variants/{variant}/known_example_issues.txt"): + with open(f"variants/{variant}/known_example_issues.txt", 'r') as f: + for line in f: + sketch_pattern = line.split('#')[0].strip() + if sketch_pattern: + exceptions.append(re.compile(f"^(ArduinoCore-zephyr/)?{sketch_pattern}")) + + # Get raw data from report files for both static and dynamic linking modes + for link_mode in ("static", "dynamic"): + # Get job link for this test + # NOTE: This must match the name used in the workflow YAML + job_link = JOB_URLS.get(f"Test {board}:{link_mode}") + if job_link: + job_link += "#step:6:1" + + # Extract data from the report file + report_file = f"arduino-{subarch}-{board}-link_mode={link_mode}.json" + if not os.path.exists(report_file): + log_test(artifact, board, 'CI test', '', [], FAILURE, f"Report file for {link_mode} not found.", job_link) + continue # Skip to the next board + + try: + with open(report_file, 'r') as f: + report_data = json.load(f) + except Exception as e: + log_test(artifact, board, 'CI test', '', [], FAILURE, f"Error reading {link_mode} report file: {e}", job_link) + continue # Skip to the next board + + reports = report_data.get('boards', [{}])[0].get('sketches', []) + if not reports: + log_test(artifact, board, 'CI test', '', [], FAILURE, "Test report for {link_mode} is empty, check CI log.", job_link) + continue # Skip to the next board + + # Iterate through individual sketch reports + for report in reports: + sketch = report.get('name', 'unknown_sketch') + success = report.get('compilation_success', False) + issues = report.get('issues', []) + + # Replace long absolute paths with '...' for brevity. + sketch_issues = [ re.sub(r'(/.+?)((/[^/]+){3}):', r'...\2:', issue) for issue in issues ] + + if not success: + status = ERROR + elif len(sketch_issues): # Implies warnings/non-critical issues + status = WARNING + else: + status = PASS + + # Log the test result to all data structures + log_test(artifact, board, sketch, link_mode, exceptions, status, sketch_issues, job_link) + +ARTIFACTS = sorted(ARTIFACT_TESTS.keys()) + +ci_run_status = max(res.status for res in ARTIFACT_TESTS.values()) +ci_run_passed = ci_run_status.passed + +# Serialize all data to JSON +output = { + 'job_link_stem': JOB_LINK_STEM, + 'artifacts': ARTIFACTS, + 'ci_run_passed': ci_run_passed, + 'all_board_data': ALL_BOARD_DATA, + 'regions_by_soc': {soc: list(regions) for soc, regions in REGIONS_BY_SOC.items()}, + 'board_loaders': {board: loader.to_dict() for board, loader in BOARD_LOADERS.items()}, + 'all_tests': [t.to_dict() for t in ALL_TESTS], +} + +with open(json_file, 'w') as f: + json.dump(output, f) diff --git a/extra/ci_dependabot_config.sh b/extra/ci_dependabot_config.sh new file mode 100755 index 000000000..6df6b73df --- /dev/null +++ b/extra/ci_dependabot_config.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Copyright (c) Arduino s.r.l. and/or its affiliated companies +# SPDX-License-Identifier: Apache-2.0 + +BASE_DIR=$(readlink -f $(dirname $0)/..) +OUTPUT_FILE=${1:-$BASE_DIR/.github/dependabot.yml} + +dependabot_rule_for() { + local ecosystem=$1 + local tool=$(basename $2) + cat << EOF + + - package-ecosystem: "$ecosystem" + directory: "/tools/$tool" + schedule: + interval: "weekly" +EOF +} + +cat > $OUTPUT_FILE << EOF +# Autogenerated by extra/ci_dependabot_config.sh - DO NOT EDIT" + +version: 2 +updates: +EOF +for tool in $(find $BASE_DIR/tools -name "go.mod" -exec dirname '{}' \; | sort); do + dependabot_rule_for gomod $tool +done >> $OUTPUT_FILE diff --git a/extra/ci_inspect_logs.py b/extra/ci_generate_report.py similarity index 52% rename from extra/ci_inspect_logs.py rename to extra/ci_generate_report.py index 1f4ed8464..0ba7f1a14 100755 --- a/extra/ci_inspect_logs.py +++ b/extra/ci_generate_report.py @@ -3,232 +3,57 @@ # Copyright (c) Arduino s.r.l. and/or its affiliated companies # SPDX-License-Identifier: Apache-2.0 -# Script to analyze CI build and test logs, summarize results, -# and generate a markdown report. +# Script to generate CI markdown reports from a JSON data file. # -# The script reads build artifacts and test reports generated during a GitHub -# Actions CI run for Arduino Zephyr cores. It aggregates results by board, -# artifact, and sketch, reports failures and warnings, and produces a -# comprehensive Github-friendly Markdown report. -# -# This scripts expects the following inputs: -# -# - Environment variables: -# - ALL_BOARD_DATA: JSON array of all board metadata, generated by get_board_details.sh -# - WORKFLOW_JOBS: JSON array of job names and URLs, generated by workflow YAML -# - GITHUB_REPOSITORY, GITHUB_RUN_ID: workflow context variables for writing links -# -# - Files in the current directory: -# - zephyr-.config: Kconfig settings, generated at loader build time -# - zephyr-.warnings: Loader compilation warnings -# - zephyr-.meminfo: Loader memory usage report -# - arduino---link_mode=.json: Compilation test report files -# - variants//known_example_issues.txt: Expected errors for that variant -# -# This script produces three output files: -# -# - : simple text file with "PASSED" in it if all tests passed, or an error message +# This script reads the JSON file produced by ci_collect_data.py and generates +# the same three output files as the original ci_inspect_logs.py script: +# - : simple text file with "PASSED" or an error message # - : markdown summary report with overall results # - : full markdown report with detailed logs # +# Usage: ci_generate_report.py [ ] +# If output files are not specified, summary and full report are written to /dev/stdout +# and results to /dev/null. from collections import defaultdict import json -import os -import re import sys -# Constants for test statuses, in increasing order of severity -SKIP = -1 # Test was not performed -PASS = 0 # (PASS) Compiled successfully -WARNING = 1 # (PASS) Compiled with warnings -EXPECTED_ERROR = 2 # (PASS*) Compilation failed with expected errors -ERROR = 3 # (FAIL) Compilation failed with errors -FAILURE = 4 # Test run failed to complete - -# Status legends and icons, indexed by status constant -TEST_LEGEND = [ - "Test passed successfully, with no warnings or errors.", - "Test completed with some warnings; no errors detected.", - "Test completed with errors, but all are known/expected.", - "Test completed with unexpected errors.", - "Test run failed to complete.", - "Test was skipped." # -1 -] - -TEST_STATUS = [ - ":green_circle:", - ":yellow_circle:", - ":no_entry_sign:", - ":red_circle:", - ":fire:", - ":new_moon:" # -1 -] - -BOARD_STATUS = [ - ":white_check_mark:", - ":white_check_mark:*", - ":heavy_check_mark:*", - ":x:", - ":fire:", - ":new_moon:" # -1 -] - -# Loader build status data structure, one per loader -class LoaderEntry: - def __init__(self, artifact, board, variant, job_link): - self.artifact = artifact - self.board = board - self.variant = variant - self.job_link = job_link - - self.warnings = self.read_warnings() # list of warning messages - self.config = self.read_config() # set of Kconfig settings - self.meminfo = self.read_meminfo() # memory usage report - - if not (self.config and self.meminfo): - self.status = FAILURE - elif self.warnings: - self.status = WARNING - else: - self.status = PASS - - def read_config(self): - """ - Extract Kconfig settings from the loader config file. - Format: SYMBOL=VALUE per line or # comment lines for disabled symbols. - """ - report_file = f"zephyr-{self.variant}.config" - try: - with open(report_file, 'r') as f: - configs = {} - for line in f: - if line.startswith('#') or '=' not in line: - continue - sym, val = line.strip().split('=', 1) - if val.startswith('"'): - configs[sym] = val.strip('"') - elif val=='y': - configs[sym] = 1 - else: - configs[sym] = eval(val) - return configs - except Exception as e: - return {} - - def read_warnings(self): - """ - Read loader compilation warnings from the warnings file. - File may be missing in case of no warnings. - Format: one line per warning message. - """ - report_file = f"zephyr-{self.variant}.warnings" - try: - with open(report_file, 'r') as f: - return [ line.strip() for line in f if line.strip() ] - except Exception as e: - return [] - - def read_meminfo(self): - """ - Extract memory usage data from the meminfo file. - Input format: JSON array of region_name, used_bytes, total_bytes tuples - Output format: dict of { region_name: [ used_bytes, total_bytes ] } - """ - report_file = f"zephyr-{self.variant}.meminfo" - try: - with open(report_file, 'r') as f: - report_data = json.load(f) - meminfo = { region.replace(':',''): [used, total] for region, used, total in report_data } - meminfo.pop('IDT_LIST', None) - return meminfo - except Exception as e: - return {} - -# Single test data structure, one per compilation test -class TestEntry: - def __init__(self, artifact, board, sketch, link_mode, excepted, status, issues, job_link): - self.artifact = artifact - self.board = board - self.sketch = sketch - self.link_mode = link_mode - self.excepted = excepted - self.status = EXPECTED_ERROR if excepted and status == ERROR else status - self.issues = issues - self.job_link = job_link - self.invalid_exception = excepted and status in (PASS, WARNING) - - # Extract group and name from sketch path: - # (1.................) (2....) (3................) (4.) - match = re.search(r'(libraries|examples)/([^/]+)/(examples/|extras/)?(.*)', sketch) - if match: - self.group = match.group(2) - self.name = match.group(4) - else: - self.group = "" - self.name = sketch - -# Summary data structure, used to group test results -class TestGroup: - def __init__(self): - # Sets to track unique board, sketch and (group,name) tuples - self.boards = set() - self.sketches = set() - self.group_names = set() - # Counts of test results by status - self.counts = { status : 0 for status in [PASS, WARNING, EXPECTED_ERROR, ERROR, FAILURE] } - # Overall status of the group - self.status = SKIP - # List of individual TestEntry objects by feature - self.tests = [] - self.tests_with_issues = [] - self.tests_with_invalid_exceptions = [] - - def track(self, test_entry): - """ - Update this group with a new test entry - """ - self.tests.append(test_entry) - if test_entry.issues: - self.tests_with_issues.append(test_entry) - if test_entry.invalid_exception: - self.tests_with_invalid_exceptions.append(test_entry) - - self.counts[test_entry.status] += 1 - self.status = max(self.status, test_entry.status) - self.boards.add(test_entry.board) - self.sketches.add(test_entry.sketch) - self.group_names.add((test_entry.group, test_entry.name)) - -# Global Data Structures -# ---------------------- - -# Loader build results, one per board -BOARD_LOADERS = {} # { board: LoaderEntry() } - -# Test results grouped by artifact, board, and artifact/sketch -# (grouping sketch results across different artifacts is really confusing) -ARTIFACT_TESTS = defaultdict(TestGroup) # { artifact: TestGroup() } -BOARD_TESTS = defaultdict(TestGroup) # { board: TestGroup() } -SKETCH_TESTS = defaultdict(lambda: defaultdict(TestGroup)) # { artifact: { sketch: TestGroup() } } - -def log_test(artifact, board, sketch, link_mode, exceptions, status, issues, job_link=None): +import ci_shared +from ci_shared import ( + TestStatus, SKIP, PASS, WARNING, EXPECTED_ERROR, INVALID_EXCEPTION, ERROR, FAILURE, + LoaderEntry, TestEntry, TestGroup, +) + +BASE_COLOR = 0x20 # darkest tone +DELTA_COLOR = 0xff-2*BASE_COLOR # max color change (brightest tone - darkest tone) + +def get_percent(values): + if not values: + return 0.0 + return values[0] / values[1] + +def color_cmd(percent): """ - Logs individual test results into the global test tracking structures. + Returns a LaTeX color command string based on the given percentage. + The color hue transitions linearly from fully green (0) to fully red (1). """ + color_amt = int(DELTA_COLOR * percent) + return f"\\color{{#{BASE_COLOR + color_amt:02x}{0xff - color_amt:02x}{BASE_COLOR:02x}}}" - # Ensure issues is a list - if isinstance(issues, str): - issues = [ issues ] - - # Create the test entry - excepted = any(pattern.match(sketch) for pattern in exceptions) - test_entry = TestEntry(artifact, board, sketch, link_mode, excepted, status, issues, job_link) +def color_entry(values, full=True): + """ + Returns a colored LaTeX-formatted string representing memory usage. + If full is True, shows used/total as a fraction and percent; otherwise shows only percent. + """ + if not values: + return "" - # Track in global structures - ARTIFACT_TESTS[artifact].track(test_entry) - BOARD_TESTS[board].track(test_entry) - SKETCH_TESTS[artifact][sketch].track(test_entry) + percent = get_percent(values) + if full: + return f"${{{color_cmd(percent)}\\frac{{{values[0]}}}{{{values[1]}}}\\space({percent*100:0.1f}\\\\%)}}$" + else: + return f"{'' if percent < 0.85 else ':warning:'} ${{{color_cmd(percent)}{percent*100:0.1f}\\\\%}}$" def print_summary(): """ @@ -239,7 +64,7 @@ def print_summary(): if ci_run_passed: title = f"# [CI run]({JOB_LINK_STEM}#user-content-summary) PASSED :green_circle:\n" else: - failed_boards = [ f"{BOARD_STATUS[res.status]} `{board}`" for board, res in BOARD_TESTS.items() if res.status in (ERROR, FAILURE) ] + failed_boards = [ f"{res.status.board_icon} `{board}`" for board, res in BOARD_TESTS.items() if not res.status.passed ] title = f"# [CI run]({JOB_LINK_STEM}#user-content-summary) FAILED: {', '.join(failed_boards)}\n" f_print("\n") f_print(title) @@ -260,7 +85,7 @@ def print_summary(): artifact_boards = sorted(ARTIFACT_TESTS[artifact].boards) artifact_status = ARTIFACT_TESTS[artifact].status - first_row_text = f"{BOARD_STATUS[artifact_status]} {artifact}" + first_row_text = f"{artifact_status.board_icon} {artifact}" for board in artifact_boards: # Artifact name (multi-row) f_print(f"{first_row_text}") @@ -275,7 +100,7 @@ def print_summary(): # Core build status + message on failure if res.status == FAILURE: - f_print(f"{BOARD_STATUS[FAILURE]}Core build failed!") + f_print(f"{res.status.board_icon}Core build failed!") continue pin = f"{len(res.warnings)} :label:" if res.status == WARNING else ":green_book:" @@ -283,7 +108,7 @@ def print_summary(): # Sketch build status + message on failure res = BOARD_TESTS[board] - f_print(f"{BOARD_STATUS[res.status]}") + f_print(f"{res.status.board_icon}") if res.status == FAILURE: f_print(f"") f_print("
".join(f"{test.issues[0]} (full log)" for test in res.tests)) @@ -308,16 +133,16 @@ def print_summary(): # Print the legend f_print("
Legend") f_print("

") - for status in FAILURE, ERROR, EXPECTED_ERROR, WARNING, PASS, SKIP: - f_print(f"") - f_print(f"") - f_print(f"") + for status in reversed(TestStatus): # worst errors first + f_print(f"") + f_print(f"") + f_print(f"") f_print("
BoardTestStatus description
{BOARD_STATUS[status]}{TEST_STATUS[status]}{TEST_LEGEND[status]}
{status.board_icon}{status.test_icon}{status.legend}
\n") # Print artifact error warnings for artifact in ARTIFACTS: artifact_boards = sorted(ARTIFACT_TESTS[artifact].boards) - failed_boards = [ f"`{board}`" for board in artifact_boards if BOARD_TESTS[board].status in (ERROR, FAILURE) ] + failed_boards = [ f"`{board}`" for board in artifact_boards if not BOARD_TESTS[board].status.passed ] if failed_boards: f_print("> [!CAUTION]") @@ -335,7 +160,7 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: header_row = f"{artifact} {title}" for board in artifact_boards: res = BOARD_TESTS[board] - header_col = f"{board}
{BOARD_STATUS[res.status]}" + header_col = f"{board}
{res.status.board_icon}" header_row += f"{header_col}" header_row += "" @@ -358,7 +183,7 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: data_rows.append(f"{group}{group}") #data_rows.append(f"{group}{''.join('---' for x in artifact_boards)}") for sample, res in sorted(sketch_groups[group]): - row_data = f"{TEST_STATUS[res.status]}" + row_data = f"{res.status.test_icon}" # If there are issues, make the sketch name a link to the detailed logs below name_link = f"{sample}" if res.tests_with_issues: @@ -369,14 +194,10 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: for board in artifact_boards: # there are multiple tests per sketch&board due to FQBN variations - status = max( [ t.status for t in res.tests if t.board == board ], default=SKIP) - invalid = any( [ t.invalid_exception for t in res.tests if t.board == board ] ) - if invalid and status in (PASS, WARNING): - status_icon = ":interrobang:" - invalid_exceptions[board].add(sketch) - else: - status_icon = TEST_STATUS[status] - row_data += f"{status_icon}" + status = max( [ t.status for t in res.tests if t.board == board ], default=TestStatus.SKIP) + if status == INVALID_EXCEPTION: + invalid_exceptions[board].add(sample) + row_data += f"{status.test_icon}" row_data += "" data_rows.append(row_data) @@ -412,7 +233,7 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: sketch = next(iter(res.sketches)) # only one sketch_id = sketch.replace('/', '_').replace(' ', '_').replace('-', '_') f_print(f"") - f_print(f"
{artifact} logs for {TEST_STATUS[res.status]} {group} {sample}") + f_print(f"
{artifact} logs for {res.status.test_icon} {group} {sample}") f_print("

") # Test logs by board, group similar messages @@ -421,7 +242,7 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: test_text = f"{test.board}:{test.link_mode}" if test.job_link: test_text += f" (full log)" - test_text = f"{TEST_STATUS[test.status]} {test_text}" + test_text = f"{test.status.test_icon} {test_text}" boards_by_issues[tuple(test.issues)].append(test_text) @@ -433,38 +254,6 @@ def print_test_matrix(artifact, artifact_boards, title, sketch_filter=lambda x: f_print("
\n") -REGIONS_BY_SOC = defaultdict(set) # { soc: set(regions) } - -BASE_COLOR = 0x20 # darkest tone -DELTA_COLOR = 0xff-2*BASE_COLOR # max color change (brightest tone - darkest tone) - -def get_percent(values): - if not values: - return 0.0 - return values[0] / values[1] - -def color_cmd(percent): - """ - Returns a LaTeX color command string based on the given percentage. - The color hue transitions linearly from fully green (0) to fully red (1). - """ - color_amt = int(DELTA_COLOR * percent) - return f"\\color{{#{BASE_COLOR + color_amt:02x}{0xff - color_amt:02x}{BASE_COLOR:02x}}}" - -def color_entry(values, full=True): - """ - Returns a colored LaTeX-formatted string representing memory usage. - If full is True, shows used/total as a fraction and percent; otherwise shows only percent. - """ - if not values: - return "" - - percent = get_percent(values) - if full: - return f"${{{color_cmd(percent)}\\frac{{{values[0]}}}{{{values[1]}}}\\space({percent*100:0.1f}\\\\%)}}$" - else: - return f"{'' if percent < 0.85 else ':warning:'} ${{{color_cmd(percent)}{percent*100:0.1f}\\\\%}}$" - def print_mem_report(artifact, artifact_boards): """ Prints the memory usage report for the given artifact and its boards. @@ -549,130 +338,52 @@ def print_mem_report(artifact, artifact_boards): if extra_data_present: f_print("
") - - # --------------------------------------------------------------------------- # Main Logic # --------------------------------------------------------------------------- -# Environment Variable Checks -ALL_BOARD_DATA_STR = os.environ.get('ALL_BOARD_DATA') -WORKFLOW_JOBS_STR = os.environ.get('WORKFLOW_JOBS') -GITHUB_REPOSITORY = os.environ.get('GITHUB_REPOSITORY') -GITHUB_RUN_ID = os.environ.get('GITHUB_RUN_ID') -JOB_LINK_STEM = f"https://github.com/{GITHUB_REPOSITORY}/actions/runs/{GITHUB_RUN_ID}" - -if not ALL_BOARD_DATA_STR or not GITHUB_REPOSITORY or not GITHUB_RUN_ID: - print("Not in a Github CI run, cannot proceed.") - sys.exit(0) - -if not len(sys.argv) in (1, 4): - print("Usage: ci_inspect_logs.py [ ]") +if not len(sys.argv) in (2, 5): + print("Usage: ci_generate_report.py [ ]") sys.exit(1) -if len(sys.argv) == 4: - results_file = sys.argv[1] - summary_file = sys.argv[2] - full_report_file = sys.argv[3] +json_file = sys.argv[1] + +if len(sys.argv) == 5: + results_file = sys.argv[2] + summary_file = sys.argv[3] + full_report_file = sys.argv[4] else: results_file = "/dev/null" summary_file = full_report_file = "/dev/stdout" -# Load board data and job URLs from environment variables -ALL_BOARD_DATA = json.loads(ALL_BOARD_DATA_STR) -ALL_BOARD_DATA = { b['board']: b for b in ALL_BOARD_DATA } - -JOB_URLS = json.loads(WORKFLOW_JOBS_STR) -JOB_URLS = { j['name']: j['url'] for j in JOB_URLS } - -# Import and process data for each board -for board_data in ALL_BOARD_DATA.values(): - # Extract common fields from board data - artifact = board_data['artifact'] - board = board_data['board'] - variant = board_data['variant'] - subarch = board_data['subarch'] - - # Get job link for this build - # NOTE: This must match the name used in the workflow YAML - job_link = JOB_URLS.get(f"Build for {board}") - if job_link: - job_link += "#step:5:1" - - # Read loader build data - BOARD_LOADERS[board] = LoaderEntry(artifact, board, variant, job_link) - if BOARD_LOADERS[board].status == FAILURE: - log_test(artifact, board, 'CI test', '', [], FAILURE, "Core data could not be read.") - continue - - # Get SoC-specific info from loader config - soc = BOARD_LOADERS[board].config['CONFIG_SOC'] - board_data['soc'] = soc - REGIONS_BY_SOC[soc].update(BOARD_LOADERS[board].meminfo.keys()) - - # Get list of expected errors for this board - exceptions = [] - if os.path.exists(f"variants/{variant}/known_example_issues.txt"): - with open(f"variants/{variant}/known_example_issues.txt", 'r') as f: - for line in f: - sketch_pattern = line.split('#')[0].strip() - if sketch_pattern: - exceptions.append(re.compile(f"^(ArduinoCore-zephyr/)?{sketch_pattern}")) - - # Get raw data from report files for both static and dynamic linking modes - for link_mode in ("static", "dynamic"): - # Get job link for this test - # NOTE: This must match the name used in the workflow YAML - job_link = JOB_URLS.get(f"Test {board}:{link_mode}") - if job_link: - job_link += "#step:6:1" - - # Extract data from the report file - report_file = f"arduino-{subarch}-{board}-link_mode={link_mode}.json" - if not os.path.exists(report_file): - log_test(artifact, board, 'CI test', '', [], FAILURE, f"Report file for {link_mode} not found.", job_link) - continue # Skip to the next board - - try: - with open(report_file, 'r') as f: - report_data = json.load(f) - except Exception as e: - log_test(artifact, board, 'CI test', '', [], FAILURE, f"Error reading {link_mode} report file: {e}", job_link) - continue # Skip to the next board - - reports = report_data.get('boards', [{}])[0].get('sketches', []) - if not reports: - log_test(artifact, board, 'CI test', '', [], FAILURE, "Test report for {link_mode} is empty, check CI log.", job_link) - continue # Skip to the next board - - # Iterate through individual sketch reports - for report in reports: - sketch = report.get('name', 'unknown_sketch') - success = report.get('compilation_success', False) - issues = report.get('issues', []) - - # Replace long absolute paths with '...' for brevity. - sketch_issues = [ re.sub(r'(/.+?)((/[^/]+){3}):', r'...\2:', issue) for issue in issues ] - - if not success: - status = ERROR - elif len(sketch_issues): # Implies warnings/non-critical issues - status = WARNING - else: - status = PASS - - # Log the test result to all data structures - log_test(artifact, board, sketch, link_mode, exceptions, status, sketch_issues, job_link) - -ARTIFACTS = sorted(ARTIFACT_TESTS.keys()) - -# Begin output of the report -# -------------------------- - -ci_run_status = max(res.status for res in ARTIFACT_TESTS.values()) -ci_run_passed = ci_run_status in (PASS, WARNING, EXPECTED_ERROR) - -# update the results file +# Load data from JSON +with open(json_file, 'r') as f: + data = json.load(f) + +JOB_LINK_STEM = data['job_link_stem'] +ARTIFACTS = data['artifacts'] +ci_run_passed = data['ci_run_passed'] +ALL_BOARD_DATA = data['all_board_data'] +REGIONS_BY_SOC = {soc: set(regions) for soc, regions in data['regions_by_soc'].items()} + +# Reconstruct BOARD_LOADERS from JSON +BOARD_LOADERS = { + board: LoaderEntry.from_dict(loader) + for board, loader in data['board_loaders'].items() +} + +# Reconstruct all test entries and rebuild groups via track() +ALL_TESTS = [TestEntry.from_dict(t) for t in data['all_tests']] + +ARTIFACT_TESTS = defaultdict(TestGroup) +BOARD_TESTS = defaultdict(TestGroup) +SKETCH_TESTS = defaultdict(lambda: defaultdict(TestGroup)) +for t in ALL_TESTS: + ARTIFACT_TESTS[t.artifact].track(t) + BOARD_TESTS[t.board].track(t) + SKETCH_TESTS[t.artifact][t.sketch].track(t) + +# Update the results file with open(results_file, 'w') as f: f.write('Tests PASSED.' if ci_run_passed else '::error::Tests FAILED.'); f.write(f" See {JOB_LINK_STEM}#user-content-summary for details.\n") @@ -714,7 +425,7 @@ def print_mem_report(artifact, artifact_boards): f_print("\n") # print failed tests matrix - print_test_matrix(artifact, artifact_boards, "issues", sketch_filter=lambda res: res.status in (ERROR, EXPECTED_ERROR) or res.tests_with_invalid_exceptions) + print_test_matrix(artifact, artifact_boards, "issues", sketch_filter=lambda res: res.status >= EXPECTED_ERROR) # print successful tests matrix in a collapsible section successful_tests = ARTIFACT_TESTS[artifact].counts[PASS] + ARTIFACT_TESTS[artifact].counts[WARNING] @@ -725,7 +436,7 @@ def print_mem_report(artifact, artifact_boards): summary += f" ({warning_tests} with warnings)" f_print(f"
{summary}

\n") - print_test_matrix(artifact, artifact_boards, "tests", sketch_filter=lambda res: res.status in (PASS, WARNING)) + print_test_matrix(artifact, artifact_boards, "tests", sketch_filter=lambda res: res.status.built) f_print("
\n") # print memory usage report in a collapsible section diff --git a/extra/ci_shared.py b/extra/ci_shared.py new file mode 100644 index 000000000..9c65c50e3 --- /dev/null +++ b/extra/ci_shared.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 + +# Copyright (c) Arduino s.r.l. and/or its affiliated companies +# SPDX-License-Identifier: Apache-2.0 + +# Shared constants and data classes for CI log inspection scripts. + +import enum +import json + +class TestStatus(enum.IntEnum): + """ + Test result status codes, in increasing order of severity. + Each member carries display metadata: test_icon, board_icon, legend. + passed is True for statuses that do not represent a build/test failure. + built is True for statuses that represent a build that completed successfully. + """ + def __new__(cls, value, passed, built, test_icon, board_icon, legend): + obj = int.__new__(cls, value) + obj._value_ = value + obj.passed = passed + obj.built = built + obj.test_icon = test_icon + obj.board_icon = board_icon + obj.legend = legend + return obj + + SKIP = (-1, True, False, ":new_moon:", ":new_moon:", "Test was skipped.") + PASS = ( 0, True, True, ":green_circle:", ":white_check_mark:", "Test passed successfully, with no warnings or errors.") + WARNING = ( 1, True, True, ":yellow_circle:", ":white_check_mark:*", "Test completed with some warnings; no errors detected.") + EXPECTED_ERROR = ( 2, True, False, ":no_entry_sign:", ":heavy_check_mark:*", "Test completed with errors, but all are known/expected.") + INVALID_EXCEPTION = ( 3, False, False, ":interrobang:", ":interrobang:", "Test was expected to fail but passed; exception entry is outdated.") + ERROR = ( 4, False, False, ":red_circle:", ":x:", "Test completed with unexpected errors.") + FAILURE = ( 5, False, False, ":fire:", ":fire:", "Test run failed to complete.") + +# Module-level aliases so consumers can import status constants directly +SKIP, PASS, WARNING, EXPECTED_ERROR, INVALID_EXCEPTION, ERROR, FAILURE = TestStatus + +# Loader build status data structure, one per loader +class LoaderEntry: + def __init__(self, artifact, board, variant, job_link): + self.artifact = artifact + self.board = board + self.variant = variant + self.job_link = job_link + + self.warnings = self.read_warnings() # list of warning messages + self.config = self.read_config() # set of Kconfig settings + self.meminfo = self.read_meminfo() # memory usage report + + if not (self.config and self.meminfo): + self.status = FAILURE + elif self.warnings: + self.status = WARNING + else: + self.status = PASS + + def read_config(self): + """ + Extract Kconfig settings from the loader config file. + Format: SYMBOL=VALUE per line or # comment lines for disabled symbols. + """ + report_file = f"zephyr-{self.variant}.config" + try: + with open(report_file, 'r') as f: + configs = {} + for line in f: + if line.startswith('#') or '=' not in line: + continue + sym, val = line.strip().split('=', 1) + if val.startswith('"'): + configs[sym] = val.strip('"') + elif val=='y': + configs[sym] = 1 + else: + configs[sym] = eval(val) + return configs + except Exception as e: + return {} + + def read_warnings(self): + """ + Read loader compilation warnings from the warnings file. + File may be missing in case of no warnings. + Format: one line per warning message. + """ + report_file = f"zephyr-{self.variant}.warnings" + try: + with open(report_file, 'r') as f: + return [ line.strip() for line in f if line.strip() ] + except Exception as e: + return [] + + def read_meminfo(self): + """ + Extract memory usage data from the meminfo file. + Input format: JSON array of region_name, used_bytes, total_bytes tuples + Output format: dict of { region_name: [ used_bytes, total_bytes ] } + """ + report_file = f"zephyr-{self.variant}.meminfo" + try: + with open(report_file, 'r') as f: + report_data = json.load(f) + meminfo = { region.replace(':',''): [used, total] for region, used, total in report_data } + meminfo.pop('IDT_LIST', None) + return meminfo + except Exception as e: + return {} + + def to_dict(self): + return { + 'artifact': self.artifact, + 'board': self.board, + 'variant': self.variant, + 'job_link': self.job_link, + 'warnings': self.warnings, + 'config': self.config, + 'meminfo': self.meminfo, + 'status': int(self.status), + } + + @classmethod + def from_dict(cls, d): + obj = cls.__new__(cls) + obj.artifact = d['artifact'] + obj.board = d['board'] + obj.variant = d['variant'] + obj.job_link = d['job_link'] + obj.warnings = d['warnings'] + obj.config = d['config'] + obj.meminfo = d['meminfo'] + obj.status = TestStatus(d['status']) + return obj + + +# Single test data structure, one per compilation test +class TestEntry: + def __init__(self, artifact, board, sketch, link_mode, excepted, status, issues, job_link, + group=None, name=None): + import re + self.artifact = artifact + self.board = board + self.sketch = sketch + self.link_mode = link_mode + self.excepted = excepted + self.status = INVALID_EXCEPTION if (excepted and status.built) else status + self.issues = issues + self.job_link = job_link + + if group is not None and name is not None: + self.group = group + self.name = name + else: + match = re.search(r'(libraries|examples)/([^/]+)/(examples/|extras/)?(.*)', sketch) + if match: + self.group = match.group(2) + self.name = match.group(4) + else: + self.group = "" + self.name = sketch + + def to_dict(self): + return { + 'artifact': self.artifact, + 'board': self.board, + 'sketch': self.sketch, + 'link_mode': self.link_mode, + 'excepted': self.excepted, + 'status': int(self.status), + 'issues': self.issues, + 'job_link': self.job_link, + 'group': self.group, + 'name': self.name, + } + + @classmethod + def from_dict(cls, d): + return cls( + artifact=d['artifact'], + board=d['board'], + sketch=d['sketch'], + link_mode=d['link_mode'], + excepted=d['excepted'], + status=TestStatus(d['status']), + issues=d['issues'], + job_link=d['job_link'], + group=d['group'], + name=d['name'], + ) + + +# Summary data structure, used to group test results +class TestGroup: + def __init__(self): + # Sets to track unique board, sketch and (group,name) tuples + self.boards = set() + self.sketches = set() + self.group_names = set() + # Counts of test results by status + self.counts = { s: 0 for s in TestStatus } + # Overall status of the group + self.status = SKIP + # List of individual TestEntry objects by feature + self.tests = [] + self.tests_with_issues = [] + + def track(self, test_entry): + """ + Update this group with a new test entry + """ + self.tests.append(test_entry) + if test_entry.issues: + self.tests_with_issues.append(test_entry) + + self.counts[test_entry.status] += 1 + self.status = max(self.status, test_entry.status) + self.boards.add(test_entry.board) + self.sketches.add(test_entry.sketch) + self.group_names.add((test_entry.group, test_entry.name)) diff --git a/extra/ci_test_list.sh b/extra/ci_test_list.sh index 7bf664807..573f66213 100755 --- a/extra/ci_test_list.sh +++ b/extra/ci_test_list.sh @@ -31,6 +31,10 @@ search_for_sketches_in() { } fetch_and_extract() { + # $1: URL of the archive to fetch + # $2: Pattern to match the inner folder (e.g. "core-*" + # $3: Output folder to move the extracted content to + # $4...: Additional paths to search for examples within the extracted content local temp_file=$(mktemp).tar.gz local temp_dir=$(mktemp -d) local link="$1" @@ -59,7 +63,16 @@ get_latest_release() { local folder="$1" local repo="$2" local project="${repo##*/}" - local url=$(curl -s "https://api.github.com/repos/${repo}/releases/latest" | jq -r '.tarball_url') + # Retry up to 3 times in case of transient API issues + for i in {1..3}; do + url=$(curl -s "https://api.github.com/repos/${repo}/releases/latest" | jq -r '.tarball_url') + if [ -n "$url" ] && [ "$url" != "null" ]; then + break + fi + echo "Failed to get URL from GitHub API, attempt $i/3." + # sleep a random time between 1 and 5 seconds before retrying + sleep $((RANDOM % 5 + 1)) + done shift 2 echo "::group::Getting latest release for ${repo}" diff --git a/extra/gen_arduino_files.cmake b/extra/gen_arduino_files.cmake index 7c21a11fb..8f438488f 100644 --- a/extra/gen_arduino_files.cmake +++ b/extra/gen_arduino_files.cmake @@ -48,6 +48,11 @@ foreach(variant ${VARIANTS}) # exclude other problematic macros shared between C and C++ list(FILTER LLEXT_BASE_CFLAGS EXCLUDE REGEX "-fdiagnostics-color=always") + # get machine flags (-msomething) in a separate list + set(LLEXT_MACHINE_FLAGS ${LLEXT_BASE_CFLAGS}) + list(FILTER LLEXT_MACHINE_FLAGS INCLUDE REGEX "-m.*") + list(FILTER LLEXT_BASE_CFLAGS EXCLUDE REGEX "-m.*") + # (temp) generate C++ flags from C flags set(LLEXT_BASE_CXXFLAGS ${LLEXT_BASE_CFLAGS}) list(FILTER LLEXT_BASE_CXXFLAGS EXCLUDE REGEX "-Wno-pointer-sign") @@ -55,10 +60,12 @@ foreach(variant ${VARIANTS}) list(FILTER LLEXT_BASE_CXXFLAGS EXCLUDE REGEX "-std=c.*") # save flag files + list(JOIN LLEXT_MACHINE_FLAGS "\n" EDK_MACHINE_FLAGS) + file(WRITE ${dir}/machine_flags.txt "${EDK_MACHINE_FLAGS}") + list(JOIN LLEXT_BASE_CFLAGS "\n" EDK_CFLAGS) file(WRITE ${dir}/cflags.txt "${EDK_CFLAGS}") - list(JOIN LLEXT_BASE_CXXFLAGS "\n" EDK_CXXFLAGS) file(WRITE ${dir}/cxxflags.txt "${EDK_CXXFLAGS}") endforeach() diff --git a/extra/gen_provides.py b/extra/gen_provides.py index 39bfa8efd..47a303312 100755 --- a/extra/gen_provides.py +++ b/extra/gen_provides.py @@ -122,6 +122,9 @@ def main(): argparser.add_argument('-F', '--funcs', action='store_true', help='Extract all public functions') + argparser.add_argument('-T', '--tls-defs', + action='store_true', + help='Extract TLS symbol offsets to a .S file') argparser.add_argument('file', help='ELF file to parse') argparser.add_argument('syms', nargs='*', @@ -129,10 +132,19 @@ def main(): args = argparser.parse_intermixed_args() + wants_provides = bool(args.syms or args.funcs or args.llext) + if wants_provides and args.tls_defs: + sys.stderr.write("Cannot generate TLS defs when also generating PROVIDEs.\n") + sys.exit(1) + elif not wants_provides and not args.tls_defs: + sys.stderr.write("Nothing specified for export.\n") + sys.exit(1) + exact_syms = set() regex_syms = set() deref_syms = set() sized_syms = set() + tls_syms = set() # tuple of (name, value, size) rename_map = {} for sym in args.syms: sym_class = None @@ -184,6 +196,11 @@ def main(): fail = False for name, sym in all_syms.items(): + if sym['st_info']['type'] == 'STT_TLS': + # Collect TLS symbol information, ignore for PROVIDEs + tls_syms.add((name, sym['st_value'], sym['st_size'])) + continue + value = None comment = [] if name in exact_syms or any(re.match(r, name) for r in regex_syms): @@ -220,10 +237,6 @@ def main(): if name in sized_syms: out_syms[name + "_size"] = (sym['st_size'], [f"size of {name}"]) - if not out_syms: - sys.stderr.write("No symbols found matching the criteria.\n") - fail = True - if fail: sys.exit(1) @@ -235,16 +248,47 @@ def main(): * SHA256: {elf_sha} */ """) - sym_comment = nul_comment = "" - for name, (value, comments) in sorted(out_syms.items(), key=lambda x: x[0]): - if args.verbose: - comment = ', '.join(sorted(comments)) - sym_comment = f"/* {comment} */" - nul_comment = f" ({comment})" - if value: - print(f"PROVIDE({name} = {value:#010x});{sym_comment}") + + if wants_provides: + if not out_syms: + print("/* No symbols found matching the criteria */") + sys.stderr.write("warning: no symbols found matching the criteria.\n") else: - print(f"/* NULL {name}{nul_comment} */") + sym_comment = nul_comment = "" + for name, (value, comments) in sorted(out_syms.items(), key=lambda x: x[0]): + if args.verbose: + comment = ', '.join(sorted(comments)) + sym_comment = f"/* {comment} */" + nul_comment = f" ({comment})" + if value: + print(f"PROVIDE({name} = {value:#010x});{sym_comment}") + else: + print(f"/* NULL {name}{nul_comment} */") + + if args.tls_defs: + # ARM and AArch64 use '@' as a line-comment character in GAS, so the + # assembler requires '%' as the type prefix there. All other targets use '@'. + prefix = '%' if elf['e_machine'] in ('EM_ARM', 'EM_AARCH64') else '@' + + # The TLS Variant 1 layout (used by ARM/AArch64) places a Thread + # Control Block (TCB) before the TLS data. The thread pointer + # returned by __aeabi_read_tp() points to the TCB, so the actual + # runtime address of a TLS variable must be offset by that size. + # + # TCB is 2 pointers: 8 bytes on 32-bit, 16 bytes on 64-bit. + # See zephyr/arch/arm/core/tls.c: arch_tls_stack_setup(). + tcb_size = (elf.elfclass // 8) * 2 + print(f"/* Offsets include {tcb_size} bytes for TCB data */") + + # Sort by offset first, then size + for name, offset, size in sorted(tls_syms, key=lambda x: (x[1], x[2])): + offset += tcb_size + print( + f"\n/* TLS offset {offset:#x}: {name} ({size} bytes) */\n" + f".global {name}\n" + f".type {name}, {prefix}tls_object\n" + f".set {name}, {offset}" + ) #------------------------------------------------------------------------------- if __name__ == '__main__': diff --git a/extra/get_core_version.sh b/extra/get_core_version.sh index 8e8cdcc9d..51171cee6 100755 --- a/extra/get_core_version.sh +++ b/extra/get_core_version.sh @@ -13,31 +13,82 @@ # # ..--g # -# The regexp will remove the commit hash and split the patch number, then awk -# converts the tokens to: +# A bash regex extracts the components and produces: # -# ..-0.dev +# ..-0.