Skip to content

Commit

Permalink
add acceptance filter configuration helper
Browse files Browse the repository at this point in the history
  • Loading branch information
coderkalyan committed Jul 19, 2021
1 parent 2a11617 commit 0b4d95d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
30 changes: 30 additions & 0 deletions libcanard/canard.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,3 +1099,33 @@ int8_t canardRxUnsubscribe(CanardInstance* const ins,
}
return out;
}

CanardAcceptanceFilterConfig canardMakeAcceptanceFilterConfigForSubject(const CanardPortID subject_id)
{
CanardAcceptanceFilterConfig out = {0};

out.extended_can_id = subject_id << OFFSET_SUBJECT_ID;
out.extended_mask = FLAG_SERVICE_NOT_MESSAGE | FLAG_RESERVED_07 | (CANARD_SUBJECT_ID_MAX << OFFSET_SUBJECT_ID);

return out;
}

CanardAcceptanceFilterConfig canardMakeAcceptanceFilterConfigForService(const CanardPortID service_id, const CanardNodeID local_node_id)
{
CanardAcceptanceFilterConfig out = {0};

out.extended_can_id = FLAG_SERVICE_NOT_MESSAGE | (service_id << OFFSET_SERVICE_ID) | (local_node_id << OFFSET_DST_NODE_ID);
out.extended_mask = FLAG_SERVICE_NOT_MESSAGE | FLAG_RESERVED_23 | (CANARD_SERVICE_ID_MAX << OFFSET_SERVICE_ID) | (CANARD_NODE_ID_MAX << OFFSET_DST_NODE_ID);

return out;
}

CanardAcceptanceFilterConfig canardConsolidateAcceptanceFilterConfigs(const CanardAcceptanceFilterConfig *a, const CanardAcceptanceFilterConfig *b)
{
CanardAcceptanceFilterConfig out = {0};

out.extended_mask = a->extended_mask & b->extended_mask & ~(a->extended_can_id ^ b->extended_can_id);
out.extended_can_id = a->extended_can_id & out.extended_mask;

return out;
}
47 changes: 47 additions & 0 deletions libcanard/canard.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,19 @@ struct CanardInstance
struct CanardInternalTxQueueItem* _tx_queue;
};

/// CAN acceptance filter configuration with an extended 29-bit ID utilizing an ID + mask filter scheme.
/// Filter configuration can be programmed into a CAN controller to filter out irrelevant messages in hardware.
/// This allows the software application to reduce CPU load spent on processing irrelevant messages.
typedef struct CanardAcceptanceFilterConfig {
/// 29-bit extended ID. Defines the extended CAN ID to filter incoming frames against.
/// The bits above 29-th shall be zero.
uint32_t extended_can_id;
/// 29-bit extended mask. Defines the bitmask used to enable/disable bits used to filter messages.
/// Only bits that are enabled are compared to the extended_can_id for filtering.
/// The bits above 29-th shall be zero.
uint32_t extended_mask;
} CanardAcceptanceFilterConfig;

/// Construct a new library instance.
/// The default values will be assigned as specified in the structure field documentation.
/// If any of the pointers are NULL, the behavior is undefined.
Expand Down Expand Up @@ -622,6 +635,40 @@ int8_t canardRxUnsubscribe(CanardInstance* const ins,
const CanardTransferKind transfer_kind,
const CanardPortID port_id);


/// Generate an acceptance filter configuration to accept a specific subject ID.
///
/// Complex applications will likely subscribe to more subject IDs than there are
/// acceptance filters available in the CAN hardware. In this case, the application
/// should implement filter consolidation. See canardConsolidateAcceptanceFilterConfigs()
/// as well as the UAVCAN specification for details.
CanardAcceptanceFilterConfig canardMakeAcceptanceFilterConfigForSubject(const CanardPortID subject_id);

/// Generate an acceptance filter configuration to accept a specific service.
///
/// Complex applications will likely subscribe to more subject IDs than there are
/// acceptance filters available in the CAN hardware. In this case, the application
/// should implement filter consolidation. See canardConsolidateAcceptanceFilterConfigs()
/// as well as the UAVCAN specification for details.
CanardAcceptanceFilterConfig canardMakeAcceptanceFilterConfigForService(const CanardPortID service_id, const CanardNodeID local_node_id);

/// Consolidate two acceptance filter configurations into a single configuration.
///
/// Complex applications will likely subscribe to more subject IDs than there are
/// acceptance filters available in the CAN hardware. In this case, the application
/// should implement filter consolidation. While this may make it impossible to create
/// a 'perfect' filter that only accepts desired subject IDs, the application should apply
/// consolidation in a manner that minimizes the number of undesired messages that pass
/// through the hardware acceptance filters and require software filtering (implemented by canardRxSubscribe).
///
/// While optimal choice of filter consildation is a function of the number of available hardware filters,
/// the set of transfers needed by the application, and the expected frequency of occurence
/// of all possible distinct transfers on the bus, it is possible to generate a quasi-optimal configuration
/// if information about the frequency of occurence of different transfers is not known.
/// For details, see the "Automatic hardware acceptance filter configuration" note under the UAVCAN/CAN section
/// in the Transport Layer chapter of the UAVCAN specification.
CanardAcceptanceFilterConfig canardConsolidateAcceptanceFilterConfigs(const CanardAcceptanceFilterConfig *a, const CanardAcceptanceFilterConfig *b);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 0b4d95d

Please sign in to comment.