drivers: can: remove run-time RTR filtering, add build-time RTR filter
A growing number of CAN controllers do not have support for individual RX hardware filters based on the Remote Transmission Request (RTR) bit. This leads to various work-arounds on the driver level mixing hardware and software filtering. As the use of RTR frames is discouraged by CAN in Automation (CiA) - and not even supported by newer standards, e.g. CAN FD - this often leads to unnecessary overhead, added complexity, and worst-case to non-portable behavior between various CAN controller drivers. Instead, move to a simpler approach where the ability to accept/reject RTR frames is globally configured via Kconfig. By default, all incoming RTR frames are rejected at the driver level, a setting which can be supported in hardware by most in-tree CAN controllers drivers. Legacy applications or protocol implementations, where RTR reception is required, can now select CONFIG_CAN_ACCEPT_RTR to accept incoming RTR frames matching added CAN filters. These applications or protocols will need to distinguish between RTR and data frames in their respective CAN RX frame handling routines. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
c5b7aabc06
commit
3436c93387
29 changed files with 243 additions and 235 deletions
|
@ -96,6 +96,11 @@ static void canopen_rx_callback(const struct device *dev, struct can_frame *fram
|
|||
}
|
||||
|
||||
if (((frame->id ^ buffer->ident) & buffer->mask) == 0U) {
|
||||
#ifdef CONFIG_CAN_ACCEPT_RTR
|
||||
if (buffer->rtr && ((frame->flags & CAN_FRAME_RTR) == 0U)) {
|
||||
continue;
|
||||
}
|
||||
#endif /* CONFIG_CAN_ACCEPT_RTR */
|
||||
rxMsg.ident = frame->id;
|
||||
rxMsg.DLC = frame->dlc;
|
||||
memcpy(rxMsg.data, frame->data, frame->dlc);
|
||||
|
@ -310,7 +315,18 @@ CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t *CANmodule, uint16_t index,
|
|||
buffer->ident = ident;
|
||||
buffer->mask = mask;
|
||||
|
||||
filter.flags = (rtr ? CAN_FILTER_RTR : CAN_FILTER_DATA);
|
||||
#ifndef CONFIG_CAN_ACCEPT_RTR
|
||||
if (rtr) {
|
||||
LOG_ERR("request for RTR frames, but RTR frames are rejected");
|
||||
CO_errorReport(CANmodule->em, CO_EM_GENERIC_SOFTWARE_ERROR,
|
||||
CO_EMC_SOFTWARE_INTERNAL, 0);
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
#else /* !CONFIG_CAN_ACCEPT_RTR */
|
||||
buffer->rtr = rtr;
|
||||
#endif /* CONFIG_CAN_ACCEPT_RTR */
|
||||
|
||||
filter.flags = 0U;
|
||||
filter.id = ident;
|
||||
filter.mask = mask;
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ typedef struct canopen_rx {
|
|||
CO_CANrxBufferCallback_t pFunct;
|
||||
uint16_t ident;
|
||||
uint16_t mask;
|
||||
#ifdef CONFIG_CAN_ACCEPT_RTR
|
||||
bool rtr;
|
||||
#endif /* CONFIG_CAN_ACCEPT_RTR */
|
||||
} CO_CANrx_t;
|
||||
|
||||
typedef struct canopen_tx {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue