Skip to content

Commit

Permalink
Libcanard v2.0 (#182)
Browse files Browse the repository at this point in the history
* Drop canard_dsdl, use Nunavut instead

* Upgrade CI to LLVM 13

* Actualize license headers

* Support redundant transmission queues and use more consistent public field naming

* Ditch the deprecated canardRxAccept(), rename canardRxAccept2()

* Refactor the API to eliminate the need to cast away const qualifiers; fixes #175

* Tighten up memory checking in the test suite -- add canaries

* Fix race condition in the roundtrip test

* Do not use Catch2 macros from non-main thread because it is not thread-safe

* Support CANARD_CONFIG_HEADER

* CI: add style_check job

* Use AVL tree in the transmission queue

* Remove all linked lists

* Reduce indirection, pointer casts, and memory footprint by exposing the AVL tree in the public API

* Disable C++-specific warnings as they make no sense for a C library

* Add table-based CRC option (#186)

* CI: disable SonarCloud on forks

* Add docker utilities (#187)

* Add acceptance filter configuration helpers (#171)

Co-authored-by: Kalyan Sriram <coder.kalyan@gmail.com>
  • Loading branch information
pavel-kirienko and coderkalyan authored Dec 4, 2021
1 parent 2d44945 commit cf0a8bc
Show file tree
Hide file tree
Showing 30 changed files with 3,759 additions and 2,473 deletions.
210 changes: 95 additions & 115 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,10 @@
name: Main Workflow

on:
push:
branches: [ master ]
pull_request:
branches: [ master, actions ]

on: [push, pull_request]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

LLVM_VERSION: 13
jobs:
debug:
env:
BUILD_TYPE: Debug

runs-on: ubuntu-latest

strategy:
matrix:
toolchain: ['clang', 'gcc']
include:
- toolchain: gcc
c-compiler: gcc
cxx-compiler: g++
- toolchain: clang
c-compiler: clang-11
cxx-compiler: clang++-11

steps:
- uses: actions/checkout@v2

- name: Install Dependencies
run: sudo apt install gcc-multilib g++-multilib clang-tidy-11 clang-format-11

- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_C_COMPILER=${{ matrix.c-compiler }} -DCMAKE_CXX_COMPILER=${{ matrix.cxx-compiler }} tests

- name: Build
working-directory: ${{github.workspace}}/build
run: make VERBOSE=1

- name: Test
working-directory: ${{github.workspace}}/build
run: make test

release:
env:
BUILD_TYPE: Release

runs-on: ubuntu-latest

strategy:
matrix:
toolchain: ['clang', 'gcc']
Expand All @@ -59,95 +13,104 @@ jobs:
c-compiler: gcc
cxx-compiler: g++
- toolchain: clang
c-compiler: clang-11
cxx-compiler: clang++-11

c-compiler: clang
cxx-compiler: clang++
steps:
- uses: actions/checkout@v2

- name: Install Dependencies
run: sudo apt install gcc-multilib g++-multilib

- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_C_COMPILER=${{ matrix.c-compiler }} -DCMAKE_CXX_COMPILER=${{ matrix.cxx-compiler }} -DNO_STATIC_ANALYSIS=1 tests

- name: Build
working-directory: ${{github.workspace}}/build
run: make VERBOSE=1

- name: Test
working-directory: ${{github.workspace}}/build
run: make test

minsizerel:
env:
BUILD_TYPE: MinSizeRel

- run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh $LLVM_VERSION
sudo apt-get -y install gcc-multilib g++-multilib clang-tidy-$LLVM_VERSION
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$LLVM_VERSION 50
clang-tidy --version
- run: >
cmake
-B ${{ github.workspace }}/build
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_COMPILER=${{ matrix.c-compiler }}
-DCMAKE_CXX_COMPILER=${{ matrix.cxx-compiler }}
tests
- working-directory: ${{github.workspace}}/build
run: |
make VERBOSE=1
make test
- uses: actions/upload-artifact@v2
if: always()
with:
name: ${{github.job}}
path: ${{github.workspace}}/**/*
retention-days: 2

optimizations:
runs-on: ubuntu-latest

strategy:
matrix:
toolchain: ['clang', 'gcc']
build_type: [Release, MinSizeRel]
include:
- toolchain: gcc
c-compiler: gcc
cxx-compiler: g++
- toolchain: clang
c-compiler: clang-11
cxx-compiler: clang++-11

c-compiler: clang
cxx-compiler: clang++
steps:
- uses: actions/checkout@v2

- name: Install Dependencies
run: sudo apt install gcc-multilib g++-multilib

- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_C_COMPILER=${{ matrix.c-compiler }} -DCMAKE_CXX_COMPILER=${{ matrix.cxx-compiler }} -DNO_STATIC_ANALYSIS=1 tests

- name: Build
working-directory: ${{github.workspace}}/build
run: make VERBOSE=1

- name: Test
working-directory: ${{github.workspace}}/build
run: make test
- run: sudo apt install gcc-multilib g++-multilib
- run: >
cmake
-B ${{ github.workspace }}/build
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DCMAKE_C_COMPILER=${{ matrix.c-compiler }}
-DCMAKE_CXX_COMPILER=${{ matrix.cxx-compiler }}
-DNO_STATIC_ANALYSIS=1
tests
- working-directory: ${{github.workspace}}/build
run: |
make VERBOSE=1
make test
- uses: actions/upload-artifact@v2
if: always()
with:
name: ${{github.job}}
path: ${{github.workspace}}/**/*
retention-days: 2

avr:
runs-on: ubuntu-latest
env:
mcu: at90can64
flags: -Wall -Wextra -Werror -pedantic -Wconversion -Wtype-limits

steps:
- uses: actions/checkout@v2
- run: |
sudo apt install gcc-avr avr-libc
avr-gcc --version
- run: avr-gcc libcanard/*.c -c -std=c99 -mmcu=${{ env.mcu }} ${{ env.flags }}
- run: avr-gcc libcanard/*.c -c -std=c11 -mmcu=${{ env.mcu }} ${{ env.flags }}
- run: avr-gcc libcanard/*.c -c -std=gnu99 -mmcu=${{ env.mcu }} ${{ env.flags }}
- run: avr-gcc libcanard/*.c -c -std=gnu11 -mmcu=${{ env.mcu }} ${{ env.flags }}

style_check:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Install Dependencies
run: sudo apt install gcc-avr avr-libc

- name: Build C99
run: avr-gcc libcanard/*.c -c -std=c99 -mmcu=${{ env.mcu }} ${{ env.flags }}

- name: Build C11
run: avr-gcc libcanard/*.c -c -std=c11 -mmcu=${{ env.mcu }} ${{ env.flags }}

- name: Build GNU99
run: avr-gcc libcanard/*.c -c -std=gnu99 -mmcu=${{ env.mcu }} ${{ env.flags }}

- name: Build GNU11
run: avr-gcc libcanard/*.c -c -std=gnu11 -mmcu=${{ env.mcu }} ${{ env.flags }}
- uses: DoozyX/clang-format-lint-action@v0.13
with:
source: './libcanard ./tests'
exclude: './tests/catch'
extensions: 'c,h,cpp,hpp'
clangFormatVersion: ${{ env.LLVM_VERSION }}

sonarcloud:
runs-on: ubuntu-latest
env:
SONAR_SCANNER_VERSION: 4.6.1.2450
SONAR_SERVER_URL: "https://sonarcloud.io"
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
with:
Expand All @@ -156,7 +119,7 @@ jobs:
- name: Install Dependencies
run: sudo apt install gcc-multilib g++-multilib

- name: Set up JDK 11
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 11
Expand All @@ -173,7 +136,7 @@ jobs:
SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip
run: |
mkdir -p $HOME/.sonar
curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }}
curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }}
unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH
Expand All @@ -190,10 +153,27 @@ jobs:
cmake tests -DCMAKE_BUILD_TYPE=Debug -DNO_STATIC_ANALYSIS=1 -DCMAKE_C_FLAGS='-DNDEBUG=1'
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
make test
gcov-10 --preserve-paths --long-file-names $(find CMakeFiles/test_private_cov.dir -name '*.gcno')
gcov-10 --preserve-paths --long-file-names $(find CMakeFiles/test_private_le_cov.dir -name '*.gcno')
gcov-10 --preserve-paths --long-file-names $(find CMakeFiles/test_public_cov.dir -name '*.gcno')
gcov --preserve-paths --long-file-names $(find CMakeFiles/test_private_cov.dir -name '*.gcno')
gcov --preserve-paths --long-file-names $(find CMakeFiles/test_public_cov.dir -name '*.gcno')
- name: Run sonar-scanner
run: |
sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" --define sonar.login=${{ secrets.SONAR_TOKEN }}
# Don't run sonar-scanner on builds originating from forks due to secrets not being available
run: >
[ -z "$SONAR_TOKEN" ] || sonar-scanner
--define sonar.organization=uavcan
--define sonar.projectName=libcanard
--define sonar.projectKey=libcanard
--define sonar.sources=libcanard
--define sonar.exclusions=libcanard/cavl.h
--define sonar.cfamily.gcov.reportsPath=.
--define sonar.cfamily.cache.enabled=false
--define sonar.cfamily.threads=2
--define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
--define sonar.host.url="${{ env.SONAR_SERVER_URL }}"
- uses: actions/upload-artifact@v2
if: always()
with:
name: ${{github.job}}
path: ${{github.workspace}}/**/*
retention-days: 2
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,5 @@ build-avr/
!**/.idea/dictionaries
!**/.idea/dictionaries/*

# Generated files
dsdlc_generated/

# Pycache
__pycache__/
6 changes: 6 additions & 0 deletions .idea/dictionaries/pavel.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 10 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ The code shall follow applicable high-reliability coding guidelines as explained
The implementation shall be fully compliant with the UAVCAN/CAN specification.

The implementation and the API should be kept simple.
The core library `canard.c` (that is, excluding the optional DSDL presentation layer extension) shall never become
larger than 1000 logical lines of code.
This restriction ensures that the library is kept simple and easy to validate and verify.
There will be no high-level abstractions -- if that is desired, other implementations of UAVCAN should be used.

The library is intended for deeply embedded systems where the resources may be scarce.
Expand Down Expand Up @@ -53,12 +50,13 @@ to prevent non-compliant code from being accepted into upstream.

## Tools

The following tools are required to conduct library development locally:
The following tools are required to conduct library development locally
(check the CI workflow files for the required versions):

- GCC v10 or newer.
- Clang and Clang-Tools v11 or newer.
- CMake v3.12 or newer.
- An AMD64 machine.
- GCC
- Clang and Clang-Tools
- CMake
- An AMD64 machine

### Clang-Tidy

Expand Down Expand Up @@ -102,6 +100,10 @@ We would welcome contributions implementing CI/CD testing against popular embedd
the ARM Cortex M series and AVR in an emulator.
As a high-integrity library, the Libcanard test suite should provide full test coverage for all commonly used platforms.

**WARNING:**
[Catch2 is NOT thread-safe!](https://github.com/catchorg/Catch2/blob/1e379de9d7522b294e201700dcbb36d4f8037301/docs/limitations.md#thread-safe-assertions)
Never use `REQUIRE` etc. anywhere but the main thread.

## Releasing

Simply create a new release on GitHub: <https://github.com/UAVCAN/libcanard/releases/new>
Loading

0 comments on commit cf0a8bc

Please sign in to comment.