Skip to content

Commit 2b9c7f6

Browse files
Cyphalize and release v1.0 (#15)
* Cyphalize * Update catch, clang-format, Yakut * Release v1.0
1 parent 39496f3 commit 2b9c7f6

18 files changed

+10939
-4982
lines changed

.github/workflows/main.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
tests
3636
- working-directory: ${{github.workspace}}/build
3737
run: |
38-
yakut compile https://github.com/UAVCAN/public_regulated_data_types/archive/refs/heads/master.zip
38+
yakut compile https://github.com/OpenCyphal/public_regulated_data_types/archive/refs/heads/master.zip
3939
make VERBOSE=1 -j2
4040
make test
4141
- uses: actions/upload-artifact@v2
@@ -76,7 +76,7 @@ jobs:
7676
- working-directory: ${{github.workspace}}/build
7777
run: |
7878
make VERBOSE=1 -j2
79-
yakut compile https://github.com/UAVCAN/public_regulated_data_types/archive/refs/heads/master.zip
79+
yakut compile https://github.com/OpenCyphal/public_regulated_data_types/archive/refs/heads/master.zip
8080
make test
8181
- uses: actions/upload-artifact@v2
8282
if: always()
@@ -101,12 +101,12 @@ jobs:
101101
runs-on: ubuntu-latest
102102
steps:
103103
- uses: actions/checkout@v2
104-
- uses: DoozyX/clang-format-lint-action@v0.12
104+
- uses: DoozyX/clang-format-lint-action@v0.13
105105
with:
106106
source: ./kocherga ./tests
107107
exclude: ./tests/3rd_party
108108
extensions: cpp,hpp
109-
clangFormatVersion: 12
109+
clangFormatVersion: 13
110110
- run: |
111111
pip install black
112112
black --check ./tools/
@@ -167,7 +167,7 @@ jobs:
167167
run: |
168168
cmake tests -DCMAKE_BUILD_TYPE=Debug -DNO_STATIC_ANALYSIS=1 -DCMAKE_CXX_FLAGS='-DNDEBUG=1'
169169
build-wrapper-linux-x86-64 --out-dir . make all VERBOSE=1
170-
yakut compile https://github.com/UAVCAN/public_regulated_data_types/archive/refs/heads/master.zip
170+
yakut compile https://github.com/OpenCyphal/public_regulated_data_types/archive/refs/heads/master.zip
171171
make test
172172
gcov --preserve-paths --long-file-names $(find integration/CMakeFiles/bootloader.dir -name '*.gcno')
173173
gcov --preserve-paths --long-file-names $(find unit/CMakeFiles/test_cov.dir -name '*.gcno')

README.md

+20-20
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,20 @@ boot. Only if a valid `AppInfo` structure is found the application will be launc
4949
structure closer to the beginning of the image in order to speed up its verification. The structure is defined as
5050
follows:
5151

52-
Offset | Type | Description
53-
-------|----------|-----------------------------------------------------------------------------------------------------
54-
-16 |`uint64` | Constant value 0x5E4415146FC0C4C7 used for locating the descriptor and detecting the byte order.
55-
-8 |`uint8[8]`| Set to `APDesc00`; used for compatibility with legacy deployments.
56-
0 |`uint64` | CRC-64-WE of the entire application image when this field itself is set to zero.
57-
8 |`uint32` | Size of the application image, in bytes. Note that the image must be padded to eight bytes.
58-
12 |`void32` | Reserved. Used to contain the 32-bit version control system revision ID; see replacement below.
59-
16 |`uint8[2]`| Major and minor semantic version numbers.
60-
18 |`uint8` | Flags: 1 - this is a release build; 2 - this is a dirty build (uncommitted changes present).
61-
19 |`void8` | Reserved; set to 0.
62-
20 |`uint32` | UNIX UTC build timestamp; i.e., the number of seconds since 1970-01-01T00:00:00Z.
63-
24 |`uint64` | Version control system (VCS) revision ID (e.g., the git commit hash).
64-
32 |`void64` | Reserved.
65-
40 |`void64` | Reserved.
52+
| Offset | Type | Description |
53+
|--------|------------|--------------------------------------------------------------------------------------------------|
54+
| -16 | `uint64` | Constant value 0x5E4415146FC0C4C7 used for locating the descriptor and detecting the byte order. |
55+
| -8 | `uint8[8]` | Set to `APDesc00`; used for compatibility with legacy deployments. |
56+
| 0 | `uint64` | CRC-64-WE of the entire application image when this field itself is set to zero. |
57+
| 8 | `uint32` | Size of the application image, in bytes. Note that the image must be padded to eight bytes. |
58+
| 12 | `void32` | Reserved. Used to contain the 32-bit version control system revision ID; see replacement below. |
59+
| 16 | `uint8[2]` | Major and minor semantic version numbers. |
60+
| 18 | `uint8` | Flags: 1 - this is a release build; 2 - this is a dirty build (uncommitted changes present). |
61+
| 19 | `void8` | Reserved; set to 0. |
62+
| 20 | `uint32` | UNIX UTC build timestamp; i.e., the number of seconds since 1970-01-01T00:00:00Z. |
63+
| 24 | `uint64` | Version control system (VCS) revision ID (e.g., the git commit hash). |
64+
| 32 | `void64` | Reserved. |
65+
| 40 | `void64` | Reserved. |
6666

6767
When computing the application image CRC, the process will eventually encounter the location where the CRC itself is
6868
stored. In order to avoid recursive dependency, the CRC storage location must be replaced with zero bytes when
@@ -94,12 +94,12 @@ The following diagram documents the state machine of the bootloader:
9494

9595
The bootloader states are mapped onto Cyphal node states as follows:
9696

97-
Bootloader state | Node mode | Node health| Vendor-specific status code
98-
---------------------|-----------------|------------|-------------------------------
99-
NoAppToBoot |`SOFTWARE_UPDATE`| `WARNING` | 0
100-
BootDelay |`SOFTWARE_UPDATE`| `NOMINAL` | 0
101-
BootCancelled |`SOFTWARE_UPDATE`| `ADVISORY` | 0
102-
AppUpdateInProgress |`SOFTWARE_UPDATE`| `NOMINAL` | number of read requests, always >0
97+
| Bootloader state | Node mode | Node health | Vendor-specific status code |
98+
|---------------------|-------------------|-------------|------------------------------------|
99+
| NoAppToBoot | `SOFTWARE_UPDATE` | `WARNING` | 0 |
100+
| BootDelay | `SOFTWARE_UPDATE` | `NOMINAL` | 0 |
101+
| BootCancelled | `SOFTWARE_UPDATE` | `ADVISORY` | 0 |
102+
| AppUpdateInProgress | `SOFTWARE_UPDATE` | `NOMINAL` | number of read requests, always >0 |
103103

104104
### API usage
105105

kocherga/kocherga.hpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include <optional>
1313
#include <type_traits>
1414

15-
#define KOCHERGA_VERSION_MAJOR 0 // NOLINT NOSONAR
16-
#define KOCHERGA_VERSION_MINOR 2 // NOLINT NOSONAR
15+
#define KOCHERGA_VERSION_MAJOR 1 // NOLINT NOSONAR
16+
#define KOCHERGA_VERSION_MINOR 0 // NOLINT NOSONAR
1717

1818
#ifndef KOCHERGA_ASSERT
1919
# include <cassert>
@@ -31,7 +31,7 @@ using TransferID = std::uint64_t;
3131
using NodeID = std::uint16_t;
3232
using PortID = std::uint16_t;
3333

34-
/// UAVCAN subjects used by Kocherga.
34+
/// Cyphal subjects used by Kocherga.
3535
enum class SubjectID : PortID
3636
{
3737
NodeHeartbeat = 7509,
@@ -40,16 +40,16 @@ enum class SubjectID : PortID
4040
DiagnosticRecord = 8184,
4141
};
4242

43-
/// UAVCAN services used by Kocherga.
43+
/// Cyphal services used by Kocherga.
4444
enum class ServiceID : PortID
4545
{
4646
FileRead = 408,
4747
NodeGetInfo = 430,
4848
NodeExecuteCommand = 435,
4949
};
5050

51-
/// Version of the UAVCAN specification implemented by this library, major and minor.
52-
static constexpr SemanticVersion UAVCANSpecificationVersion{{1, 0}};
51+
/// Version of the Cyphal specification implemented by this library, major and minor.
52+
static constexpr SemanticVersion CyphalSpecificationVersion{{1, 0}};
5353

5454
/// The service response timeout used by the bootloader.
5555
/// This value applies when the bootloader invokes uavcan.file.Read during the update.
@@ -770,8 +770,8 @@ class Presenter final : public IReactor
770770
const auto app_info = controller_.getAppInfo();
771771
auto* const base_ptr = out_response;
772772
auto* ptr = base_ptr;
773-
*ptr++ = UAVCANSpecificationVersion.at(0);
774-
*ptr++ = UAVCANSpecificationVersion.at(1);
773+
*ptr++ = CyphalSpecificationVersion.at(0);
774+
*ptr++ = CyphalSpecificationVersion.at(1);
775775
*ptr++ = system_info_.hardware_version.at(0);
776776
*ptr++ = system_info_.hardware_version.at(1);
777777
if (app_info)

kocherga/kocherga_can.hpp

+24-24
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ inline auto makePseudoUniqueID(const SystemInfo::UniqueID& uid) -> std::uint64_t
296296

297297
/// If the local-ID is provided, the filter will match only on service transfers addressed to the local node.
298298
/// If the local-ID is not provided, the filter will match on PnP allocation response messages only.
299-
template <std::uint8_t UAVCANVersion>
299+
template <std::uint8_t Version>
300300
[[nodiscard]] auto makeAcceptanceFilter(const std::optional<std::uint8_t> local_node_id) -> CANAcceptanceFilterConfig;
301301
template <>
302302
[[nodiscard]] inline auto makeAcceptanceFilter<0>(const std::optional<std::uint8_t> local_node_id)
@@ -383,7 +383,7 @@ struct ServiceFrameModel : FrameModel
383383
const std::uint8_t transfer_id = (tail & MaxTransferID);
384384
if (start_of_transfer && (!toggle))
385385
{
386-
return {}; // UAVCAN v0
386+
return {}; // DroneCAN
387387
}
388388
if (((!start_of_transfer) || (!end_of_transfer)) && (out_payload_size == 0))
389389
{
@@ -450,7 +450,7 @@ struct ServiceFrameModel : FrameModel
450450
-> std::optional<std::variant<MessageFrameModel, ServiceFrameModel>>
451451
{
452452
KOCHERGA_ASSERT(payload != nullptr);
453-
if ((payload_size < 1) || (payload_size > 8)) // Legacy UAVCAN v0 is compatible only with Classic CAN.
453+
if ((payload_size < 1) || (payload_size > 8)) // Legacy is compatible only with Classic CAN.
454454
{ // This is because the low granularity of DLC in CAN FD breaks TAO.
455455
return {};
456456
}
@@ -462,7 +462,7 @@ struct ServiceFrameModel : FrameModel
462462
const std::uint8_t transfer_id = (tail & MaxTransferID);
463463
if (start_of_transfer && toggle)
464464
{
465-
return {}; // UAVCAN v1
465+
return {}; // Cyphal
466466
}
467467
const auto priority = static_cast<std::uint8_t>((extended_can_id >> 24U) & 31U);
468468
const auto source_node_id = static_cast<std::uint8_t>(extended_can_id & 0x7FU);
@@ -671,7 +671,7 @@ class BasicTransferReasmV0
671671
}
672672
if (frame.payload_size > (buffer_.size() - state_->payload_size))
673673
{
674-
state_.reset(); // Too much payload -- UAVCAN v0 does not define payload truncation.
674+
state_.reset(); // Too much payload -- DroneCAN does not define payload truncation.
675675
return {};
676676
}
677677
std::copy_n(frame.payload, frame.payload_size, buffer_.begin() + state_->payload_size);
@@ -778,7 +778,7 @@ class BasicServiceTransferReasmV0 : public BasicTransferReasmV0<MaxPayloadSize>
778778
const std::uint8_t local_node_id_;
779779
};
780780

781-
/// Send one UAVCAN/CAN v1 transfer. The push_frame callback is invoked per each transmitted frame; its type should be:
781+
/// Send one Cyphal/CAN transfer. The push_frame callback is invoked per each transmitted frame; its type should be:
782782
/// (std::size_t, const std::uint8_t*) -> bool
783783
/// The return value is true on success, false otherwise.
784784
/// The callback shall not be an std::function<> or std::bind<> to avoid heap allocation.
@@ -1070,7 +1070,7 @@ class IActivity
10701070
auto operator=(IActivity&&) -> IActivity& = delete;
10711071
};
10721072

