Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libcanard v2.0 #182

Merged
merged 47 commits into from
Dec 4, 2021
Merged

Libcanard v2.0 #182

merged 47 commits into from
Dec 4, 2021

Conversation

pavel-kirienko
Copy link
Member

See the changelog in the README for a brief overview of the changes. The most interesting changes are two:

  • Split API into smaller entities to improve its orthogonality and fix the problem of const correctness reported by Scott.
  • Replace all linked lists with AVL trees to reduce the asymptotic complexity of both RX and TX pipelines from linear to logarithmic.

@coderkalyan do you want to include #171 into this release or should we wait for v2.1?

@coderkalyan
Copy link
Contributor

@coderkalyan do you want to include #171 into this release or should we wait for v2.1?

Preferably, yes. I'm a bit busy at the moment, I'll try to get it done in the next few days but if I'm unable to you can cut it and release 2.0.

@coderkalyan
Copy link
Contributor

And I'll review the rest of this soon as well :)

Copy link
Contributor

@coderkalyan coderkalyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only gave this a quick look, will take a deeper dive into the API changes later.

Copy link
Member

@thirtytwobits thirtytwobits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In-general, this is your usual strong work and really exciting. I'm only concerned about the lack of formal tests for the AVL tree. I'd like to see a set of tests dedicated to just this headers that enumerates and verifies its required properties.

@@ -7,29 +7,23 @@
/// ----o------o------------o---------o------o---------o-------
///
/// Libcanard is a compact implementation of the UAVCAN/CAN protocol for high-integrity real-time embedded systems.
/// It is designed for use in robust deterministic embedded systems equipped with at least 32K ROM and 4..8K RAM.
/// It is designed for use in robust deterministic embedded systems equipped with at least 32K ROM and 8K RAM.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me nervous. I'll keep reading but why are we giving up on 4k RAM? For example the Microchip SAMC21E15A is a perfectly modern automotive chip with CAN-FD support that has only 4k of SRAM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no changes in this PR that are expected to significantly alter the memory footprint. The AVL tree does add a couple of extra pointers per node compared to the linked list but that hardly matters. I updated this description to minimize the chances of submitting the first-time user to the bad experience of trying to squeeze this library into an MCU that is borderline unsuitable. You can make it work with 4K RAM but you really need to know what you are doing, whereas an 8K chip provides some laxity in memory allocation.

#include <assert.h>
#include <string.h>

// --------------------------------------------- BUILD CONFIGURATION ---------------------------------------------

/// Define this macro to include build configuration header.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to add something like:

#if CANARD_VERSION_MAJOR != 2
#    error "Wrong canard.h"
#endif

I'm sure it wouldn't compile, ultimately, but this error is easier to figure out then trying to parse out the random failures including the v1 header by accident would cause.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean putting this check inside your build configuration header? It is user-provided so one can put there whatever is desired.

/// just pointers, but it would push the size of this instance from about 0.5 KiB to ~3 KiB for a typical 32-bit
/// system. Since this is a general-purpose library, we have to pick a middle ground so we use the more complex
/// but more memory-efficient approach.
struct CanardInternalRxSession* _sessions[CANARD_NODE_ID_MAX + 1U];
struct CanardInternalRxSession* sessions[CANARD_NODE_ID_MAX + 1U]; ///< Read-only DO NOT MODIFY THIS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding @thirtytwobits statement

I'll keep reading but why are we giving up on 4k RAM?

Would utilizing CAVL here save enough memory to support 4KB RAM targets?
The maximum number of sessions is 128 thus would give you at most 7 hops in a binary tree.
Didn't look into the specifics of CAVL yet, but I suppose it's more memory efficient then allocating 128 pointers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maximum number of sessions is 128 thus would give you at most 7 hops in a binary tree.

10 hops in the worst case (the upper bound is a bit more involved than log2(size))

Didn't look into the specifics of CAVL yet, but I suppose it's more memory efficient then allocating 128 pointers.

This is true. From the time complexity perspective though, CAVL is less desirable because O(1) array lookup is much easier to analyze and validate than O(log n) tree search. We can certainly go this way but should we really?

pavel-kirienko and others added 5 commits November 28, 2021 01:13
Adds a build option `CANARD_CRC_TABLE` which replaces the
runtime-computed CRC with a static table. This option adds ~512 bytes
ROM but reduces computation time significantly.

Fixes #185 

CI: disable sonarcloud on forks

Co-authored-by: Pavel Kirienko <pavel.kirienko@gmail.com>
Fixes #143 

Co-authored-by: Pavel Kirienko <pavel.kirienko@gmail.com>
Adds helper API functions for configuring CAN controller hardware acceptance filters.

Closes #169

Co-authored-by: Pavel Kirienko <pavel.kirienko@gmail.com>
@pavel-kirienko pavel-kirienko merged commit cf0a8bc into master Dec 4, 2021
@pavel-kirienko pavel-kirienko deleted the v2 branch December 4, 2021 20:56
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 4, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment