Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ jobs:
with:
submodules: true
- run: cmake -S . -B $GITHUB_WORKSPACE/build -DCMAKE_BUILD_TYPE=Debug -DNO_STATIC_ANALYSIS=ON
- run: cd $GITHUB_WORKSPACE/build && make -j"$(nproc)" udp_echo udp_time_pub
- run: cd $GITHUB_WORKSPACE/build && make -j"$(nproc)" example_echo example_time_pub
- run: python3 tools/ci_example_smoke.py --build-dir $GITHUB_WORKSPACE/build

test_model_montecarlo:
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
[submodule "lib/unity"]
path = lib/unity
url = https://github.com/ThrowTheSwitch/Unity
[submodule "lib/libcanard"]
path = lib/libcanard
url = https://github.com/OpenCyphal/libcanard
branch = experimental
1 change: 1 addition & 0 deletions .idea/dictionaries/project.xml

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

8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ if (NOT NO_STATIC_ANALYSIS)
${CMAKE_SOURCE_DIR}/tests/*/*.[ch]pp
${CMAKE_SOURCE_DIR}/examples/*.[ch]
${CMAKE_SOURCE_DIR}/cy_udp_posix/*.[ch]
${CMAKE_SOURCE_DIR}/cy_udp_posix/tests/*.[ch]
${CMAKE_SOURCE_DIR}/cy_can/tests/*.[ch]
${CMAKE_SOURCE_DIR}/cy_udp_posix/tests/*/*.[ch]
${CMAKE_SOURCE_DIR}/cy_udp_posix/tests/*/*.[ch]pp
${CMAKE_SOURCE_DIR}/cy_can/*.[ch]
${CMAKE_SOURCE_DIR}/cy_can/tests/*/*.[ch]
${CMAKE_SOURCE_DIR}/cy_can/tests/*/*.[ch]pp
)
message(STATUS "Using clang-format: ${clang_format}; files to format: ${format_files}")
add_custom_target(format COMMAND ${clang_format} -i -fallback-style=none -style=file --verbose ${format_files})
Expand Down Expand Up @@ -105,5 +112,6 @@ endif ()

# SUBDIRECTORIES
add_subdirectory(cy_udp_posix)
add_subdirectory(cy_can)
add_subdirectory(examples)
add_subdirectory(tests)
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ On an embedded system, one may also prefer to use [`o1heap`](https://github.com/
management, but this is not a hard dependency -- any allocator will work. O1Heap is the recommended choice for embedded
platforms due to its hard determinism and low fragmentation.

Pick one of the transport/platform glue layers suitable for your application: `cy_can`, `cy_udp_posix`, etc.
The integration instructions are identical: simply copy the C files and add them to your build system.
These components may be moved into dedicated repositories in the future.

🌐 A live demo of the distributed consensus algorithm can be found at <https://gerasim.opencyphal.org>.

For a detailed design overview, refer to `model/`.
Expand All @@ -49,15 +53,20 @@ The specifics of setting up a local node depend on the platform and transport us
unlike the rest of the API, which is entirely platform- and transport-agnostic.

```c++
#include <cy.h> // platform- and transport-agnostic Cyphal API
#include <cy_udp_posix.h> // thin low-level glue specific to Cyphal/UDP on POSIX systems; choose one for your setup
#include <cy.h> // platform- and transport-agnostic Cyphal API
#include <cy_udp_posix.h> // thin low-level glue specific to Cyphal/UDP on POSIX systems; choose one for your setup
#include <cy_can_socketcan.h> // thin low-level glue specific to Cyphal/CAN on SocketCAN; choose one for your setup

int main(void)
{
// Set up the platform layer that connects Cy to the underlying transport and OS.
// Here we're using Cyphal/UDP on POSIX as an example.
cy_platform_t* platform = cy_udp_posix_new();
if (platform == NULL) { ... }

// If you need Cyphal/CAN on SocketCAN instead, just replace the above with:
cy_platform_t* platform = cy_can_socketcan_new(1, (const char*[]){"can0"}, 1000); // 1 iface, 1000 frames TX queue
if (platform == NULL) { ... }

// Set up the local Cyphal node instance.
// Every node needs a home, which should be unique across the network.
Expand Down Expand Up @@ -150,7 +159,7 @@ Do not destroy unwanted futures right away because that cancels the associated o
cy_future_callback_set(future, cy_future_destroy); // Will destroy itself when done, no need to keep the reference.
```

The examples folder contains a simple publisher example `main_udp_time_pub.c`.
The examples folder contains a simple publisher example `example_time_pub.c`.

### 📩 Subscribe to topics and receive messages

Expand Down Expand Up @@ -255,7 +264,7 @@ for (size_t i = 0; i < subs.count; i++) {
It is also possible to monitor subscriber liveness and alert the application via its callback when messages cease to
arrive; see the API docs for details.

The examples folder contains a simple subscriber example `main_udp_echo.c`.
The examples folder contains a simple subscriber example `example_echo.c`.

### 🔄 RPC & streaming

Expand Down
3 changes: 2 additions & 1 deletion cy/cy.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,8 @@ static cy_tree_t* reader_cavl_factory(void* const user)
return NULL;
}
r->handle->subject_id = ctx->subject_id;
r->handle->extent = ctx->extent; // In case the platform layer didn't set it.
// Some platforms may revive a tombstoned incumbent whose extent is already larger than requested.
r->handle->extent = larger(r->handle->extent, ctx->extent);
}
return (cy_tree_t*)r;
}
Expand Down
3 changes: 2 additions & 1 deletion cy/cy_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ typedef struct cy_subject_writer_t
typedef struct cy_subject_reader_t
{
uint32_t subject_id;
size_t extent;
size_t extent; // Platform must either set this to the initial value or zero at construction time.
} cy_subject_reader_t;

/// Abstracts away the specifics of the transport (UDP, serial, CAN, etc) and the platform where Cy is running
Expand Down Expand Up @@ -170,6 +170,7 @@ typedef struct cy_platform_vtable_t
/// The cy_on_message() callback will be invoked from this function.
/// This is the only platform function that is allowed to block.
/// May return additional error codes, which will be forwarded to the application as-is.
/// This can only be invoked from within cy_spin*() functions, and is never invoked from cy_on_message().
cy_err_t (*spin)(cy_platform_t*, cy_us_t deadline);

// === MISC ===
Expand Down
36 changes: 36 additions & 0 deletions cy_can/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) Pavel Kirienko

cmake_minimum_required(VERSION 3.24)
project(cy_can C)

include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/lib")

# Libcanard static library.
add_library(canard STATIC "${CMAKE_SOURCE_DIR}/lib/libcanard/libcanard/canard.c")
target_compile_options(canard PRIVATE -Wno-cast-align)
target_include_directories(canard SYSTEM INTERFACE ${CMAKE_SOURCE_DIR}/lib/libcanard/libcanard)
set_target_properties(
canard
PROPERTIES
COMPILE_WARNING_AS_ERROR OFF
C_STANDARD_REQUIRED ON
C_EXTENSIONS OFF
C_CLANG_TIDY ""
CXX_CLANG_TIDY ""
C_CPPCHECK ""
CXX_CPPCHECK ""
)

# Platform-agnostic CAN transport glue static library.
# Consumers link cy/cy.c themselves; this target only contains the transport/platform layer.
add_library(cy_can STATIC cy_can.c)
target_link_libraries(cy_can PUBLIC canard)
target_include_directories(cy_can PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/cy)
set_target_properties(cy_can PROPERTIES COMPILE_WARNING_AS_ERROR ON C_STANDARD_REQUIRED ON C_EXTENSIONS OFF)

# Linux SocketCAN backend for cy_can. Includes cy_can and canard, making it self-contained except for cy.c.
add_library(cy_can_socketcan STATIC cy_can_socketcan.c)
target_link_libraries(cy_can_socketcan PUBLIC cy_can)
set_target_properties(cy_can_socketcan PROPERTIES COMPILE_WARNING_AS_ERROR ON C_STANDARD_REQUIRED ON C_EXTENSIONS OFF)
Comment thread
pavel-kirienko marked this conversation as resolved.
Outdated

add_subdirectory(tests)
Loading