1073-
/// The v0 main activity is a simplified translation layer between UAVCAN/CAN v1 and UAVCAN v0.
1073+
/// The v0 main activity is a simplified translation layer between Cyphal/CAN and DroneCAN.
10741074
/// The following ports are supported:
10751075
///
10761076
/// Service RX TX
@@ -1437,7 +1437,7 @@ class V0MainActivity : public IActivity
14371437
BasicServiceTransferReasmV0<300> rx_res_file_read_{FileReadSignature, local_node_id_};
14381438
};
14391439

1440-
/// The following example shows the CAN exchange dump collected from a real network using the old UAVCAN v0 GUI Tool.
1440+
/// The following example shows the CAN exchange dump collected from a real network using the old GUI Tool.
14411441
///
14421442
/// Unique-ID of the allocatee: 35 FF D5 05 50 59 31 34 61 41 23 43 00 00 00 00
14431443
/// Preferred node-ID: 0 (any, no preference)
@@ -1619,7 +1619,6 @@ class V0NodeIDAllocationActivity : public IActivity
16191619
KOCHERGA_ASSERT((0 <= randomized) && (randomized <= delta));
16201620
const auto delay = std::max(std::chrono::microseconds(1), range.first) + std::chrono::microseconds(randomized);
16211621
KOCHERGA_ASSERT(range.first <= delay);
1622-
KOCHERGA_ASSERT(range.second >= delay);
16231622
deadline_ = now + delay;
16241623
}
16251624

