Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
---
# Use the Google style in this project.
BasedOnStyle: Google
ColumnLimit: 140

# Some folks prefer to write "int& foo" while others prefer "int &foo". The
# Google Style Guide only asks for consistency within a project, we chose
# "int& foo" for this project:
DerivePointerAlignment: false
PointerAlignment: Left

# The Google Style Guide only asks for consistency w.r.t. "east const" vs.
# "const west" alignment of cv-qualifiers. In this project we use "const west".
QualifierAlignment: Left

IncludeBlocks: Merge

CommentPragmas: '(@copydoc|@copybrief|@see|@overload|@snippet)'

ColumnLimit: 110
BinPackArguments: false
BinPackParameters: false
PenaltyBreakBeforeFirstCallParameter: 1000
82 changes: 55 additions & 27 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
---
# SPDX-License-Identifier: Apache-2.0
Checks: >
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-exception-escape,
google-build-explicit-make-pairs,
google-build-namespaces,
google-build-using-namespace,
google-explicit-constructor,
google-global-names-in-headers,
google-readability-braces-around-statements,
google-readability-casting,
google-readability-namespace-comments,
-google-readability-todo,
google-runtime-int,
google-runtime-operator,
modernize-use-nullptr,
modernize-use-override,
modernize-use-emplace,
performance-for-range-copy,
performance-unnecessary-copy-initialization,
readability-braces-around-statements,
readability-const-return-type,
readability-container-size-empty,
readability-delete-null-pointer,
readability-else-after-return
clang-diagnostic-*,
clang-analyzer-*,
cppcoreguidelines-*,
modernize-*,
performance-*,
readability-*,
-modernize-use-trailing-return-type,
-readability-magic-numbers,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-bounds-constant-array-index

WarningsAsErrors: ''
HeaderFilterRegex: 'include/cymon/.*'
# Indices into fixed-size arrays are loop counters bounded by the array size
# constant. The suggested replacement (gsl::at or .at()) adds an abort path to
# the zero-latency hot path, so the check is off.

# The checks and naming rules of UNIMOC, so the library is clean when UNIMOC
# builds it. The public headers are checked with the sources.
HeaderFilterRegex: '.*/include/cymon/[^/]+\.hpp$'

WarningsAsErrors: ""

CheckOptions:
# Phase (a, b, c), axis (d, q), per-phase names (ia, da, ...) and the time
# step (dt) are the vocabulary of the motor-control code.
- key: readability-identifier-length.IgnoredVariableNames
value: "^(a|b|c|d|q|dt|ia|ib|ic|da|db|dc)$"
- key: readability-identifier-length.IgnoredParameterNames
value: "^(a|b|c|d|q|dt|ia|ib|ic|da|db|dc)$"
# Zephyr macros (LOG_*, K_USEC, zassert) would dominate the count.
- key: readability-function-cognitive-complexity.IgnoreMacros
value: true
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.ConstantCase
value: CamelCase
- key: readability-identifier-naming.ConstantPrefix
value: "k"
- key: readability-identifier-naming.MemberCase
value: lower_case
- key: readability-identifier-naming.MemberSuffix
value: "_"
- key: readability-identifier-naming.PublicMemberSuffix
value: ""
# Parameters are variables (snake_case), also when they are const.
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.ConstantParameterCase
value: lower_case
51 changes: 27 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
name: CI
on:
push:
branches: [main, develop, "copilot/**"]
# Pull requests only; a push to a branch runs nothing.
pull_request:
branches: [main, develop, "copilot/**"]
workflow_dispatch:

jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
compiler: [g++, clang++]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4

- name: Install system dependencies
- name: Install dependencies
run: |
sudo apt-get update -q
sudo apt-get install -y \
ninja-build clang clang-format clang-tidy

- name: Install CMake 4.x
run: pip install "cmake>=4,<5" --quiet
sudo apt-get install -y ninja-build clang clang-tidy

- name: Configure
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCYMON_BUILD_TESTS=ON \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

- name: Build
- name: Build (warnings are errors)
run: cmake --build build

- name: Test
run: ctest --test-dir build --output-on-failure

- name: clang-format check
run: |
find include src tests -name "*.hpp" -o -name "*.cpp" | \
xargs clang-format --dry-run --Werror

- name: clang-tidy
run: |
find src -name "*.cpp" | \
xargs clang-tidy -p build/
if: matrix.compiler == 'clang++'
run: clang-tidy -p build --warnings-as-errors='*' src/cymon/*.cpp

format-and-dsdl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install tools
run: pip install clang-format==22.1.1 "nunavut>=2.3,<3"
- name: clang-format
run: git ls-files '*.hpp' '*.cpp' | xargs clang-format --dry-run --Werror
- name: DSDL and generated C serialization
run: scripts/check_dsdl.sh
57 changes: 32 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 Tecnologic
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# cymon-lib: device side of the cymon trace protocol (C++20, no heap, no
# Cyphal dependency). Built standalone (host tests) or with add_subdirectory()
# from a firmware build such as the UNIMOC Zephyr module, which then applies
# its own toolchain flags; this file adds warnings only when it is the top
# level project.

cmake_minimum_required(VERSION 3.20)
project(cymon-lib VERSION 0.2.0 LANGUAGES CXX)

cmake_minimum_required(VERSION 3.20.0)
project(cymon-lib VERSION 0.1.0 LANGUAGES CXX)
set(CYMON_MAX_BUFFER_BYTES 4096 CACHE STRING "Capture buffer size in bytes")
set(CYMON_MAX_VARS 64 CACHE STRING "Variables the registry holds (1..255)")
set(CYMON_MAX_CHANNELS 8 CACHE STRING "Channels of one capture (1..16)")

# Library
add_library(cymon
add_library(cymon STATIC
src/cymon/trigger.cpp
src/cymon/sample_buffer.cpp
src/cymon/device.cpp
)
target_compile_features(cymon PUBLIC cxx_std_23)
target_include_directories(cymon PUBLIC include)
target_compile_options(cymon PRIVATE -Wall -Wextra -Wpedantic)
add_library(cymon::cymon ALIAS cymon)
target_compile_features(cymon PUBLIC cxx_std_20)
target_include_directories(cymon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(cymon PUBLIC
CYMON_MAX_BUFFER_BYTES=${CYMON_MAX_BUFFER_BYTES}U
CYMON_MAX_VARS=${CYMON_MAX_VARS}U
CYMON_MAX_CHANNELS=${CYMON_MAX_CHANNELS}U
)

# Directory of the DSDL root namespace for the firmware's Nunavut generation.
set(CYMON_DSDL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dsdl/cymon CACHE INTERNAL "cymon DSDL root namespace")

# Optional nunavut DSDL code generation
option(CYMON_GENERATE_DSDL "Generate C++ types from DSDL via nunavut" OFF)
if(CYMON_GENERATE_DSDL)
include(cmake/nunavut.cmake)
generate_cyphal_types(cymon ${CMAKE_CURRENT_SOURCE_DIR}/dsdl)
if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_CXX_EXTENSIONS OFF)
# The warning set of UNIMOC, so the library builds clean inside it.
target_compile_options(cymon PRIVATE
-Wall -Wextra -Wpedantic -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused
-Woverloaded-virtual -Wconversion -Wsign-conversion -Wnull-dereference -Wdouble-promotion
-Wformat=2 -Werror)
endif()

# Tests
option(CYMON_BUILD_TESTS "Build tests" OFF)
option(CYMON_BUILD_TESTS "Build the GoogleTest host tests" ${PROJECT_IS_TOP_LEVEL})
if(CYMON_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
Expand Down
Loading
Loading