Skip to content

Commit

Permalink
New libcyphal C++ demo (#26)
Browse files Browse the repository at this point in the history
Merge PR of the new "libcyphal demo" sub-project
  • Loading branch information
serges147 authored Nov 7, 2024
1 parent 8e49db2 commit 1257662
Show file tree
Hide file tree
Showing 36 changed files with 3,421 additions and 20 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ name: build

on:
push:
branches: [ "sshirokov/libcyphal" ]
branches:
- main
- 'issue/*'
pull_request:
branches: [ "sshirokov/libcyphal" ]
branches:
- main
- 'issue/*'

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
Expand All @@ -25,7 +29,7 @@ jobs:

- name: get nunavut
run: >
pip install git+https://github.com/OpenCyphal/nunavut.git@23b84f76d4fc0e75595efc02fde30140e3cef2fb
pip install git+https://github.com/OpenCyphal/nunavut.git@3.0.preview
- name: Configure CMake
run: cmake -B ${{github.workspace}}/libcyphal_demo/build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ${{github.workspace}}/libcyphal_demo
Expand Down
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
[submodule "submodules/libcyphal"]
path = submodules/libcyphal
url = https://github.com/OpenCyphal-Garage/libcyphal.git
branch = issue/registry
7 changes: 5 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"cSpell.words": [
"baremetal",
"cetl",
"Cyphal",
"POSIX"
"libcyphal",
"POSIX",
"uavcan"
],
"cmake.sourceDirectory": "/home/sergei/Develop/git/OpenCyphal-Garage/demos/libcyphal_demo"
}
}
1 change: 0 additions & 1 deletion libcyphal_demo/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ CheckOptions:
- key: readability-magic-numbers.IgnoredIntegerValues
value: '1;2;3;4;5;8;10;16;20;32;60;64;100;128;256;500;512;1000'
WarningsAsErrors: '*'
HeaderFilterRegex: 'include/libcyphal/.*\.hpp'
FormatStyle: file
10 changes: 10 additions & 0 deletions libcyphal_demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ project(libcyphal_demo
HOMEPAGE_URL https://github.com/OpenCyphal-Garage/libcyphal)

set(CMAKE_CXX_STANDARD "14" CACHE STRING "C++ standard to use when compiling.")
set(DISABLE_CPP_EXCEPTIONS ON CACHE STRING "Disable C++ exceptions.")

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (DISABLE_CPP_EXCEPTIONS)
message(STATUS "DISABLE_CPP_EXCEPTIONS is true. Adding -fno-exceptions to compiler flags.")
list(APPEND CXX_FLAG_SET "-fno-exceptions")
endif()
endif()

add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:${CXX_FLAG_SET}>")

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
set(submodules "${CMAKE_SOURCE_DIR}/../submodules")
Expand Down
7 changes: 6 additions & 1 deletion libcyphal_demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ This document will walk you through the process of building, running, and evalua
on a GNU/Linux-based OS.
It can be easily ported to another platform, such as a baremetal MCU,
by replacing the POSIX socket API and stdio with suitable alternatives;
for details, please consult with `udp.h` and `storage.h`. **FIXME**
for details, please consult with:
- `platform/posix/udp/*` files regarding UDP transport
- `platform/linux/can/*` files regarding CAN transport
- `platform/linux/epoll_single_threaded_executor.hpp` file regarding the executor
- `platform/storage.hpp` file regarding the non-volatile storage
- `platform/o1_heap_memory_resource.hpp` file regarding the memory resource

## Preparation

Expand Down
7 changes: 6 additions & 1 deletion libcyphal_demo/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@

cmake_minimum_required(VERSION 3.20)

add_subdirectory(platform)

# Define the demo application build target and link it with the library.
add_executable(
demo
${CMAKE_SOURCE_DIR}/src/application.cpp
${CMAKE_SOURCE_DIR}/src/main.cpp
${CMAKE_SOURCE_DIR}/src/no_cpp_heap.cpp
)
target_link_libraries(demo PRIVATE udpard)
target_link_libraries(demo PRIVATE canard)
target_link_libraries(demo PRIVATE o1heap)
target_link_libraries(demo PRIVATE udpard)
target_link_libraries(demo PRIVATE platform)
target_include_directories(demo PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(demo PRIVATE ${submodules}/cetl/include)
target_include_directories(demo PRIVATE ${submodules}/libcyphal/include)
add_dependencies(demo dsdl_uavcan)
Expand Down
111 changes: 111 additions & 0 deletions libcyphal_demo/src/application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// This software is distributed under the terms of the MIT License.
// Copyright (C) OpenCyphal Development Team <opencyphal.org>
// Copyright Amazon.com Inc. or its affiliates.
// SPDX-License-Identifier: MIT
// Author: Sergei Shirokov <[email protected]>

#include "application.hpp"

#include <libcyphal/application/registry/registry_impl.hpp>
#include <libcyphal/platform/storage.hpp>

#include <cetl/pf17/cetlpf.hpp>
#include <o1heap.h>

#include <uavcan/node/GetInfo_1_0.hpp>

#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <random>
#include <string> // for std::stoul

namespace
{

constexpr std::size_t HeapSize = 16ULL * 1024ULL;
alignas(O1HEAP_ALIGNMENT) std::array<cetl::byte, HeapSize> s_heap_arena{};

} // namespace

Application::Application()
: o1_heap_mr_{s_heap_arena}
, storage_{"/tmp/" NODE_NAME}
, registry_{o1_heap_mr_}
, regs_{o1_heap_mr_, registry_}
{
cetl::pmr::set_default_resource(&o1_heap_mr_);

load(storage_, registry_);

// Maybe override some of the registry values with environment variables.
//
auto iface_params = getIfaceParams();
if (const auto* const iface_addresses_str = std::getenv("CYPHAL__UDP__IFACE"))
{
iface_params.udp_iface.value() = iface_addresses_str;
}
if (const auto* const iface_addresses_str = std::getenv("CYPHAL__CAN__IFACE"))
{
iface_params.can_iface.value() = iface_addresses_str;
}
auto node_params = getNodeParams();
if (const auto* const node_id_str = std::getenv("CYPHAL__NODE__ID"))
{
node_params.id.value()[0] = static_cast<std::uint16_t>(std::stoul(node_id_str));
}
}

Application::~Application()
{
save(storage_, registry_);

const auto mr_diag = o1_heap_mr_.queryDiagnostics();
std::cout << "O(1) Heap diagnostics:" << "\n"
<< " capacity=" << mr_diag.capacity << "\n"
<< " allocated=" << mr_diag.allocated << "\n"
<< " peak_allocated=" << mr_diag.peak_allocated << "\n"
<< " peak_request_size=" << mr_diag.peak_request_size << "\n"
<< " oom_count=" << mr_diag.oom_count << "\n";

cetl::pmr::set_default_resource(cetl::pmr::new_delete_resource());
}

/// Returns the 128-bit unique-ID of the local node. This value is used in `uavcan.node.GetInfo.Response`.
///
void Application::getUniqueId(uavcan::node::GetInfo::Response_1_0::_traits_::TypeOf::unique_id& out)
{
const auto result = storage_.get(".unique_id", out);
if (cetl::get_if<libcyphal::platform::storage::Error>(&result) != nullptr)
{
std::random_device rd; // Seed for the random number engine
std::mt19937 gen{rd()}; // Mersenne Twister engine
std::uniform_int_distribution<std::uint8_t> dis{0, 255}; // Distribution range for bytes

// Populate the default; it is only used at the first run.
for (auto& b : out)
{
b = dis(gen);
}

(void) storage_.put(".unique_id", out);
}
}

Application::Regs::Value Application::Regs::getSysInfoMem() const
{
Value value{{&o1_heap_mr_}};
auto& uint64s = value.set_natural64();

const auto diagnostics = o1_heap_mr_.queryDiagnostics();
uint64s.value.reserve(5); // five fields gonna push
uint64s.value.push_back(diagnostics.capacity);
uint64s.value.push_back(diagnostics.allocated);
uint64s.value.push_back(diagnostics.peak_allocated);
uint64s.value.push_back(diagnostics.peak_request_size);
uint64s.value.push_back(diagnostics.oom_count);

return value;
}
Loading

0 comments on commit 1257662

Please sign in to comment.