@@ -2090,17 +2089,17 @@ class VersionDetectionActivity : public IActivity
20902089
while (const auto frame = driver_.pop(buf))
20912090
{
20922091
const auto [can_id, payload_size] = *frame;
2093-
if (payload_size > 0) // UAVCAN frames are guaranteed to contain the tail byte always.
2092+
if (payload_size > 0) // Cyphal frames are guaranteed to contain the tail byte always.
20942093
{
2095-
if (const auto uavcan_version = tryDetectVersionFromFrame(can_id, buf.at(payload_size - 1U)))
2094+
if (const auto version = tryDetectVersionFromFrame(can_id, buf.at(payload_size - 1U)))
20962095
{
20972096
if (!highest_version_seen_)
20982097
{
20992098
deadline_ = uptime + ListeningPeriod;
21002099
}
2101-
if ((!highest_version_seen_) || (*highest_version_seen_ < *uavcan_version))
2100+
if ((!highest_version_seen_) || (*highest_version_seen_ < *version))
21022101
{
2103-
highest_version_seen_ = uavcan_version;
2102+
highest_version_seen_ = version;
21042103
KOCHERGA_ASSERT(highest_version_seen_);
21052104
}
21062105
}
@@ -2114,7 +2113,7 @@ class VersionDetectionActivity : public IActivity
21142113
-> std::optional<std::uint8_t>
21152114
{
21162115
// CAN ID is not validated at the moment. This may be improved in the future to avoid misdetection if there
2117-
// are other protocols besides UAVCAN on the same network.
2116+
// are other protocols besides Cyphal on the same network.
21182117
(void) can_id;
21192118
if ((tail_byte & TailByteStartOfTransfer) != 0)
21202119
{
@@ -2200,22 +2199,23 @@ class BitrateDetectionActivity : public IActivity
22002199

22012200
} // namespace detail
22022201

2203-
/// Kocherga node implementing the UAVCAN/CAN v1 transport along with UAVCAN v0 with automatic version detection.
2202+
/// Kocherga node implementing the Cyphal/CAN transport along with DroneCAN with automatic version detection.
22042203
class CANNode : public kocherga::INode
22052204
{
22062205
public:
22072206
/// The local UID shall be the same that is passed to the bootloader. It is used for PnP node-ID allocation.
2207+
/// The protocol version is 0 for DroneCAN (derived from legacy UAVCAN v0) and 1 for Cyphal/CAN.
22082208
/// By default, this implementation will auto-detect the parameters of the network and do a PnP node-ID allocation.
22092209
/// The application can opt-out of autoconfiguration by providing the required data to the constructor.
22102210
/// Unknown parameters shall be set to empty options.
22112211
CANNode(ICANDriver& driver,
22122212
const SystemInfo::UniqueID& local_unique_id,
2213-
const std::optional<ICANDriver::Bitrate>& can_bitrate = {},
2214-
const std::optional<std::uint8_t> uavcan_version = {},
2215-
const std::optional<NodeID> local_node_id = {})
2213+
const std::optional<ICANDriver::Bitrate>& can_bitrate = {},
2214+
const std::optional<std::uint8_t> protocol_version = {},
2215+
const std::optional<NodeID> local_node_id = {})
22162216
{
2217-
if ((activity_ == nullptr) && can_bitrate && //
2218-
uavcan_version && (*uavcan_version == 0) && //
2217+
if ((activity_ == nullptr) && can_bitrate && //
2218+
protocol_version && (*protocol_version == 0) && //
22192219
local_node_id && (*local_node_id > 0) && (*local_node_id <= MaxNodeID))
22202220
{
22212221
if (const auto bus_mode =
@@ -2229,8 +2229,8 @@ class CANNode : public kocherga::INode
22292229
static_cast<std::uint8_t>(*local_node_id));
22302230
}
22312231
}
2232-
if ((activity_ == nullptr) && can_bitrate && //
2233-
uavcan_version && (*uavcan_version == 1) && //
2232+
if ((activity_ == nullptr) && can_bitrate && //
2233+
protocol_version && (*protocol_version == 1) && //
22342234
local_node_id && (*local_node_id <= MaxNodeID))
22352235
{
22362236
if (const auto bus_mode =
@@ -2244,7 +2244,7 @@ class CANNode : public kocherga::INode
22442244
static_cast<std::uint8_t>(*local_node_id));
22452245
}
22462246
}
2247-
if ((activity_ == nullptr) && can_bitrate && uavcan_version && (*uavcan_version == 0))
2247+
if ((activity_ == nullptr) && can_bitrate && protocol_version && (*protocol_version == 0))
22482248
{
22492249
if (const auto bus_mode = driver.configure(*can_bitrate, false, detail::makeAcceptanceFilter<0>({})))
22502250
{
@@ -2255,7 +2255,7 @@ class CANNode : public kocherga::INode
22552255
*can_bitrate);
22562256
}
22572257
}
2258-
if ((activity_ == nullptr) && can_bitrate && uavcan_version && (*uavcan_version == 1))
2258+
if ((activity_ == nullptr) && can_bitrate && protocol_version && (*protocol_version == 1))
22592259
{
22602260
if (const auto bus_mode = driver.configure(*can_bitrate, false, detail::makeAcceptanceFilter<1>({})))
22612261
{

kocherga/kocherga_serial.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ struct Transfer
241241
const std::uint8_t* payload = nullptr;
242242
};
243243

244-
/// UAVCAN/serial stream parser. Extracts UAVCAN/serial frames from raw stream of bytes in constant time.
244+
/// Cyphal/serial stream parser. Extracts Cyphal/serial frames from raw stream of bytes in constant time.
245245
/// Frames that contain more than MaxPayloadSize bytes of payload are rejected as invalid.
246246
template <std::size_t MaxPayloadSize>
247247
class StreamParser
@@ -465,7 +465,7 @@ class ISerialPort
465465
auto operator=(ISerialPort&&) -> ISerialPort& = delete;
466466
};
467467

468-
/// Kocherga node implementing the UAVCAN/serial transport.
468+
/// Kocherga node implementing the Cyphal/serial transport.
469469
class SerialNode : public kocherga::INode
470470
{
471471
public:

0 commit comments

Comments
 (0)