mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-10 01:50:04 +08:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a83e43cfd5 | |||
| 0e31dd560d | |||
| ae47d69f50 | |||
| eed4457d71 | |||
| a0e42f2032 | |||
| 0f15eea283 | |||
| 9eddd0cdbc | |||
| 5d5d9e399b | |||
| a3ad956394 | |||
| c72a11fe9f | |||
| fc53da51fa | |||
| a49cffb09f | |||
| 8552465408 | |||
| 100d9c97fb | |||
| 5db3060c2a | |||
| 9e93fd753e | |||
| e8c19a2006 | |||
| 1777d6bcd2 | |||
| 9adda29da2 | |||
| e34cb8ccb5 | |||
| 2557a7441c | |||
| c4abeed3a4 | |||
| 20cad48707 | |||
| 0954e43708 | |||
| b53036c2d7 | |||
| fffd434068 | |||
| a74076e539 | |||
| 00d3c4badc | |||
| 397a54abc1 | |||
| bd5cdd3276 | |||
| ff31d5a04f | |||
| fc11c207b9 | |||
| 104e7f2a9c | |||
| a3d51a62a2 | |||
| d09b3abcf9 | |||
| 8c4b703103 | |||
| c9f1d2ab0f | |||
| 4c8c9a1e0f | |||
| 35391ed8d0 | |||
| 48b04b1c81 | |||
| 3ab7895af7 | |||
| 3c5574c051 | |||
| eb9a76cfaf | |||
| f545f2227d | |||
| 4e5c0fac7a | |||
| fa0618463d | |||
| f025bb42eb |
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\nci-orchestrator: cache emscripten SDK in failsafe-sim job\n\nCache the _emscripten_sdk directory keyed on version 4.0.15 so\nsubsequent runs skip the git clone and install steps \\(~30s savings\non cache hit\\). The build step sources emsdk_env.sh unchanged.\nEOF\n\\)\")",
|
||||
"WebFetch(domain:gist.github.com)",
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\nci-orchestrator: upgrade SITL and ROS integration runners to 8cpu\n\nROS Integration Tests \\(31m\\) is the critical path bottleneck,\nfollowed by SITL Tests tailsitter \\(20m\\). Both spend significant\ntime compiling dependencies \\(xrce-dds, ROS2 libs, gazebo\\). Upgrade\nfrom 4cpu to 8cpu to parallelize compilation and reduce wall-clock.\nEOF\n\\)\")",
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\nci-orchestrator: fix flash analysis comment alignment\n\nRemove extra indentation from code fences and bloaty output inside\nthe PR comment body so the column alignment renders correctly in\nGitHub markdown.\nEOF\n\\)\")",
|
||||
"Bash(docker run:*)",
|
||||
"Bash(docker rm:*)",
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\nci-orchestrator: increase SITL test speed factor to 20x\n\nBump simulation speed factor from 10x to 20x for MAVSDK SITL tests.\nWith the 8cpu runners this should be sustainable and roughly halve\nthe 18min test execution phase.\nEOF\n\\)\")",
|
||||
"Bash(docker exec:*)",
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\nci-orchestrator: build Gazebo plugins in cache seed job\n\nAdd Gazebo Classic plugin build to the build-sitl cache seed job so\ndownstream SITL test jobs get ccache hits for both PX4 firmware and\nGazebo objects. Bump ccache max_size from 250M to 400M to fit both.\nEOF\n\\)\")",
|
||||
"Bash(git -C /Users/rroche/Work/Dronecode/PX4-Autopilot-ci-orchestrator commit -S -s -m \"$\\(cat <<''EOF''\ndocs: update CI orchestrator docs for 4-tier architecture and caching\n\nUpdate documentation to reflect recent changes:\n- 5-tier to 4-tier restructure \\(old T3 merged into T2\\)\n- Add comprehensive caching strategy section covering ccache key\n patterns, scopes, sizes, and the cache seed pattern\n- Document Emscripten SDK cache for failsafe-sim\n- Update runner types \\(8cpu for SITL/ROS, 16cpu for clang-tidy\\)\n- SITL tests now run at 20x speed factor\n- Remove CI summary job references\n- Update tier numbering throughout troubleshooting and best practices\nEOF\n\\)\")",
|
||||
"Bash(docker build:*)",
|
||||
"WebFetch(domain:raw.githubusercontent.com)",
|
||||
"Bash(docker system prune:*)",
|
||||
"WebSearch",
|
||||
"WebFetch(domain:hub.docker.com)",
|
||||
"WebFetch(domain:docs.px4.io)",
|
||||
"WebFetch(domain:github.com)",
|
||||
"Bash(find:*)",
|
||||
"Bash(docker search:*)",
|
||||
"Bash(docker images:*)",
|
||||
"Bash(gh pr create --draft --title \"packaging: add PX4 SITL .deb package\" --body \"$\\(cat <<''EOF''\nSingle .deb package for PX4 SITL with Gazebo Harmonic resources. Installs to /opt/px4-sitl with a px4-sitl wrapper script symlinked to /usr/bin.\n\nChanges:\n- cmake/package.cmake: CPack config for px4-sitl .deb with minimal Gazebo runtime deps\n- platforms/posix/CMakeLists.txt: install targets for Gazebo models, worlds, plugins\n- Tools/packaging/px4-sitl.sh: launcher script \\(XDG dirs, gz_env.sh generation, dartsim symlink fix\\)\n- Tools/packaging/postinst, postrm: create/remove /usr/bin/px4-sitl symlink\n- .github/workflows/build_deb_package.yml: CI to build and validate the .deb\n- docs/en/packaging/px4_sitl_deb.md: usage and build docs\n\nTested with PX4_SIM_MODEL=gz_x500 and sihsim_quadx in Ubuntu 24.04 container.\nEOF\n\\)\")",
|
||||
"Bash(gh gist create:*)",
|
||||
"Bash(git commit -S -s -m \"$\\(cat <<''EOF''\npackaging: exclude legacy install rules from .deb builds\n\nGate legacy install rules behind if\\(NOT DPKG_PROGRAM\\) so they only\nrun for tarball/ROS workflows. Gate .deb install rules behind\nif\\(DPKG_PROGRAM\\) so they only run when building .deb packages.\n\nWithout this, both rule sets execute during .deb builds, triplicating\nfiles and pulling in the entire source tree \\(integrationtests, launch,\nTools, CMakeLists.txt, gazebo-classic models\\) into the package.\nEOF\n\\)\")",
|
||||
"Bash(gh issue create:*)",
|
||||
"Bash(git commit -S -s --amend -m \"$\\(cat <<''EOF''\npackaging: exclude legacy install rules from .deb builds\n\nMove find_program\\(DPKG_PROGRAM dpkg\\) into platforms/posix/CMakeLists.txt\nso it is available before the install rules are processed \\(package.cmake\nruns later\\). Gate both the top-level posix install block and the\nSITL-specific legacy install rules behind if\\(NOT DPKG_PROGRAM\\) so they\nonly run for tarball/ROS workflows.\n\nGate .deb install rules behind if\\(DPKG_PROGRAM\\) so they only run when\nbuilding .deb packages. Mark Gazebo resource installs as OPTIONAL so\nCPack does not fail when the gz submodule is not checked out.\n\nWithout this, both rule sets execute during .deb builds, triplicating\nfiles and pulling in the entire source tree \\(integrationtests, launch,\nTools, CMakeLists.txt, gazebo-classic models\\) into the package.\n\nSigned-off-by: Ramon Roche <mrpollo@gmail.com>\nEOF\n\\)\")",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(kill:*)",
|
||||
"WebFetch(domain:cmake.org)",
|
||||
"Bash(gh run watch:*)",
|
||||
"Bash(gh pr list:*)",
|
||||
"Bash(gh pr checks:*)",
|
||||
"WebFetch(domain:discuss.px4.io)",
|
||||
"Bash(gh issue list:*)",
|
||||
"Bash(pkill:*)",
|
||||
"WebFetch(domain:runs-on.com)",
|
||||
"Bash(gh release:*)",
|
||||
"Bash(docker manifest:*)",
|
||||
"Bash(gh pr:*)",
|
||||
"Bash(GIT_EDITOR=true git cherry-pick --continue)"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ runs:
|
||||
steps:
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ inputs.ccache-key-prefix }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
@@ -52,7 +52,7 @@ runs:
|
||||
run: ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@v5
|
||||
if: always()
|
||||
with:
|
||||
path: ~/.ccache
|
||||
@@ -108,7 +108,7 @@ runs:
|
||||
echo "PASS: gazebo package validation successful"
|
||||
|
||||
- name: Upload .deb artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ inputs.artifact-name }}
|
||||
path: build/px4_sitl_${{ inputs.target }}/*.deb
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Build Gazebo Classic SITL
|
||||
description: Build PX4 firmware and Gazebo Classic plugins with ccache stats
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Build - PX4 Firmware (SITL)
|
||||
shell: bash
|
||||
run: make px4_sitl_default
|
||||
|
||||
- name: Cache - Stats after PX4 Firmware
|
||||
shell: bash
|
||||
run: ccache -s
|
||||
|
||||
- name: Build - Gazebo Classic Plugins
|
||||
shell: bash
|
||||
run: make px4_sitl_default sitl_gazebo-classic
|
||||
|
||||
- name: Cache - Stats after Gazebo Plugins
|
||||
shell: bash
|
||||
run: ccache -s
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Save ccache
|
||||
description: Print ccache stats and save to cache
|
||||
|
||||
inputs:
|
||||
cache-primary-key:
|
||||
description: Primary cache key from setup-ccache output
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Cache - Stats
|
||||
if: always()
|
||||
shell: bash
|
||||
run: ccache -s
|
||||
|
||||
- name: Cache - Save ccache
|
||||
if: always()
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ inputs.cache-primary-key }}
|
||||
@@ -0,0 +1,56 @@
|
||||
name: Setup ccache
|
||||
description: Restore ccache from cache and configure ccache.conf
|
||||
|
||||
inputs:
|
||||
cache-key-prefix:
|
||||
description: Cache key prefix (e.g. ccache-sitl)
|
||||
required: true
|
||||
max-size:
|
||||
description: Max ccache size (e.g. 300M)
|
||||
required: false
|
||||
default: '300M'
|
||||
base-dir:
|
||||
description: ccache base_dir value
|
||||
required: false
|
||||
default: '${GITHUB_WORKSPACE}'
|
||||
install-ccache:
|
||||
description: Install ccache via apt before configuring
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
outputs:
|
||||
cache-primary-key:
|
||||
description: Primary cache key (pass to save-ccache)
|
||||
value: ${{ steps.restore.outputs.cache-primary-key }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Cache - Install ccache
|
||||
if: inputs.install-ccache == 'true'
|
||||
shell: bash
|
||||
run: apt-get update && apt-get install -y ccache
|
||||
|
||||
- name: Cache - Restore ccache
|
||||
id: restore
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ inputs.cache-key-prefix }}-${{ github.ref_name }}-
|
||||
${{ inputs.cache-key-prefix }}-${{ github.base_ref || 'main' }}-
|
||||
${{ inputs.cache-key-prefix }}-
|
||||
|
||||
- name: Cache - Configure ccache
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${{ inputs.base-dir }}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = ${{ inputs.max-size }}" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
echo "compiler_check = content" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
@@ -72,10 +72,10 @@ jobs:
|
||||
timestamp: ${{ steps.set-timestamp.outputs.timestamp }}
|
||||
branchname: ${{ steps.set-branch.outputs.branchname }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Cache Python pip
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**./Tools/setup/requirements.txt') }}
|
||||
@@ -131,11 +131,10 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Git ownership workaround
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
# ccache key breakdown:
|
||||
@@ -144,7 +143,7 @@ jobs:
|
||||
# ccache-<linux>-<x64>-<nuttx-0>-
|
||||
- name: Cache Restore from Key
|
||||
id: cc_restore
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ format('ccache-{0}-{1}-{2}', runner.os, matrix.runner, matrix.group) }}
|
||||
@@ -176,7 +175,7 @@ jobs:
|
||||
./Tools/ci/package_build_artifacts.sh
|
||||
|
||||
- name: Upload Build Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: px4_${{matrix.group}}_build_artifacts
|
||||
path: artifacts/
|
||||
@@ -189,7 +188,7 @@ jobs:
|
||||
|
||||
- name: Cache Save
|
||||
if: always()
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ steps.cc_restore.outputs.cache-primary-key }}
|
||||
@@ -211,7 +210,7 @@ jobs:
|
||||
uploadlocation: ${{ steps.upload-location.outputs.uploadlocation }}
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: artifacts/
|
||||
merge-multiple: true
|
||||
|
||||
@@ -40,11 +40,10 @@ jobs:
|
||||
should_push: ${{ steps.push.outputs.should_push }}
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-tags: true
|
||||
submodules: false
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Set PX4 version
|
||||
id: version
|
||||
@@ -93,7 +92,7 @@ jobs:
|
||||
apt-get update && apt-get install -y git
|
||||
git config --global --add safe.directory $(realpath .)
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
@@ -103,7 +102,7 @@ jobs:
|
||||
run: ./Tools/ci/use_aws_apt_mirror.sh
|
||||
|
||||
- name: Cache apt packages
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /var/cache/apt/archives
|
||||
key: apt-${{ matrix.target }}-${{ matrix.codename }}-${{ matrix.arch }}-${{ hashFiles('Tools/setup/ubuntu.sh') }}
|
||||
@@ -136,13 +135,12 @@ jobs:
|
||||
- { image: gazebo, repo: px4-sitl-gazebo, target: default, arch: arm64, runner: arm64, platform: "linux/arm64", dockerfile: Dockerfile.gazebo }
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Download Noble .deb artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: px4-sitl-debs-${{ matrix.target }}-noble-${{ matrix.arch }}
|
||||
path: docker-context
|
||||
@@ -157,13 +155,13 @@ jobs:
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
with:
|
||||
driver: docker-container
|
||||
platforms: ${{ matrix.platform }}
|
||||
|
||||
- name: Build and push container image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: docker-context
|
||||
file: Tools/packaging/${{ matrix.dockerfile }}
|
||||
|
||||
@@ -12,51 +12,88 @@ on:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
gate_checks:
|
||||
name: Gate Checks [${{ matrix.check }}]
|
||||
runs-on: [runs-on,runner=2cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
strategy:
|
||||
fail-fast: false
|
||||
fail-fast: true
|
||||
matrix:
|
||||
check: [
|
||||
"check_format",
|
||||
"check_newlines",
|
||||
"tests",
|
||||
"tests_coverage",
|
||||
"px4_fmu-v2_default stack_check",
|
||||
"validate_module_configs",
|
||||
"shellcheck_all",
|
||||
"NO_NINJA_BUILD=1 px4_fmu-v5_default",
|
||||
"NO_NINJA_BUILD=1 px4_sitl_default",
|
||||
"px4_sitl_allyes",
|
||||
"module_documentation",
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Building [${{ matrix.check }}]
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
make ${{ matrix.check }}
|
||||
run: make ${{ matrix.check }}
|
||||
|
||||
- name: Uploading Coverage to Codecov.io
|
||||
if: contains(matrix.check, 'coverage')
|
||||
uses: codecov/codecov-action@v1
|
||||
tests:
|
||||
name: Unit Tests
|
||||
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
GIT_COMMITTER_EMAIL: bot@px4.io
|
||||
GIT_COMMITTER_NAME: PX4BuildBot
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
flags: unittests
|
||||
file: coverage/lcov.info
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-sitl
|
||||
max-size: 300M
|
||||
|
||||
- name: Build and run unit tests
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: make tests
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Auto-update EKF change indication baselines
|
||||
if: github.event_name == 'push'
|
||||
uses: stefanzweifel/git-auto-commit-action@v7
|
||||
with:
|
||||
file_pattern: 'src/modules/ekf2/test/change_indication/*.csv'
|
||||
commit_user_name: ${{ env.GIT_COMMITTER_NAME }}
|
||||
commit_user_email: ${{ env.GIT_COMMITTER_EMAIL }}
|
||||
commit_message: |
|
||||
[AUTO COMMIT] update EKF change indication
|
||||
|
||||
See .github/workflows/checks.yml for more details
|
||||
|
||||
- name: Check for EKF functional changes
|
||||
run: git diff --exit-code
|
||||
working-directory: src/modules/ekf2/test/change_indication
|
||||
|
||||
@@ -20,50 +20,77 @@ jobs:
|
||||
name: Clang-Tidy
|
||||
runs-on: [runs-on, runner=16cpu-linux-x64, "run-id=${{ github.run_id }}", "extras=s3-cache"]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.17.0-beta1
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Restore Compiler Cache
|
||||
id: cc_restore
|
||||
uses: actions/cache/restore@v4
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-clang-tidy-${{ github.head_ref || github.ref_name }}
|
||||
restore-keys: |
|
||||
ccache-clang-tidy-${{ github.head_ref || github.ref_name }}-
|
||||
ccache-clang-tidy-main-
|
||||
ccache-clang-tidy-
|
||||
cache-key-prefix: ccache-clang-tidy
|
||||
max-size: 150M
|
||||
|
||||
- name: Configure Compiler Cache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = 120M" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
echo "compiler_check = content" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
- name: Build - px4_sitl_default (Clang)
|
||||
run: make -j16 px4_sitl_default-clang
|
||||
|
||||
- name: Run Clang-Tidy Analysis
|
||||
run: make -j16 clang-tidy
|
||||
id: clang_tidy
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||
make -j$(nproc) clang-tidy
|
||||
else
|
||||
python3 Tools/ci/run-clang-tidy-pr.py origin/${{ github.base_ref }}
|
||||
fi
|
||||
|
||||
- name: Compiler Cache Stats
|
||||
if: always()
|
||||
run: ccache -s
|
||||
# On PRs, also produce a `pr-review` artifact for the PR Review Poster
|
||||
# workflow to consume. clang-tidy-diff-18 emits a unified fixes.yml that
|
||||
# the producer script translates into line-anchored review comments.
|
||||
# Running this inside the same container as the build means there is no
|
||||
# workspace-path rewriting and no cross-runner artifact handoff.
|
||||
- name: Export clang-tidy fixes for PR review
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
run: |
|
||||
mkdir -p pr-review
|
||||
git diff -U0 origin/${{ github.base_ref }}...HEAD \
|
||||
| clang-tidy-diff-18.py -p1 \
|
||||
-path build/px4_sitl_default-clang \
|
||||
-export-fixes pr-review/fixes.yml \
|
||||
-j0 || true
|
||||
|
||||
- name: Save Compiler Cache
|
||||
if: always()
|
||||
uses: actions/cache/save@v4
|
||||
- name: Build pr-review artifact
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
python3 Tools/ci/clang-tidy-fixes-to-review.py \
|
||||
--fixes pr-review/fixes.yml \
|
||||
--repo-root "$GITHUB_WORKSPACE" \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--pr-number "${{ github.event.pull_request.number }}" \
|
||||
--commit-sha "${{ github.event.pull_request.head.sha }}" \
|
||||
--out-dir pr-review \
|
||||
--event REQUEST_CHANGES
|
||||
|
||||
- name: Upload pr-review artifact
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ steps.cc_restore.outputs.cache-primary-key }}
|
||||
name: pr-review
|
||||
path: |
|
||||
pr-review/manifest.json
|
||||
pr-review/comments.json
|
||||
retention-days: 1
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: Tools/ci
|
||||
fetch-depth: 1
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: Tools/ci
|
||||
fetch-depth: 1
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
if: env.IS_FORK == 'false'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: Tools/ci
|
||||
fetch-depth: 1
|
||||
|
||||
@@ -19,49 +19,49 @@ concurrency:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
config: [
|
||||
px4_fmu-v5_default,
|
||||
px4_sitl
|
||||
]
|
||||
steps:
|
||||
- name: install Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Cache - Restore Homebrew Packages
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/Library/Caches/Homebrew/downloads
|
||||
key: macos-homebrew-${{ runner.arch }}-${{ hashFiles('Tools/setup/macos.sh') }}
|
||||
restore-keys: |
|
||||
macos-homebrew-${{ runner.arch }}-
|
||||
|
||||
- name: Cache - Restore pip Packages
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
key: macos-pip-${{ runner.arch }}-${{ hashFiles('Tools/setup/requirements.txt') }}
|
||||
restore-keys: |
|
||||
macos-pip-${{ runner.arch }}-
|
||||
|
||||
- name: setup
|
||||
run: |
|
||||
./Tools/setup/macos.sh
|
||||
run: ./Tools/setup/macos.sh
|
||||
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_timestamp
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
file(APPEND "$ENV{GITHUB_OUTPUT}" "timestamp=${current_date}\n")
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: macos_${{matrix.config}}-ccache-${{steps.ccache_cache_timestamp.outputs.timestamp}}
|
||||
restore-keys: macos_${{matrix.config}}-ccache-
|
||||
- name: setup ccache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = 40M" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
cache-key-prefix: ccache-macos
|
||||
max-size: 200M
|
||||
|
||||
- name: make ${{matrix.config}}
|
||||
run: |
|
||||
ccache -z
|
||||
make ${{matrix.config}}
|
||||
ccache -s
|
||||
- name: Build px4_sitl
|
||||
run: make px4_sitl
|
||||
|
||||
- name: Cache - Stats after px4_sitl
|
||||
run: ccache -s
|
||||
|
||||
- name: Build px4_fmu-v5_default
|
||||
run: make px4_fmu-v5_default
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -29,12 +29,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ['ubuntu:22.04', 'ubuntu:24.04']
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,"image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false]
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,"image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: ${{ matrix.version }}
|
||||
volumes:
|
||||
- /github/workspace:/github/workspace
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
|
||||
- name: Fix git in container
|
||||
run: |
|
||||
@@ -47,15 +48,25 @@ jobs:
|
||||
apt update && apt install git -y
|
||||
git config --global --add safe.directory $(realpath .)
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Use AWS regional apt mirror
|
||||
if: startsWith(runner.name, 'runs-on--')
|
||||
run: ./Tools/ci/use_aws_apt_mirror.sh
|
||||
|
||||
- name: Install Deps, Build, and Make Quick Check
|
||||
run: |
|
||||
# we need to install dependencies and build on the same step
|
||||
# given the stateless nature of docker images
|
||||
./Tools/setup/ubuntu.sh
|
||||
make quick_check
|
||||
- name: Install Deps
|
||||
run: ./Tools/setup/ubuntu.sh
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-ubuntu-${{ matrix.version }}
|
||||
max-size: 200M
|
||||
|
||||
- name: Make Quick Check
|
||||
run: make quick_check
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -51,12 +51,11 @@ jobs:
|
||||
meta_labels: ${{ steps.meta.outputs.labels }}
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.inputs.build_ref || github.ref }}
|
||||
fetch-tags: true
|
||||
submodules: false
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
# If manual dispatch, take the user‐provided input
|
||||
- name: Set PX4 Tag Version
|
||||
@@ -96,12 +95,11 @@ jobs:
|
||||
runs-on: [runs-on,"runner=4cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.inputs.build_ref || github.ref }}
|
||||
fetch-tags: true
|
||||
submodules: false
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
@@ -153,12 +151,11 @@ jobs:
|
||||
(startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry == 'true'))
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.inputs.build_ref || github.ref }}
|
||||
fetch-tags: true
|
||||
submodules: false
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
|
||||
@@ -46,8 +46,8 @@ jobs:
|
||||
source_changed: ${{ steps.changes.outputs.source }}
|
||||
docs_changed: ${{ steps.changes.outputs.docs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v3
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dorny/paths-filter@v4
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
@@ -70,22 +70,19 @@ jobs:
|
||||
contents: read
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.17.0-beta1
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Git ownership workaround
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Cache Restore - ccache
|
||||
id: cache-ccache
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
@@ -104,7 +101,7 @@ jobs:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Cache Save - ccache
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@v5
|
||||
if: always()
|
||||
with:
|
||||
path: ~/.ccache
|
||||
@@ -116,7 +113,7 @@ jobs:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Upload metadata artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
@@ -132,12 +129,12 @@ jobs:
|
||||
contents: write
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.17.0-beta1
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
- uses: runs-on/action@v2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
@@ -148,7 +145,7 @@ jobs:
|
||||
|
||||
- name: Cache Restore - ccache
|
||||
id: cache-ccache
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
@@ -167,7 +164,7 @@ jobs:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Cache Save - ccache
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@v5
|
||||
if: always()
|
||||
with:
|
||||
path: ~/.ccache
|
||||
@@ -213,25 +210,24 @@ jobs:
|
||||
if: always() && (github.event_name == 'pull_request')
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download metadata artifact
|
||||
if: needs.pr-metadata-regen.result == 'success'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
|
||||
- name: Get changed doc files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v46.0.5
|
||||
uses: tj-actions/changed-files@v47
|
||||
with:
|
||||
json: true
|
||||
write_output_files: true
|
||||
@@ -248,7 +244,7 @@ jobs:
|
||||
cat ./logs/prFiles.json
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
@@ -281,15 +277,35 @@ jobs:
|
||||
> ./logs/link-check-results.md || true
|
||||
cat ./logs/link-check-results.md
|
||||
|
||||
- name: Post PR comment with link check results
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
- name: Prepare pr-comment artifact
|
||||
id: prepare-pr-comment
|
||||
run: |
|
||||
if [ ! -s ./logs/filtered-link-check-results.md ]; then
|
||||
echo "No link-check results file; skipping pr-comment artifact."
|
||||
echo "prepared=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
mkdir -p pr-comment
|
||||
cp ./logs/filtered-link-check-results.md pr-comment/body.md
|
||||
cat > pr-comment/manifest.json <<EOF
|
||||
{
|
||||
"pr_number": ${{ github.event.pull_request.number }},
|
||||
"marker": "<!-- pr-comment-poster:docs-link-check -->",
|
||||
"mode": "upsert"
|
||||
}
|
||||
EOF
|
||||
echo "prepared=true" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload pr-comment artifact
|
||||
if: steps.prepare-pr-comment.outputs.prepared == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
header: flaws
|
||||
path: ./logs/filtered-link-check-results.md
|
||||
name: pr-comment
|
||||
path: pr-comment/
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload link check results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: link-check-results
|
||||
path: logs/
|
||||
@@ -313,16 +329,14 @@ jobs:
|
||||
branchname: ${{ steps.set-branch.outputs.branchname }}
|
||||
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Download metadata artifact (PR)
|
||||
if: github.event_name == 'pull_request' && needs.pr-metadata-regen.result == 'success'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
@@ -346,7 +360,7 @@ jobs:
|
||||
echo "releaseversion=$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
@@ -365,7 +379,7 @@ jobs:
|
||||
npm run docs:sitemap
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: docs/.vitepress/dist/
|
||||
@@ -387,7 +401,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: ~/_book
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
lc: [ko, uk, zh-CN] # Target languages https://developer.crowdin.com/language-codes/
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Debug Environment Variables
|
||||
run: |
|
||||
echo "CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_DOCS_PROJECT_ID }}"
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: crowdin push
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
|
||||
@@ -22,12 +22,11 @@ jobs:
|
||||
build:
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
@@ -46,7 +45,7 @@ jobs:
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: docs/.vitepress/dist/
|
||||
@@ -59,7 +58,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: ~/_book
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
name: EKF Change Indicator
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
# If two events are triggered within a short time in the same PR, cancel the run of the oldest event
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
unit_tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: main test
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
make tests TESTFILTER=EKF
|
||||
|
||||
- name: Check if there is a functional change
|
||||
run: git diff --exit-code
|
||||
working-directory: src/modules/ekf2/test/change_indication
|
||||
@@ -1,54 +0,0 @@
|
||||
name: EKF Update Change Indicator
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
jobs:
|
||||
unit_tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
|
||||
env:
|
||||
GIT_COMMITTER_EMAIL: bot@px4.io
|
||||
GIT_COMMITTER_NAME: PX4BuildBot
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: main test
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
make tests TESTFILTER=EKF
|
||||
|
||||
- name: Check if there exists diff and save result in variable
|
||||
id: diff-check
|
||||
working-directory: src/modules/ekf2/test/change_indication
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "CHANGE_INDICATED=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "CHANGE_INDICATED=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: auto-commit any changes to change indication
|
||||
if: steps.diff-check.outputs.CHANGE_INDICATED == 'true'
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
file_pattern: 'src/modules/ekf2/test/change_indication/*.csv'
|
||||
commit_user_name: ${{ env.GIT_COMMITTER_NAME }}
|
||||
commit_user_email: ${{ env.GIT_COMMITTER_EMAIL }}
|
||||
commit_message: |
|
||||
[AUTO COMMIT] update change indication
|
||||
|
||||
See .github/workflows/ekf_update_change_indicator.yml for more details
|
||||
|
||||
- name: if there is a functional change, fail check
|
||||
if: steps.diff-check.outputs.CHANGE_INDICATED == 'true'
|
||||
run: exit 1
|
||||
@@ -18,7 +18,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -29,22 +29,30 @@ jobs:
|
||||
"failsafe_web",
|
||||
]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Install Node v20.18.0
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.18.0
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache - Restore Emscripten SDK
|
||||
id: cache-emsdk
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Git ownership workaround
|
||||
run: git config --system --add safe.directory '*'
|
||||
path: _emscripten_sdk
|
||||
key: emsdk-4.0.15
|
||||
|
||||
- name: Install empscripten
|
||||
if: steps.cache-emsdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
git clone https://github.com/emscripten-core/emsdk.git _emscripten_sdk
|
||||
cd _emscripten_sdk
|
||||
|
||||
@@ -24,9 +24,9 @@ env:
|
||||
jobs:
|
||||
analyze_flash:
|
||||
name: Analyzing ${{ matrix.target }}
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
strategy:
|
||||
matrix:
|
||||
target: [px4_fmu-v5x, px4_fmu-v6x]
|
||||
@@ -36,25 +36,58 @@ jobs:
|
||||
px4_fmu-v6x-bloaty-output: ${{ steps.gen-output.outputs.px4_fmu-v6x-bloaty-output }}
|
||||
px4_fmu-v6x-bloaty-summary-map: ${{ steps.gen-output.outputs.px4_fmu-v6x-bloaty-summary-map }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Git ownership workaround
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Cache - Restore ccache (current)
|
||||
id: cache_current
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-flash-${{ matrix.target }}-current-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-flash-${{ matrix.target }}-current-${{ github.ref_name }}-
|
||||
ccache-flash-${{ matrix.target }}-current-
|
||||
|
||||
- name: Cache - Configure ccache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = 200M" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
echo "compiler_check = content" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
|
||||
- name: Build Target
|
||||
run: make ${{ matrix.target }}_flash-analysis
|
||||
|
||||
- name: Store the ELF with the change
|
||||
run: cp ./build/**/*.elf ./with-change.elf
|
||||
|
||||
- name: Cache - Stats after Current Build
|
||||
run: ccache -s
|
||||
|
||||
- name: Cache - Save ccache (current)
|
||||
if: always()
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ steps.cache_current.outputs.cache-primary-key }}
|
||||
|
||||
- name: Clean previous build
|
||||
run: |
|
||||
make clean
|
||||
make distclean
|
||||
make submodulesclean
|
||||
ccache -C
|
||||
|
||||
- name: If it's a PR checkout the base branch
|
||||
if: ${{ github.event.pull_request }}
|
||||
@@ -68,12 +101,34 @@ jobs:
|
||||
- name: Update submodules
|
||||
run: make submodulesupdate
|
||||
|
||||
- name: Cache - Restore ccache (baseline)
|
||||
id: cache_baseline
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-flash-${{ matrix.target }}-baseline-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-flash-${{ matrix.target }}-baseline-
|
||||
|
||||
- name: Cache - Reset ccache stats
|
||||
run: ccache -z
|
||||
|
||||
- name: Build
|
||||
run: make ${{ matrix.target }}_flash-analysis
|
||||
|
||||
- name: Store the ELF before the change
|
||||
run: cp ./build/**/*.elf ./before-change.elf
|
||||
|
||||
- name: Cache - Stats after Baseline Build
|
||||
run: ccache -s
|
||||
|
||||
- name: Cache - Save ccache (baseline)
|
||||
if: always()
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ steps.cache_baseline.outputs.cache-primary-key }}
|
||||
|
||||
- name: bloaty-action
|
||||
uses: PX4/bloaty-action@v1.0.0
|
||||
id: bloaty-step
|
||||
@@ -93,9 +148,6 @@ jobs:
|
||||
echo '${{ steps.bloaty-step.outputs.bloaty-summary-map }}' >> $GITHUB_OUTPUT
|
||||
echo "$EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
# TODO:
|
||||
# This part of the workflow is causing errors for forks. We should find a way to fix this and enable it again for forks.
|
||||
# Track this issue https://github.com/PX4/PX4-Autopilot/issues/24408
|
||||
post_pr_comment:
|
||||
name: Publish Results
|
||||
runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}"]
|
||||
@@ -105,22 +157,22 @@ jobs:
|
||||
V5X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-percentage) }}
|
||||
V6X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-absolute) }}
|
||||
V6X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-percentage) }}
|
||||
if: github.event.pull_request && github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event.pull_request
|
||||
steps:
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v3
|
||||
uses: peter-evans/find-comment@v4
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: FLASH Analysis
|
||||
body-includes: '<!-- pr-comment-poster:flash-analysis -->'
|
||||
|
||||
- name: Set Build Time
|
||||
id: bt
|
||||
run: |
|
||||
echo "timestamp=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create or update comment
|
||||
- name: Write pr-comment artifact
|
||||
# This can't be moved to the job-level conditions, as GH actions don't allow a job-level if condition to access the env.
|
||||
if: |
|
||||
steps.fc.outputs.comment-id != '' ||
|
||||
@@ -128,27 +180,46 @@ jobs:
|
||||
env.V5X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT) ||
|
||||
env.V6X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
|
||||
env.V6X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT)
|
||||
uses: peter-evans/create-or-update-comment@v4
|
||||
run: |
|
||||
mkdir -p pr-comment
|
||||
cat > pr-comment/manifest.json <<EOF
|
||||
{
|
||||
"pr_number": ${{ github.event.pull_request.number }},
|
||||
"marker": "<!-- pr-comment-poster:flash-analysis -->",
|
||||
"mode": "upsert"
|
||||
}
|
||||
EOF
|
||||
cat > pr-comment/body.md <<'PR_COMMENT_BODY_EOF'
|
||||
<!-- pr-comment-poster:flash-analysis -->
|
||||
## 🔎 FLASH Analysis
|
||||
<details>
|
||||
<summary>px4_fmu-v5x [Total VM Diff: ${{ env.V5X-SUMMARY-MAP-ABS }} byte (${{ env.V5X-SUMMARY-MAP-PERC}} %)]</summary>
|
||||
|
||||
```
|
||||
${{ needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-output }}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>px4_fmu-v6x [Total VM Diff: ${{ env.V6X-SUMMARY-MAP-ABS }} byte (${{ env.V6X-SUMMARY-MAP-PERC }} %)]</summary>
|
||||
|
||||
```
|
||||
${{ needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-output }}
|
||||
```
|
||||
</details>
|
||||
|
||||
**Updated: _${{ steps.bt.outputs.timestamp }}_**
|
||||
PR_COMMENT_BODY_EOF
|
||||
|
||||
- name: Upload pr-comment artifact
|
||||
if: |
|
||||
steps.fc.outputs.comment-id != '' ||
|
||||
env.V5X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
|
||||
env.V5X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT) ||
|
||||
env.V6X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
|
||||
env.V6X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT)
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## 🔎 FLASH Analysis
|
||||
<details>
|
||||
<summary>px4_fmu-v5x [Total VM Diff: ${{ env.V5X-SUMMARY-MAP-ABS }} byte (${{ env.V5X-SUMMARY-MAP-PERC}} %)]</summary>
|
||||
|
||||
```
|
||||
${{ needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-output }}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>px4_fmu-v6x [Total VM Diff: ${{ env.V6X-SUMMARY-MAP-ABS }} byte (${{ env.V6X-SUMMARY-MAP-PERC }} %)]</summary>
|
||||
|
||||
```
|
||||
${{ needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-output }}
|
||||
```
|
||||
</details>
|
||||
|
||||
**Updated: _${{ steps.bt.outputs.timestamp }}_**
|
||||
edit-mode: replace
|
||||
name: pr-comment
|
||||
path: pr-comment/
|
||||
retention-days: 1
|
||||
|
||||
@@ -12,19 +12,24 @@ env:
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc2-4-gb67c65bfe6
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
apt update && apt install -y clang
|
||||
- uses: runs-on/action@v2
|
||||
|
||||
- name: Fix git in Container
|
||||
run: |
|
||||
git config --global --add safe.directory $(realpath .)
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-sitl
|
||||
max-size: 300M
|
||||
|
||||
- name: Build and Run Fuzz Tests
|
||||
run: |
|
||||
@@ -38,7 +43,11 @@ jobs:
|
||||
./Tools/ci/run_fuzz_tests.sh $fuzz_binary 15m
|
||||
done
|
||||
|
||||
# Create a github issue in case of a failure
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Create Issue
|
||||
if: ${{ failure() }}
|
||||
uses: JasonEtco/create-an-issue@v2
|
||||
|
||||
@@ -22,9 +22,9 @@ concurrency:
|
||||
jobs:
|
||||
check_itcm:
|
||||
name: Checking ${{ matrix.target }}
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
image: ghcr.io/px4/px4-dev:v1.17.0-rc2
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -46,14 +46,19 @@ jobs:
|
||||
boards/nxp/mr-tropic/nuttx-config/scripts/itcm_functions_includes.ld
|
||||
boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Git ownership workaround
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-itcm-${{ matrix.target }}
|
||||
max-size: 200M
|
||||
|
||||
- name: Build Target
|
||||
run: make ${{ matrix.target }}
|
||||
|
||||
@@ -65,3 +70,8 @@ jobs:
|
||||
|
||||
- name: Execute the itcm-check
|
||||
run: python3 Tools/itcm_check.py --elf-file built.elf --script-files ${{ matrix.scripts }}
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -16,6 +16,6 @@ jobs:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v6
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
name: MAVROS Mission Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build SITL and Run Tests (inside old ROS container)
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "${GITHUB_WORKSPACE}:/workspace" \
|
||||
-w /workspace \
|
||||
px4io/px4-dev-ros-melodic:2021-09-08 \
|
||||
bash -c '
|
||||
git config --global --add safe.directory /workspace
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
|
||||
./test/rostest_px4_run.sh \
|
||||
mavros_posix_test_mission.test \
|
||||
mission:=MC_mission_box \
|
||||
vehicle:=iris
|
||||
'
|
||||
@@ -1,44 +0,0 @@
|
||||
name: MAVROS Offboard Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build SITL and Run Tests (inside old ROS container)
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "${GITHUB_WORKSPACE}:/workspace" \
|
||||
-w /workspace \
|
||||
px4io/px4-dev-ros-melodic:2021-09-08 \
|
||||
bash -c '
|
||||
git config --global --add safe.directory /workspace
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
|
||||
./test/rostest_px4_run.sh \
|
||||
mavros_posix_tests_offboard_posctl.test \
|
||||
vehicle:=iris
|
||||
'
|
||||
@@ -0,0 +1,73 @@
|
||||
name: MAVROS Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "MAVROS ${{ matrix.config.name }}"
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: px4io/px4-dev-ros-noetic:2021-09-08
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {name: "Mission", test_file: "mavros_posix_test_mission.test", params: "mission:=MC_mission_box vehicle:=iris"}
|
||||
- {name: "Offboard", test_file: "mavros_posix_tests_offboard_posctl.test", params: "vehicle:=iris"}
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Setup - Install Python Test Dependencies
|
||||
run: pip3 install -r Tools/setup/requirements.txt
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-sitl-gazebo-classic
|
||||
max-size: 350M
|
||||
|
||||
- uses: ./.github/actions/build-gazebo-sitl
|
||||
|
||||
- name: Test - MAVROS ${{ matrix.config.name }}
|
||||
run: |
|
||||
./test/rostest_px4_run.sh \
|
||||
${{ matrix.config.test_file }} \
|
||||
${{ matrix.config.params }}
|
||||
timeout-minutes: 10
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Upload - Failed Test Logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: failed-mavros-${{ matrix.config.name }}-logs.zip
|
||||
path: |
|
||||
logs/**/**/**/*.log
|
||||
logs/**/**/**/*.ulg
|
||||
@@ -1,46 +0,0 @@
|
||||
name: Nuttx Target with extra env config
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- px4_fmu-v5_default
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build PX4 and Run Test [${{ matrix.config }}]
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
export PX4_EXTRA_NUTTX_CONFIG='CONFIG_NSH_LOGIN_PASSWORD="test";CONFIG_NSH_CONSOLE_LOGIN=y'
|
||||
echo "PX4_EXTRA_NUTTX_CONFIG: $PX4_EXTRA_NUTTX_CONFIG"
|
||||
|
||||
make ${{ matrix.config }} nuttx_context
|
||||
|
||||
echo "Check that the config option is set"
|
||||
grep CONFIG_NSH_LOGIN_PASSWORD build/${{ matrix.config }}/NuttX/nuttx/.config
|
||||
@@ -0,0 +1,155 @@
|
||||
name: PR Comment Poster
|
||||
|
||||
# Generic PR comment poster. Any analysis workflow (clang-tidy, flash_analysis,
|
||||
# fuzz coverage, SITL perf, etc.) can produce a `pr-comment` artifact and this
|
||||
# workflow will post or update a sticky PR comment with its contents. Designed
|
||||
# so that analysis jobs running on untrusted fork PRs can still get their
|
||||
# results posted back to the PR.
|
||||
#
|
||||
# ==============================================================================
|
||||
# SECURITY INVARIANTS
|
||||
# ==============================================================================
|
||||
# This workflow runs on `workflow_run` which means it runs in the BASE REPO
|
||||
# context with a WRITE token, even when the triggering PR comes from a fork.
|
||||
# That is the entire reason it exists, and also the reason it is a loaded
|
||||
# footgun. Anyone modifying this file MUST preserve the following invariants:
|
||||
#
|
||||
# 1. NEVER check out PR code. No `actions/checkout` with a ref. No git clone
|
||||
# of a fork branch. No execution of scripts from the downloaded artifact.
|
||||
# The ONLY things read from the artifact are `manifest.json` and `body.md`,
|
||||
# and both are treated as opaque data (JSON parsed by the poster script
|
||||
# and markdown posted verbatim via the GitHub API).
|
||||
#
|
||||
# 2. `pr_number` is validated to be a positive integer before use.
|
||||
# `marker` is validated to be printable ASCII only before use. Validation
|
||||
# happens inside Tools/ci/pr-comment-poster.py which is checked out from
|
||||
# the base branch, not from the artifact.
|
||||
#
|
||||
# 3. The comment body is passed to the GitHub API as a JSON field, never
|
||||
# interpolated into a shell command string.
|
||||
#
|
||||
# 4. This workflow file lives on the default branch. `workflow_run` only
|
||||
# loads workflow files from the default branch, so a fork cannot modify
|
||||
# THIS file as part of a PR. The fork CAN cause this workflow to fire
|
||||
# by triggering a producer workflow that uploads a `pr-comment` artifact.
|
||||
# That is intended.
|
||||
#
|
||||
# 5. The artifact-name filter (`pr-comment`) is the only gate on which
|
||||
# workflow runs get processed. Any workflow in this repo that uploads
|
||||
# an artifact named `pr-comment` is trusted to have written the
|
||||
# manifest and body itself, NOT copied fork-controlled content into
|
||||
# them. Producer workflows are responsible for that.
|
||||
#
|
||||
# 6. `actions/checkout@v6` below uses NO ref (so it pulls the base branch,
|
||||
# the default-branch commit this workflow file was loaded from) AND uses
|
||||
# sparse-checkout to materialize ONLY Tools/ci/pr-comment-poster.py and
|
||||
# its stdlib-only helper module Tools/ci/_github_helpers.py. The rest of
|
||||
# the repo never touches the workspace. This is safe: the only files the
|
||||
# job executes are base-repo Python scripts that were reviewed through
|
||||
# normal code review, never anything from the PR.
|
||||
#
|
||||
# ==============================================================================
|
||||
# ARTIFACT CONTRACT
|
||||
# ==============================================================================
|
||||
# Producers upload an artifact named exactly `pr-comment` containing:
|
||||
#
|
||||
# manifest.json:
|
||||
# {
|
||||
# "pr_number": 12345, // required, int > 0
|
||||
# "marker": "<!-- pr-comment-poster:flash-analysis -->", // required, printable ASCII
|
||||
# "mode": "upsert" // optional, default "upsert"
|
||||
# }
|
||||
#
|
||||
# body.md: the markdown content of the comment. Posted verbatim.
|
||||
#
|
||||
# The `marker` string is used to find an existing comment to update. It MUST
|
||||
# be unique per producer (e.g. include the producer name). If no existing
|
||||
# comment contains the marker, a new one is created. If the marker is found
|
||||
# in an existing comment, that comment is edited in place.
|
||||
#
|
||||
# Producers MUST write `pr_number` from their own workflow context
|
||||
# (`github.event.pull_request.number`) and MUST NOT read it from any
|
||||
# fork-controlled source.
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
# Producers that may upload a `pr-comment` artifact. When a new producer
|
||||
# is wired up, add its workflow name here. Runs of workflows not in this
|
||||
# list will never trigger the poster. Every run of a listed workflow will
|
||||
# trigger the poster, which will no-op if no `pr-comment` artifact exists.
|
||||
workflows:
|
||||
- "FLASH usage analysis"
|
||||
- "Docs - Orchestrator"
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
post:
|
||||
name: Post PR Comment
|
||||
runs-on: ubuntu-latest
|
||||
# Only run for pull_request producer runs. Push-to-main and other
|
||||
# non-PR triggers would have no comment to post, and silently no-oping
|
||||
# inside the script made it look like the poster was broken. Gating at
|
||||
# the job level surfaces those as a clean "Skipped" in the UI instead.
|
||||
if: >-
|
||||
github.event.workflow_run.conclusion != 'cancelled'
|
||||
&& github.event.workflow_run.event == 'pull_request'
|
||||
steps:
|
||||
# Checkout runs first so the poster script is available AND so that
|
||||
# actions/checkout@v6's default clean step does not delete the artifact
|
||||
# zip that the next step writes into the workspace. Sparse-checkout
|
||||
# restricts the materialized tree to just the poster script.
|
||||
- name: Checkout poster script only
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: |
|
||||
Tools/ci/pr-comment-poster.py
|
||||
Tools/ci/_github_helpers.py
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
- name: Download pr-comment artifact
|
||||
id: download
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
const match = artifacts.data.artifacts.find(a => a.name === 'pr-comment');
|
||||
if (!match) {
|
||||
core.info('No pr-comment artifact on this run; nothing to post.');
|
||||
core.setOutput('found', 'false');
|
||||
return;
|
||||
}
|
||||
const download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: match.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
const fs = require('fs');
|
||||
fs.writeFileSync('pr-comment.zip', Buffer.from(download.data));
|
||||
core.setOutput('found', 'true');
|
||||
|
||||
- name: Unpack artifact
|
||||
if: steps.download.outputs.found == 'true'
|
||||
run: |
|
||||
mkdir -p pr-comment
|
||||
unzip -q pr-comment.zip -d pr-comment
|
||||
|
||||
- name: Validate artifact
|
||||
if: steps.download.outputs.found == 'true'
|
||||
run: python3 Tools/ci/pr-comment-poster.py validate pr-comment
|
||||
|
||||
- name: Upsert sticky comment
|
||||
if: steps.download.outputs.found == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: python3 Tools/ci/pr-comment-poster.py post pr-comment
|
||||
@@ -0,0 +1,177 @@
|
||||
name: PR Review Poster
|
||||
|
||||
# Generic PR review-comment poster. Sibling of "PR Comment Poster": that
|
||||
# workflow posts sticky issue-style comments, this one posts line-anchored
|
||||
# review comments on the "Files changed" tab. Any analysis workflow that
|
||||
# wants to flag specific lines can produce a `pr-review` artifact and this
|
||||
# workflow will dismiss any stale matching review and post a fresh one.
|
||||
# Designed so analysis jobs running on untrusted fork PRs can still get
|
||||
# their inline annotations posted back to the PR.
|
||||
#
|
||||
# ==============================================================================
|
||||
# SECURITY INVARIANTS
|
||||
# ==============================================================================
|
||||
# This workflow runs on `workflow_run` which means it runs in the BASE REPO
|
||||
# context with a WRITE token, even when the triggering PR comes from a fork.
|
||||
# That is the entire reason it exists, and also the reason it is a loaded
|
||||
# footgun. Anyone modifying this file MUST preserve the following invariants:
|
||||
#
|
||||
# 1. NEVER check out PR code. No `actions/checkout` with a ref. No git clone
|
||||
# of a fork branch. No execution of scripts from the downloaded artifact.
|
||||
# The ONLY things read from the artifact are `manifest.json` and
|
||||
# `comments.json`, and both are treated as opaque data (JSON parsed by
|
||||
# the poster script and the comment fields posted via the GitHub API).
|
||||
#
|
||||
# 2. `pr_number` is validated to be a positive integer before use.
|
||||
# `marker` is validated to be printable ASCII only before use.
|
||||
# `commit_sha` is validated to be 40 lowercase hex characters.
|
||||
# `event` is validated against an allowlist of `COMMENT` and
|
||||
# `REQUEST_CHANGES`. `APPROVE` is intentionally forbidden so a bot
|
||||
# cannot approve a pull request. Validation happens inside
|
||||
# Tools/ci/pr-review-poster.py which is checked out from the base
|
||||
# branch, not from the artifact.
|
||||
#
|
||||
# 3. Comment bodies and the optional summary are passed to the GitHub API
|
||||
# as JSON fields, never interpolated into a shell command string.
|
||||
#
|
||||
# 4. This workflow file lives on the default branch. `workflow_run` only
|
||||
# loads workflow files from the default branch, so a fork cannot modify
|
||||
# THIS file as part of a PR. The fork CAN cause this workflow to fire
|
||||
# by triggering a producer workflow that uploads a `pr-review`
|
||||
# artifact. That is intended.
|
||||
#
|
||||
# 5. The artifact-name filter (`pr-review`) is the only gate on which
|
||||
# workflow runs get processed. Any workflow in this repo that uploads
|
||||
# an artifact named `pr-review` is trusted to have written the
|
||||
# manifest and comments itself, NOT copied fork-controlled content
|
||||
# into them. Producer workflows are responsible for that.
|
||||
#
|
||||
# 6. `actions/checkout@v6` below uses NO ref (so it pulls the base branch,
|
||||
# the default-branch commit this workflow file was loaded from) AND
|
||||
# uses sparse-checkout to materialize ONLY
|
||||
# Tools/ci/pr-review-poster.py and its stdlib-only helper module
|
||||
# Tools/ci/_github_helpers.py. The rest of the repo never touches the
|
||||
# workspace. This is safe: the only files the job executes are
|
||||
# base-repo Python scripts that were reviewed through normal code
|
||||
# review, never anything from the PR.
|
||||
#
|
||||
# 7. Stale-review dismissal is restricted to reviews whose AUTHOR is
|
||||
# `github-actions[bot]` AND whose body contains the producer's
|
||||
# marker. A fork PR cannot impersonate the bot login, and cannot
|
||||
# inject the marker into a human reviewer's body without API
|
||||
# access. Both filters together prevent the poster from ever
|
||||
# dismissing a human review.
|
||||
#
|
||||
# ==============================================================================
|
||||
# ARTIFACT CONTRACT
|
||||
# ==============================================================================
|
||||
# Producers upload an artifact named exactly `pr-review` containing:
|
||||
#
|
||||
# manifest.json:
|
||||
# {
|
||||
# "pr_number": 12345, // required, int > 0
|
||||
# "marker": "<!-- pr-review-poster:clang-tidy -->", // required, printable ASCII
|
||||
# "event": "REQUEST_CHANGES", // required, "COMMENT" | "REQUEST_CHANGES"
|
||||
# "commit_sha": "0123456789abcdef0123456789abcdef01234567", // required, 40 hex chars
|
||||
# "summary": "Optional review summary text" // optional
|
||||
# }
|
||||
#
|
||||
# comments.json: JSON array of line-anchored review comment objects:
|
||||
# [
|
||||
# {"path": "src/foo.cpp", "line": 42, "side": "RIGHT", "body": "..."},
|
||||
# {"path": "src/bar.hpp", "start_line": 10, "line": 15,
|
||||
# "side": "RIGHT", "start_side": "RIGHT", "body": "..."}
|
||||
# ]
|
||||
#
|
||||
# The `marker` string is used to find an existing matching review to
|
||||
# dismiss before posting a new one. It MUST be unique per producer (e.g.
|
||||
# include the producer name).
|
||||
#
|
||||
# Producers MUST write `pr_number` and `commit_sha` from their own
|
||||
# workflow context (`github.event.pull_request.number` and
|
||||
# `github.event.pull_request.head.sha`) and MUST NOT read either from any
|
||||
# fork-controlled source.
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
# Producers that may upload a `pr-review` artifact. When a new
|
||||
# producer is wired up, add its workflow name here. Runs of workflows
|
||||
# not in this list will never trigger the poster. Every run of a
|
||||
# listed workflow will trigger the poster, which will no-op if no
|
||||
# `pr-review` artifact exists.
|
||||
workflows:
|
||||
- "Static Analysis"
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
post:
|
||||
name: Post PR Review
|
||||
runs-on: ubuntu-latest
|
||||
# Only run for pull_request producer runs. Push-to-main and other
|
||||
# non-PR triggers have no review to post, so gating at the job level
|
||||
# surfaces those as a clean "Skipped" in the UI instead of a
|
||||
# silent no-op buried inside the script.
|
||||
if: >-
|
||||
github.event.workflow_run.conclusion != 'cancelled'
|
||||
&& github.event.workflow_run.event == 'pull_request'
|
||||
steps:
|
||||
# Checkout runs first so the poster scripts are available AND so
|
||||
# that actions/checkout@v6's default clean step does not delete the
|
||||
# artifact zip that the next step writes into the workspace.
|
||||
# Sparse-checkout restricts the materialized tree to just the
|
||||
# poster script and its stdlib helper module.
|
||||
- name: Checkout poster script only
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: |
|
||||
Tools/ci/pr-review-poster.py
|
||||
Tools/ci/_github_helpers.py
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
- name: Download pr-review artifact
|
||||
id: download
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
const match = artifacts.data.artifacts.find(a => a.name === 'pr-review');
|
||||
if (!match) {
|
||||
core.info('No pr-review artifact on this run; nothing to post.');
|
||||
core.setOutput('found', 'false');
|
||||
return;
|
||||
}
|
||||
const download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: match.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
const fs = require('fs');
|
||||
fs.writeFileSync('pr-review.zip', Buffer.from(download.data));
|
||||
core.setOutput('found', 'true');
|
||||
|
||||
- name: Unpack artifact
|
||||
if: steps.download.outputs.found == 'true'
|
||||
run: |
|
||||
mkdir -p pr-review
|
||||
unzip -q pr-review.zip -d pr-review
|
||||
|
||||
- name: Validate artifact
|
||||
if: steps.download.outputs.found == 'true'
|
||||
run: python3 Tools/ci/pr-review-poster.py validate pr-review
|
||||
|
||||
- name: Post PR review
|
||||
if: steps.download.outputs.found == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: python3 Tools/ci/pr-review-poster.py post pr-review
|
||||
@@ -14,20 +14,23 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install Python3
|
||||
run: sudo apt-get install python3 python3-setuptools python3-pip -y
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install tools
|
||||
run: python3 -m pip install mypy types-requests flake8 --break-system-packages
|
||||
run: pip install mypy types-requests flake8
|
||||
|
||||
- name: Check MAVSDK test scripts with mypy
|
||||
run: $HOME/.local/bin/mypy --strict test/mavsdk_tests/*.py
|
||||
run: mypy --strict test/mavsdk_tests/*.py
|
||||
|
||||
- name: Check MAVSDK test scripts with flake8
|
||||
run: $HOME/.local/bin/flake8 test/mavsdk_tests/*.py
|
||||
run: flake8 test/mavsdk_tests/*.py
|
||||
|
||||
@@ -23,16 +23,18 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev-ros2-galactic:2021-09-08
|
||||
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Git Ownership Workaround
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Update ROS Keys
|
||||
@@ -45,30 +47,21 @@ jobs:
|
||||
run: |
|
||||
apt update && apt install -y gazebo11 libgazebo11-dev gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly libgstreamer-plugins-base1.0-dev
|
||||
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_timestamp
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ros_integration_tests-${{matrix.config.build_type}}-ccache-${{steps.ccache_cache_timestamp.outputs.timestamp}}
|
||||
restore-keys: ros_integration_tests-${{matrix.config.build_type}}-ccache-
|
||||
- name: setup ccache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = 300M" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
cache-key-prefix: ccache-ros-integration
|
||||
max-size: 400M
|
||||
|
||||
- name: Get and build micro-xrce-dds-agent
|
||||
- name: Cache - Restore Micro-XRCE-DDS Agent
|
||||
id: cache-xrce-agent
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /opt/Micro-XRCE-DDS-Agent
|
||||
key: xrce-agent-v2.2.1-fastdds-2.8.2-galactic-2021-09-08
|
||||
|
||||
- name: Build - Micro-XRCE-DDS Agent (v2.2.1)
|
||||
if: steps.cache-xrce-agent.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd /opt
|
||||
git clone --recursive https://github.com/eProsima/Micro-XRCE-DDS-Agent.git
|
||||
@@ -79,10 +72,18 @@ jobs:
|
||||
cd build
|
||||
cmake ..
|
||||
make -j2
|
||||
- name: ccache post-run micro-xrce-dds-agent
|
||||
run: ccache -s
|
||||
|
||||
- name: Get and build the ros2 interface library
|
||||
- name: Cache - Restore PX4 ROS 2 Interface Library Workspace
|
||||
id: cache-px4-ros2-ws
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /opt/px4_ws
|
||||
# Bump 'v1' when the cached workspace layout changes in a way
|
||||
# that is not captured by the message/service hash below.
|
||||
key: px4-ros2-ws-v1-galactic-2021-09-08-${{ hashFiles('msg/*.msg', 'msg/versioned/*.msg', 'srv/*.srv') }}
|
||||
|
||||
- name: Build - PX4 ROS 2 Interface Library
|
||||
if: steps.cache-px4-ros2-ws.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
PX4_DIR="$(pwd)"
|
||||
@@ -108,19 +109,8 @@ jobs:
|
||||
"${PX4_DIR}/Tools/copy_to_ros_ws.sh" "$(pwd)"
|
||||
rm -rf src/translation_node src/px4_msgs_old
|
||||
colcon build --symlink-install
|
||||
- name: ccache post-run ros workspace
|
||||
run: ccache -s
|
||||
|
||||
- name: Build PX4
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: make px4_sitl_default
|
||||
- name: ccache post-run px4/firmware
|
||||
run: ccache -s
|
||||
- name: Build SITL Gazebo
|
||||
run: make px4_sitl_default sitl_gazebo-classic
|
||||
- name: ccache post-run sitl_gazebo-classic
|
||||
run: ccache -s
|
||||
- uses: ./.github/actions/build-gazebo-sitl
|
||||
|
||||
- name: Core dump settings
|
||||
run: |
|
||||
@@ -135,9 +125,14 @@ jobs:
|
||||
test/ros_test_runner.py --verbose --model iris --force-color
|
||||
timeout-minutes: 45
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Upload failed logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: failed-logs.zip
|
||||
path: |
|
||||
|
||||
@@ -10,6 +10,9 @@ on:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -20,8 +23,8 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
name: Build and test
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
name: Build and test [${{ matrix.config.ros_version }}]
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -29,33 +32,43 @@ jobs:
|
||||
- {ros_version: "humble", ubuntu: "jammy"}
|
||||
- {ros_version: "jazzy", ubuntu: "noble"}
|
||||
container:
|
||||
image: rostooling/setup-ros-docker:ubuntu-${{ matrix.config.ubuntu }}-latest
|
||||
image: ros:${{ matrix.config.ros_version }}-ros-base-${{ matrix.config.ubuntu }}
|
||||
steps:
|
||||
- name: Setup ROS 2 (${{ matrix.config.ros_version }})
|
||||
uses: ros-tooling/setup-ros@v0.7
|
||||
with:
|
||||
required-ros-distributions: ${{ matrix.config.ros_version }}
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Workaround for https://github.com/actions/runner/issues/2033
|
||||
- name: ownership workaround
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
cache-key-prefix: ccache-ros-translation-${{ matrix.config.ros_version }}
|
||||
max-size: 150M
|
||||
base-dir: /ros_ws
|
||||
install-ccache: 'true'
|
||||
|
||||
- name: Check .msg file versioning
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
./Tools/ci/check_msg_versioning.sh ${{ github.event.pull_request.base.sha }} ${{github.event.pull_request.head.sha}}
|
||||
|
||||
- name: Build and test
|
||||
- name: Build - Translation Node
|
||||
run: |
|
||||
ros_ws=/ros_ws
|
||||
mkdir -p $ros_ws/src
|
||||
./Tools/copy_to_ros_ws.sh $ros_ws
|
||||
cd $ros_ws
|
||||
source /opt/ros/${{ matrix.config.ros_version }}/setup.sh
|
||||
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --symlink-install --event-handlers=console_cohesion+
|
||||
source ./install/setup.sh
|
||||
./build/translation_node/translation_node_unit_tests
|
||||
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache --symlink-install --event-handlers=console_cohesion+
|
||||
|
||||
- name: Test - Translation Node Unit Tests
|
||||
run: |
|
||||
source /ros_ws/install/setup.sh
|
||||
/ros_ws/build/translation_node/translation_node_unit_tests
|
||||
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: false
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.branch || github.ref }}
|
||||
fetch-depth: 1
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
- name: Create issue if problems found
|
||||
if: steps.check.outputs.has_issues == 'true'
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
@@ -24,7 +24,7 @@ concurrency:
|
||||
jobs:
|
||||
build:
|
||||
name: Testing PX4 ${{ matrix.config.model }}
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev-simulation-focal:2021-09-08
|
||||
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
|
||||
@@ -37,53 +37,25 @@ jobs:
|
||||
# transitions). Re-enable once the test infrastructure is stabilized.
|
||||
# - {model: "tailsitter" , latitude: "29.660316", longitude: "-82.316658", altitude: "30", build_type: "RelWithDebInfo" } # Florida
|
||||
# - {model: "standard_vtol", latitude: "47.397742", longitude: "8.545594", altitude: "488", build_type: "Coverage" } # Zurich
|
||||
env:
|
||||
PX4_CMAKE_BUILD_TYPE: ${{ matrix.config.build_type }}
|
||||
PX4_SBOM_DISABLE: 1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Git Ownership Workaround
|
||||
fetch-depth: 1
|
||||
- name: Configure Git Safe Directory
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- id: set-timestamp
|
||||
name: Set timestamp for cache
|
||||
run: echo "::set-output name=timestamp::$(date +"%Y%m%d%H%M%S")"
|
||||
|
||||
- name: Cache Key Config
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/setup-ccache
|
||||
id: ccache
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: sitl-ccache-${{ steps.set-timestamp.outputs.timestamp }}
|
||||
restore-keys: sitl-ccache-${{ steps.set-timestamp.outputs.timestamp }}
|
||||
cache-key-prefix: ccache-sitl-gazebo-classic
|
||||
max-size: 350M
|
||||
|
||||
- name: Cache Conf Config
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
echo "compression_level = 6" >> ~/.ccache/ccache.conf
|
||||
echo "max_size = 120M" >> ~/.ccache/ccache.conf
|
||||
echo "hash_dir = false" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
ccache -z
|
||||
|
||||
- name: Build PX4
|
||||
env:
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: make px4_sitl_default
|
||||
|
||||
- name: Cache Post-Run [px4_sitl_default]
|
||||
run: ccache -s
|
||||
|
||||
- name: Build SITL Gazebo
|
||||
env:
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
run: make px4_sitl_default sitl_gazebo-classic
|
||||
|
||||
- name: Cache Post-Run [sitl_gazebo-classic]
|
||||
run: ccache -s
|
||||
- uses: ./.github/actions/build-gazebo-sitl
|
||||
|
||||
- name: Download MAVSDK
|
||||
run: wget "https://github.com/mavlink/MAVSDK/releases/download/v$(cat test/mavsdk_tests/MAVSDK_VERSION)/libmavsdk-dev_$(cat test/mavsdk_tests/MAVSDK_VERSION)_ubuntu20.04_amd64.deb"
|
||||
@@ -96,19 +68,19 @@ jobs:
|
||||
PX4_HOME_LAT: ${{matrix.config.latitude}}
|
||||
PX4_HOME_LON: ${{matrix.config.longitude}}
|
||||
PX4_HOME_ALT: ${{matrix.config.altitude}}
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
run: |
|
||||
export
|
||||
ulimit -a
|
||||
|
||||
- name: Build PX4 / MAVSDK tests
|
||||
env:
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
DONT_RUN: 1
|
||||
run: make px4_sitl_default sitl_gazebo-classic mavsdk_tests
|
||||
|
||||
- name: Cache Post-Run [px4_sitl_default sitl_gazebo-classic mavsdk_tests]
|
||||
run: ccache -s
|
||||
- uses: ./.github/actions/save-ccache
|
||||
if: always()
|
||||
with:
|
||||
cache-primary-key: ${{ steps.ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Core Dump Settings
|
||||
run: |
|
||||
@@ -120,13 +92,12 @@ jobs:
|
||||
PX4_HOME_LAT: ${{matrix.config.latitude}}
|
||||
PX4_HOME_LON: ${{matrix.config.longitude}}
|
||||
PX4_HOME_ALT: ${{matrix.config.altitude}}
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
run: test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 10 --abort-early --model ${{matrix.config.model}} test/mavsdk_tests/configs/sitl.json --verbose --force-color
|
||||
timeout-minutes: 45
|
||||
|
||||
- name: Upload failed logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: failed-${{matrix.config.model}}-logs.zip
|
||||
path: |
|
||||
@@ -140,7 +111,7 @@ jobs:
|
||||
|
||||
- name: Upload PX4 coredump
|
||||
if: failure() && ${{ hashFiles('px4.core') != '' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: coredump
|
||||
path: px4.core
|
||||
@@ -157,7 +128,7 @@ jobs:
|
||||
|
||||
- name: Upload Coverage Information to Codecov
|
||||
if: contains(matrix.config.build_type, 'Coverage')
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
flags: mavsdk
|
||||
|
||||
@@ -2,6 +2,7 @@ name: 'Handle stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
@@ -9,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
operations-per-run: 250
|
||||
operations-per-run: 1500
|
||||
days-before-stale: 90
|
||||
days-before-close: 30
|
||||
stale-issue-label: 'stale'
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
steps:
|
||||
- name: Checkout PX4 repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup git credentials
|
||||
run: |
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
TAG_NAME: ${{ github.event_name == 'workflow_dispatch' && inputs.tag_name || github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout PX4 repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
@@ -229,6 +229,28 @@ endif()
|
||||
#
|
||||
project(px4 CXX C ASM)
|
||||
|
||||
# Silence Apple ranlib "has no symbols" warnings. Several PX4 sources are
|
||||
# wrapped in #if defined(CONFIG_*) guards (e.g. platforms/common/i2c.cpp,
|
||||
# spi.cpp, board_common.c, pab_manifest.c, px4_log_history.cpp) and some
|
||||
# libraries carry a dummy.cpp placeholder, all of which legitimately produce
|
||||
# empty object files on POSIX/SITL. GNU ranlib ignores this; Apple's warns.
|
||||
#
|
||||
# The warning is actually emitted by `ar qc` (which implicitly builds a symbol
|
||||
# table), not by the standalone ranlib call. So we use `ar qcS` to skip the
|
||||
# implicit symbol table, then let CMAKE_*_ARCHIVE_FINISH run ranlib with the
|
||||
# -no_warning_for_no_symbols flag to add it quietly.
|
||||
if(APPLE)
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_ASM_ARCHIVE_CREATE "<CMAKE_AR> qcS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_ASM_ARCHIVE_APPEND "<CMAKE_AR> qS <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
set(CMAKE_ASM_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
|
||||
# CMake build type (Debug Release RelWithDebInfo MinSizeRel Coverage)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
if(${PX4_PLATFORM} STREQUAL "nuttx")
|
||||
|
||||
+13
-2
@@ -1,9 +1,11 @@
|
||||
Maintainers
|
||||
===========
|
||||
|
||||
See [the documentation on Maintainers](https://docs.px4.io/main/en/contribute/maintainers.html) to learn about the role of the maintainers and the process to become one.
|
||||
PX4 is maintained by a group of contributors trusted to steward the project. All maintainers listed below are members of the @PX4/dev-team, have write access, and participate in maintainer decisions. We recognize two types: **Code Owners**, responsible for specific components, and **Reviewers**, who help across the project without a fixed component.
|
||||
|
||||
**Active Maintainers**
|
||||
See [the documentation on Maintainers](https://docs.px4.io/main/en/contribute/maintainers) to learn about the role of the maintainers and the process to become one.
|
||||
|
||||
**Code Owners**
|
||||
|
||||
| Name | Sector | GitHub | Chat | email
|
||||
|-------------------------|--------|--------|------|----------------
|
||||
@@ -23,6 +25,15 @@ See [the documentation on Maintainers](https://docs.px4.io/main/en/contribute/ma
|
||||
| Jacob Dahl | Simulation | [@dakejahl](https://github.com/dakejahl) | dakejahl | <dahl.jakejacob@gmail.com>
|
||||
|
||||
|
||||
**Reviewers**
|
||||
|
||||
Reviewers help maintain PX4 across the project without ownership of a specific component.
|
||||
|
||||
| Name | GitHub | Chat | email
|
||||
|------|--------|------|----------------------
|
||||
| Onur Ozkan | [@onur-ozkan](https://github.com/onur-ozkan) | onur_ozkan0126 | <onur@orkavian.com>
|
||||
|
||||
|
||||
**Documentation Maintainers**
|
||||
|
||||
| Name | GitHub | Chat | email
|
||||
|
||||
@@ -70,7 +70,17 @@ PX4 is an open-source autopilot stack for drones and unmanned vehicles. It suppo
|
||||
|
||||
<sub>…and many more: helicopters, autogyros, airships, submarines, boats, and other experimental platforms. These frames have basic support but are not part of the regular flight-test program. See the <a href="https://docs.px4.io/main/en/airframes/airframe_reference.html">full airframe reference</a>.</sub>
|
||||
|
||||
## Quick Start
|
||||
## Try PX4
|
||||
|
||||
Run PX4 in simulation with a single command. No build tools, no dependencies beyond Docker:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -p 14550:14550/udp px4io/px4-sitl:latest
|
||||
```
|
||||
|
||||
Open [QGroundControl](https://qgroundcontrol.com) and fly. See [PX4 Simulation Quickstart](../dev_setup/px4_simulation_quickstart.md) for more options.
|
||||
|
||||
## Build from Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
|
||||
|
||||
@@ -193,6 +193,7 @@ endif()
|
||||
# board custom init files
|
||||
set(OPTIONAL_BOARD_RC)
|
||||
list(APPEND OPTIONAL_BOARD_RC
|
||||
rc.board_early
|
||||
rc.board_defaults
|
||||
rc.board_sensors
|
||||
rc.board_extras
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
param set UAVCAN_ENABLE 0
|
||||
|
||||
param set-default CA_AIRFRAME 1
|
||||
param set-default CA_ROTOR_COUNT 1
|
||||
param set-default CA_ROTOR0_PX 0.3
|
||||
|
||||
@@ -38,7 +39,6 @@ param set-default SYS_HITL 2
|
||||
# - without real battery
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
param set SIH_T_MAX 6
|
||||
param set SIH_MASS 0.3
|
||||
param set SIH_IXX 0.00402
|
||||
param set SIH_IYY 0.0144
|
||||
@@ -48,3 +48,21 @@ param set SIH_KDV 0.2
|
||||
|
||||
param set SIH_VEHICLE_TYPE 1 # sih as fixed wing
|
||||
param set RWTO_TKOFF 1 # enable takeoff from runway (as opposed to launched)
|
||||
|
||||
# pusher propeller model with advance ratio, model from UIUC APC 8x6"
|
||||
param set SIH_F_T_MAX 6
|
||||
param set SIH_F_Q_MAX 0.03
|
||||
# if SIH_F_CT0 > 0, SIH_F_T_MAX and SIH_F_Q_MAX will be overridden
|
||||
param set SIH_F_CT0 0.131
|
||||
param set SIH_F_CT1 0.004
|
||||
param set SIH_F_CT2 -0.146
|
||||
param set SIH_F_CP0 0.0777
|
||||
param set SIH_F_CP1 0.0498
|
||||
param set SIH_F_CP2 -0.11
|
||||
param set SIH_F_DIA_INCH 8
|
||||
param set SIH_F_RPM_MAX 9000
|
||||
|
||||
param set-default FW_AIRSPD_MIN 7
|
||||
param set-default FW_AIRSPD_TRIM 10
|
||||
param set-default FW_AIRSPD_MAX 12
|
||||
param set-default FW_PSP_OFF 0.5
|
||||
|
||||
@@ -28,6 +28,7 @@ param set-default VT_FW_DIFTHR_EN 1
|
||||
param set-default VT_FW_DIFTHR_S_Y 0.3
|
||||
param set-default MPC_MAN_Y_MAX 60
|
||||
param set-default MC_PITCH_P 5
|
||||
param set-default FW_PSP_OFF 5
|
||||
|
||||
param set-default CA_AIRFRAME 4
|
||||
param set-default CA_ROTOR_COUNT 2
|
||||
@@ -56,7 +57,6 @@ param set-default HIL_ACT_REV 32
|
||||
param set-default MAV_TYPE 19
|
||||
|
||||
|
||||
|
||||
# set SYS_HITL to 2 to start the SIH and avoid sensors startup
|
||||
param set-default SYS_HITL 2
|
||||
|
||||
@@ -66,8 +66,9 @@ param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
param set-default SENS_DPRES_OFF 0.001
|
||||
|
||||
param set SIH_T_MAX 2.0
|
||||
param set SIH_Q_MAX 0.0165
|
||||
# tailsitter is equipped with two forward propellers
|
||||
param set SIH_F_T_MAX 2
|
||||
param set SIH_F_Q_MAX 0.0165
|
||||
param set SIH_MASS 0.2
|
||||
# IXX and IZZ are inverted from the thesis as the body frame is pitched by 90 deg
|
||||
param set SIH_IXX 0.00354
|
||||
@@ -77,6 +78,19 @@ param set SIH_IXZ 0
|
||||
param set SIH_KDV 0.2
|
||||
param set SIH_L_ROLL 0.145
|
||||
|
||||
# propeller diameter, rpm, and coeffs coming from the thesis
|
||||
# Modeling and control of a flying wing tailsitter unmanned aerial vehicle."
|
||||
# Chiappinelli, Romain, supervised by Nahon, Meyer, McGill University, Masters thesis, 2018.
|
||||
# if SIH_F_CT0 > 0, SIH_F_T_MAX and SIH_F_Q_MAX will be overridden
|
||||
param set SIH_F_CT0 0.1342
|
||||
param set SIH_F_CT1 -0.1196
|
||||
param set SIH_F_CT2 -0.1281
|
||||
param set SIH_F_CP0 0.0522
|
||||
param set SIH_F_CP1 -0.0146
|
||||
param set SIH_F_CP2 -0.0602
|
||||
param set SIH_F_DIA_INCH 5
|
||||
param set SIH_F_RPM_MAX 14000
|
||||
|
||||
# sih as tailsitter
|
||||
param set SIH_VEHICLE_TYPE 2
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ param set-default CA_SV_CS2_TYPE 4 # rudder
|
||||
param set-default FW_AIRSPD_MIN 7
|
||||
param set-default FW_AIRSPD_TRIM 10
|
||||
param set-default FW_AIRSPD_MAX 12
|
||||
param set-default VT_FWD_THRUST_EN 1
|
||||
|
||||
param set-default HIL_ACT_FUNC1 101
|
||||
param set-default HIL_ACT_FUNC2 102
|
||||
@@ -77,6 +78,7 @@ param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
param set-default SENS_DPRES_OFF 0.001
|
||||
|
||||
# quadrotor propellers
|
||||
param set SIH_T_MAX 2.0
|
||||
param set SIH_Q_MAX 0.0165
|
||||
param set SIH_MASS 0.2
|
||||
@@ -88,5 +90,18 @@ param set SIH_IXZ 0
|
||||
param set SIH_KDV 0.2
|
||||
param set SIH_L_ROLL 0.2
|
||||
|
||||
# pusher propeller model with advance ratio, model from UIUC APC 8x6"
|
||||
param set SIH_F_T_MAX 6
|
||||
param set SIH_F_Q_MAX 0.03
|
||||
# if SIH_F_CT0 > 0, SIH_F_T_MAX and SIH_F_Q_MAX will be overridden
|
||||
param set SIH_F_CT0 0.131
|
||||
param set SIH_F_CT1 0.004
|
||||
param set SIH_F_CT2 -0.146
|
||||
param set SIH_F_CP0 0.0777
|
||||
param set SIH_F_CP1 0.0498
|
||||
param set SIH_F_CP2 -0.11
|
||||
param set SIH_F_DIA_INCH 8
|
||||
param set SIH_F_RPM_MAX 9000
|
||||
|
||||
# sih as standard vtol
|
||||
param set SIH_VEHICLE_TYPE 3
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# @name SIH Hexacopter X
|
||||
#
|
||||
# @type Simulation
|
||||
# @class Copter
|
||||
#
|
||||
# @maintainer Romain Chiappinelli <romain.chiap@gmail.com>
|
||||
#
|
||||
# @board px4_fmu-v2 exclude
|
||||
#
|
||||
|
||||
. ${R}etc/init.d/rc.mc_defaults
|
||||
|
||||
param set UAVCAN_ENABLE 0
|
||||
|
||||
# set SYS_HITL to 2 to start the SIH and avoid sensors startup
|
||||
param set SYS_HITL 2
|
||||
|
||||
# disable some checks to allow to fly:
|
||||
# - without real battery
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
param set SIH_VEHICLE_TYPE 4
|
||||
|
||||
# Symmetric hexacopter X clockwise motor numbering
|
||||
param set-default CA_ROTOR_COUNT 6
|
||||
param set-default CA_ROTOR0_PX 0.866
|
||||
param set-default CA_ROTOR0_PY 0.5
|
||||
param set-default CA_ROTOR1_PX 0
|
||||
param set-default CA_ROTOR1_PY 1
|
||||
param set-default CA_ROTOR1_KM -0.05
|
||||
param set-default CA_ROTOR2_PX -0.866
|
||||
param set-default CA_ROTOR2_PY 0.5
|
||||
param set-default CA_ROTOR3_PX -0.866
|
||||
param set-default CA_ROTOR3_PY -0.5
|
||||
param set-default CA_ROTOR3_KM -0.05
|
||||
param set-default CA_ROTOR4_PX 0
|
||||
param set-default CA_ROTOR4_PY -1
|
||||
param set-default CA_ROTOR5_PX 0.866
|
||||
param set-default CA_ROTOR5_PY -0.5
|
||||
param set-default CA_ROTOR5_KM -0.05
|
||||
|
||||
param set-default HIL_ACT_FUNC1 101
|
||||
param set-default HIL_ACT_FUNC2 102
|
||||
param set-default HIL_ACT_FUNC3 103
|
||||
param set-default HIL_ACT_FUNC4 104
|
||||
param set-default HIL_ACT_FUNC5 105
|
||||
param set-default HIL_ACT_FUNC6 106
|
||||
@@ -49,6 +49,7 @@ if(CONFIG_MODULES_SIMULATION_PWM_OUT_SIM)
|
||||
1101_rc_plane_sih.hil
|
||||
1102_tailsitter_duo_sih.hil
|
||||
1103_standard_vtol_sih.hil
|
||||
1105_rc_hexa_x_sih.hil
|
||||
)
|
||||
if(CONFIG_MODULES_ROVER_ACKERMANN)
|
||||
px4_add_romfs_files(
|
||||
|
||||
+103
-48
@@ -31,11 +31,20 @@ set PARAM_FILE ""
|
||||
set PARAM_BACKUP_FILE ""
|
||||
set RC_INPUT_ARGS ""
|
||||
set STORAGE_AVAILABLE no
|
||||
set STORAGE_CHECK yes
|
||||
set SDCARD_EXT_PATH /fs/microsd/ext_autostart
|
||||
set SDCARD_FORMAT no
|
||||
set STARTUP_TUNE 1
|
||||
set VEHICLE_TYPE none
|
||||
|
||||
# Fine-grained feature gates.
|
||||
set USE_HARDFAULT_LOG no
|
||||
set USE_EXTERNAL_AIRFRAMES no
|
||||
set USE_PARAM_BACKUPS no
|
||||
set USE_PARAM_IMPORT_DEBUG no
|
||||
set USE_TASK_WATCHDOG no
|
||||
set USE_ALT_UPDATE_DIRS no
|
||||
|
||||
# Airframe parameter versioning
|
||||
# Value set to 1 by default but can optionally be overridden in the airframe configuration startup script.
|
||||
# Airframe maintainers can ensure a reset to the airframe defaults during an update by increasing by one.
|
||||
@@ -48,53 +57,81 @@ set PARAM_DEFAULTS_VER 1
|
||||
ver all
|
||||
|
||||
#
|
||||
# Try to mount the microSD card.
|
||||
# Optional early board init: rc.board_early
|
||||
# Can be used for setting env vars for rcS.
|
||||
#
|
||||
if [ -b "/dev/mmcsd0" ]
|
||||
set BOARD_RC_EARLY ${R}etc/init.d/rc.board_early
|
||||
if [ -f $BOARD_RC_EARLY ]
|
||||
then
|
||||
if mount -t vfat /dev/mmcsd0 /fs/microsd
|
||||
then
|
||||
if [ -f "/fs/microsd/.format" ]
|
||||
then
|
||||
echo "INFO [init] format /dev/mmcsd0 requested (/fs/microsd/.format)"
|
||||
set SDCARD_FORMAT yes
|
||||
rm /fs/microsd/.format
|
||||
umount /fs/microsd
|
||||
. $BOARD_RC_EARLY
|
||||
fi
|
||||
unset BOARD_RC_EARLY
|
||||
|
||||
else
|
||||
#
|
||||
# Try to mount/check storage (rc.board_early can disable this).
|
||||
#
|
||||
if [ $STORAGE_CHECK = yes ]
|
||||
then
|
||||
#
|
||||
# Try to mount the microSD card.
|
||||
#
|
||||
if [ -b "/dev/mmcsd0" ]
|
||||
then
|
||||
if mount -t vfat /dev/mmcsd0 /fs/microsd
|
||||
then
|
||||
if [ -f "/fs/microsd/.format" ]
|
||||
then
|
||||
echo "INFO [init] format /dev/mmcsd0 requested (/fs/microsd/.format)"
|
||||
set SDCARD_FORMAT yes
|
||||
rm /fs/microsd/.format
|
||||
umount /fs/microsd
|
||||
|
||||
else
|
||||
set STORAGE_AVAILABLE yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $STORAGE_AVAILABLE = no -o $SDCARD_FORMAT = yes ]
|
||||
then
|
||||
echo "INFO [init] formatting /dev/mmcsd0"
|
||||
set STARTUP_TUNE 15 # tune 15 = SD_ERROR (overridden to SD_INIT if format + mount succeeds)
|
||||
|
||||
if mkfatfs -F 32 /dev/mmcsd0
|
||||
then
|
||||
echo "INFO [init] card formatted"
|
||||
|
||||
if mount -t vfat /dev/mmcsd0 /fs/microsd
|
||||
then
|
||||
set STORAGE_AVAILABLE yes
|
||||
set STARTUP_TUNE 14 # tune 14 = SD_INIT
|
||||
else
|
||||
echo "ERROR [init] card mount failed"
|
||||
fi
|
||||
else
|
||||
echo "ERROR [init] format failed"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Is there a device mounted for storage
|
||||
if mft query -q -k MTD -s MTD_PARAMETERS -v /mnt/microsd
|
||||
then
|
||||
set STORAGE_AVAILABLE yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $STORAGE_AVAILABLE = no -o $SDCARD_FORMAT = yes ]
|
||||
then
|
||||
echo "INFO [init] formatting /dev/mmcsd0"
|
||||
set STARTUP_TUNE 15 # tune 15 = SD_ERROR (overridden to SD_INIT if format + mount succeeds)
|
||||
|
||||
if mkfatfs -F 32 /dev/mmcsd0
|
||||
then
|
||||
echo "INFO [init] card formatted"
|
||||
|
||||
if mount -t vfat /dev/mmcsd0 /fs/microsd
|
||||
then
|
||||
set STORAGE_AVAILABLE yes
|
||||
set STARTUP_TUNE 14 # tune 14 = SD_INIT
|
||||
else
|
||||
echo "ERROR [init] card mount failed"
|
||||
fi
|
||||
else
|
||||
echo "ERROR [init] format failed"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Is there a device mounted for storage
|
||||
if mft query -q -k MTD -s MTD_PARAMETERS -v /mnt/microsd
|
||||
then
|
||||
set STORAGE_AVAILABLE yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $STORAGE_AVAILABLE = yes ]
|
||||
then
|
||||
set USE_HARDFAULT_LOG yes
|
||||
set USE_EXTERNAL_AIRFRAMES yes
|
||||
set USE_PARAM_BACKUPS yes
|
||||
set USE_PARAM_IMPORT_DEBUG yes
|
||||
set USE_ALT_UPDATE_DIRS yes
|
||||
set PARAM_FILE /fs/microsd/params
|
||||
set PARAM_BACKUP_FILE "/fs/microsd/parameters_backup.bson"
|
||||
fi
|
||||
|
||||
if [ $USE_HARDFAULT_LOG = yes ]
|
||||
then
|
||||
if hardfault_log check
|
||||
then
|
||||
@@ -104,7 +141,15 @@ then
|
||||
hardfault_log reset
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $USE_TASK_WATCHDOG = yes ]
|
||||
then
|
||||
task_watchdog start
|
||||
fi
|
||||
|
||||
if [ $USE_ALT_UPDATE_DIRS = yes ]
|
||||
then
|
||||
# Check for an update of the ext_autostart folder, and replace the old one with it
|
||||
if [ -e /fs/microsd/ext_autostart_new ]
|
||||
then
|
||||
@@ -112,9 +157,6 @@ then
|
||||
rm -r $SDCARD_EXT_PATH
|
||||
mv /fs/microsd/ext_autostart_new $SDCARD_EXT_PATH
|
||||
fi
|
||||
|
||||
set PARAM_FILE /fs/microsd/params
|
||||
set PARAM_BACKUP_FILE "/fs/microsd/parameters_backup.bson"
|
||||
fi
|
||||
|
||||
#
|
||||
@@ -155,8 +197,11 @@ else
|
||||
|
||||
if [ -d "/fs/microsd" ]
|
||||
then
|
||||
# try to make a backup copy
|
||||
cp $PARAM_FILE /fs/microsd/param_import_fail.bson
|
||||
if [ $USE_PARAM_IMPORT_DEBUG = yes ]
|
||||
then
|
||||
# save copy of the failed param file for debugging
|
||||
cp $PARAM_FILE /fs/microsd/param_import_fail.bson
|
||||
fi
|
||||
|
||||
# try importing from backup file
|
||||
if [ -f $PARAM_BACKUP_FILE ]
|
||||
@@ -174,11 +219,14 @@ else
|
||||
|
||||
param status
|
||||
|
||||
dmesg >> /fs/microsd/param_import_fail.txt &
|
||||
if [ $USE_PARAM_IMPORT_DEBUG = yes ]
|
||||
then
|
||||
dmesg >> /fs/microsd/param_import_fail.txt &
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $STORAGE_AVAILABLE = yes ]
|
||||
if [ $USE_PARAM_BACKUPS = yes ]
|
||||
then
|
||||
param select-backup $PARAM_BACKUP_FILE
|
||||
fi
|
||||
@@ -234,12 +282,12 @@ else
|
||||
|
||||
if [ ${VEHICLE_TYPE} = none ]
|
||||
then
|
||||
# Run external airframe script on SD card
|
||||
if [ $STORAGE_AVAILABLE = yes ]
|
||||
# Run external airframe script on SD card or EEPROM-backed storage
|
||||
if [ $USE_EXTERNAL_AIRFRAMES = yes ]
|
||||
then
|
||||
. ${R}etc/init.d/rc.autostart_ext
|
||||
else
|
||||
echo "ERROR [init] SD not mounted, skipping external airframe"
|
||||
echo "ERROR [init] no external airframe storage, skipping"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -679,9 +727,16 @@ unset PARAM_BACKUP_FILE
|
||||
unset PARAM_DEFAULTS_VER
|
||||
unset RC_INPUT_ARGS
|
||||
unset STORAGE_AVAILABLE
|
||||
unset STORAGE_CHECK
|
||||
unset SDCARD_EXT_PATH
|
||||
unset SDCARD_FORMAT
|
||||
unset STARTUP_TUNE
|
||||
unset USE_HARDFAULT_LOG
|
||||
unset USE_EXTERNAL_AIRFRAMES
|
||||
unset USE_PARAM_BACKUPS
|
||||
unset USE_PARAM_IMPORT_DEBUG
|
||||
unset USE_TASK_WATCHDOG
|
||||
unset USE_ALT_UPDATE_DIRS
|
||||
unset VEHICLE_TYPE
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Shared GitHub REST helpers for PX4 CI scripts.
|
||||
|
||||
This module is imported by the PR poster scripts under Tools/ci/. It is
|
||||
NOT an executable entry point; do not run it directly.
|
||||
|
||||
Provides:
|
||||
- fail(msg) terminates the caller with a clear error
|
||||
- GitHubClient(token) thin stdlib-only GitHub REST client with
|
||||
single-request and paginated helpers
|
||||
|
||||
Python stdlib only. No third-party dependencies.
|
||||
|
||||
History: extracted from Tools/ci/pr-comment-poster.py so that
|
||||
pr-comment-poster.py and pr-review-poster.py share the same HTTP plumbing
|
||||
without duplicating ~100 lines of request/pagination/error-handling code.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import typing
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
|
||||
GITHUB_API = 'https://api.github.com'
|
||||
DEFAULT_USER_AGENT = 'px4-ci'
|
||||
API_VERSION = '2022-11-28'
|
||||
|
||||
|
||||
def fail(msg: str) -> typing.NoReturn:
|
||||
"""Print an error to stderr and exit with status 1.
|
||||
|
||||
Annotated NoReturn so static checkers understand control does not
|
||||
continue past a fail() call.
|
||||
"""
|
||||
print('error: {}'.format(msg), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _parse_next_link(link_header):
|
||||
"""Return the URL for rel="next" from an RFC 5988 Link header, or None.
|
||||
|
||||
The Link header is comma-separated entries of the form:
|
||||
<https://...?page=2>; rel="next", <https://...?page=5>; rel="last"
|
||||
We walk each entry and return the URL of the one whose rel attribute is
|
||||
"next". Accept single-quoted rel values for robustness even though
|
||||
GitHub always emits double quotes.
|
||||
"""
|
||||
if not link_header:
|
||||
return None
|
||||
for part in link_header.split(','):
|
||||
segs = part.strip().split(';')
|
||||
if len(segs) < 2:
|
||||
continue
|
||||
url_seg = segs[0].strip()
|
||||
if not (url_seg.startswith('<') and url_seg.endswith('>')):
|
||||
continue
|
||||
url = url_seg[1:-1]
|
||||
for attr in segs[1:]:
|
||||
attr = attr.strip()
|
||||
if attr == 'rel="next"' or attr == "rel='next'":
|
||||
return url
|
||||
return None
|
||||
|
||||
|
||||
class GitHubClient:
|
||||
"""Minimal GitHub REST client backed by the Python stdlib.
|
||||
|
||||
Each instance holds a token and a user-agent so callers do not have to
|
||||
thread them through every call. Methods return parsed JSON (or None for
|
||||
empty responses) and raise RuntimeError with the server response body on
|
||||
HTTP errors, so CI logs show what the API actually objected to.
|
||||
|
||||
Usage:
|
||||
client = GitHubClient(token, user_agent='px4-pr-comment-poster')
|
||||
body, headers = client.request('GET', 'repos/{o}/{r}/pulls/123')
|
||||
for item in client.paginated('repos/{o}/{r}/pulls/123/reviews'):
|
||||
...
|
||||
"""
|
||||
|
||||
def __init__(self, token, user_agent=DEFAULT_USER_AGENT):
|
||||
if not token:
|
||||
raise ValueError('GitHub token is required')
|
||||
self._token = token
|
||||
self._user_agent = user_agent
|
||||
|
||||
def request(self, method, path_or_url, json_body=None):
|
||||
"""GET/POST/PATCH/PUT/DELETE a single API path or absolute URL.
|
||||
|
||||
`path_or_url` may be either a relative API path (e.g.
|
||||
"repos/PX4/PX4-Autopilot/pulls/123") or an absolute URL such as the
|
||||
next-page URL returned from paginated results. Relative paths are
|
||||
prefixed with the GitHub API base.
|
||||
|
||||
Returns (parsed_json_or_none, headers_dict). Raises RuntimeError
|
||||
on HTTP or transport errors.
|
||||
"""
|
||||
url = self._resolve(path_or_url)
|
||||
return self._do_request(method, url, json_body)
|
||||
|
||||
def paginated(self, path, per_page=100):
|
||||
"""GET a path and follow rel="next" Link headers.
|
||||
|
||||
Yields items from each page's JSON array. Bumps per_page to 100
|
||||
(GitHub's max) so large result sets take fewer round-trips.
|
||||
Raises RuntimeError if any page response is not a JSON array.
|
||||
"""
|
||||
url = self._resolve(path)
|
||||
sep = '&' if '?' in url else '?'
|
||||
url = '{}{}per_page={}'.format(url, sep, per_page)
|
||||
while url is not None:
|
||||
body, headers = self._do_request('GET', url, None)
|
||||
if body is None:
|
||||
return
|
||||
if not isinstance(body, list):
|
||||
raise RuntimeError(
|
||||
'expected JSON array from {}, got {}'.format(
|
||||
url, type(body).__name__))
|
||||
for item in body:
|
||||
yield item
|
||||
url = _parse_next_link(headers.get('Link'))
|
||||
|
||||
def _resolve(self, path_or_url):
|
||||
if path_or_url.startswith('http://') or path_or_url.startswith('https://'):
|
||||
return path_or_url
|
||||
return '{}/{}'.format(GITHUB_API.rstrip('/'), path_or_url.lstrip('/'))
|
||||
|
||||
def _do_request(self, method, url, json_body):
|
||||
data = None
|
||||
headers = {
|
||||
'Authorization': 'Bearer {}'.format(self._token),
|
||||
'Accept': 'application/vnd.github+json',
|
||||
# Pin the API version so GitHub deprecations don't silently
|
||||
# change the response shape under us.
|
||||
'X-GitHub-Api-Version': API_VERSION,
|
||||
'User-Agent': self._user_agent,
|
||||
}
|
||||
if json_body is not None:
|
||||
data = json.dumps(json_body).encode('utf-8')
|
||||
headers['Content-Type'] = 'application/json; charset=utf-8'
|
||||
|
||||
req = urllib.request.Request(
|
||||
url, data=data, method=method, headers=headers)
|
||||
try:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
raw = resp.read()
|
||||
# HTTPMessage is case-insensitive on lookup but its items()
|
||||
# preserves the original case. GitHub sends "Link" with a
|
||||
# capital L, which is what _parse_next_link expects.
|
||||
resp_headers = dict(resp.headers.items())
|
||||
if not raw:
|
||||
return None, resp_headers
|
||||
return json.loads(raw.decode('utf-8')), resp_headers
|
||||
except urllib.error.HTTPError as e:
|
||||
# GitHub error bodies are JSON with a "message" field and often
|
||||
# a "documentation_url". Dump the raw body into the exception so
|
||||
# the CI log shows exactly what the API objected to. A bare
|
||||
# "HTTP 422" tells us nothing useful.
|
||||
try:
|
||||
err_body = e.read().decode('utf-8', errors='replace')
|
||||
except Exception:
|
||||
err_body = '(no body)'
|
||||
raise RuntimeError(
|
||||
'GitHub API {} {} failed: HTTP {} {}\n{}'.format(
|
||||
method, url, e.code, e.reason, err_body))
|
||||
except urllib.error.URLError as e:
|
||||
# Network layer failure (DNS, TLS, connection reset). No HTTP
|
||||
# response to parse; just surface the transport reason.
|
||||
raise RuntimeError(
|
||||
'GitHub API {} {} failed: {}'.format(method, url, e.reason))
|
||||
@@ -0,0 +1,539 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# clang-tidy-fixes-to-review.py
|
||||
#
|
||||
# Producer-side helper that converts a clang-tidy fixes.yml file into a
|
||||
# pr-review artifact (manifest.json + comments.json) suitable for
|
||||
# Tools/ci/pr-review-poster.py.
|
||||
#
|
||||
# This script runs inside the clang-tidy job's px4-dev container so it can
|
||||
# read the source tree directly and look up byte offsets in the original
|
||||
# files. The output it writes is a fully-baked array of review comments;
|
||||
# the poster never reads source files or fixes.yml.
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# ATTRIBUTION
|
||||
# ----------------------------------------------------------------------------
|
||||
# This script reuses the diagnostic-to-review-comment translation logic
|
||||
# from platisd/clang-tidy-pr-comments. The original work is:
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2021 Dimitris Platis
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Adapted parts:
|
||||
# - get_diff_line_ranges_per_file() and its inner change_to_line_range()
|
||||
# - generate_review_comments() and its nested helpers
|
||||
# (get_line_by_offset, validate_warning_applicability,
|
||||
# calculate_replacements_diff, markdown, markdown_url,
|
||||
# diagnostic_name_visual, generate_single_comment)
|
||||
# - reorder_diagnostics()
|
||||
#
|
||||
# Removed parts (handled by Tools/ci/pr-review-poster.py instead):
|
||||
# - post_review_comments / dismiss_change_requests / resolve_conversations
|
||||
# - the original argparse main and the requests-based HTTP layer
|
||||
#
|
||||
# Adaptation notes:
|
||||
# - The HTTP layer is rewritten on top of Tools/ci/_github_helpers.py so
|
||||
# this script does not depend on the third-party `requests` package.
|
||||
# - Conversation resolution (the GraphQL path) is intentionally dropped
|
||||
# for v1; revisit if it turns out to be missed.
|
||||
# - Clang-Tidy 8 upconvert is preserved verbatim.
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# Bounded assumptions (documented for future maintainers):
|
||||
# - Source files are UTF-8 (we read them as latin_1, matching clang-tidy's
|
||||
# own byte-offset model, and the offsets we surface are line counts)
|
||||
# - Source files use LF line endings
|
||||
# - Malformed entries in fixes.yml are skipped with a warning rather than
|
||||
# crashing the job
|
||||
#
|
||||
# Dependencies: pyyaml + Tools/ci/_github_helpers.py.
|
||||
# pyyaml is preinstalled in the px4-dev container; this script is intended
|
||||
# to run there, not on bare ubuntu-latest.
|
||||
"""Convert a clang-tidy fixes.yml into a pr-review artifact."""
|
||||
|
||||
import argparse
|
||||
import difflib
|
||||
import json
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
import yaml
|
||||
|
||||
import _github_helpers
|
||||
from _github_helpers import fail as _fail
|
||||
|
||||
|
||||
# Markers used inside the per-comment body to call out severity. Plain
|
||||
# strings rather than emojis to keep the file emoji-free per project
|
||||
# preferences; the rendered Markdown is unaffected.
|
||||
SINGLE_COMMENT_MARKERS = {
|
||||
'Error': '**[error]**',
|
||||
'Warning': '**[warning]**',
|
||||
'Remark': '**[remark]**',
|
||||
'fallback': '**[note]**',
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Diff-range parsing (adapted from platisd)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def get_diff_line_ranges_per_file(pr_files):
|
||||
"""Return a dict mapping each PR file path to a list of line ranges
|
||||
(the +new-side hunks) parsed from its patch."""
|
||||
|
||||
def change_to_line_range(change):
|
||||
split_change = change.split(',')
|
||||
start = int(split_change[0])
|
||||
size = int(split_change[1]) if len(split_change) > 1 else 1
|
||||
return range(start, start + size)
|
||||
|
||||
result = {}
|
||||
for pr_file in pr_files:
|
||||
# Removed binary files etc. have no patch section.
|
||||
if 'patch' not in pr_file:
|
||||
continue
|
||||
file_name = pr_file['filename']
|
||||
# Match lines like '@@ -101,8 +102,11 @@'
|
||||
git_line_tags = re.findall(
|
||||
r'^@@ -.*? +.*? @@', pr_file['patch'], re.MULTILINE)
|
||||
changes = [
|
||||
tag.replace('@@', '').strip().split()[1].replace('+', '')
|
||||
for tag in git_line_tags
|
||||
]
|
||||
result[file_name] = [
|
||||
change_to_line_range(change) for change in changes
|
||||
]
|
||||
return result
|
||||
|
||||
|
||||
def fetch_pull_request_files(client, repo, pr_number):
|
||||
"""Yield file metadata objects for each file modified by the PR."""
|
||||
path = 'repos/{}/pulls/{}/files'.format(repo, pr_number)
|
||||
for entry in client.paginated(path):
|
||||
yield entry
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Diagnostic ordering (adapted from platisd)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def reorder_diagnostics(diags):
|
||||
"""Return diagnostics ordered Error -> Warning -> Remark -> other."""
|
||||
errors = [d for d in diags if d.get('Level') == 'Error']
|
||||
warnings = [d for d in diags if d.get('Level') == 'Warning']
|
||||
remarks = [d for d in diags if d.get('Level') == 'Remark']
|
||||
others = [
|
||||
d for d in diags
|
||||
if d.get('Level') not in {'Error', 'Warning', 'Remark'}
|
||||
]
|
||||
if others:
|
||||
print(
|
||||
'warning: some fixes have an unexpected Level (not Error, '
|
||||
'Warning, or Remark)', file=sys.stderr)
|
||||
return errors + warnings + remarks + others
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Comment generation (adapted from platisd)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def generate_review_comments(clang_tidy_fixes, repository_root,
|
||||
diff_line_ranges_per_file,
|
||||
single_comment_markers):
|
||||
"""Yield review comment dicts for each clang-tidy diagnostic that
|
||||
intersects the PR diff."""
|
||||
|
||||
def get_line_by_offset(file_path, offset):
|
||||
# Clang-Tidy doesn't support multibyte encodings and measures
|
||||
# offsets in bytes; latin_1 makes byte offsets and string offsets
|
||||
# equivalent.
|
||||
with open(repository_root + file_path, encoding='latin_1') as fh:
|
||||
source = fh.read()
|
||||
return source[:offset].count('\n') + 1
|
||||
|
||||
def validate_warning_applicability(file_path, start_line_num, end_line_num):
|
||||
assert end_line_num >= start_line_num
|
||||
for line_range in diff_line_ranges_per_file[file_path]:
|
||||
assert line_range.step == 1
|
||||
if (line_range.start <= start_line_num
|
||||
and end_line_num < line_range.stop):
|
||||
return True
|
||||
return False
|
||||
|
||||
def calculate_replacements_diff(file_path, replacements):
|
||||
# Apply replacements in reverse order so subsequent offsets do not
|
||||
# shift.
|
||||
replacements.sort(key=lambda item: (-item['Offset']))
|
||||
with open(repository_root + file_path, encoding='latin_1') as fh:
|
||||
source = fh.read()
|
||||
changed = source
|
||||
for replacement in replacements:
|
||||
changed = (
|
||||
changed[:replacement['Offset']]
|
||||
+ replacement['ReplacementText']
|
||||
+ changed[replacement['Offset'] + replacement['Length']:]
|
||||
)
|
||||
return difflib.Differ().compare(
|
||||
source.splitlines(keepends=True),
|
||||
changed.splitlines(keepends=True),
|
||||
)
|
||||
|
||||
def markdown(s):
|
||||
md_chars = '\\`*_{}[]<>()#+-.!|'
|
||||
|
||||
def escape_chars(s):
|
||||
for ch in md_chars:
|
||||
s = s.replace(ch, '\\' + ch)
|
||||
return s
|
||||
|
||||
def unescape_chars(s):
|
||||
for ch in md_chars:
|
||||
s = s.replace('\\' + ch, ch)
|
||||
return s
|
||||
|
||||
s = escape_chars(s)
|
||||
s = re.sub(
|
||||
"'([^']*)'",
|
||||
lambda m: '`` ' + unescape_chars(m.group(1)) + ' ``',
|
||||
s,
|
||||
)
|
||||
return s
|
||||
|
||||
def markdown_url(label, url):
|
||||
return '[{}]({})'.format(label, url)
|
||||
|
||||
def diagnostic_name_visual(diagnostic_name):
|
||||
visual = '**{}**'.format(markdown(diagnostic_name))
|
||||
try:
|
||||
first_dash_idx = diagnostic_name.index('-')
|
||||
except ValueError:
|
||||
return visual
|
||||
namespace = urllib.parse.quote_plus(diagnostic_name[:first_dash_idx])
|
||||
check_name = urllib.parse.quote_plus(
|
||||
diagnostic_name[first_dash_idx + 1:])
|
||||
return markdown_url(
|
||||
visual,
|
||||
'https://clang.llvm.org/extra/clang-tidy/checks/{}/{}.html'.format(
|
||||
namespace, check_name),
|
||||
)
|
||||
|
||||
def generate_single_comment(file_path, start_line_num, end_line_num,
|
||||
name, message, single_comment_marker,
|
||||
replacement_text=None):
|
||||
result = {
|
||||
'path': file_path,
|
||||
'line': end_line_num,
|
||||
'side': 'RIGHT',
|
||||
'body': '{} {} {}\n{}'.format(
|
||||
single_comment_marker,
|
||||
diagnostic_name_visual(name),
|
||||
single_comment_marker,
|
||||
markdown(message),
|
||||
),
|
||||
}
|
||||
if start_line_num != end_line_num:
|
||||
result['start_line'] = start_line_num
|
||||
result['start_side'] = 'RIGHT'
|
||||
if replacement_text is not None:
|
||||
if not replacement_text or replacement_text[-1] != '\n':
|
||||
replacement_text += '\n'
|
||||
result['body'] += '\n```suggestion\n{}```'.format(replacement_text)
|
||||
return result
|
||||
|
||||
for diag in clang_tidy_fixes['Diagnostics']:
|
||||
# Upconvert clang-tidy 8 format to 9+
|
||||
if 'DiagnosticMessage' not in diag:
|
||||
diag['DiagnosticMessage'] = {
|
||||
'FileOffset': diag.get('FileOffset'),
|
||||
'FilePath': diag.get('FilePath'),
|
||||
'Message': diag.get('Message'),
|
||||
'Replacements': diag.get('Replacements', []),
|
||||
}
|
||||
|
||||
diag_message = diag['DiagnosticMessage']
|
||||
diag_message['FilePath'] = posixpath.normpath(
|
||||
(diag_message.get('FilePath') or '').replace(repository_root, ''))
|
||||
for replacement in diag_message.get('Replacements') or []:
|
||||
replacement['FilePath'] = posixpath.normpath(
|
||||
replacement['FilePath'].replace(repository_root, ''))
|
||||
|
||||
diag_name = diag.get('DiagnosticName', '<unknown>')
|
||||
diag_message_msg = diag_message.get('Message', '')
|
||||
level = diag.get('Level', 'Warning')
|
||||
single_comment_marker = single_comment_markers.get(
|
||||
level, single_comment_markers['fallback'])
|
||||
|
||||
replacements = diag_message.get('Replacements') or []
|
||||
if not replacements:
|
||||
file_path = diag_message['FilePath']
|
||||
offset = diag_message.get('FileOffset')
|
||||
if offset is None:
|
||||
print('warning: skipping {!r}: missing FileOffset'.format(
|
||||
diag_name), file=sys.stderr)
|
||||
continue
|
||||
if file_path not in diff_line_ranges_per_file:
|
||||
print(
|
||||
"'{}' for {} does not apply to the files changed in "
|
||||
'this PR'.format(diag_name, file_path))
|
||||
continue
|
||||
try:
|
||||
line_num = get_line_by_offset(file_path, offset)
|
||||
except (OSError, ValueError) as e:
|
||||
print('warning: skipping {!r} on {}: {}'.format(
|
||||
diag_name, file_path, e), file=sys.stderr)
|
||||
continue
|
||||
|
||||
print("Processing '{}' at line {} of {}...".format(
|
||||
diag_name, line_num, file_path))
|
||||
if validate_warning_applicability(file_path, line_num, line_num):
|
||||
yield generate_single_comment(
|
||||
file_path,
|
||||
line_num,
|
||||
line_num,
|
||||
diag_name,
|
||||
diag_message_msg,
|
||||
single_comment_marker=single_comment_marker,
|
||||
)
|
||||
else:
|
||||
print('This warning does not apply to the lines changed '
|
||||
'in this PR')
|
||||
else:
|
||||
for file_path in {item['FilePath'] for item in replacements}:
|
||||
if file_path not in diff_line_ranges_per_file:
|
||||
print(
|
||||
"'{}' for {} does not apply to the files changed "
|
||||
'in this PR'.format(diag_name, file_path))
|
||||
continue
|
||||
|
||||
line_num = 1
|
||||
start_line_num = None
|
||||
end_line_num = None
|
||||
replacement_text = None
|
||||
|
||||
try:
|
||||
diff_iter = calculate_replacements_diff(
|
||||
file_path,
|
||||
[r for r in replacements if r['FilePath'] == file_path],
|
||||
)
|
||||
except (OSError, ValueError) as e:
|
||||
print('warning: skipping {!r} on {}: {}'.format(
|
||||
diag_name, file_path, e), file=sys.stderr)
|
||||
continue
|
||||
|
||||
for line in diff_iter:
|
||||
# Comment line, ignore.
|
||||
if line.startswith('? '):
|
||||
continue
|
||||
# A '-' line is the start or continuation of a region
|
||||
# to replace.
|
||||
if line.startswith('- '):
|
||||
if start_line_num is None:
|
||||
start_line_num = line_num
|
||||
end_line_num = line_num
|
||||
else:
|
||||
end_line_num = line_num
|
||||
if replacement_text is None:
|
||||
replacement_text = ''
|
||||
line_num += 1
|
||||
# A '+' line is part of the replacement text.
|
||||
elif line.startswith('+ '):
|
||||
if replacement_text is None:
|
||||
replacement_text = line[2:]
|
||||
else:
|
||||
replacement_text += line[2:]
|
||||
# A context line marks the end of a replacement region.
|
||||
elif line.startswith(' '):
|
||||
if replacement_text is not None:
|
||||
if start_line_num is None:
|
||||
# Pure addition: synthesize a one-line
|
||||
# range and append the context line to
|
||||
# the replacement.
|
||||
start_line_num = line_num
|
||||
end_line_num = line_num
|
||||
replacement_text += line[2:]
|
||||
|
||||
print("Processing '{}' at lines {}-{} of {}...".format(
|
||||
diag_name, start_line_num, end_line_num, file_path))
|
||||
|
||||
if validate_warning_applicability(
|
||||
file_path, start_line_num, end_line_num):
|
||||
yield generate_single_comment(
|
||||
file_path,
|
||||
start_line_num,
|
||||
end_line_num,
|
||||
diag_name,
|
||||
diag_message_msg,
|
||||
single_comment_marker=single_comment_marker,
|
||||
replacement_text=replacement_text,
|
||||
)
|
||||
else:
|
||||
print(
|
||||
'This warning does not apply to the '
|
||||
'lines changed in this PR')
|
||||
|
||||
start_line_num = None
|
||||
end_line_num = None
|
||||
replacement_text = None
|
||||
|
||||
line_num += 1
|
||||
else:
|
||||
# Unknown difflib prefix; skip rather than abort.
|
||||
print('warning: unexpected diff prefix {!r}; '
|
||||
'skipping diagnostic'.format(line[:2]),
|
||||
file=sys.stderr)
|
||||
break
|
||||
|
||||
# End of file with a pending replacement region.
|
||||
if replacement_text is not None and start_line_num is not None:
|
||||
print("Processing '{}' at lines {}-{} of {}...".format(
|
||||
diag_name, start_line_num, end_line_num, file_path))
|
||||
if validate_warning_applicability(
|
||||
file_path, start_line_num, end_line_num):
|
||||
yield generate_single_comment(
|
||||
file_path,
|
||||
start_line_num,
|
||||
end_line_num,
|
||||
diag_name,
|
||||
diag_message_msg,
|
||||
single_comment_marker=single_comment_marker,
|
||||
replacement_text=replacement_text,
|
||||
)
|
||||
else:
|
||||
print('This warning does not apply to the lines '
|
||||
'changed in this PR')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Entry point
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Convert a clang-tidy fixes.yml into a pr-review '
|
||||
'artifact (manifest.json + comments.json).',
|
||||
)
|
||||
parser.add_argument('--fixes', required=True,
|
||||
help='Path to fixes.yml from clang-tidy')
|
||||
parser.add_argument('--repo-root', required=True,
|
||||
help='Path to the repository root containing the '
|
||||
'source files referenced by fixes.yml')
|
||||
parser.add_argument('--repo', required=True,
|
||||
help='owner/name of the repository')
|
||||
parser.add_argument('--pr-number', required=True, type=int,
|
||||
help='Pull request number')
|
||||
parser.add_argument('--commit-sha', required=True,
|
||||
help='40-char hex commit SHA the review will pin to')
|
||||
parser.add_argument('--out-dir', required=True,
|
||||
help='Directory to write manifest.json and '
|
||||
'comments.json')
|
||||
parser.add_argument(
|
||||
'--marker',
|
||||
default='<!-- pr-review-poster:clang-tidy -->',
|
||||
help='Marker string embedded in the review body so the poster '
|
||||
'can find and dismiss stale runs')
|
||||
parser.add_argument(
|
||||
'--event',
|
||||
default='REQUEST_CHANGES',
|
||||
choices=('COMMENT', 'REQUEST_CHANGES'),
|
||||
help='GitHub review event type')
|
||||
parser.add_argument(
|
||||
'--summary', default='',
|
||||
help='Optional review summary text appended to the review body')
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.pr_number <= 0:
|
||||
_fail('--pr-number must be > 0')
|
||||
if not re.match(r'^[0-9a-f]{40}$', args.commit_sha):
|
||||
_fail('--commit-sha must be a 40-char lowercase hex string')
|
||||
|
||||
token = os.environ.get('GITHUB_TOKEN')
|
||||
if not token:
|
||||
_fail('GITHUB_TOKEN is not set')
|
||||
|
||||
# Normalize the repo root with a trailing slash so the platisd-style
|
||||
# str.replace() trick still strips it cleanly.
|
||||
repo_root = args.repo_root
|
||||
if not repo_root.endswith(os.sep):
|
||||
repo_root = repo_root + os.sep
|
||||
|
||||
os.makedirs(args.out_dir, exist_ok=True)
|
||||
|
||||
client = _github_helpers.GitHubClient(token, user_agent='px4-clang-tidy-fixes-to-review')
|
||||
|
||||
print('Fetching PR file list from GitHub...')
|
||||
pr_files = list(fetch_pull_request_files(client, args.repo, args.pr_number))
|
||||
diff_line_ranges_per_file = get_diff_line_ranges_per_file(pr_files)
|
||||
|
||||
print('Loading clang-tidy fixes from {}...'.format(args.fixes))
|
||||
if not os.path.isfile(args.fixes):
|
||||
# No fixes file means clang-tidy ran cleanly. Emit an empty
|
||||
# comments.json so the poster can short-circuit.
|
||||
comments = []
|
||||
else:
|
||||
with open(args.fixes, encoding='utf-8') as fh:
|
||||
clang_tidy_fixes = yaml.safe_load(fh)
|
||||
if (not clang_tidy_fixes
|
||||
or 'Diagnostics' not in clang_tidy_fixes
|
||||
or not clang_tidy_fixes['Diagnostics']):
|
||||
comments = []
|
||||
else:
|
||||
clang_tidy_fixes['Diagnostics'] = reorder_diagnostics(
|
||||
clang_tidy_fixes['Diagnostics'])
|
||||
comments = list(generate_review_comments(
|
||||
clang_tidy_fixes,
|
||||
repo_root,
|
||||
diff_line_ranges_per_file,
|
||||
single_comment_markers=SINGLE_COMMENT_MARKERS,
|
||||
))
|
||||
|
||||
print('Generated {} review comment(s)'.format(len(comments)))
|
||||
|
||||
manifest = {
|
||||
'pr_number': args.pr_number,
|
||||
'marker': args.marker,
|
||||
'event': args.event,
|
||||
'commit_sha': args.commit_sha,
|
||||
}
|
||||
if args.summary:
|
||||
manifest['summary'] = args.summary
|
||||
|
||||
manifest_path = os.path.join(args.out_dir, 'manifest.json')
|
||||
comments_path = os.path.join(args.out_dir, 'comments.json')
|
||||
with open(manifest_path, 'w', encoding='utf-8') as fh:
|
||||
json.dump(manifest, fh, indent=2)
|
||||
fh.write('\n')
|
||||
with open(comments_path, 'w', encoding='utf-8') as fh:
|
||||
json.dump(comments, fh, indent=2)
|
||||
fh.write('\n')
|
||||
|
||||
print('Wrote {} and {}'.format(manifest_path, comments_path))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Executable
+288
@@ -0,0 +1,288 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
PR comment poster for analysis workflows.
|
||||
|
||||
This script is invoked from the `PR Comment Poster` workflow which runs on
|
||||
`workflow_run` in the base repository context. It consumes a `pr-comment`
|
||||
artifact produced by an upstream analysis job (clang-tidy, flash_analysis,
|
||||
etc.) and posts or updates a sticky PR comment via the GitHub REST API.
|
||||
|
||||
Artifact contract (directory passed on the command line):
|
||||
|
||||
manifest.json
|
||||
{
|
||||
"pr_number": 12345, (required, int > 0)
|
||||
"marker": "<!-- pr-comment-poster:flash-analysis -->", (required, printable ASCII)
|
||||
"mode": "upsert" (optional, default "upsert")
|
||||
}
|
||||
|
||||
body.md
|
||||
Markdown comment body, posted verbatim. Must be non-empty and
|
||||
<= 60000 bytes (GitHub's hard limit is 65535, we cap under).
|
||||
|
||||
Security: this script is run in a write-token context from a workflow that
|
||||
MUST NOT check out PR code. Both manifest.json and body.md are treated as
|
||||
opaque data. The marker is validated to printable ASCII only before use.
|
||||
|
||||
Subcommands:
|
||||
|
||||
validate <dir> Validate that <dir> contains a conforming manifest + body.
|
||||
post <dir> Validate, then upsert a sticky comment on the target PR.
|
||||
Requires env GITHUB_TOKEN and GITHUB_REPOSITORY.
|
||||
|
||||
Python stdlib only. No third-party dependencies.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import _github_helpers
|
||||
from _github_helpers import fail as _fail
|
||||
|
||||
|
||||
# GitHub hard limit is 65535 bytes. Cap well under to leave headroom for
|
||||
# the appended marker line and any future wrapping.
|
||||
MAX_BODY_BYTES = 60000
|
||||
|
||||
# Marker length bounds. 1..200 is plenty for an HTML comment tag such as
|
||||
# "<!-- pr-comment-poster:flash-analysis -->".
|
||||
MARKER_MIN_LEN = 1
|
||||
MARKER_MAX_LEN = 200
|
||||
|
||||
ACCEPTED_MODES = ('upsert',)
|
||||
|
||||
USER_AGENT = 'px4-pr-comment-poster'
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _is_printable_ascii(s):
|
||||
# Space (0x20) through tilde (0x7E) inclusive.
|
||||
return all(0x20 <= ord(ch) <= 0x7E for ch in s)
|
||||
|
||||
|
||||
def validate_marker(marker):
|
||||
"""Validate the marker string.
|
||||
|
||||
The marker is printable ASCII only and bounded in length. The original
|
||||
shell implementation also rejected quotes, backticks, and backslashes
|
||||
because the value flowed through jq and shell contexts. Now that Python
|
||||
owns the handling (the value is only ever used as a substring match in
|
||||
comment bodies and as a literal string in JSON request payloads that
|
||||
urllib serialises for us) those characters are safe. We keep the
|
||||
printable-ASCII and length rules as a belt-and-braces sanity check.
|
||||
"""
|
||||
if not isinstance(marker, str):
|
||||
_fail('marker must be a string')
|
||||
n = len(marker)
|
||||
if n < MARKER_MIN_LEN or n > MARKER_MAX_LEN:
|
||||
_fail('marker length out of range ({}..{}): {}'.format(
|
||||
MARKER_MIN_LEN, MARKER_MAX_LEN, n))
|
||||
if not _is_printable_ascii(marker):
|
||||
_fail('marker contains non-printable or non-ASCII character')
|
||||
|
||||
|
||||
def validate_manifest(directory):
|
||||
"""Validate <directory>/manifest.json and <directory>/body.md.
|
||||
|
||||
Returns a dict with keys: pr_number (int), marker (str), mode (str),
|
||||
body (str, verbatim contents of body.md).
|
||||
"""
|
||||
manifest_path = os.path.join(directory, 'manifest.json')
|
||||
body_path = os.path.join(directory, 'body.md')
|
||||
|
||||
if not os.path.isfile(manifest_path):
|
||||
_fail('manifest.json missing at {}'.format(manifest_path))
|
||||
if not os.path.isfile(body_path):
|
||||
_fail('body.md missing at {}'.format(body_path))
|
||||
|
||||
try:
|
||||
with open(manifest_path, 'r', encoding='utf-8') as f:
|
||||
manifest = json.load(f)
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
_fail('manifest.json is not valid JSON: {}'.format(e))
|
||||
|
||||
if not isinstance(manifest, dict):
|
||||
_fail('manifest.json must be a JSON object')
|
||||
|
||||
pr_number = manifest.get('pr_number')
|
||||
# bool is a subclass of int in Python, so isinstance(True, int) is True.
|
||||
# Reject bools explicitly so "true"/"false" in the manifest doesn't silently
|
||||
# validate as 1/0 and then either fail upstream or poke the wrong PR.
|
||||
if not isinstance(pr_number, int) or isinstance(pr_number, bool):
|
||||
_fail('pr_number must be an integer')
|
||||
if pr_number <= 0:
|
||||
_fail('pr_number must be > 0 (got {})'.format(pr_number))
|
||||
|
||||
marker = manifest.get('marker')
|
||||
validate_marker(marker)
|
||||
|
||||
mode = manifest.get('mode', 'upsert')
|
||||
if mode not in ACCEPTED_MODES:
|
||||
_fail('unsupported mode {!r} (accepted: {})'.format(
|
||||
mode, ', '.join(ACCEPTED_MODES)))
|
||||
|
||||
# Read as bytes first so the size check is an honest byte count (matching
|
||||
# GitHub's own 65535-byte comment limit) before we pay the cost of decoding.
|
||||
try:
|
||||
with open(body_path, 'rb') as f:
|
||||
body_bytes = f.read()
|
||||
except OSError as e:
|
||||
_fail('could not read body.md: {}'.format(e))
|
||||
|
||||
if len(body_bytes) == 0:
|
||||
_fail('body.md is empty')
|
||||
if len(body_bytes) > MAX_BODY_BYTES:
|
||||
_fail('body.md too large: {} bytes (max {})'.format(
|
||||
len(body_bytes), MAX_BODY_BYTES))
|
||||
|
||||
# Require UTF-8 up front so a producer that wrote a garbage encoding fails
|
||||
# here rather than later inside json.dumps with a less obvious traceback.
|
||||
try:
|
||||
body = body_bytes.decode('utf-8')
|
||||
except UnicodeDecodeError as e:
|
||||
_fail('body.md is not valid UTF-8: {}'.format(e))
|
||||
|
||||
return {
|
||||
'pr_number': pr_number,
|
||||
'marker': marker,
|
||||
'mode': mode,
|
||||
'body': body,
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Comment upsert
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def find_existing_comment_id(client, repo, pr_number, marker):
|
||||
"""Return the id of the first PR comment whose body contains marker, or None.
|
||||
|
||||
PR comments are issue comments in GitHub's data model, so we hit
|
||||
/issues/{n}/comments rather than /pulls/{n}/comments (the latter only
|
||||
returns review comments tied to specific code lines, which is not what
|
||||
we want). The match is a plain substring check against the comment body;
|
||||
the marker is expected to be an HTML comment that will not accidentally
|
||||
appear in user-written prose.
|
||||
"""
|
||||
path = 'repos/{}/issues/{}/comments'.format(repo, pr_number)
|
||||
for comment in client.paginated(path):
|
||||
body = comment.get('body') or ''
|
||||
if marker in body:
|
||||
return comment.get('id')
|
||||
return None
|
||||
|
||||
|
||||
def build_final_body(body, marker):
|
||||
"""Append the marker to body if not already present.
|
||||
|
||||
If the caller already embedded the marker (e.g. inside a hidden HTML
|
||||
comment anywhere in their body) we leave the body alone; otherwise we
|
||||
rstrip trailing newlines and append the marker on its own line after a
|
||||
blank-line separator. Trailing-newline stripping keeps the output from
|
||||
accumulating extra blank lines every time an existing comment is
|
||||
re-rendered and re-posted.
|
||||
"""
|
||||
if marker in body:
|
||||
return body
|
||||
return '{}\n\n{}\n'.format(body.rstrip('\n'), marker)
|
||||
|
||||
|
||||
def upsert_comment(client, repo, pr_number, marker, body):
|
||||
final_body = build_final_body(body, marker)
|
||||
existing_id = find_existing_comment_id(client, repo, pr_number, marker)
|
||||
|
||||
if existing_id is not None:
|
||||
print('Updating comment {} on PR #{}'.format(existing_id, pr_number))
|
||||
client.request(
|
||||
'PATCH',
|
||||
'repos/{}/issues/comments/{}'.format(repo, existing_id),
|
||||
json_body={'body': final_body},
|
||||
)
|
||||
else:
|
||||
print('Creating new comment on PR #{}'.format(pr_number))
|
||||
client.request(
|
||||
'POST',
|
||||
'repos/{}/issues/{}/comments'.format(repo, pr_number),
|
||||
json_body={'body': final_body},
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Entry points
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def cmd_validate(args):
|
||||
result = validate_manifest(args.directory)
|
||||
print('ok: pr_number={} marker_len={} mode={} body_bytes={}'.format(
|
||||
result['pr_number'],
|
||||
len(result['marker']),
|
||||
result['mode'],
|
||||
len(result['body'].encode('utf-8')),
|
||||
))
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_post(args):
|
||||
result = validate_manifest(args.directory)
|
||||
|
||||
# GITHUB_TOKEN is provided by the workflow via env; GITHUB_REPOSITORY is
|
||||
# auto-set on every Actions runner. Both are required here because a local
|
||||
# developer running the script directly won't have either unless they
|
||||
# export them, and we want a clear error in that case.
|
||||
token = os.environ.get('GITHUB_TOKEN')
|
||||
if not token:
|
||||
_fail('GITHUB_TOKEN is not set')
|
||||
repo = os.environ.get('GITHUB_REPOSITORY')
|
||||
if not repo:
|
||||
_fail('GITHUB_REPOSITORY is not set (expected "owner/name")')
|
||||
# Minimal shape check. If "owner/name" is malformed the subsequent API
|
||||
# calls would 404 with an unhelpful URL. Fail fast here instead.
|
||||
if '/' not in repo:
|
||||
_fail('GITHUB_REPOSITORY must be "owner/name", got {!r}'.format(repo))
|
||||
|
||||
try:
|
||||
client = _github_helpers.GitHubClient(token, user_agent=USER_AGENT)
|
||||
upsert_comment(
|
||||
client=client,
|
||||
repo=repo,
|
||||
pr_number=result['pr_number'],
|
||||
marker=result['marker'],
|
||||
body=result['body'],
|
||||
)
|
||||
except RuntimeError as e:
|
||||
_fail(str(e))
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Validate and post sticky PR comments from CI artifacts.',
|
||||
)
|
||||
sub = parser.add_subparsers(dest='command', required=True)
|
||||
|
||||
p_validate = sub.add_parser(
|
||||
'validate',
|
||||
help='Validate manifest.json and body.md in the given directory.',
|
||||
)
|
||||
p_validate.add_argument('directory')
|
||||
p_validate.set_defaults(func=cmd_validate)
|
||||
|
||||
p_post = sub.add_parser(
|
||||
'post',
|
||||
help='Validate, then upsert a sticky PR comment. Requires env '
|
||||
'GITHUB_TOKEN and GITHUB_REPOSITORY.',
|
||||
)
|
||||
p_post.add_argument('directory')
|
||||
p_post.set_defaults(func=cmd_post)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,468 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
PR review-comment poster for analysis workflows.
|
||||
|
||||
Sibling of Tools/ci/pr-comment-poster.py. Where pr-comment-poster.py posts
|
||||
sticky issue-style PR comments, this script posts line-anchored review
|
||||
comments on the "Files changed" tab. Use it for tools like clang-tidy that
|
||||
want to flag specific lines instead of (or in addition to) a rollup
|
||||
comment.
|
||||
|
||||
This script is invoked from the `PR Review Poster` workflow which runs on
|
||||
`workflow_run` in the base repository context. It consumes a `pr-review`
|
||||
artifact produced by an upstream analysis job and posts a fresh PR review
|
||||
via the GitHub REST API, dismissing any stale review the same producer
|
||||
left on a previous run.
|
||||
|
||||
Artifact contract (directory passed on the command line):
|
||||
|
||||
manifest.json
|
||||
{
|
||||
"pr_number": 12345, (required, int > 0)
|
||||
"marker": "<!-- pr-review-poster:clang-tidy -->", (required, printable ASCII)
|
||||
"event": "REQUEST_CHANGES", (required, "COMMENT" | "REQUEST_CHANGES")
|
||||
"commit_sha": "0123456789abcdef0123456789abcdef01234567",(required, 40 hex chars)
|
||||
"summary": "Optional review body text" (optional)
|
||||
}
|
||||
|
||||
comments.json
|
||||
JSON array of line-anchored review comment objects:
|
||||
[
|
||||
{"path": "src/foo.cpp", "line": 42, "side": "RIGHT",
|
||||
"body": "..."},
|
||||
{"path": "src/bar.hpp", "start_line": 10, "line": 15,
|
||||
"side": "RIGHT", "start_side": "RIGHT", "body": "..."}
|
||||
]
|
||||
|
||||
Note: an `APPROVE` event is intentionally NOT supported. Bots should never
|
||||
approve a pull request.
|
||||
|
||||
Security: this script is run in a write-token context from a workflow that
|
||||
MUST NOT check out PR code. Both manifest.json and comments.json are
|
||||
treated as opaque data. The marker is validated to printable ASCII only
|
||||
before use, and only reviews authored by github-actions[bot] whose body
|
||||
contains the marker can be dismissed (a fork cannot spoof either).
|
||||
|
||||
Subcommands:
|
||||
|
||||
validate <dir> Validate that <dir> contains a conforming manifest +
|
||||
comments file.
|
||||
post <dir> Validate, then dismiss any stale matching review and
|
||||
post a new review on the target PR. Requires env
|
||||
GITHUB_TOKEN and GITHUB_REPOSITORY.
|
||||
|
||||
Python stdlib only. No third-party dependencies.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
import _github_helpers
|
||||
from _github_helpers import fail as _fail
|
||||
|
||||
|
||||
USER_AGENT = 'px4-pr-review-poster'
|
||||
|
||||
# Marker length bounds. 1..200 is plenty for an HTML comment tag such as
|
||||
# "<!-- pr-review-poster:clang-tidy -->".
|
||||
MARKER_MIN_LEN = 1
|
||||
MARKER_MAX_LEN = 200
|
||||
|
||||
# Cap per-comment body size well under GitHub's hard limit so we leave
|
||||
# headroom for the wrapping JSON envelope. Empirically GitHub allows ~65535
|
||||
# bytes per review comment body; 60000 is a safe ceiling.
|
||||
MAX_COMMENT_BODY_BYTES = 60000
|
||||
|
||||
# Cap on number of comments per single review POST. platisd uses 10. The
|
||||
# value matters because GitHub's review-creation endpoint has a payload
|
||||
# size limit and review comments occasionally trip an abuse-detection
|
||||
# threshold when posted in very large batches. Smaller chunks also let us
|
||||
# spread the work across multiple reviews so a single bad entry only
|
||||
# fails its own chunk.
|
||||
COMMENTS_PER_REVIEW = 10
|
||||
|
||||
# Sleep between successive review POSTs to stay clear of GitHub's
|
||||
# secondary rate limits. platisd uses 10s; 5s is enough for our volume
|
||||
# and cuts user-visible latency.
|
||||
SLEEP_BETWEEN_CHUNKS_SECONDS = 5
|
||||
|
||||
ACCEPTED_EVENTS = ('COMMENT', 'REQUEST_CHANGES')
|
||||
ACCEPTED_SIDES = ('LEFT', 'RIGHT')
|
||||
COMMIT_SHA_RE = re.compile(r'^[0-9a-f]{40}$')
|
||||
|
||||
# The login GitHub assigns to the built-in actions token. Used to filter
|
||||
# the list of existing reviews so we never touch a human reviewer's review.
|
||||
BOT_LOGIN = 'github-actions[bot]'
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _is_printable_ascii(s):
|
||||
return all(0x20 <= ord(ch) <= 0x7E for ch in s)
|
||||
|
||||
|
||||
def validate_marker(marker):
|
||||
"""Validate the marker string. See pr-comment-poster.py for rationale."""
|
||||
if not isinstance(marker, str):
|
||||
_fail('marker must be a string')
|
||||
n = len(marker)
|
||||
if n < MARKER_MIN_LEN or n > MARKER_MAX_LEN:
|
||||
_fail('marker length out of range ({}..{}): {}'.format(
|
||||
MARKER_MIN_LEN, MARKER_MAX_LEN, n))
|
||||
if not _is_printable_ascii(marker):
|
||||
_fail('marker contains non-printable or non-ASCII character')
|
||||
|
||||
|
||||
def _validate_comment_entry(idx, entry):
|
||||
"""Validate a single review-comment entry. Raises via _fail on error."""
|
||||
if not isinstance(entry, dict):
|
||||
_fail('comments[{}]: must be an object'.format(idx))
|
||||
|
||||
path = entry.get('path')
|
||||
if not isinstance(path, str) or not path:
|
||||
_fail('comments[{}].path: required non-empty string'.format(idx))
|
||||
|
||||
line = entry.get('line')
|
||||
if not isinstance(line, int) or isinstance(line, bool) or line <= 0:
|
||||
_fail('comments[{}].line: required positive integer'.format(idx))
|
||||
|
||||
side = entry.get('side', 'RIGHT')
|
||||
if side not in ACCEPTED_SIDES:
|
||||
_fail('comments[{}].side: must be one of {} (got {!r})'.format(
|
||||
idx, ', '.join(ACCEPTED_SIDES), side))
|
||||
|
||||
if 'start_line' in entry:
|
||||
start_line = entry['start_line']
|
||||
if (not isinstance(start_line, int)
|
||||
or isinstance(start_line, bool)
|
||||
or start_line <= 0):
|
||||
_fail('comments[{}].start_line: must be positive integer'.format(idx))
|
||||
if start_line >= line:
|
||||
_fail('comments[{}].start_line ({}) must be < line ({})'.format(
|
||||
idx, start_line, line))
|
||||
start_side = entry.get('start_side', side)
|
||||
if start_side not in ACCEPTED_SIDES:
|
||||
_fail('comments[{}].start_side: must be one of {}'.format(
|
||||
idx, ', '.join(ACCEPTED_SIDES)))
|
||||
|
||||
body = entry.get('body')
|
||||
if not isinstance(body, str) or not body:
|
||||
_fail('comments[{}].body: required non-empty string'.format(idx))
|
||||
body_bytes = len(body.encode('utf-8'))
|
||||
if body_bytes > MAX_COMMENT_BODY_BYTES:
|
||||
_fail('comments[{}].body too large: {} bytes (max {})'.format(
|
||||
idx, body_bytes, MAX_COMMENT_BODY_BYTES))
|
||||
|
||||
|
||||
def validate_manifest(directory):
|
||||
"""Validate <directory>/manifest.json and <directory>/comments.json.
|
||||
|
||||
Returns a dict with keys: pr_number, marker, event, commit_sha,
|
||||
summary, comments (list of validated comment dicts).
|
||||
"""
|
||||
manifest_path = os.path.join(directory, 'manifest.json')
|
||||
comments_path = os.path.join(directory, 'comments.json')
|
||||
|
||||
if not os.path.isfile(manifest_path):
|
||||
_fail('manifest.json missing at {}'.format(manifest_path))
|
||||
if not os.path.isfile(comments_path):
|
||||
_fail('comments.json missing at {}'.format(comments_path))
|
||||
|
||||
try:
|
||||
with open(manifest_path, 'r', encoding='utf-8') as f:
|
||||
manifest = json.load(f)
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
_fail('manifest.json is not valid JSON: {}'.format(e))
|
||||
|
||||
if not isinstance(manifest, dict):
|
||||
_fail('manifest.json must be a JSON object')
|
||||
|
||||
pr_number = manifest.get('pr_number')
|
||||
if not isinstance(pr_number, int) or isinstance(pr_number, bool):
|
||||
_fail('pr_number must be an integer')
|
||||
if pr_number <= 0:
|
||||
_fail('pr_number must be > 0 (got {})'.format(pr_number))
|
||||
|
||||
marker = manifest.get('marker')
|
||||
validate_marker(marker)
|
||||
|
||||
event = manifest.get('event')
|
||||
if event not in ACCEPTED_EVENTS:
|
||||
_fail('event must be one of {} (got {!r}). APPROVE is intentionally '
|
||||
'forbidden.'.format(', '.join(ACCEPTED_EVENTS), event))
|
||||
|
||||
commit_sha = manifest.get('commit_sha')
|
||||
if not isinstance(commit_sha, str) or not COMMIT_SHA_RE.match(commit_sha):
|
||||
_fail('commit_sha must be a 40-character lowercase hex string')
|
||||
|
||||
summary = manifest.get('summary', '')
|
||||
if summary is None:
|
||||
summary = ''
|
||||
if not isinstance(summary, str):
|
||||
_fail('summary must be a string if present')
|
||||
|
||||
try:
|
||||
with open(comments_path, 'r', encoding='utf-8') as f:
|
||||
comments = json.load(f)
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
_fail('comments.json is not valid JSON: {}'.format(e))
|
||||
|
||||
if not isinstance(comments, list):
|
||||
_fail('comments.json must be a JSON array')
|
||||
|
||||
for idx, entry in enumerate(comments):
|
||||
_validate_comment_entry(idx, entry)
|
||||
|
||||
return {
|
||||
'pr_number': pr_number,
|
||||
'marker': marker,
|
||||
'event': event,
|
||||
'commit_sha': commit_sha,
|
||||
'summary': summary,
|
||||
'comments': comments,
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stale-review dismissal
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def find_stale_reviews(client, repo, pr_number, marker):
|
||||
"""Yield (id, state) for each existing review owned by the bot AND
|
||||
whose body contains the marker.
|
||||
|
||||
Filtering on BOTH author == github-actions[bot] AND marker-in-body is
|
||||
the security invariant: a fork PR cannot impersonate the bot login,
|
||||
and a fork PR also cannot inject the marker into a human reviewer's
|
||||
body without API access.
|
||||
"""
|
||||
path = 'repos/{}/pulls/{}/reviews'.format(repo, pr_number)
|
||||
for review in client.paginated(path):
|
||||
user = review.get('user') or {}
|
||||
if user.get('login') != BOT_LOGIN:
|
||||
continue
|
||||
body = review.get('body') or ''
|
||||
if marker not in body:
|
||||
continue
|
||||
yield review.get('id'), review.get('state')
|
||||
|
||||
|
||||
def dismiss_stale_reviews(client, repo, pr_number, marker):
|
||||
"""Dismiss (or, for PENDING reviews, delete) every stale matching review."""
|
||||
dismissal_message = 'Superseded by a newer run'
|
||||
for review_id, state in find_stale_reviews(client, repo, pr_number, marker):
|
||||
if review_id is None:
|
||||
continue
|
||||
if state == 'DISMISSED':
|
||||
# Already inert; nothing to do.
|
||||
continue
|
||||
if state == 'PENDING':
|
||||
# PENDING reviews cannot be dismissed; they must be deleted.
|
||||
print('Deleting pending stale review {}'.format(review_id))
|
||||
try:
|
||||
client.request(
|
||||
'DELETE',
|
||||
'repos/{}/pulls/{}/reviews/{}'.format(
|
||||
repo, pr_number, review_id))
|
||||
except RuntimeError as e:
|
||||
# Don't abort the run on dismissal failure: the new review
|
||||
# will still be posted.
|
||||
print('warning: failed to delete pending review {}: {}'.format(
|
||||
review_id, e), file=sys.stderr)
|
||||
continue
|
||||
print('Dismissing stale review {} (state={})'.format(review_id, state))
|
||||
try:
|
||||
client.request(
|
||||
'PUT',
|
||||
'repos/{}/pulls/{}/reviews/{}/dismissals'.format(
|
||||
repo, pr_number, review_id),
|
||||
json_body={
|
||||
'message': dismissal_message,
|
||||
'event': 'DISMISS',
|
||||
},
|
||||
)
|
||||
except RuntimeError as e:
|
||||
print('warning: failed to dismiss review {}: {}'.format(
|
||||
review_id, e), file=sys.stderr)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Review posting
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _chunk(lst, n):
|
||||
"""Yield successive n-sized slices of lst."""
|
||||
for i in range(0, len(lst), n):
|
||||
yield lst[i:i + n]
|
||||
|
||||
|
||||
def _build_review_body(marker, summary, chunk_index, chunk_total):
|
||||
"""Construct the review body text.
|
||||
|
||||
Always begins with the marker (so future runs can find and dismiss
|
||||
this review). Appends a chunk index when the comment set is split
|
||||
across multiple reviews, and the producer-supplied summary if any.
|
||||
"""
|
||||
parts = [marker]
|
||||
if chunk_total > 1:
|
||||
parts.append('({}/{})'.format(chunk_index + 1, chunk_total))
|
||||
if summary:
|
||||
parts.append('')
|
||||
parts.append(summary)
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
def _comment_to_api(entry):
|
||||
"""Project a validated comment dict to the GitHub API shape."""
|
||||
api = {
|
||||
'path': entry['path'],
|
||||
'line': entry['line'],
|
||||
'side': entry.get('side', 'RIGHT'),
|
||||
'body': entry['body'],
|
||||
}
|
||||
if 'start_line' in entry:
|
||||
api['start_line'] = entry['start_line']
|
||||
api['start_side'] = entry.get('start_side', api['side'])
|
||||
return api
|
||||
|
||||
|
||||
def post_review(client, repo, pr_number, marker, event, commit_sha, summary,
|
||||
comments):
|
||||
"""Post one or more reviews containing the validated comments.
|
||||
|
||||
Comments are split into COMMENTS_PER_REVIEW-sized chunks. Each chunk
|
||||
becomes its own review POST. A failed chunk logs a warning and the
|
||||
loop continues to the next chunk.
|
||||
"""
|
||||
chunks = list(_chunk(comments, COMMENTS_PER_REVIEW))
|
||||
total = len(chunks)
|
||||
if total == 0:
|
||||
print('No comments to post; skipping review creation.')
|
||||
return
|
||||
|
||||
posted_any = False
|
||||
for idx, chunk in enumerate(chunks):
|
||||
if idx > 0:
|
||||
time.sleep(SLEEP_BETWEEN_CHUNKS_SECONDS)
|
||||
body = _build_review_body(marker, summary, idx, total)
|
||||
payload = {
|
||||
'commit_id': commit_sha,
|
||||
'body': body,
|
||||
'event': event,
|
||||
'comments': [_comment_to_api(c) for c in chunk],
|
||||
}
|
||||
print('Posting review chunk {}/{} with {} comment(s)'.format(
|
||||
idx + 1, total, len(chunk)))
|
||||
try:
|
||||
client.request(
|
||||
'POST',
|
||||
'repos/{}/pulls/{}/reviews'.format(repo, pr_number),
|
||||
json_body=payload,
|
||||
)
|
||||
posted_any = True
|
||||
except RuntimeError as e:
|
||||
# Most common cause is HTTP 422: a comment refers to a line
|
||||
# GitHub does not consider part of the diff. Skip the bad
|
||||
# chunk and keep going so other findings still get posted.
|
||||
print('warning: review chunk {}/{} failed: {}'.format(
|
||||
idx + 1, total, e), file=sys.stderr)
|
||||
|
||||
if not posted_any:
|
||||
# If every single chunk failed, surface that as a hard error so
|
||||
# the workflow turns red and a human looks at it.
|
||||
_fail('all review chunks failed to post; see warnings above')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Entry points
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def cmd_validate(args):
|
||||
result = validate_manifest(args.directory)
|
||||
print(('ok: pr_number={} marker_len={} event={} commit_sha={} '
|
||||
'comments={} summary_len={}').format(
|
||||
result['pr_number'],
|
||||
len(result['marker']),
|
||||
result['event'],
|
||||
result['commit_sha'],
|
||||
len(result['comments']),
|
||||
len(result['summary']),
|
||||
))
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_post(args):
|
||||
result = validate_manifest(args.directory)
|
||||
|
||||
# Empty comment lists short-circuit silently. A producer that ran but
|
||||
# found nothing to flag should not generate noise on the PR.
|
||||
if len(result['comments']) == 0:
|
||||
print('No comments in artifact; nothing to post.')
|
||||
return 0
|
||||
|
||||
token = os.environ.get('GITHUB_TOKEN')
|
||||
if not token:
|
||||
_fail('GITHUB_TOKEN is not set')
|
||||
repo = os.environ.get('GITHUB_REPOSITORY')
|
||||
if not repo:
|
||||
_fail('GITHUB_REPOSITORY is not set (expected "owner/name")')
|
||||
if '/' not in repo:
|
||||
_fail('GITHUB_REPOSITORY must be "owner/name", got {!r}'.format(repo))
|
||||
|
||||
try:
|
||||
client = _github_helpers.GitHubClient(token, user_agent=USER_AGENT)
|
||||
dismiss_stale_reviews(
|
||||
client=client,
|
||||
repo=repo,
|
||||
pr_number=result['pr_number'],
|
||||
marker=result['marker'],
|
||||
)
|
||||
post_review(
|
||||
client=client,
|
||||
repo=repo,
|
||||
pr_number=result['pr_number'],
|
||||
marker=result['marker'],
|
||||
event=result['event'],
|
||||
commit_sha=result['commit_sha'],
|
||||
summary=result['summary'],
|
||||
comments=result['comments'],
|
||||
)
|
||||
except RuntimeError as e:
|
||||
_fail(str(e))
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Validate and post line-anchored PR review comments '
|
||||
'from CI artifacts.',
|
||||
)
|
||||
sub = parser.add_subparsers(dest='command', required=True)
|
||||
|
||||
p_validate = sub.add_parser(
|
||||
'validate',
|
||||
help='Validate manifest.json and comments.json in the given directory.',
|
||||
)
|
||||
p_validate.add_argument('directory')
|
||||
p_validate.set_defaults(func=cmd_validate)
|
||||
|
||||
p_post = sub.add_parser(
|
||||
'post',
|
||||
help='Validate, then dismiss any stale review and post a new one. '
|
||||
'Requires env GITHUB_TOKEN and GITHUB_REPOSITORY.',
|
||||
)
|
||||
p_post.add_argument('directory')
|
||||
p_post.set_defaults(func=cmd_post)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Run clang-tidy incrementally on files changed in a PR.
|
||||
|
||||
Usage: run-clang-tidy-pr.py <base-ref>
|
||||
base-ref: e.g. origin/main
|
||||
|
||||
Computes the set of translation units (TUs) affected by the PR diff,
|
||||
then invokes Tools/run-clang-tidy.py on that subset only.
|
||||
Exits 0 silently when no C++ files were changed.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
EXTENSIONS_CPP = {'.cpp', '.c'}
|
||||
EXTENSIONS_HDR = {'.hpp', '.h'}
|
||||
# Manual exclusions from Makefile:508
|
||||
EXCLUDE_EXTRA = '|'.join([
|
||||
'src/systemcmds/tests',
|
||||
'src/examples',
|
||||
'src/modules/gyro_fft/CMSIS_5',
|
||||
'src/lib/drivers/smbus',
|
||||
'src/drivers/gpio',
|
||||
r'src/modules/commander/failsafe/emscripten',
|
||||
r'failsafe_test\.dir',
|
||||
])
|
||||
|
||||
|
||||
def repo_root():
|
||||
try:
|
||||
return subprocess.check_output(
|
||||
['git', 'rev-parse', '--show-toplevel'], text=True).strip()
|
||||
except subprocess.CalledProcessError:
|
||||
print('error: not inside a git repository', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def changed_files(base_ref, root):
|
||||
try:
|
||||
out = subprocess.check_output(
|
||||
['git', 'diff', '--name-only', f'{base_ref}...HEAD',
|
||||
'--', '*.cpp', '*.hpp', '*.h', '*.c'],
|
||||
text=True, cwd=root).strip()
|
||||
return out.splitlines() if out else []
|
||||
except subprocess.CalledProcessError:
|
||||
print(f'error: could not diff against "{base_ref}" — '
|
||||
'is the ref valid and fetched?', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def submodule_paths(root):
|
||||
# Returns [] if .gitmodules is absent or has no paths — both valid
|
||||
try:
|
||||
out = subprocess.check_output(
|
||||
['git', 'config', '--file', '.gitmodules',
|
||||
'--get-regexp', 'path'],
|
||||
text=True, cwd=root).strip()
|
||||
return [line.split()[1] for line in out.splitlines()]
|
||||
except subprocess.CalledProcessError:
|
||||
return []
|
||||
|
||||
|
||||
def build_exclude(root):
|
||||
submodules = '|'.join(submodule_paths(root))
|
||||
return f'{submodules}|{EXCLUDE_EXTRA}' if submodules else EXCLUDE_EXTRA
|
||||
|
||||
|
||||
def load_db(build_dir):
|
||||
db_path = os.path.join(build_dir, 'compile_commands.json')
|
||||
if not os.path.isfile(db_path):
|
||||
print(f'error: {db_path} not found', file=sys.stderr)
|
||||
print('Run "make px4_sitl_default-clang" first to generate '
|
||||
'the compilation database', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
try:
|
||||
with open(db_path) as f:
|
||||
return json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f'error: compile_commands.json is malformed: {e}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def find_tus(changed, db, root):
|
||||
db_files = {e['file'] for e in db}
|
||||
result = set()
|
||||
for f in changed:
|
||||
abs_path = os.path.join(root, f)
|
||||
ext = os.path.splitext(f)[1]
|
||||
if ext in EXTENSIONS_CPP:
|
||||
if abs_path in db_files:
|
||||
result.add(abs_path)
|
||||
elif ext in EXTENSIONS_HDR:
|
||||
hdr = os.path.basename(f)
|
||||
for e in db:
|
||||
try:
|
||||
if hdr in open(e['file']).read():
|
||||
result.add(e['file'])
|
||||
except OSError:
|
||||
pass # file deleted in PR — skip
|
||||
return sorted(result)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('base_ref',
|
||||
help='Git ref to diff against, e.g. origin/main')
|
||||
args = parser.parse_args()
|
||||
|
||||
root = repo_root()
|
||||
build_dir = os.path.join(root, 'build', 'px4_sitl_default-clang')
|
||||
|
||||
run_tidy = os.path.join(root, 'Tools', 'run-clang-tidy.py')
|
||||
if not os.path.isfile(run_tidy):
|
||||
print(f'error: {run_tidy} not found', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
changed = changed_files(args.base_ref, root)
|
||||
if not changed:
|
||||
print('No C++ files changed — skipping clang-tidy')
|
||||
sys.exit(0)
|
||||
|
||||
db = load_db(build_dir)
|
||||
tus = find_tus(changed, db, root)
|
||||
|
||||
if not tus:
|
||||
print('No matching TUs in compile_commands.json — skipping clang-tidy')
|
||||
sys.exit(0)
|
||||
|
||||
print(f'Running clang-tidy on {len(tus)} translation unit(s)')
|
||||
|
||||
result = subprocess.run(
|
||||
[sys.executable, run_tidy,
|
||||
'-header-filter=.*\\.hpp',
|
||||
'-j0',
|
||||
f'-exclude={build_exclude(root)}',
|
||||
'-p', build_dir] + tus
|
||||
)
|
||||
sys.exit(result.returncode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -10,6 +10,7 @@ CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3"
|
||||
CONFIG_DRIVERS_ADC_ADS1115=y
|
||||
CONFIG_DRIVERS_ADC_BOARD_ADC=y
|
||||
CONFIG_DRIVERS_BAROMETER_BMP388=y
|
||||
CONFIG_DRIVERS_BAROMETER_DPS310=y
|
||||
CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y
|
||||
CONFIG_DRIVERS_BAROMETER_MS5611=y
|
||||
CONFIG_DRIVERS_CAMERA_CAPTURE=y
|
||||
@@ -47,6 +48,7 @@ CONFIG_MODULES_CAMERA_FEEDBACK=y
|
||||
CONFIG_MODULES_COMMANDER=y
|
||||
CONFIG_MODULES_CONTROL_ALLOCATOR=y
|
||||
CONFIG_MODULES_DATAMAN=y
|
||||
CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000
|
||||
CONFIG_MODULES_EKF2=y
|
||||
CONFIG_MODULES_ESC_BATTERY=y
|
||||
CONFIG_MODULES_EVENTS=y
|
||||
@@ -73,7 +75,6 @@ CONFIG_MODULES_MC_POS_CONTROL=y
|
||||
CONFIG_MODULES_MC_RATE_CONTROL=y
|
||||
CONFIG_MODULES_NAVIGATOR=y
|
||||
CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y
|
||||
CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000
|
||||
CONFIG_MODULES_RC_UPDATE=y
|
||||
CONFIG_MODULES_SENSORS=y
|
||||
CONFIG_MODULES_TEMPERATURE_COMPENSATION=y
|
||||
@@ -101,3 +102,4 @@ CONFIG_SYSTEMCMDS_TUNE_CONTROL=y
|
||||
CONFIG_SYSTEMCMDS_UORB=y
|
||||
CONFIG_SYSTEMCMDS_VER=y
|
||||
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
||||
CONFIG_ARCH_CHIP_STM32H7=y
|
||||
|
||||
@@ -83,10 +83,12 @@ ist8310 -X -b 1 -R 10 start
|
||||
if param compare SENS_INT_BARO_EN 1
|
||||
then
|
||||
icp201xx -I -a 0x64 start
|
||||
dps310 -I start
|
||||
fi
|
||||
|
||||
#external baro
|
||||
icp201xx -X start
|
||||
dps310 -X start
|
||||
|
||||
unset INA_CONFIGURED
|
||||
unset HAVE_PM2
|
||||
|
||||
@@ -34,8 +34,5 @@ nshterm /dev/ttyS3 &
|
||||
# Start the time_persistor to cyclically store the RTC in FRAM
|
||||
time_persistor start
|
||||
|
||||
# Start the task_watchdog as we do not have the logger watchdog
|
||||
task_watchdog start
|
||||
|
||||
# Start the ESC telemetry
|
||||
dshot telemetry -d /dev/ttyS5 -x
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Board early init.
|
||||
#
|
||||
# On FRAM boards STORAGE_AVAILABLE=yes will set the USE_* flags. Additional
|
||||
# enable required for task watchdog as this is not a generally used feature.
|
||||
# On EEPROM boards: Only airframes and params are needed.
|
||||
#
|
||||
|
||||
if mft query -q -k MTD -s MTD_PARAMETERS -v /mnt/microsd
|
||||
then
|
||||
# Start the task_watchdog as we do not have the logger watchdog
|
||||
set USE_TASK_WATCHDOG yes
|
||||
else
|
||||
set PARAM_FILE /fs/microsd/params
|
||||
set STORAGE_CHECK no
|
||||
set USE_EXTERNAL_AIRFRAMES yes
|
||||
set USE_ALT_UPDATE_DIRS yes
|
||||
fi
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_CUTOFF 80
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
# Flywoo GNF405 board specific defaults
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# default airframe quadrotor
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_RATEMAX 2000
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -9,9 +9,6 @@ param set-default BAT1_A_PER_V 17
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
param set-default SYS_HAS_MAG 0
|
||||
|
||||
# enable gravity fusion
|
||||
|
||||
@@ -19,9 +19,6 @@ param set-default BAT1_A_PER_V 59.5
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
# use EKF2 without mag
|
||||
param set-default SYS_HAS_MAG 0
|
||||
# and enable gravity fusion
|
||||
|
||||
@@ -19,9 +19,6 @@ param set-default BAT1_A_PER_V 59.5
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
# use EKF2 without mag
|
||||
param set-default SYS_HAS_MAG 0
|
||||
# and enable gravity fusion
|
||||
|
||||
@@ -19,9 +19,6 @@ param set-default BAT1_A_PER_V 59.5
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
# use EKF2 without mag
|
||||
param set-default SYS_HAS_MAG 0
|
||||
# and enable gravity fusion
|
||||
|
||||
@@ -19,9 +19,6 @@ param set-default BAT1_A_PER_V 59.5
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
# use EKF2 without mag
|
||||
param set-default SYS_HAS_MAG 0
|
||||
# and enable gravity fusion
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_CUTOFF 100
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -17,7 +17,6 @@ param set-default MAV_2_CONFIG 104
|
||||
param set-default SER_TEL4_BAUD 115200
|
||||
|
||||
param set-default IMU_GYRO_CUTOFF 80
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -16,7 +16,6 @@ param set-default MAV_2_CONFIG 104
|
||||
param set-default SER_TEL4_BAUD 115200
|
||||
|
||||
param set-default IMU_GYRO_CUTOFF 80
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_CUTOFF 80
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -287,8 +287,8 @@
|
||||
|
||||
/* AUX */
|
||||
|
||||
#define GPIO_LPUART4_RX (GPIO_LPUART4_RX_3 | LPUART_IOMUX) /* GPIO_B1_01 */
|
||||
#define GPIO_LPUART4_TX (GPIO_LPUART4_TX_3 | LPUART_IOMUX) /* GPIO_B1_00 */
|
||||
#define GPIO_LPUART4_RX (GPIO_LPUART4_RX_1 | LPUART_IOMUX) /* GPIO_B1_01 */
|
||||
#define GPIO_LPUART4_TX (GPIO_LPUART4_TX_1 | LPUART_IOMUX) /* GPIO_B1_00 */
|
||||
|
||||
/* GPS 1 */
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
CONFIG_BOARD_TOOLCHAIN="arm-none-eabi"
|
||||
CONFIG_BOARD_ARCHITECTURE="cortex-m4"
|
||||
CONFIG_BOARD_CONSTRAINED_MEMORY=y
|
||||
CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3"
|
||||
CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1"
|
||||
CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2"
|
||||
CONFIG_DRIVERS_ADC_ADS1115=y
|
||||
CONFIG_DRIVERS_ADC_BOARD_ADC=y
|
||||
CONFIG_COMMON_BAROMETERS=y
|
||||
CONFIG_DRIVERS_BATT_SMBUS=y
|
||||
CONFIG_DRIVERS_CAMERA_CAPTURE=y
|
||||
CONFIG_DRIVERS_CAMERA_TRIGGER=y
|
||||
CONFIG_DRIVERS_CDCACM_AUTOSTART=y
|
||||
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
|
||||
CONFIG_COMMON_DISTANCE_SENSOR=y
|
||||
CONFIG_DRIVERS_GPS=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_MPU6500=y
|
||||
CONFIG_DRIVERS_IMU_ST_L3GD20=y
|
||||
CONFIG_DRIVERS_IMU_ST_LSM303D=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y
|
||||
CONFIG_DRIVERS_IRLOCK=y
|
||||
CONFIG_COMMON_LIGHT=y
|
||||
CONFIG_COMMON_MAGNETOMETER=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
|
||||
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
|
||||
CONFIG_DRIVERS_PWM_INPUT=y
|
||||
CONFIG_DRIVERS_PWM_OUT=y
|
||||
CONFIG_DRIVERS_RC_INPUT=y
|
||||
CONFIG_DRIVERS_SMART_BATTERY_BATMON=y
|
||||
CONFIG_COMMON_TELEMETRY=y
|
||||
CONFIG_DRIVERS_TONE_ALARM=y
|
||||
CONFIG_DRIVERS_UAVCAN=y
|
||||
CONFIG_BOARD_UAVCAN_INTERFACES=1
|
||||
CONFIG_MODULES_AIRSPEED_SELECTOR=y
|
||||
CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y
|
||||
CONFIG_MODULES_BATTERY_STATUS=y
|
||||
CONFIG_MODULES_CAMERA_FEEDBACK=y
|
||||
CONFIG_MODULES_COMMANDER=y
|
||||
CONFIG_MODULES_CONTROL_ALLOCATOR=y
|
||||
CONFIG_MODULES_DATAMAN=y
|
||||
CONFIG_MODULES_EKF2=y
|
||||
CONFIG_MODULES_ESC_BATTERY=y
|
||||
CONFIG_MODULES_EVENTS=y
|
||||
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
|
||||
CONFIG_MODULES_FW_ATT_CONTROL=y
|
||||
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y
|
||||
CONFIG_MODULES_FW_MODE_MANAGER=y
|
||||
CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y
|
||||
CONFIG_MODULES_FW_RATE_CONTROL=y
|
||||
CONFIG_MODULES_GIMBAL=y
|
||||
CONFIG_MODULES_GYRO_CALIBRATION=y
|
||||
CONFIG_MODULES_GYRO_FFT=y
|
||||
CONFIG_MODULES_LAND_DETECTOR=y
|
||||
CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
|
||||
CONFIG_MODULES_LOAD_MON=y
|
||||
CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y
|
||||
CONFIG_MODULES_LOGGER=y
|
||||
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
|
||||
CONFIG_MODULES_MANUAL_CONTROL=y
|
||||
CONFIG_MODULES_MAVLINK=y
|
||||
CONFIG_MODULES_MC_ATT_CONTROL=y
|
||||
CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y
|
||||
CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
|
||||
CONFIG_MODULES_MC_POS_CONTROL=y
|
||||
CONFIG_MODULES_MC_RATE_CONTROL=y
|
||||
CONFIG_MODULES_NAVIGATOR=y
|
||||
CONFIG_MODULES_RC_UPDATE=y
|
||||
CONFIG_MODULES_SENSORS=y
|
||||
CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y
|
||||
CONFIG_MODULES_TEMPERATURE_COMPENSATION=y
|
||||
CONFIG_MODULES_UUV_ATT_CONTROL=y
|
||||
CONFIG_MODULES_UUV_POS_CONTROL=y
|
||||
CONFIG_MODULES_VTOL_ATT_CONTROL=y
|
||||
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
|
||||
CONFIG_SYSTEMCMDS_BL_UPDATE=y
|
||||
CONFIG_SYSTEMCMDS_BSONDUMP=y
|
||||
CONFIG_SYSTEMCMDS_DUMPFILE=y
|
||||
CONFIG_SYSTEMCMDS_GPIO=y
|
||||
CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y
|
||||
CONFIG_SYSTEMCMDS_I2CDETECT=y
|
||||
CONFIG_SYSTEMCMDS_LED_CONTROL=y
|
||||
CONFIG_SYSTEMCMDS_MFT=y
|
||||
CONFIG_SYSTEMCMDS_MTD=y
|
||||
CONFIG_SYSTEMCMDS_NSHTERM=y
|
||||
CONFIG_SYSTEMCMDS_PARAM=y
|
||||
CONFIG_SYSTEMCMDS_PERF=y
|
||||
CONFIG_SYSTEMCMDS_REBOOT=y
|
||||
CONFIG_SYSTEMCMDS_REFLECT=y
|
||||
CONFIG_SYSTEMCMDS_SD_BENCH=y
|
||||
CONFIG_SYSTEMCMDS_SD_STRESS=y
|
||||
CONFIG_SYSTEMCMDS_SERIAL_TEST=y
|
||||
CONFIG_SYSTEMCMDS_SYSTEM_TIME=y
|
||||
CONFIG_SYSTEMCMDS_TOP=y
|
||||
CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y
|
||||
CONFIG_SYSTEMCMDS_TUNE_CONTROL=y
|
||||
CONFIG_SYSTEMCMDS_UORB=y
|
||||
CONFIG_SYSTEMCMDS_USB_CONNECTED=y
|
||||
CONFIG_SYSTEMCMDS_VER=y
|
||||
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
||||
CONFIG_EXAMPLES_FAKE_GPS=y
|
||||
CONFIG_BOARD_VENDOR="saam"
|
||||
CONFIG_BOARD_MODEL="saampixv1_1"
|
||||
CONFIG_BOARD_NAME="SaamPixV1_1"
|
||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"board_id": 1,
|
||||
"magic": "PX4FWv1",
|
||||
"description": "Firmware for the SaamPixV1_1 board",
|
||||
"image": "",
|
||||
"build_time": 0,
|
||||
"summary": "SaamPixV1_1",
|
||||
"version": "1.1",
|
||||
"image_size": 0,
|
||||
"image_maxsize": 2080768,
|
||||
"git_identity": "",
|
||||
"board_revision": 0
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# board specific defaults
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
param set-default BAT1_V_DIV 10.1
|
||||
param set-default BAT1_A_PER_V 17.0
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# SaamPixV1_1 specific board sensors init
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
board_adc start
|
||||
|
||||
# external I2C compasses, if present
|
||||
hmc5883 -X start
|
||||
qmc5883l -X start
|
||||
|
||||
# internal SPI sensors
|
||||
ms5611 -s start
|
||||
icm20602 -s start
|
||||
mpu9250 -s start
|
||||
lis3mdl -s start
|
||||
@@ -0,0 +1,271 @@
|
||||
/************************************************************************************
|
||||
* boards/saam/saampixv1_1/nuttx-config/include/board.h
|
||||
* include/arch/board/board.h
|
||||
*
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_BOARD_BOARD_H
|
||||
#define __ARCH_BOARD_BOARD_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
#include "board_dma_map.h"
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <stm32.h>
|
||||
|
||||
/************************************************************************************
|
||||
* Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* Clocking *************************************************************************/
|
||||
/* The SaamPixV1_1 uses a 8MHz crystal connected to the HSE.
|
||||
*
|
||||
* This is the "standard" configuration as set up by arch/arm/src/stm32f40xx_rcc.c:
|
||||
* System Clock source : PLL (HSE)
|
||||
* SYSCLK(Hz) : 168000000 Determined by PLL configuration
|
||||
* HCLK(Hz) : 168000000 (STM32_RCC_CFGR_HPRE)
|
||||
* AHB Prescaler : 1 (STM32_RCC_CFGR_HPRE)
|
||||
* APB1 Prescaler : 4 (STM32_RCC_CFGR_PPRE1)
|
||||
* APB2 Prescaler : 2 (STM32_RCC_CFGR_PPRE2)
|
||||
* HSE Frequency(Hz) : 8000000 (STM32_BOARD_XTAL)
|
||||
* PLLM : 8 (STM32_PLLCFG_PLLM)
|
||||
* PLLN : 336 (STM32_PLLCFG_PLLN)
|
||||
* PLLP : 2 (STM32_PLLCFG_PLLP)
|
||||
* PLLQ : 7 (STM32_PLLCFG_PPQ)
|
||||
* Main regulator output voltage : Scale1 mode Needed for high speed SYSCLK
|
||||
* Flash Latency(WS) : 5
|
||||
* Prefetch Buffer : OFF
|
||||
* Instruction cache : ON
|
||||
* Data cache : ON
|
||||
* Require 48MHz for USB OTG FS, : Enabled
|
||||
* SDIO and RNG clock
|
||||
*/
|
||||
|
||||
/* HSI - 16 MHz RC factory-trimmed
|
||||
* LSI - 32 KHz RC
|
||||
* HSE - On-board crystal frequency is 8MHz
|
||||
* LSE - not installed
|
||||
*/
|
||||
|
||||
#define STM32_BOARD_XTAL 8000000ul
|
||||
|
||||
#define STM32_HSI_FREQUENCY 16000000ul
|
||||
#define STM32_LSI_FREQUENCY 32000
|
||||
#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
|
||||
//#define STM32_LSE_FREQUENCY 32768
|
||||
|
||||
/* Main PLL Configuration.
|
||||
*
|
||||
* PLL source is HSE
|
||||
* PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN
|
||||
* = (8,000,000 / 8) * 336
|
||||
* = 336,000,000
|
||||
* SYSCLK = PLL_VCO / PLLP
|
||||
* = 336,000,000 / 2 = 168,000,000
|
||||
* USB OTG FS, SDIO and RNG Clock
|
||||
* = PLL_VCO / PLLQ
|
||||
* = 48,000,000
|
||||
*/
|
||||
|
||||
#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8)
|
||||
#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(336)
|
||||
#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
|
||||
#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(7)
|
||||
|
||||
#define STM32_SYSCLK_FREQUENCY 168000000ul
|
||||
|
||||
/* AHB clock (HCLK) is SYSCLK (168MHz) */
|
||||
|
||||
#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */
|
||||
#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
|
||||
#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */
|
||||
|
||||
/* APB1 clock (PCLK1) is HCLK/4 (42MHz) */
|
||||
|
||||
#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */
|
||||
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4)
|
||||
|
||||
/* Timers driven from APB1 will be twice PCLK1 */
|
||||
|
||||
#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
|
||||
|
||||
/* APB2 clock (PCLK2) is HCLK/2 (84MHz) */
|
||||
|
||||
#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
|
||||
#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
|
||||
|
||||
/* Timers driven from APB2 will be twice PCLK2 */
|
||||
|
||||
#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
|
||||
#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
|
||||
#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY)
|
||||
#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY)
|
||||
#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY)
|
||||
|
||||
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
|
||||
* otherwise frequency is 2xAPBx.
|
||||
* Note: TIM1,8-11 are on APB2, others on APB1
|
||||
*/
|
||||
|
||||
#define BOARD_TIM1_FREQUENCY STM32_APB2_TIM1_CLKIN
|
||||
#define BOARD_TIM2_FREQUENCY STM32_APB1_TIM2_CLKIN
|
||||
#define BOARD_TIM3_FREQUENCY STM32_APB1_TIM3_CLKIN
|
||||
#define BOARD_TIM4_FREQUENCY STM32_APB1_TIM4_CLKIN
|
||||
#define BOARD_TIM5_FREQUENCY STM32_APB1_TIM5_CLKIN
|
||||
#define BOARD_TIM6_FREQUENCY STM32_APB1_TIM6_CLKIN
|
||||
#define BOARD_TIM7_FREQUENCY STM32_APB1_TIM7_CLKIN
|
||||
#define BOARD_TIM8_FREQUENCY STM32_APB2_TIM8_CLKIN
|
||||
#define BOARD_TIM9_FREQUENCY STM32_APB2_TIM9_CLKIN
|
||||
#define BOARD_TIM10_FREQUENCY STM32_APB2_TIM10_CLKIN
|
||||
#define BOARD_TIM11_FREQUENCY STM32_APB2_TIM11_CLKIN
|
||||
#define BOARD_TIM12_FREQUENCY STM32_APB1_TIM12_CLKIN
|
||||
#define BOARD_TIM13_FREQUENCY STM32_APB1_TIM13_CLKIN
|
||||
#define BOARD_TIM14_FREQUENCY STM32_APB1_TIM14_CLKIN
|
||||
|
||||
/* SDIO dividers. Note that slower clocking is required when DMA is disabled
|
||||
* in order to avoid RX overrun/TX underrun errors due to delayed responses
|
||||
* to service FIFOs in interrupt driven mode. These values have not been
|
||||
* tuned!!!
|
||||
*
|
||||
* SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz
|
||||
*/
|
||||
|
||||
#define SDIO_INIT_CLKDIV (118 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||
|
||||
/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
|
||||
* DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_DMA
|
||||
# define SDIO_MMCXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||
#else
|
||||
# define SDIO_MMCXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||
#endif
|
||||
|
||||
/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
|
||||
* DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_DMA
|
||||
# define SDIO_SDXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||
#else
|
||||
# define SDIO_SDXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT)
|
||||
#endif
|
||||
|
||||
/* Alternate function pin selections ************************************************/
|
||||
|
||||
/*
|
||||
* UARTs.
|
||||
*/
|
||||
#define GPIO_USART1_RX GPIO_USART1_RX_2 /* RC_INPUT */
|
||||
#define GPIO_USART1_TX GPIO_USART1_TX_2
|
||||
|
||||
#define GPIO_USART2_RX GPIO_USART2_RX_2
|
||||
#define GPIO_USART2_TX GPIO_USART2_TX_2
|
||||
#define GPIO_USART2_RTS GPIO_USART2_RTS_2
|
||||
#define GPIO_USART2_CTS GPIO_USART2_CTS_2
|
||||
|
||||
#define GPIO_USART3_RX GPIO_USART3_RX_3
|
||||
#define GPIO_USART3_TX GPIO_USART3_TX_3
|
||||
#define GPIO_USART3_CTS 0 // unused
|
||||
#define GPIO_USART3_RTS 0 // unused
|
||||
|
||||
#define GPIO_UART4_RX GPIO_UART4_RX_1
|
||||
#define GPIO_UART4_TX GPIO_UART4_TX_1
|
||||
|
||||
#define GPIO_USART6_RX GPIO_USART6_RX_2
|
||||
#define GPIO_USART6_TX GPIO_USART6_TX_2
|
||||
|
||||
#define GPIO_UART7_RX GPIO_UART7_RX_1
|
||||
#define GPIO_UART7_TX GPIO_UART7_TX_1
|
||||
|
||||
/* UART8 has no alternate pin config */
|
||||
|
||||
/*
|
||||
* CAN
|
||||
*
|
||||
* CAN1 is routed to the onboard transceiver.
|
||||
*/
|
||||
#define GPIO_CAN1_RX GPIO_CAN1_RX_3
|
||||
#define GPIO_CAN1_TX GPIO_CAN1_TX_3
|
||||
|
||||
/*
|
||||
* I2C
|
||||
*
|
||||
* The optional _GPIO configurations allow the I2C driver to manually
|
||||
* reset the bus to clear stuck slaves. They match the pin configuration,
|
||||
* but are normally-high GPIOs.
|
||||
*/
|
||||
#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2
|
||||
#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2
|
||||
#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN8)
|
||||
#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN9)
|
||||
|
||||
#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1
|
||||
#define GPIO_I2C2_SDA GPIO_I2C2_SDA_1
|
||||
#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN10)
|
||||
#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN11)
|
||||
|
||||
/*
|
||||
* SPI
|
||||
*
|
||||
* There are sensors on SPI1, and SPI2 is connected to the FRAM.
|
||||
*/
|
||||
#define GPIO_SPI1_MISO (GPIO_SPI1_MISO_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI1_MOSI (GPIO_SPI1_MOSI_2|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI1_SCK (GPIO_SPI1_SCK_1|GPIO_SPEED_50MHz)
|
||||
|
||||
#define GPIO_SPI2_MISO (GPIO_SPI2_MISO_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI2_MOSI (GPIO_SPI2_MOSI_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI2_SCK (GPIO_SPI2_SCK_2|GPIO_SPEED_50MHz)
|
||||
|
||||
#define GPIO_SPI4_MISO (GPIO_SPI4_MISO_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI4_MOSI (GPIO_SPI4_MOSI_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI4_SCK (GPIO_SPI4_SCK_1|GPIO_SPEED_50MHz)
|
||||
|
||||
|
||||
#endif /* __ARCH_BOARD_BOARD_H */
|
||||
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
/*
|
||||
| DMA1 | Stream 0 | Stream 1 | Stream 2 | Stream 3 | Stream 4 | Stream 5 | Stream 6 | Stream 7 |
|
||||
|------------|------------------|------------------|------------------|------------------|------------------|------------------|------------------|------------------|
|
||||
| Channel 0 | SPI3_RX_1 | - | SPI3_RX_2 | SPI2_RX | SPI2_TX | SPI3_TX_1 | - | SPI3_TX_2 |
|
||||
| Channel 1 | I2C1_RX | - | TIM7_UP_1 | - | TIM7_UP_2 | I2C1_RX_1 | I2C1_TX | I2C1_TX_1 |
|
||||
| Channel 2 | TIM4_CH1 | - | I2C4_RX | TIM4_CH2 | - | I2C4_RX | TIM4_UP | TIM4_CH3 |
|
||||
| Channel 3 | - | TIM2_UP_1 | I2C3_RX_1 | I2C2_EXT_RX | I2C3_TX | TIM2_CH1 | TIM2_CH2 | TIM2_UP_2 |
|
||||
| | | TIM2_CH3 | | | | | TIM2_CH4_1 | TIM2_CH4_2 |
|
||||
| Channel 4 | UART5_RX | USART3_RX | UART4_RX | USART3_TX_1 | UART4_TX | USART2_RX | USART2_TX | UART5_TX |
|
||||
| Channel 5 | UART8_TX | UART7_TX | TIM3_CH4 | UART7_RX | TIM3_CH1 | TIM3_CH2 | UART8_RX | TIM3_CH3 |
|
||||
| | | | TIM3_UP | | TIM3_TRIG | | | |
|
||||
| Channel 6 | TIM5_CH3 | TIM5_CH4_1 | TIM5_CH1 | TIM5_CH4_2 | TIM5_CH2 | - | TIM5_UP_2 | - |
|
||||
| | TIM5_UP_1 | TIM5_TRIG_1 | | TIM5_TRIG_2 | | | | |
|
||||
| Channel 7 | - | TIM6_UP | I2C2_RX | I2C2_RX_1 | USART3_TX_2 | DAC1 | DAC2 | I2C2_TX |
|
||||
| | | | | | | | | |
|
||||
| Usage | | | | | | | | |
|
||||
|
||||
|
||||
| DMA2 | Stream 0 | Stream 1 | Stream 2 | Stream 3 | Stream 4 | Stream 5 | Stream 6 | Stream 7 |
|
||||
|------------|------------------|------------------|------------------|------------------|------------------|------------------|------------------|------------------|
|
||||
| Channel 0 | ADC1_1 | SAI1_A | TIM8_CH1_1 | SAI1_A_1 | ADC1_2 | SAI1_B_1 | TIM1_CH1_1 | - |
|
||||
| | | | TIM8_CH2_1 | | | | TIM1_CH2_1 | |
|
||||
| | | | TIM8_CH3_1 | | | | TIM1_CH3_1 | |
|
||||
| Channel 1 | - | DCMI_1 | ADC2_1 | ADC2_2 | SAI1_B | SPI6_TX | SPI6_RX | DCMI_2 |
|
||||
| Channel 2 | ADC3_1 | ADC3_2 | - | SPI5_RX_1 | SPI5_TX_1 | CRYP_OUT | CRYP_IN | HASH_IN |
|
||||
| Channel 3 | SPI1_RX_1 | - | SPI1_RX_2 | SPI1_TX_1 | - | SPI1_TX_2 | - | QUADSPI |
|
||||
| Channel 4 | SPI4_RX_1 | SPI4_TX_1 | USART1_RX_1 | SDIO | - | USART1_RX_2 | SDIO | USART1_TX |
|
||||
| Channel 5 | - | USART6_RX_1 | USART6_RX_2 | SPI4_RX_2 | SPI4_TX_2 | - | USART6_TX_1 | USART6_TX_2 |
|
||||
| Channel 6 | TIM1_TRIG_1 | TIM1_CH1_2 | TIM1_CH2_2 | TIM1_CH1 | TIM1_CH4 | TIM1_UP | TIM1_CH3_2 | - |
|
||||
| | | | | | TIM1_TRIG_2 | | | |
|
||||
| | | | | | TIM1_COM | | | |
|
||||
| Channel 7 | - | TIM8_UP | TIM8_CH1_2 | TIM8_CH2_2 | TIM8_CH3_2 | SPI5_RX_2 | SPI5_TX_2 | TIM8_CH4 |
|
||||
| | | | | | | | | TIM8_TRIG |
|
||||
| | | | | | | | | TIM8_COM |
|
||||
| | | | | | | | | |
|
||||
| Usage | SPI4_RX_1 | USART6_RX_1 | USART1_RX_1 | | SPI4_TX_2 | | SDIO | |
|
||||
*/
|
||||
|
||||
// DMA1 Channel/Stream Selections
|
||||
//--------------------------------------------//---------------------------//----------------
|
||||
|
||||
|
||||
// DMA2 Channel/Stream Selections
|
||||
//--------------------------------------------//---------------------------//----------------
|
||||
#define DMACHAN_SPI4_RX DMAMAP_SPI4_RX_1 // DMA2, Stream 0, Channel 4 (SPI sensors RX)
|
||||
#define DMAMAP_USART6_RX DMAMAP_USART6_RX_1 // DMA2, Stream 1, Channel 4
|
||||
#define DMAMAP_USART1_RX DMAMAP_USART1_RX_1 // DMA2, Stream 2, Channel 4
|
||||
// AVAILABLE // DMA2, Stream 3
|
||||
#define DMACHAN_SPI4_TX DMAMAP_SPI4_TX_2 // DMA2, Stream 4, Channel 5 (SPI sensors TX)
|
||||
// AVAILABLE // DMA2, Stream 5, Channel 6
|
||||
#define DMAMAP_SDIO DMAMAP_SDIO_2 // DMA2, Stream 6, Channel 4
|
||||
@@ -0,0 +1,255 @@
|
||||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_DISABLE_ENVIRON is not set
|
||||
# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
|
||||
# CONFIG_DISABLE_PTHREAD is not set
|
||||
# CONFIG_MMCSD_HAVE_CARDDETECT is not set
|
||||
# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set
|
||||
# CONFIG_MMCSD_MMCSUPPORT is not set
|
||||
# CONFIG_MMCSD_SPI is not set
|
||||
# CONFIG_NSH_DISABLEBG is not set
|
||||
# CONFIG_NSH_DISABLESCRIPT is not set
|
||||
# CONFIG_NSH_DISABLE_CAT is not set
|
||||
# CONFIG_NSH_DISABLE_CD is not set
|
||||
# CONFIG_NSH_DISABLE_CP is not set
|
||||
# CONFIG_NSH_DISABLE_DATE is not set
|
||||
# CONFIG_NSH_DISABLE_DF is not set
|
||||
# CONFIG_NSH_DISABLE_ECHO is not set
|
||||
# CONFIG_NSH_DISABLE_ENV is not set
|
||||
# CONFIG_NSH_DISABLE_EXEC is not set
|
||||
# CONFIG_NSH_DISABLE_EXIT is not set
|
||||
# CONFIG_NSH_DISABLE_EXPORT is not set
|
||||
# CONFIG_NSH_DISABLE_FREE is not set
|
||||
# CONFIG_NSH_DISABLE_GET is not set
|
||||
# CONFIG_NSH_DISABLE_HELP is not set
|
||||
# CONFIG_NSH_DISABLE_ITEF is not set
|
||||
# CONFIG_NSH_DISABLE_KILL is not set
|
||||
# CONFIG_NSH_DISABLE_LOOPS is not set
|
||||
# CONFIG_NSH_DISABLE_LS is not set
|
||||
# CONFIG_NSH_DISABLE_MKDIR is not set
|
||||
# CONFIG_NSH_DISABLE_MKFATFS is not set
|
||||
# CONFIG_NSH_DISABLE_MOUNT is not set
|
||||
# CONFIG_NSH_DISABLE_MV is not set
|
||||
# CONFIG_NSH_DISABLE_PRINTF is not set
|
||||
# CONFIG_NSH_DISABLE_PS is not set
|
||||
# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set
|
||||
# CONFIG_NSH_DISABLE_PWD is not set
|
||||
# CONFIG_NSH_DISABLE_RM is not set
|
||||
# CONFIG_NSH_DISABLE_RMDIR is not set
|
||||
# CONFIG_NSH_DISABLE_SEMICOLON is not set
|
||||
# CONFIG_NSH_DISABLE_SET is not set
|
||||
# CONFIG_NSH_DISABLE_SLEEP is not set
|
||||
# CONFIG_NSH_DISABLE_SOURCE is not set
|
||||
# CONFIG_NSH_DISABLE_TEST is not set
|
||||
# CONFIG_NSH_DISABLE_TIME is not set
|
||||
# CONFIG_NSH_DISABLE_UMOUNT is not set
|
||||
# CONFIG_NSH_DISABLE_UNSET is not set
|
||||
# CONFIG_NSH_DISABLE_USLEEP is not set
|
||||
# CONFIG_STM32_CCMEXCLUDE is not set
|
||||
CONFIG_ARCH="arm"
|
||||
CONFIG_ARCH_BOARD_CUSTOM=y
|
||||
CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/saam/saampixv1_1/nuttx-config"
|
||||
CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y
|
||||
CONFIG_ARCH_BOARD_CUSTOM_NAME="px4"
|
||||
CONFIG_ARCH_CHIP="stm32"
|
||||
CONFIG_ARCH_CHIP_STM32=y
|
||||
CONFIG_ARCH_CHIP_STM32F427V=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=768
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARMV7M_MEMCPY=y
|
||||
CONFIG_ARMV7M_USEBASEPRI=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_ASSERT_RESET_VALUE=0
|
||||
CONFIG_BOARD_CRASHDUMP=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=16717
|
||||
CONFIG_BOARD_RESET_ON_ASSERT=2
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CDCACM=y
|
||||
CONFIG_CDCACM_IFLOWCONTROL=y
|
||||
CONFIG_CDCACM_PRODUCTID=0x008E
|
||||
CONFIG_CDCACM_PRODUCTSTR="SaamPixV1_1 Flight Controller"
|
||||
CONFIG_CDCACM_RXBUFSIZE=600
|
||||
CONFIG_CDCACM_TXBUFSIZE=2000
|
||||
CONFIG_CDCACM_VENDORID=0x26ac
|
||||
CONFIG_CDCACM_VENDORSTR="Saam Drones"
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_HARDFAULT_ALERT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_TCBINFO=y
|
||||
CONFIG_DEFAULT_SMALL=y
|
||||
CONFIG_DEV_FIFO_SIZE=0
|
||||
CONFIG_DEV_PIPE_MAXSIZE=1024
|
||||
CONFIG_DEV_PIPE_SIZE=70
|
||||
CONFIG_FAT_DMAMEMORY=y
|
||||
CONFIG_FAT_LCNAMES=y
|
||||
CONFIG_FAT_LFN=y
|
||||
CONFIG_FAT_LFN_ALIAS_HASH=y
|
||||
CONFIG_FDCLONE_STDIO=y
|
||||
CONFIG_FS_BINFS=y
|
||||
CONFIG_FS_CROMFS=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FS_FATTIME=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_GRAN=y
|
||||
CONFIG_GRAN_INTR=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_RESET=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=750
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INIT_STACKSIZE=3194
|
||||
CONFIG_LIBC_FLOATINGPOINT=y
|
||||
CONFIG_LIBC_LONG_LONG=y
|
||||
CONFIG_LIBC_MAX_EXITFUNS=1
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_MEMSET_64BIT=y
|
||||
CONFIG_MEMSET_OPTSPEED=y
|
||||
CONFIG_MMCSD=y
|
||||
CONFIG_MMCSD_SDIO=y
|
||||
CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y
|
||||
CONFIG_MM_REGIONS=2
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BYTE_WRITE=y
|
||||
CONFIG_MTD_PARTITION=y
|
||||
CONFIG_MTD_RAMTRON=y
|
||||
CONFIG_NAME_MAX=40
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_ARGCAT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_CMDPARMS=y
|
||||
CONFIG_NSH_CROMFSETC=y
|
||||
CONFIG_NSH_LINELEN=128
|
||||
CONFIG_NSH_MAXARGUMENTS=15
|
||||
CONFIG_NSH_NESTDEPTH=8
|
||||
CONFIG_NSH_QUOTE=y
|
||||
CONFIG_NSH_ROMFSETC=y
|
||||
CONFIG_NSH_ROMFSSECTSIZE=128
|
||||
CONFIG_NSH_STRERROR=y
|
||||
CONFIG_NSH_VARS=y
|
||||
CONFIG_PIPES=y
|
||||
CONFIG_PREALLOC_TIMERS=50
|
||||
CONFIG_PRIORITY_INHERITANCE=y
|
||||
CONFIG_PTHREAD_MUTEX_ROBUST=y
|
||||
CONFIG_PTHREAD_STACK_MIN=512
|
||||
CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
|
||||
CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
|
||||
CONFIG_RAMTRON_SETSPEED=y
|
||||
CONFIG_RAM_SIZE=262144
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RTC_DATETIME=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=249
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=1280
|
||||
CONFIG_SCHED_INSTRUMENTATION=y
|
||||
CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y
|
||||
CONFIG_SCHED_INSTRUMENTATION_SWITCH=y
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=50
|
||||
CONFIG_SCHED_LPWORKSTACKSIZE=1632
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDIO_BLOCKSETUP=y
|
||||
CONFIG_SEM_PREALLOCHOLDERS=32
|
||||
CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
CONFIG_SIG_DEFAULT=y
|
||||
CONFIG_SIG_SIGALRM_ACTION=y
|
||||
CONFIG_SIG_SIGUSR1_ACTION=y
|
||||
CONFIG_SIG_SIGUSR2_ACTION=y
|
||||
CONFIG_SIG_SIGWORK=4
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=30
|
||||
CONFIG_START_MONTH=11
|
||||
CONFIG_STDIO_BUFFER_SIZE=32
|
||||
CONFIG_STM32_ADC1=y
|
||||
CONFIG_STM32_BBSRAM=y
|
||||
CONFIG_STM32_BBSRAM_FILES=5
|
||||
CONFIG_STM32_BKPSRAM=y
|
||||
CONFIG_STM32_CCMDATARAM=y
|
||||
CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
|
||||
CONFIG_STM32_DMA1=y
|
||||
CONFIG_STM32_DMA2=y
|
||||
CONFIG_STM32_FLASH_CONFIG_I=y
|
||||
CONFIG_STM32_FLOWCONTROL_BROKEN=y
|
||||
CONFIG_STM32_I2C1=y
|
||||
CONFIG_STM32_I2C2=y
|
||||
CONFIG_STM32_I2CTIMEOMS=10
|
||||
CONFIG_STM32_I2CTIMEOTICKS=10
|
||||
CONFIG_STM32_JTAG_SW_ENABLE=y
|
||||
CONFIG_STM32_OTGFS=y
|
||||
CONFIG_STM32_PWR=y
|
||||
CONFIG_STM32_RTC=y
|
||||
CONFIG_STM32_RTC_HSECLOCK=y
|
||||
CONFIG_STM32_RTC_MAGIC=0xfacefeee
|
||||
CONFIG_STM32_RTC_MAGIC_REG=1
|
||||
CONFIG_STM32_RTC_MAGIC_TIME_SET=0xfacefeef
|
||||
CONFIG_STM32_SAVE_CRASHDUMP=y
|
||||
CONFIG_STM32_SDIO=y
|
||||
CONFIG_STM32_SDIO_CARD=y
|
||||
CONFIG_STM32_SERIALBRK_BSDCOMPAT=y
|
||||
CONFIG_STM32_SERIAL_DISABLE_REORDERING=y
|
||||
CONFIG_STM32_SPI1=y
|
||||
CONFIG_STM32_SPI2=y
|
||||
CONFIG_STM32_SPI4=y
|
||||
CONFIG_STM32_SPI4_DMA=y
|
||||
CONFIG_STM32_SPI4_DMA_BUFFER=512
|
||||
CONFIG_STM32_SPI_DMATHRESHOLD=8
|
||||
CONFIG_STM32_TIM10=y
|
||||
CONFIG_STM32_TIM11=y
|
||||
CONFIG_STM32_TIM3=y
|
||||
CONFIG_STM32_TIM9=y
|
||||
CONFIG_STM32_UART4=y
|
||||
CONFIG_STM32_UART7=y
|
||||
CONFIG_STM32_UART8=y
|
||||
CONFIG_STM32_USART1=y
|
||||
CONFIG_STM32_USART2=y
|
||||
CONFIG_STM32_USART3=y
|
||||
CONFIG_STM32_USART6=y
|
||||
CONFIG_STM32_USART_BREAKS=y
|
||||
CONFIG_STM32_USART_SINGLEWIRE=y
|
||||
CONFIG_STM32_WWDG=y
|
||||
CONFIG_SYSTEM_CDCACM=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TASK_NAME_SIZE=24
|
||||
CONFIG_UART4_BAUD=57600
|
||||
CONFIG_UART4_RXBUFSIZE=300
|
||||
CONFIG_UART4_RXDMA=y
|
||||
CONFIG_UART4_TXBUFSIZE=300
|
||||
CONFIG_UART7_BAUD=57600
|
||||
CONFIG_UART7_RXBUFSIZE=300
|
||||
CONFIG_UART7_RXDMA=y
|
||||
CONFIG_UART7_SERIAL_CONSOLE=y
|
||||
CONFIG_UART7_TXBUFSIZE=300
|
||||
CONFIG_UART8_BAUD=57600
|
||||
CONFIG_UART8_RXBUFSIZE=300
|
||||
CONFIG_UART8_TXBUFSIZE=300
|
||||
CONFIG_USART1_RXBUFSIZE=128
|
||||
CONFIG_USART1_RXDMA=y
|
||||
CONFIG_USART1_TXBUFSIZE=32
|
||||
CONFIG_USART2_BAUD=57600
|
||||
CONFIG_USART2_IFLOWCONTROL=y
|
||||
CONFIG_USART2_OFLOWCONTROL=y
|
||||
CONFIG_USART2_RXBUFSIZE=600
|
||||
CONFIG_USART2_RXDMA=y
|
||||
CONFIG_USART2_TXBUFSIZE=1100
|
||||
CONFIG_USART3_BAUD=57600
|
||||
CONFIG_USART3_RXBUFSIZE=300
|
||||
CONFIG_USART3_RXDMA=y
|
||||
CONFIG_USART3_TXBUFSIZE=300
|
||||
CONFIG_USART6_BAUD=57600
|
||||
CONFIG_USART6_RXBUFSIZE=300
|
||||
CONFIG_USART6_RXDMA=y
|
||||
CONFIG_USART6_TXBUFSIZE=300
|
||||
CONFIG_USBDEV=y
|
||||
CONFIG_USBDEV_BUSPOWERED=y
|
||||
CONFIG_USBDEV_MAXPOWER=500
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
* scripts/ld.script
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* The STM32F427 has 2048Kb of FLASH beginning at address 0x0800:0000 and
|
||||
* 256Kb of SRAM. SRAM is split up into three blocks:
|
||||
*
|
||||
* 1) 112Kb of SRAM beginning at address 0x2000:0000
|
||||
* 2) 16Kb of SRAM beginning at address 0x2001:c000
|
||||
* 3) 64Kb of SRAM beginning at address 0x2002:0000
|
||||
* 4) 64Kb of TCM SRAM beginning at address 0x1000:0000
|
||||
*
|
||||
* When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
|
||||
* where the code expects to begin execution by jumping to the entry point in
|
||||
* the 0x0800:0000 address range.
|
||||
*
|
||||
* The first 0x4000 of flash is reserved for the bootloader.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x08004000, LENGTH = 2032K
|
||||
sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K
|
||||
ccsram (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(__start) /* treat __start as the anchor for dead code stripping */
|
||||
EXTERN(_vectors) /* force the vectors to be included in the output */
|
||||
|
||||
/*
|
||||
* Ensure that abort() is present in the final object. The exception handling
|
||||
* code pulled in by libgcc.a requires it (and that code cannot be easily avoided).
|
||||
*/
|
||||
EXTERN(abort)
|
||||
EXTERN(_bootdelay_signature)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.vectors)
|
||||
. = ALIGN(32);
|
||||
/*
|
||||
This signature provides the bootloader with a way to delay booting
|
||||
*/
|
||||
_bootdelay_signature = ABSOLUTE(.);
|
||||
FILL(0xffecc2925d7d05c5)
|
||||
. += 8;
|
||||
*(.text .text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.got)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.r.*)
|
||||
_etext = ABSOLUTE(.);
|
||||
|
||||
} > flash
|
||||
|
||||
/*
|
||||
* Init functions (static constructors and the like)
|
||||
*/
|
||||
.init_section : {
|
||||
_sinit = ABSOLUTE(.);
|
||||
KEEP(*(.init_array .init_array.*))
|
||||
_einit = ABSOLUTE(.);
|
||||
} > flash
|
||||
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} > flash
|
||||
|
||||
__exidx_start = ABSOLUTE(.);
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx*)
|
||||
} > flash
|
||||
__exidx_end = ABSOLUTE(.);
|
||||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
.data : {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
CONSTRUCTORS
|
||||
_edata = ABSOLUTE(.);
|
||||
} > sram AT > flash
|
||||
|
||||
.bss : {
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss .bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} > sram
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (c) 2015 PX4 Development Team. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
add_library(drivers_board
|
||||
can.c
|
||||
i2c.cpp
|
||||
init.c
|
||||
led.c
|
||||
spi.cpp
|
||||
timer_config.cpp
|
||||
usb.c
|
||||
)
|
||||
|
||||
target_link_libraries(drivers_board
|
||||
PRIVATE
|
||||
arch_spi
|
||||
drivers__led # drv_led_start
|
||||
nuttx_arch # sdio
|
||||
nuttx_drivers # sdio
|
||||
px4_layer
|
||||
)
|
||||
@@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file board_config.h
|
||||
*
|
||||
* SaamPixV1_1 internal definitions
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/****************************************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************************************/
|
||||
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************************************/
|
||||
/* Configuration ************************************************************************************/
|
||||
|
||||
|
||||
/* SaamPixV1_1 GPIOs ***********************************************************************************/
|
||||
/* LEDs */
|
||||
#define GPIO_LED1 (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
|
||||
#define BOARD_OVERLOAD_LED LED_RED
|
||||
|
||||
/*
|
||||
* ADC channels
|
||||
*
|
||||
* These are the channel numbers of the ADCs of the microcontroller that can be used by the Px4 Firmware in the adc driver
|
||||
*/
|
||||
#define ADC_CHANNELS (1 << 4) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15)
|
||||
|
||||
// ADC defines to be used in sensors.cpp to read from a particular channel
|
||||
#define ADC_5V_RAIL_SENSE 4
|
||||
#define ADC_BATTERY_CURRENT_CHANNEL 10
|
||||
#define ADC_BATTERY_VOLTAGE_CHANNEL 12
|
||||
#define ADC_RC_RSSI_CHANNEL 11
|
||||
#define ADC_AIRSPEED_VOLTAGE_CHANNEL 15
|
||||
|
||||
/* Power supply control and monitoring GPIOs */
|
||||
// #define GPIO_VDD_5V_PERIPH_EN (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
|
||||
// #define GPIO_VDD_BRICK_VALID (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN5)
|
||||
// #define GPIO_VDD_SERVO_VALID (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN7)
|
||||
// #define GPIO_VDD_3V3_SENSORS_EN (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3)
|
||||
// #define GPIO_VDD_5V_HIPOWER_OC (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN10)
|
||||
// #define GPIO_VDD_5V_PERIPH_OC (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN15)
|
||||
|
||||
/* Tone alarm output */
|
||||
#define TONE_ALARM_TIMER 14 /* timer 14 */
|
||||
#define TONE_ALARM_CHANNEL 1 /* channel 1 */
|
||||
#define GPIO_TONE_ALARM_IDLE (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
|
||||
#define GPIO_TONE_ALARM (GPIO_ALT|GPIO_AF9|GPIO_SPEED_2MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
|
||||
|
||||
/* AUX PWMs
|
||||
*/
|
||||
#define DIRECT_PWM_OUTPUT_CHANNELS 8
|
||||
|
||||
/* USB OTG FS
|
||||
*
|
||||
* PA9 OTG_FS_VBUS VBUS sensing
|
||||
*/
|
||||
#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9)
|
||||
|
||||
|
||||
|
||||
/* High-resolution timer */
|
||||
#define HRT_TIMER 8 /* use timer8 for the HRT */
|
||||
#define HRT_TIMER_CHANNEL 2 /* use capture/compare channel */
|
||||
|
||||
#define HRT_PPM_CHANNEL 1
|
||||
#define GPIO_PPM_IN GPIO_TIM8_CH1IN_1
|
||||
|
||||
/* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 1 */
|
||||
#define PWMIN_TIMER 4
|
||||
#define PWMIN_TIMER_CHANNEL 1
|
||||
#define GPIO_PWM_IN GPIO_TIM1_CH1IN_2
|
||||
|
||||
#define RC_SERIAL_PORT "/dev/ttyS0"
|
||||
|
||||
// #define GPIO_RSSI_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN1)
|
||||
#define GPIO_SBUS_INV (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN10)
|
||||
#define RC_INVERT_INPUT(_invert_true) px4_arch_gpiowrite(GPIO_SBUS_INV, _invert_true);
|
||||
|
||||
#define GPIO_FRSKY_INV (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN12)
|
||||
#define INVERT_FRSKY(_invert_true) px4_arch_gpiowrite(GPIO_FRSKY_INV, _invert_true);
|
||||
|
||||
/* Power switch controls */
|
||||
#define SPEKTRUM_POWER(_on_true) do { } while (0)
|
||||
|
||||
/*
|
||||
* SaamPixV1_1 has one RC_IN
|
||||
*
|
||||
* GPIO PPM_IN on PC6 T8CH1
|
||||
* SPEKTRUM_RX (it's TX or RX in Bind) on PC6 UART1
|
||||
* Inversion is possible via the 74LVC2G86 controlled by the FMU
|
||||
* The FMU can drive GPIO PPM_IN as an output
|
||||
*/
|
||||
|
||||
#define GPIO_PPM_IN_AS_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN6)
|
||||
#define SPEKTRUM_RX_AS_GPIO_OUTPUT() px4_arch_configgpio(GPIO_PPM_IN_AS_OUT)
|
||||
#define SPEKTRUM_RX_AS_UART() px4_arch_configgpio(GPIO_USART1_RX)
|
||||
#define SPEKTRUM_OUT(_one_true) px4_arch_gpiowrite(GPIO_PPM_IN_AS_OUT, (_one_true))
|
||||
|
||||
/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction)
|
||||
* this board support the ADC system_power interface, and therefore
|
||||
* provides the true logic GPIO BOARD_ADC_xxxx macros.
|
||||
*/
|
||||
#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_OTGFS_VBUS))
|
||||
#define BOARD_ADC_BRICK_VALID (1)
|
||||
#define BOARD_ADC_SERVO_VALID (1)
|
||||
#define BOARD_ADC_PERIPH_5V_OC (0)
|
||||
#define BOARD_ADC_HIPOWER_5V_OC (0)
|
||||
|
||||
|
||||
/* This board provides a DMA pool and APIs */
|
||||
#define BOARD_DMA_ALLOC_POOL_SIZE 5120
|
||||
|
||||
/* This board provides the board_on_reset interface */
|
||||
|
||||
#define BOARD_HAS_ON_RESET 1
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/****************************************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************************************/
|
||||
|
||||
/****************************************************************************************************
|
||||
* Public data
|
||||
****************************************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************************************/
|
||||
|
||||
/****************************************************************************************************
|
||||
* Name: stm32_spiinitialize
|
||||
*
|
||||
* Description:
|
||||
* Called to configure SPI chip select GPIO pins for the SaamPixV1_1 board.
|
||||
*
|
||||
****************************************************************************************************/
|
||||
|
||||
extern void stm32_spiinitialize(void);
|
||||
|
||||
extern void stm32_usbinitialize(void);
|
||||
|
||||
|
||||
#define board_peripheral_reset(ms)
|
||||
|
||||
|
||||
#include <px4_platform_common/board_common.h>
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
__END_DECLS
|
||||
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file can.c
|
||||
*
|
||||
* Board-specific CAN functions.
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/can/can.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
|
||||
#include "stm32.h"
|
||||
#include "stm32_can.h"
|
||||
#include "board_config.h"
|
||||
|
||||
#ifdef CONFIG_CAN
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
/* Configuration ********************************************************************/
|
||||
|
||||
#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2)
|
||||
# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1."
|
||||
# undef CONFIG_STM32_CAN2
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_CAN1
|
||||
# define CAN_PORT 1
|
||||
#else
|
||||
# define CAN_PORT 2
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
int can_devinit(void);
|
||||
/************************************************************************************
|
||||
* Name: can_devinit
|
||||
*
|
||||
* Description:
|
||||
* All STM32 architectures must provide the following interface to work with
|
||||
* examples/can.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int can_devinit(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
struct can_dev_s *can;
|
||||
int ret;
|
||||
|
||||
/* Check if we have already initialized */
|
||||
|
||||
if (!initialized) {
|
||||
/* Call stm32_caninitialize() to get an instance of the CAN interface */
|
||||
|
||||
can = stm32_caninitialize(CAN_PORT);
|
||||
|
||||
if (can == NULL) {
|
||||
canerr("ERROR: Failed to get CAN interface\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Register the CAN driver at "/dev/can0" */
|
||||
|
||||
ret = can_register("/dev/can0", can);
|
||||
|
||||
if (ret < 0) {
|
||||
canerr("ERROR: can_register failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now we are initialized */
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <px4_arch/i2c_hw_description.h>
|
||||
|
||||
constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = {
|
||||
initI2CBusInternal(1),
|
||||
initI2CBusExternal(2),
|
||||
};
|
||||
@@ -0,0 +1,299 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file init.c
|
||||
*
|
||||
* SaamPixV1_1-specific early startup code. This file implements the
|
||||
* board_app_initialize() function that is called early by nsh during startup.
|
||||
*
|
||||
* Code here is run before the rcS script is invoked; it should start required
|
||||
* subsystems and perform board-specific initialization.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
#include <px4_platform_common/tasks.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sdio.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/mm/gran.h>
|
||||
|
||||
#include <stm32.h>
|
||||
#include "board_config.h"
|
||||
#include <stm32_uart.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_board_led.h>
|
||||
|
||||
#include <px4_platform_common/init.h>
|
||||
#include <px4_platform/board_dma_alloc.h>
|
||||
#include <px4_arch/io_timer.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Ideally we'd be able to get these from arm_internal.h,
|
||||
* but since we want to be able to disable the NuttX use
|
||||
* of leds for system indication at will and there is no
|
||||
* separate switch, we need to build independent of the
|
||||
* CONFIG_ARCH_LEDS configuration switch.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern void led_init(void);
|
||||
extern void led_on(int led);
|
||||
extern void led_off(int led);
|
||||
__END_DECLS
|
||||
|
||||
/************************************************************************************
|
||||
* Name: board_on_reset
|
||||
*
|
||||
* Description:
|
||||
* Optionally provided function called on entry to board_system_reset
|
||||
* It should perform any house keeping prior to the rest.
|
||||
*
|
||||
* status - 1 if resetting to boot loader
|
||||
* 0 if just resetting
|
||||
*
|
||||
************************************************************************************/
|
||||
__EXPORT void board_on_reset(int status)
|
||||
{
|
||||
/* configure the GPIO pins to outputs and keep them low */
|
||||
for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) {
|
||||
px4_arch_configgpio(io_timer_channel_get_gpio_output(i));
|
||||
}
|
||||
|
||||
/**
|
||||
* On resets invoked from system (not boot) insure we establish a low
|
||||
* output state (discharge the pins) on PWM pins before they become inputs.
|
||||
*/
|
||||
|
||||
if (status >= 0) {
|
||||
up_mdelay(400);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
/************************************************************************************
|
||||
* Name: stm32_boardinitialize
|
||||
*
|
||||
* Description:
|
||||
* All STM32 architectures must provide the following entry point. This entry point
|
||||
* is called early in the initialization -- after all memory has been configured
|
||||
* and mapped but before any devices have been initialized.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT void
|
||||
stm32_boardinitialize(void)
|
||||
{
|
||||
// Reset all PWM to Low outputs.
|
||||
|
||||
board_on_reset(-1);
|
||||
|
||||
/* configure LEDs */
|
||||
|
||||
board_autoled_initialize();
|
||||
|
||||
/* configure ADC pins */
|
||||
|
||||
stm32_configgpio(GPIO_ADC1_IN4); /* VDD_5V_SENS */
|
||||
stm32_configgpio(GPIO_ADC1_IN10); /* BATT_CURRENT_SENS */
|
||||
stm32_configgpio(GPIO_ADC1_IN12); /* BATT_VOLTAGE_SENS */
|
||||
stm32_configgpio(GPIO_ADC1_IN11); /* RSSI analog in */
|
||||
stm32_configgpio(GPIO_ADC1_IN13); /* FMU_AUX_ADC_1 */
|
||||
stm32_configgpio(GPIO_ADC1_IN14); /* FMU_AUX_ADC_2 */
|
||||
stm32_configgpio(GPIO_ADC1_IN15); /* PRESSURE_SENS */
|
||||
|
||||
/* configure power supply control/sense pins */
|
||||
|
||||
stm32_configgpio(GPIO_SBUS_INV);
|
||||
stm32_configgpio(GPIO_FRSKY_INV);
|
||||
|
||||
/* configure CAN interface */
|
||||
|
||||
stm32_configgpio(GPIO_CAN1_RX);
|
||||
stm32_configgpio(GPIO_CAN1_TX);
|
||||
|
||||
/* configure SPI interfaces */
|
||||
|
||||
stm32_spiinitialize();
|
||||
|
||||
stm32_configgpio(GPIO_I2C2_SCL);
|
||||
stm32_configgpio(GPIO_I2C2_SDA);
|
||||
|
||||
stm32_configgpio(GPIO_I2C1_SCL);
|
||||
stm32_configgpio(GPIO_I2C1_SDA);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_app_initialize
|
||||
*
|
||||
* Description:
|
||||
* Perform application specific initialization. This function is never
|
||||
* called directly from application code, but only indirectly via the
|
||||
* (non-standard) boardctl() interface using the command BOARDIOC_INIT.
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - The boardctl() argument is passed to the board_app_initialize()
|
||||
* implementation without modification. The argument has no
|
||||
* meaning to NuttX; the meaning of the argument is a contract
|
||||
* between the board-specific initalization logic and the the
|
||||
* matching application logic. The value cold be such things as a
|
||||
* mode enumeration value, a set of DIP switch switch settings, a
|
||||
* pointer to configuration data read from a file or serial FLASH,
|
||||
* or whatever you would like to do with it. Every implementation
|
||||
* should accept zero/NULL as a default configuration.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static struct spi_dev_s *spi1;
|
||||
static struct spi_dev_s *spi2;
|
||||
static struct spi_dev_s *spi4;
|
||||
static struct sdio_dev_s *sdio;
|
||||
|
||||
__EXPORT int board_app_initialize(uintptr_t arg)
|
||||
{
|
||||
px4_platform_init();
|
||||
|
||||
/* configure the DMA allocator */
|
||||
|
||||
if (board_dma_alloc_init() < 0) {
|
||||
syslog(LOG_ERR, "DMA alloc FAILED\n");
|
||||
}
|
||||
|
||||
#if defined(SERIAL_HAVE_RXDMA)
|
||||
// set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event.
|
||||
static struct hrt_call serial_dma_call;
|
||||
hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL);
|
||||
#endif
|
||||
|
||||
/* initial LED state */
|
||||
drv_led_start();
|
||||
led_off(LED_AMBER);
|
||||
|
||||
if (board_hardfault_init(2, true) != 0) {
|
||||
led_on(LED_AMBER);
|
||||
}
|
||||
|
||||
/* Configure SPI-based devices */
|
||||
|
||||
spi4 = px4_spibus_initialize(4);
|
||||
|
||||
if (!spi4) {
|
||||
syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 4\n");
|
||||
board_autoled_on(LED_AMBER);
|
||||
}
|
||||
|
||||
/* Default SPI4 to 10MHz and de-assert the known chip selects. */
|
||||
SPI_SETFREQUENCY(spi4, 10000000);
|
||||
SPI_SETBITS(spi4, 8);
|
||||
SPI_SETMODE(spi4, SPIDEV_MODE3);
|
||||
up_udelay(20);
|
||||
|
||||
/* Get the SPI port for the FRAM */
|
||||
|
||||
spi1 = stm32_spibus_initialize(1);
|
||||
|
||||
if (!spi1) {
|
||||
syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 1\n");
|
||||
board_autoled_on(LED_AMBER);
|
||||
}
|
||||
|
||||
/* Default SPI1 to 37.5 MHz (40 MHz rounded to nearest valid divider, F4 max)
|
||||
* and de-assert the known chip selects. */
|
||||
|
||||
// XXX start with 10.4 MHz in FRAM usage and go up to 37.5 once validated
|
||||
SPI_SETFREQUENCY(spi1, 24 * 1000 * 1000);
|
||||
SPI_SETBITS(spi1, 8);
|
||||
|
||||
|
||||
spi2 = px4_spibus_initialize(2);
|
||||
|
||||
/* Default SPI2 to 10MHz and de-assert the known chip selects. */
|
||||
SPI_SETFREQUENCY(spi2, 10000000);
|
||||
SPI_SETBITS(spi2, 8);
|
||||
|
||||
|
||||
#ifdef CONFIG_MMCSD
|
||||
/* First, get an instance of the SDIO interface */
|
||||
|
||||
sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO);
|
||||
|
||||
if (!sdio) {
|
||||
syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", CONFIG_NSH_MMCSDSLOTNO);
|
||||
}
|
||||
|
||||
/* Now bind the SDIO interface to the MMC/SD driver */
|
||||
int ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdio);
|
||||
|
||||
if (ret != OK) {
|
||||
syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Then let's guess and say that there is a card in the slot. There is no card detect GPIO. */
|
||||
sdio_mediachange(sdio, true);
|
||||
|
||||
#endif
|
||||
|
||||
/* Configure the HW based on the manifest */
|
||||
|
||||
px4_platform_configure();
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file led.c
|
||||
*
|
||||
* SaamPixV1_1 LED backend.
|
||||
*/
|
||||
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "stm32.h"
|
||||
#include "board_config.h"
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/*
|
||||
* Ideally we'd be able to get these from arm_internal.h,
|
||||
* but since we want to be able to disable the NuttX use
|
||||
* of leds for system indication at will and there is no
|
||||
* separate switch, we need to build independent of the
|
||||
* CONFIG_ARCH_LEDS configuration switch.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern void led_init(void);
|
||||
extern void led_on(int led);
|
||||
extern void led_off(int led);
|
||||
extern void led_toggle(int led);
|
||||
__END_DECLS
|
||||
|
||||
__EXPORT void led_init()
|
||||
{
|
||||
/* Configure LED1 GPIO for output */
|
||||
|
||||
stm32_configgpio(GPIO_LED1);
|
||||
}
|
||||
|
||||
__EXPORT void led_on(int led)
|
||||
{
|
||||
if (led == 1) {
|
||||
/* Pull down to switch on */
|
||||
stm32_gpiowrite(GPIO_LED1, false);
|
||||
}
|
||||
}
|
||||
|
||||
__EXPORT void led_off(int led)
|
||||
{
|
||||
if (led == 1) {
|
||||
/* Pull up to switch off */
|
||||
stm32_gpiowrite(GPIO_LED1, true);
|
||||
}
|
||||
}
|
||||
|
||||
__EXPORT void led_toggle(int led)
|
||||
{
|
||||
if (led == 1) {
|
||||
if (stm32_gpioread(GPIO_LED1)) {
|
||||
stm32_gpiowrite(GPIO_LED1, false);
|
||||
|
||||
} else {
|
||||
stm32_gpiowrite(GPIO_LED1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <px4_arch/spi_hw_description.h>
|
||||
#include <drivers/drv_sensor.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
|
||||
constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
|
||||
initSPIBus(SPI::Bus::SPI1, {
|
||||
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortE, GPIO::Pin12}),
|
||||
}),
|
||||
initSPIBusExternal(SPI::Bus::SPI2, {
|
||||
initSPIConfigExternal(SPI::CS{GPIO::PortD, GPIO::Pin7}),
|
||||
}),
|
||||
initSPIBus(SPI::Bus::SPI4, {
|
||||
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortB, GPIO::Pin2}, SPI::DRDY{GPIO::PortE, GPIO::Pin4}),
|
||||
initSPIDevice(DRV_MAG_DEVTYPE_LIS3MDL, SPI::CS{GPIO::PortD, GPIO::Pin11}),
|
||||
initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortC, GPIO::Pin15}),
|
||||
initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortE, GPIO::Pin3}, SPI::DRDY{GPIO::PortE, GPIO::Pin10}),
|
||||
}),
|
||||
};
|
||||
|
||||
static constexpr bool unused = validateSPIConfig(px4_spi_buses);
|
||||
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <px4_arch/io_timer_hw_description.h>
|
||||
|
||||
constexpr io_timers_t io_timers[MAX_IO_TIMERS] = {
|
||||
initIOTimer(Timer::Timer1),
|
||||
initIOTimer(Timer::Timer4),
|
||||
};
|
||||
|
||||
constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer4, Timer::Channel1}, {GPIO::PortD, GPIO::Pin12}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer4, Timer::Channel2}, {GPIO::PortD, GPIO::Pin13}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer4, Timer::Channel3}, {GPIO::PortD, GPIO::Pin14}),
|
||||
initIOTimerChannelOutputClear(io_timers, {Timer::Timer4, Timer::Channel4}, {GPIO::PortD, GPIO::Pin15}),
|
||||
};
|
||||
|
||||
constexpr io_timers_channel_mapping_t io_timers_channel_mapping =
|
||||
initIOTimerChannelMapping(io_timers, timer_io_channels);
|
||||
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2026 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file usb.c
|
||||
*
|
||||
* Board-specific USB functions.
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/usbdev_trace.h>
|
||||
|
||||
#include <arm_internal.h>
|
||||
#include <stm32.h>
|
||||
#include "board_config.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_usbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Called to setup USB-related GPIO pins for the SaamPixV1_1 board.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT void stm32_usbinitialize(void)
|
||||
{
|
||||
/* The OTG FS has an internal soft pull-up */
|
||||
|
||||
/* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */
|
||||
|
||||
#ifdef CONFIG_STM32_OTGFS
|
||||
stm32_configgpio(GPIO_OTGFS_VBUS);
|
||||
/* XXX We only support device mode
|
||||
stm32_configgpio(GPIO_OTGFS_PWRON);
|
||||
stm32_configgpio(GPIO_OTGFS_OVER);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_usbsuspend
|
||||
*
|
||||
* Description:
|
||||
* Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is
|
||||
* used. This function is called whenever the USB enters or leaves suspend mode.
|
||||
* This is an opportunity for the board logic to shutdown clocks, power, etc.
|
||||
* while the USB is suspended.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume)
|
||||
{
|
||||
uinfo("resume: %d\n", resume);
|
||||
}
|
||||
@@ -9,7 +9,4 @@ param set-default BAT1_A_PER_V 17
|
||||
# system_power unavailable
|
||||
param set-default CBRK_SUPPLY_CHK 894281
|
||||
|
||||
# Select the Generic 250 Racer by default
|
||||
param set-default SYS_AUTOSTART 4050
|
||||
|
||||
param set-default SYS_HAS_MAG 0
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_RATEMAX 2000
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -17,10 +17,7 @@ then
|
||||
fi
|
||||
|
||||
# baro
|
||||
if ! dps310 -I start -a 0x76
|
||||
then
|
||||
spl06 -I start -a 0x76
|
||||
fi
|
||||
spl06 -I start -a 0x76
|
||||
|
||||
# internal mag
|
||||
qmc5883p -I -R 4 start
|
||||
|
||||
@@ -243,7 +243,6 @@ CONFIG_UART7_RXBUFSIZE=600
|
||||
CONFIG_UART7_TXBUFSIZE=3000
|
||||
CONFIG_UART8_BAUD=57600
|
||||
CONFIG_UART8_RXBUFSIZE=600
|
||||
CONFIG_UART8_SERIAL_CONSOLE=y
|
||||
CONFIG_UART8_TXBUFSIZE=3000
|
||||
CONFIG_USART1_BAUD=57600
|
||||
CONFIG_USART1_RXBUFSIZE=600
|
||||
|
||||
@@ -49,8 +49,6 @@ uint16_t board_get_can_interfaces(void)
|
||||
{
|
||||
uint16_t enabled_interfaces = 0x3;
|
||||
|
||||
enabled_interfaces &= ~(1 << 1);
|
||||
|
||||
return enabled_interfaces;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_RATEMAX 2000
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_RATEMAX 2000
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
@@ -13,7 +13,6 @@ param set-default PWM_MAIN_TIM0 -4
|
||||
param set-default RC_INPUT_PROTO -1
|
||||
|
||||
param set-default IMU_GYRO_RATEMAX 2000
|
||||
param set-default SYS_AUTOSTART 4001
|
||||
param set-default MC_PITCHRATE_K 0.4
|
||||
param set-default MC_ROLLRATE_K 0.35
|
||||
param set-default MC_YAWRATE_K 1.2
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
- [Introduction](index.md)
|
||||
- [Basic Concepts](getting_started/px4_basic_concepts.md)
|
||||
|
||||
- [Try PX4 (Simulation)](simulation/px4_simulation_quickstart.md)
|
||||
- [Multicopters](frames_multicopter/index.md)
|
||||
- [Features](features_mc/index.md)
|
||||
- [Flight Modes](flight_modes_mc/index.md)
|
||||
@@ -474,6 +474,7 @@
|
||||
- [Worlds](sim_gazebo_classic/worlds.md)
|
||||
- [Multi-Vehicle Sim](sim_gazebo_classic/multi_vehicle_simulation.md)
|
||||
- [Simulate Failsafes](simulation/failsafes.md)
|
||||
- [Pre-built Packages](simulation/px4_sitl_prebuilt_packages.md)
|
||||
- [Hardware](hardware/index.md)
|
||||
- [Flight Controller Reference Design](hardware/reference_design.md)
|
||||
- [Manufacturer’s Board Support Guide](hardware/board_support_guide.md)
|
||||
|
||||
@@ -40004,6 +40004,104 @@ Absolute value superior to 10000 will disable distance sensor
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | | | | -1.0 | m |
|
||||
|
||||
### SIH_F_CP0 (`FLOAT`) {#SIH_F_CP0}
|
||||
|
||||
Forward thruster static power coefficient.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | | 0.0 | |
|
||||
|
||||
### SIH_F_CP1 (`FLOAT`) {#SIH_F_CP1}
|
||||
|
||||
Forward thruster power coefficient 1.
|
||||
|
||||
CP(J) = CP0 + CP1*J + CP2*J^2
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | | | | 0.0 | |
|
||||
|
||||
### SIH_F_CP2 (`FLOAT`) {#SIH_F_CP2}
|
||||
|
||||
Forward thruster power coefficient 2.
|
||||
|
||||
CP(J) = CP0 + CP1*J + CP2*J^2
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | | 0.0 | | 0.0 | |
|
||||
|
||||
### SIH_F_CT0 (`FLOAT`) {#SIH_F_CT0}
|
||||
|
||||
Forward thruster static thrust coefficient.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | | 0.0 | |
|
||||
|
||||
### SIH_F_CT1 (`FLOAT`) {#SIH_F_CT1}
|
||||
|
||||
Forward thruster thrust coefficient 1.
|
||||
|
||||
CT(J) = CT0 + CT1*J + CT2*J^2
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | | | | 0.0 | |
|
||||
|
||||
### SIH_F_CT2 (`FLOAT`) {#SIH_F_CT2}
|
||||
|
||||
Forward thruster thrust coefficient 2.
|
||||
|
||||
CT(J) = CT0 + CT1*J + CT2*J^2
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | | 0.0 | | 0.0 | |
|
||||
|
||||
### SIH_F_DIA_INCH (`FLOAT`) {#SIH_F_DIA_INCH}
|
||||
|
||||
Forward thruster propeller diameter in inches.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.1 | | | 0.1 | |
|
||||
|
||||
### SIH_F_Q_MAX (`FLOAT`) {#SIH_F_Q_MAX}
|
||||
|
||||
Forward thruster max torque (Nm).
|
||||
|
||||
This is used for the Fixed-Wing, Tailsitter, or pusher of the Standard VTOL
|
||||
if SIH_F_CP0 <= 0.
|
||||
If SIH_F_CP0 > 0, propeller model with advance ratio J is used
|
||||
and this parameter value is overridden at simulation startup.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | | 0.0165 | Nm |
|
||||
|
||||
### SIH_F_RPM_MAX (`FLOAT`) {#SIH_F_RPM_MAX}
|
||||
|
||||
Forward thruster max RPM.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.1 | | | 6000.0 | |
|
||||
|
||||
### SIH_F_T_MAX (`FLOAT`) {#SIH_F_T_MAX}
|
||||
|
||||
Forward thruster max thrust (N).
|
||||
|
||||
This is used for the Fixed-Wing, Tailsitter, or pusher of the Standard VTOL
|
||||
if SIH_F_CT0 <= 0.
|
||||
If SIH_F_CT0 > 0, propeller model with advance ratio J is used
|
||||
and this parameter value is overridden at simulation startup.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | | 2.0 | N |
|
||||
|
||||
### SIH_IXX (`FLOAT`) {#SIH_IXX}
|
||||
|
||||
Vehicle inertia about X axis.
|
||||
@@ -40178,13 +40276,15 @@ This value can be measured by weighting the quad on a scale.
|
||||
|
||||
### SIH_Q_MAX (`FLOAT`) {#SIH_Q_MAX}
|
||||
|
||||
Max propeller torque.
|
||||
Max multicopter propeller torque.
|
||||
|
||||
This is the maximum torque delivered by one propeller
|
||||
when the motor is running at full speed.
|
||||
|
||||
This value is usually about few percent of the maximum thrust force.
|
||||
|
||||
Refer to SIH_F_Q_MAX for the propeller torque for FW, Tailsitter, and VTOL pusher.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | 0.05 | 0.1 | Nm |
|
||||
@@ -40201,13 +40301,15 @@ Gaussian noise added to simulated ranging beacon measurements. Set to 0 to disab
|
||||
|
||||
### SIH_T_MAX (`FLOAT`) {#SIH_T_MAX}
|
||||
|
||||
Max propeller thrust force.
|
||||
Max multicopter propeller thrust force.
|
||||
|
||||
This is the maximum force delivered by one propeller
|
||||
when the motor is running at full speed.
|
||||
|
||||
This value is usually about 5 times the mass of the quadrotor.
|
||||
|
||||
Refer to SIH_F_T_MAX for the thrust for FW, Tailsitter, and VTOL pusher.
|
||||
|
||||
| Reboot | minValue | maxValue | increment | default | unit |
|
||||
| ------ | -------- | -------- | --------- | ------- | ---- |
|
||||
| | 0.0 | | 0.5 | 5.0 | N |
|
||||
|
||||
@@ -457,6 +457,10 @@ div.frame_variant td, div.frame_variant th {
|
||||
<td>SIH Quadcopter X</td>
|
||||
<td>Maintainer: Romain Chiappinelli <romain.chiap@gmail.com><p><code>SYS_AUTOSTART</code> = 1100</p></td>
|
||||
</tr>
|
||||
<tr id="copter_simulation_sih_hexacopter_x">
|
||||
<td>SIH Hexacopter X</td>
|
||||
<td>Maintainer: Romain Chiappinelli <romain.chiap@gmail.com><p><code>SYS_AUTOSTART</code> = 1105</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user