zephyr/include/net/can.h
Henrik Brix Andersen 8af4bb722d drivers: can: rename API functions for better consistency
Rename a few CAN API functions for clarity and consistency with other
Zephyr RTOS APIs.

CAN_DEFINE_MSGQ() becomes CAN_MSGQ_DEFINE() to match K_MSGQ_DEFINE().

can_attach_isr() becomes can_add_rx_filter() since a filter callback
function is not an interrupt service routine (although it is called in
isr context). The word "attach" is replaced with "add" since filters are
added, not attached. This matches the terminology used is other Zephyr
APIs better.

can_detach() becomes can_remove_rx_filter() to pair with
can_add_rx_filter().

can_attach_msgq() becomes can_add_rx_filter_msgq() and documentation is
updated to mention its relationship with can_add_rx_filter().

can_register_state_change_isr() becomes can_set_state_change_callback()
since a state change callback function is not an interrupt service
routine (although it is called in isr context). The word "register" is
replaced with "set" since only one state change callback can be in
place.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2022-01-10 10:44:37 +01:00

245 lines
7.0 KiB
C

/** @file
* @brief IPv6 Networking over CAN definitions.
*
* Definitions for IPv6 Networking over CAN support.
*/
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_NET_CAN_H_
#define ZEPHYR_INCLUDE_NET_CAN_H_
#include <zephyr/types.h>
#include <net/net_ip.h>
#include <net/net_if.h>
#include <drivers/can.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief IPv6 over CAN library
* @defgroup net_can Network Core Library
* @ingroup networking
* @{
*/
/**
* CAN L2 driver API. Used by 6loCAN.
*/
/*
* Abbreviations
* BS Block Size
* CAN_DL CAN LL data size
* CF Consecutive Frame
* CTS Continue to send
* DLC Data length code
* FC Flow Control
* FF First Frame
* FS Flow Status
*/
/** @cond INTERNAL_HIDDEN */
#define NET_CAN_DL 8
#define NET_CAN_MTU 0x0FFF
/* 0x3DFF - bit 4 to 10 must not be zero. Also prevent stuffing bit*/
#define NET_CAN_MULTICAST_ADDR 0x3DFF
#define NET_CAN_DAD_ADDR 0x3DFE
#define NET_CAN_ETH_TRANSLATOR_ADDR 0x3DF0
#define NET_CAN_MAX_ADDR 0x3DEF
#define NET_CAN_MIN_ADDR 0x0100
#define CAN_NET_IF_ADDR_MASK 0x3FFF
#define CAN_NET_IF_ADDR_BYTE_LEN 2U
#define CAN_NET_IF_ADDR_DEST_POS 14U
#define CAN_NET_IF_ADDR_DEST_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_DEST_POS)
#define CAN_NET_IF_ADDR_SRC_POS 0U
#define CAN_NET_IF_ADDR_SRC_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_SRC_POS)
#define CAN_NET_IF_ADDR_MCAST_POS 28U
#define CAN_NET_IF_ADDR_MCAST_MASK (1UL << CAN_NET_IF_ADDR_MCAST_POS)
#define CAN_NET_IF_IS_MCAST_BIT (1U << 14)
#define CAN_NET_FILTER_NOT_SET -1
/** @endcond */
/*
* +-----------+ +-----------+
* | | | |
* | IPv6 | | IPv6 |
* | 6LoCAN | | 6LoCAN |
* | | | |
* +----+-+----+ +----+-+----+
* | | | | +---+
* +----+ | | | | / \ +-+
* | | | | | | +--+ / \_/ \
* +++ +---+ +--+----+ +-------+ +--+----+ +--/ \_/ \
* | | \ / | \ / \ / | \ / / |
* | | X | X CAN X | X | Internet |
* | | / \ | / \ / \ | / \ \ /
* +++ +---+ +----+--+ +-------+ +----+--+ +--+ /
* | | +-------------------+
* +----+
*/
struct net_can_api {
/**
* The net_if_api must be placed in first position in this
* struct so that we are compatible with network interface API.
*/
struct net_if_api iface_api;
/** Send a single CAN frame */
int (*send)(const struct device *dev, const struct zcan_frame *frame,
can_tx_callback_t cb, void *cb_arg, k_timeout_t timeout);
/** Add a filter with its callback */
int (*add_rx_filter)(const struct device *dev, can_rx_callback_t cb,
void *cb_arg, const struct zcan_filter *filter);
/** Remove a filter */
void (*remove_rx_filter)(const struct device *dev, int filter_id);
/** Enable or disable the reception of frames for net CAN */
int (*enable)(const struct device *dev, bool enable);
};
/* Make sure that the network interface API is properly setup inside
* net_can_api struct (it is the first one).
*/
BUILD_ASSERT(offsetof(struct net_can_api, iface_api) == 0);
/** @cond INTERNAL_HIDDEN */
#define CANBUS_L2_CTX_TYPE struct net_canbus_context *
/**
* Context for canbus net device.
*/
struct canbus_net_ctx {
/** Filter ID for link layer duplicate address detection. */
int dad_filter_id;
/** Work item for responding to link layer DAD requests. */
struct k_work dad_work;
/** The interface associated with this device */
struct net_if *iface;
/** The link layer address chosen for this interface */
uint16_t ll_addr;
/** TX queue */
struct k_fifo tx_queue;
/** RX error queue */
struct k_fifo rx_err_queue;
/** Queue handler thread */
struct k_thread queue_handler;
/** Queue handler thread stack */
K_KERNEL_STACK_MEMBER(queue_stack, 512);
};
/**
* Canbus link layer addresses have a length of 14 bit for source and destination.
* Both together are 28 bit to fit a CAN extended identifier with 29 bit length.
*/
struct net_canbus_lladdr {
uint16_t addr : 14;
};
/**
* STmin is split in two valid ranges:
* 0-127: 0ms-127ms
* 128-240: Reserved
* 241-249: 100us-900us (multiples of 100us)
* 250- : Reserved
*/
struct canbus_fc_opts {
/** Block size. Number of CF PDUs before next CF is sent */
uint8_t bs;
/**< Minimum separation time. Min time between frames */
uint8_t stmin;
};
/**
* Context for a transmission of messages that didn't fit in a single frame.
* These messages Start with a FF (First Frame) that is in case of unicast
* acknowledged by a FC (Frame Control). After that, one or more CF
* (Consecutive frames) carry the rest of the message.
*/
struct canbus_isotp_tx_ctx {
/** Pkt containing the data to transmit */
struct net_pkt *pkt;
/** Timeout for TX Timeout and separation time */
struct _timeout timeout;
/** Frame Control options received from FC frame */
struct canbus_fc_opts opts;
/** CAN destination address */
struct net_canbus_lladdr dest_addr;
/** Remaining data to transmit in bytes */
uint16_t rem_len;
/** Number of bytes in the tx queue */
int8_t tx_backlog;
/** State of the transmission */
uint8_t state;
/** Actual block number that is transmitted. Counts from BS to 0 */
uint8_t act_block_nr;
/** Number of WAIT frames received */
uint8_t wft;
/** Sequence number that is added to CF */
uint8_t sn : 4;
/** Transmission is multicast */
uint8_t is_mcast : 1;
};
/**
* Context for reception of messages that are not single frames.
* This is the counterpart of the canbus_isotp_tx_ctx.
*/
struct canbus_isotp_rx_ctx {
/** Pkt that is large enough to hold the entire message */
struct net_pkt *pkt;
/** Timeout for RX timeout*/
struct _timeout timeout;
/** Remaining data to receive. Goes from message length to zero */
uint16_t rem_len;
/** State of the reception */
uint8_t state;
/** Number of frames received in this block. Counts from BS to 0 */
uint8_t act_block_nr;
/** Number of WAIT frames transmitted */
uint8_t wft;
/** Expected sequence number in CF */
uint8_t sn : 4;
};
/**
* Initialization of the canbus L2.
*
* This function starts the TX workqueue and does some initialization.
*/
void net_6locan_init(struct net_if *iface);
/**
* Ethernet frame input function for Ethernet to 6LoCAN translation
*
* This function checks the destination link layer address for addresses
* that has to be forwarded. Frames that need to be forwarded are forwarded here.
*/
enum net_verdict net_canbus_translate_eth_frame(struct net_if *iface,
struct net_pkt *pkt);
/** @endcond */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_NET_CAN_H_ */