Skip to content

Commit

Permalink
Merge pull request #201 from 107-systems/fix-176
Browse files Browse the repository at this point in the history
Support compilation for x86 as a static library using CMake.
  • Loading branch information
aentinger committed Jan 17, 2023
2 parents 24deddd + e3f095a commit 4212b9b
Show file tree
Hide file tree
Showing 46 changed files with 1,252 additions and 205 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Build

# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
on:
push:
pull_request:
schedule:
# Run every Tuesday at 8 AM UTC
- cron: "0 8 * * TUE"
workflow_dispatch:
repository_dispatch:

permissions:
contents: read

jobs:
smoke-test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install CMake
run: sudo apt-get install cmake

- name: Create build directory, run CMake and Make
run: mkdir build && cd build && cmake -DBUILD_EXAMPLES=ON .. && make
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vscode/
.idea/
build/
cmake-build-debug/
33 changes: 33 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
##########################################################################
cmake_minimum_required(VERSION 3.15)
##########################################################################
project("cyphal++")
##########################################################################
set(CMAKE_VERBOSE_MAKEFILE OFF)
##########################################################################
option(BUILD_EXAMPLES "Build all examples provided with this library" OFF)
##########################################################################
add_subdirectory(src/libcanard)
add_subdirectory(src/libo1heap)
add_subdirectory(extras/cyphal++/libsocketcan)
##########################################################################
add_library(${PROJECT_NAME} STATIC
src/nodeinfo/NodeInfo.cpp
src/register/util/ListResponse.cpp
src/register/RegisterBase.cpp
src/register/RegisterList.cpp
src/Node.cpp
)
##########################################################################
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
##########################################################################
target_include_directories(${PROJECT_NAME} PUBLIC src extras/cyphal++/include)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
target_link_libraries(${PROJECT_NAME} canard o1heap socketcan)
##########################################################################
if(BUILD_EXAMPLES)
add_subdirectory(extras/cyphal++/examples/example-01-opencyphal-basic-node)
endif()
##########################################################################
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
====================
[![Arduino Library Badge](https://www.ardu-badge.com/badge/107-Arduino-Cyphal.svg?)](https://www.ardu-badge.com/107-Arduino-Cyphal)
[![Compile Examples](https://github.com/107-systems/107-Arduino-Cyphal/workflows/Compile%20Examples/badge.svg)](https://github.com/107-systems/107-Arduino-Cyphal/actions?workflow=Compile+Examples)
[![Smoke test status](https://github.com/107-systems/107-Arduino-Cyphal/actions/workflows/smoke-test.yml/badge.svg)](https://github.com/107-systems/107-Arduino-Cyphal/actions/workflows/smoke-test.yml)
[![Arduino Lint](https://github.com/107-systems/107-Arduino-Cyphal/workflows/Arduino%20Lint/badge.svg)](https://github.com/107-systems/107-Arduino-Cyphal/actions?workflow=Arduino+Lint)
[![keywords.txt Checks](https://github.com/107-systems/107-Arduino-Cyphal/workflows/Extra%20Library%20Checks/badge.svg)](https://github.com/107-systems/107-Arduino-Cyphal/actions?workflow=Extra+Library+Checks)
[![General Formatting Checks](https://github.com/107-systems/107-Arduino-Cyphal/workflows/General%20Formatting%20Checks/badge.svg)](https://github.com/107-systems/107-Arduino-Cyphal/actions?workflow=General+Formatting+Checks)
Expand All @@ -20,6 +21,16 @@ This library works for
* [arduino-esp32](https://github.com/espressif/arduino-esp32): `ESP32 Dev Module`, `ESP32 Wrover Module`, ... :heavy_check_mark:
* [arduino-pico](https://github.com/earlephilhower/arduino-pico): [`Raspberry Pi Pico`](https://www.raspberrypi.org/products/raspberry-pi-pico), `Adafruit Feather RP2040`, ... :heavy_check_mark:
* [adafruit/ArduinoCore-samd](https://github.com/adafruit/ArduinoCore-samd): [`Adafruit Feather M4 CAN Express`](https://www.adafruit.com/product/4759), ... :heavy_check_mark:
* **Host** (x86/x64/...): Using the CMake build system this library can be cross-compiled to a static C++ library and linked against any C++ executable. This is possible because the code itself is pure C/C++ without and dependencies to the Arduino framework.
```bash
* git clone https://github.com/107-systems/libdynamixelplusplus && cd libdynamixelplusplus
mkdir build && cd build
cmake .. && make
```
or
```bash
cmake -DBUILD_EXAMPLES=ON .. && make
```

### Reference-Implementation OpenCyphal on Arduino
* [OpenCyphal-GNSS-Node](examples/OpenCyphal-GNSS-Node): A OpenCyphal node with a GNSS sensor providing location data.
Expand Down
4 changes: 2 additions & 2 deletions examples/OpenCyphal-Blink/OpenCyphal-Blink.ino
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

Publisher<Heartbeat_1_0<>> heartbeat_pub = node_hdl.create_publisher<Heartbeat_1_0<>>(
Heartbeat_1_0<>::PORT_ID, 1*1000*1000UL /* = 1 sec in usecs. */);
Expand Down Expand Up @@ -124,7 +124,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}

/* Update the heartbeat object */
Expand Down
4 changes: 2 additions & 2 deletions examples/OpenCyphal-GNSS-Node/OpenCyphal-GNSS-Node.ino
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

Publisher<uavcan::node::Heartbeat_1_0<>> heartbeat_pub = node_hdl.create_publisher<uavcan::node::Heartbeat_1_0<>>(uavcan::node::Heartbeat_1_0<>::PORT_ID, 1*1000*1000UL /* = 1 sec in usecs. */);

Expand Down Expand Up @@ -151,7 +151,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}

/* Handle actions common to all states.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <107-Arduino-Cyphal.h>
#include <107-Arduino-MCP2515.h>
#include <107-Arduino-CriticalSection.h>

/**************************************************************************************
* NAMESPACE
Expand All @@ -40,7 +41,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

Publisher<Heartbeat_1_0<>> heartbeat_pub = node_hdl.create_publisher<Heartbeat_1_0<>>(Heartbeat_1_0<>::PORT_ID, 1*1000*1000UL /* = 1 sec in usecs. */);

Expand Down Expand Up @@ -80,7 +81,10 @@ void loop()
{
/* Process all pending OpenCyphal actions.
*/
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
{
CriticalSection crit_sec;
node_hdl.spinSome();
}

/* Update the heartbeat object */
hb_msg.data.uptime = millis() / 1000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

Subscription heartbeat_subscription =
node_hdl.create_subscription<Heartbeat_1_0<>>(Heartbeat_1_0<>::PORT_ID, CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC, onHeartbeat_1_0_Received);
Expand Down Expand Up @@ -83,7 +83,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

ServiceClient<ExecuteCommand_1_1::Request<>> srv_client = node_hdl.create_service_client<ExecuteCommand_1_1::Request<>, ExecuteCommand_1_1::Response<>>(
ExecuteCommand_1_1::Request<>::PORT_ID,
Expand Down Expand Up @@ -98,7 +98,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ArduinoMCP2515 mcp2515([]() { digitalWrite(MKRCAN_MCP2515_CS_PIN, LOW); },
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); });

ServiceServer execute_command_srv = node_hdl.create_service_server<ExecuteCommand_1_1::Request<>, ExecuteCommand_1_1::Response<>>(
ExecuteCommand_1_1::Request<>::PORT_ID,
Expand Down Expand Up @@ -86,7 +86,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ ArduinoMCP2515 mcp2515([]()
nullptr);

Node::Heap<Node::DEFAULT_O1HEAP_SIZE> node_heap;
Node node_hdl(node_heap.data(), node_heap.size(), micros, OPEN_CYPHAL_NODE_ID);
Node node_hdl(node_heap.data(), node_heap.size(), micros, [] (CanardFrame const & frame) { return mcp2515.transmit(frame); }, OPEN_CYPHAL_NODE_ID);

Publisher<Heartbeat_1_0<>> heartbeat_pub = node_hdl.create_publisher<Heartbeat_1_0<>>(Heartbeat_1_0<>::PORT_ID, 1*1000*1000UL /* = 1 sec in usecs. */);
Publisher<DistanceMessageType> tof_pub = node_hdl.create_publisher<DistanceMessageType>(OPEN_CYPHAL_ID_DISTANCE_DATA, 1*1000*1000UL /* = 1 sec in usecs. */);
Expand Down Expand Up @@ -161,10 +161,10 @@ DEBUG_INSTANCE(120, Serial);

/* REGISTER ***************************************************************************/

static RegisterNatural8 reg_rw_uavcan_node_id ("uavcan.node.id", Register::Access::ReadWrite, Register::Persistent::No, OPEN_CYPHAL_NODE_ID, [&node_hdl](uint8_t const & val) { node_hdl.setNodeId(val); });
static RegisterString reg_ro_uavcan_node_description ("uavcan.node.description", Register::Access::ReadWrite, Register::Persistent::No, "OpenCyphal-ToF-Distance-Sensor-Node");
static RegisterNatural16 reg_ro_uavcan_pub_distance_id ("uavcan.pub.distance.id", Register::Access::ReadOnly, Register::Persistent::No, OPEN_CYPHAL_ID_DISTANCE_DATA);
static RegisterString reg_ro_uavcan_pub_distance_type("uavcan.pub.distance.type", Register::Access::ReadOnly, Register::Persistent::No, "uavcan.primitive.scalar.Real32.1.0");
static RegisterNatural8 reg_rw_cyphal_node_id ("cyphal.node.id", Register::Access::ReadWrite, Register::Persistent::No, OPEN_CYPHAL_NODE_ID, [&node_hdl](uint8_t const & val) { node_hdl.setNodeId(val); });
static RegisterString reg_ro_cyphal_node_description ("cyphal.node.description", Register::Access::ReadWrite, Register::Persistent::No, "OpenCyphal-ToF-Distance-Sensor-Node");
static RegisterNatural16 reg_ro_cyphal_pub_distance_id ("cyphal.pub.distance.id", Register::Access::ReadOnly, Register::Persistent::No, OPEN_CYPHAL_ID_DISTANCE_DATA);
static RegisterString reg_ro_cyphal_pub_distance_type("cyphal.pub.distance.type", Register::Access::ReadOnly, Register::Persistent::No, "cyphal.primitive.scalar.Real32.1.0");
static RegisterList reg_list(node_hdl);

/* NODE INFO **************************************************************************/
Expand Down Expand Up @@ -234,10 +234,10 @@ void setup()

/* Register callbacks for node info and register api.
*/
reg_list.add(reg_rw_uavcan_node_id);
reg_list.add(reg_ro_uavcan_node_description);
reg_list.add(reg_ro_uavcan_pub_distance_id);
reg_list.add(reg_ro_uavcan_pub_distance_type);
reg_list.add(reg_rw_cyphal_node_id);
reg_list.add(reg_ro_cyphal_node_description);
reg_list.add(reg_ro_cyphal_pub_distance_id);
reg_list.add(reg_ro_cyphal_pub_distance_type);
}

void loop()
Expand All @@ -246,7 +246,7 @@ void loop()
*/
{
CriticalSection crit_sec;
node_hdl.spinSome([] (CanardFrame const & frame) { return mcp2515.transmit(frame); });
node_hdl.spinSome();
}

/* Handle actions common to all states.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
##########################################################################
cmake_minimum_required(VERSION 3.15)
##########################################################################
set(EXAMPLE_01_TARGET example-01-basic-cyphal-node)
##########################################################################
add_executable(${EXAMPLE_01_TARGET} example-01-opencyphal-basic-node.cpp)
target_link_libraries(${EXAMPLE_01_TARGET} cyphal++ pthread)
##########################################################################
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<a href="https://opencyphal.org/"><img align="right" src="https://raw.githubusercontent.com/107-systems/.github/main/logo/opencyphal.svg" width="25%"></a>
:floppy_disk: `example-01-opencyphal-basic-node`
================================================
* Setup a virtual CAN interface (`vcan0`)
```bash
sudo ./setup_vcan.sh
```
You can observe the frames on the virtual CAN bus using `candump`
```bash
candump vcan0
```
* Install `yakut`
```bash
python3 -m pip install yakut
```
* Compile OpenCyphal DSDL
```bash
yakut compile https://github.com/OpenCyphal/public_regulated_data_types/archive/refs/heads/master.zip
```
* Setup `yakut`
```bash
. setup_yakut.sh
```
* Start `yakut`
```bash
yakut monitor
```
* Use `yakut`

Read the register list of the node.
```bash
yakut rl 42
[cyphal.node.description, cyphal.node.id, cyphal.pub.temperature.id, cyphal.pub.temperature.type]
```
Loading

0 comments on commit 4212b9b

Please sign in to comment.