Skip to content

Commit 40ff30f

Browse files
update the filtering API
1 parent be82e49 commit 40ff30f

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

.idea/dictionaries/project.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libcanard/canard.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,15 +1546,15 @@ static canard_subscription_t* rx_route(const canard_t* const self, const frame_t
15461546
if ((fr->dst != CANARD_NODE_ID_ANONYMOUS) && (fr->dst != self->node_id)) {
15471547
return NULL; // misfiltered
15481548
}
1549-
return (canard_subscription_t*)cavl2_find(
1549+
return (canard_subscription_t*)(void*)cavl2_find(
15501550
self->rx.subscriptions[fr->kind], &fr->port_id, rx_subscription_cavl_compare);
15511551
}
15521552

15531553
// Recompute the filter configuration and apply.
15541554
// Must be invoked after modification of the subscription set and after the local node-ID is changed.
15551555
static void rx_filter_configure(const canard_t* const self)
15561556
{
1557-
if (self->vtable->filter == NULL) {
1557+
if ((self->vtable->filter == NULL) || (self->rx.filter_count == 0)) {
15581558
return; // No filtering support, nothing to do.
15591559
}
15601560
(void)self;
@@ -1602,18 +1602,16 @@ bool canard_new(canard_t* const self,
16021602
const canard_mem_set_t memory,
16031603
const size_t tx_queue_capacity,
16041604
const uint64_t prng_seed,
1605-
const size_t filter_count,
1606-
canard_filter_t* const filter_storage)
1605+
const size_t filter_count)
16071606
{
16081607
const bool ok = (self != NULL) && (vtable != NULL) && (vtable->now != NULL) && (vtable->tx != NULL) &&
16091608
mem_valid(memory.tx_transfer) && mem_valid(memory.tx_frame) && mem_valid(memory.rx_session) &&
1610-
mem_valid(memory.rx_payload) && ((filter_count == 0U) || (filter_storage != NULL));
1609+
mem_valid(memory.rx_payload);
16111610
if (ok) {
16121611
(void)memset(self, 0, sizeof(*self));
16131612
self->tx.fd = true;
16141613
self->tx.queue_capacity = tx_queue_capacity;
1615-
self->rx.filter_count = filter_count;
1616-
self->rx.filters = filter_storage;
1614+
self->rx.filter_count = (vtable->filter == NULL) ? 0 : smaller(filter_count, CANARD_FILTERS_MAX);
16171615
self->mem = memory;
16181616
self->prng_state = prng_seed ^ (uintptr_t)self;
16191617
self->vtable = vtable;

libcanard/canard.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ extern "C"
8080
#define CANARD_MTU_CAN_CLASSIC 8U
8181
#define CANARD_MTU_CAN_FD 64U
8282

83+
/// If CAN acceptance filter configuration is enabled, the library will be able to configure at most this many filters.
84+
/// The application can configure a smaller limit at runtime if necessary; this value only affects a stack array size.
85+
/// The default value is large enough to utilize all available filters in most CAN controllers out there,
86+
/// considering that we use filters in the extended ID&mask mode which tends to consume more hardware resources.
87+
/// This value can be reduced to reduce the stack pressure on the filter configuration update path,
88+
/// or increased if more filters are available (e.g., Bosch M_CAN or ST FDCAN support up to 64, SocketCAN up to 512).
89+
#ifndef CANARD_FILTERS_MAX
90+
#define CANARD_FILTERS_MAX 32U
91+
#endif
92+
8393
/// All valid transfer kind and version combinations.
8494
typedef enum canard_kind_t
8595
{
@@ -293,7 +303,8 @@ typedef struct canard_vtable_t
293303

294304
/// Reconfigure the acceptance filters of the CAN controller hardware.
295305
/// The prior configuration, if any, is replaced entirely.
296-
/// filter_count is guaranteed to not exceed the value given at initialization.
306+
/// filter_count is guaranteed to not exceed the value given at initialization and CANARD_FILTERS_MAX,
307+
/// whichever is smaller.
297308
/// This function may be NULL if the CAN controller/driver does not support filtering or it is not desired.
298309
/// The implementation is assumed to be infallible; if error handling is necessary, it must be implemented
299310
/// on the application side, perhaps with retries.
@@ -345,9 +356,7 @@ struct canard_t
345356
{
346357
canard_tree_t* subscriptions[CANARD_KIND_COUNT];
347358
canard_list_t list_session_by_animation; ///< Oldest at the head.
348-
349-
size_t filter_count;
350-
canard_filter_t* filters; ///< Storage provided by the user.
359+
size_t filter_count; ///< At most CANARD_FILTERS_MAX.
351360
} rx;
352361

353362
/// Error counters incremented automatically when the corresponding error condition occurs.
@@ -388,9 +397,9 @@ struct canard_t
388397
/// and collisions, and will automatically migrate to a free node-ID shall a collision be detected.
389398
/// If manual allocation is desired, use the corresponding function to set the node-ID after initialization.
390399
///
391-
/// The filter storage is an array of filters that is used by the library to automatically set up the acceptance
392-
/// filters when the RX pipeline is reconfigured. The filter count equals the storage size. The storage must
393-
/// outlive the library instance. It is possible to pass zero filters & NULL if filtering is unneeded/unsupported.
400+
/// The filter count is the number of CAN acceptance filters that the library can utilize. If there are fewer filters
401+
/// than subscriptions, similar filters will be coalesced. The value will be clamped to CANARD_FILTERS_MAX.
402+
/// It is possible to pass zero filters if filtering is unneeded/unsupported.
394403
///
395404
/// CAN FD mode is selected by default for outgoing frames; override the fd flag to change the mode if needed.
396405
///
@@ -400,8 +409,7 @@ bool canard_new(canard_t* const self,
400409
const canard_mem_set_t memory,
401410
const size_t tx_queue_capacity,
402411
const uint64_t prng_seed,
403-
const size_t filter_count,
404-
canard_filter_t* const filter_storage);
412+
const size_t filter_count);
405413

406414
/// The application MUST destroy all subscriptions before invoking this (this is asserted).
407415
/// The TX queue will be purged automatically if not empty.

tests/src/test_api_tx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static void init_with_capture_node_id(canard_t* const self, tx_capture_t* const
102102
capture->now = 0;
103103
capture->accept_tx = true;
104104
capture->count = 0;
105-
TEST_ASSERT_TRUE(canard_new(self, &capture_vtable, make_std_memory(), 16U, 1234U, 0U, nullptr));
105+
TEST_ASSERT_TRUE(canard_new(self, &capture_vtable, make_std_memory(), 16U, 1234U, 0U));
106106
TEST_ASSERT_TRUE(canard_set_node_id(self, node_id));
107107
self->user_context = capture;
108108
}
@@ -117,7 +117,7 @@ static void test_canard_pending_ifaces()
117117
{
118118
canard_t self = {};
119119
const canard_mem_set_t mem = make_std_memory();
120-
TEST_ASSERT_TRUE(canard_new(&self, &test_vtable, mem, 16, 1234, 0, nullptr));
120+
TEST_ASSERT_TRUE(canard_new(&self, &test_vtable, mem, 16, 1234, 0));
121121

122122
const canard_bytes_chain_t payload = { .bytes = { .size = 0, .data = nullptr }, .next = nullptr };
123123
TEST_ASSERT_EQUAL_UINT8(0U, canard_pending_ifaces(&self));

0 commit comments

Comments
 (0)