245 lines
7.0 KiB
C
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_ */
|