zephyr/modules/canopennode/CO_driver_target.h
Henrik Brix Andersen 3436c93387 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>
2024-01-21 11:00:31 +01:00

128 lines
2.9 KiB
C

/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_MODULES_CANOPENNODE_CO_DRIVER_H
#define ZEPHYR_MODULES_CANOPENNODE_CO_DRIVER_H
/*
* Zephyr RTOS CAN driver interface and configuration for CANopenNode
* CANopen protocol stack.
*
* See CANopenNode/stack/drvTemplate/CO_driver.h for API description.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/toolchain.h>
#include <zephyr/dsp/types.h> /* float32_t, float64_t */
/* Use static variables instead of calloc() */
#define CO_USE_GLOBALS
/* Use Zephyr provided crc16 implementation */
#define CO_USE_OWN_CRC16
/* Use SDO buffer size from Kconfig */
#define CO_SDO_BUFFER_SIZE CONFIG_CANOPENNODE_SDO_BUFFER_SIZE
/* Use trace buffer size from Kconfig */
#define CO_TRACE_BUFFER_SIZE_FIXED CONFIG_CANOPENNODE_TRACE_BUFFER_SIZE
#ifdef CONFIG_CANOPENNODE_LEDS
#define CO_USE_LEDS 1
#endif
#ifdef CONFIG_LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#else
#define CO_BIG_ENDIAN
#endif
typedef bool bool_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
BUILD_ASSERT(sizeof(float32_t) >= 4);
BUILD_ASSERT(sizeof(float64_t) >= 8);
typedef struct canopen_rx_msg {
uint8_t data[8];
uint16_t ident;
uint8_t DLC;
} CO_CANrxMsg_t;
typedef void (*CO_CANrxBufferCallback_t)(void *object,
const CO_CANrxMsg_t *message);
typedef struct canopen_rx {
int filter_id;
void *object;
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 {
uint8_t data[8];
uint16_t ident;
uint8_t DLC;
bool_t rtr : 1;
bool_t bufferFull : 1;
bool_t syncFlag : 1;
} CO_CANtx_t;
typedef struct canopen_module {
const struct device *dev;
CO_CANrx_t *rx_array;
CO_CANtx_t *tx_array;
uint16_t rx_size;
uint16_t tx_size;
uint32_t errors;
void *em;
bool_t configured : 1;
bool_t CANnormal : 1;
bool_t first_tx_msg : 1;
} CO_CANmodule_t;
void canopen_send_lock(void);
void canopen_send_unlock(void);
#define CO_LOCK_CAN_SEND() canopen_send_lock()
#define CO_UNLOCK_CAN_SEND() canopen_send_unlock()
void canopen_emcy_lock(void);
void canopen_emcy_unlock(void);
#define CO_LOCK_EMCY() canopen_emcy_lock()
#define CO_UNLOCK_EMCY() canopen_emcy_unlock()
void canopen_od_lock(void);
void canopen_od_unlock(void);
#define CO_LOCK_OD() canopen_od_lock()
#define CO_UNLOCK_OD() canopen_od_unlock()
/*
* CANopenNode RX callbacks run in interrupt context, no memory
* barrier needed.
*/
#define CANrxMemoryBarrier()
#define IS_CANrxNew(rxNew) ((uintptr_t)rxNew)
#define SET_CANrxNew(rxNew) { CANrxMemoryBarrier(); rxNew = (void *)1L; }
#define CLEAR_CANrxNew(rxNew) { CANrxMemoryBarrier(); rxNew = (void *)0L; }
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_MODULES_CANOPENNODE_CO_DRIVER_H */