can: Add Linux compatible frame and filter structs
Add new "struct can_frame" which is compatible with Linux so that it is easier to port socket-can applications from Linux. Rename existing can_filter to can_msg_filter so that the name will not conflict with Linux compatible can_filter struct. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
c2d5e7b01c
commit
58f3ae5334
|
@ -578,21 +578,21 @@ static inline void can_stm32_set_mode_scale(enum can_filter_type filter_type,
|
|||
*scale_reg |= scale_reg_bit;
|
||||
}
|
||||
|
||||
static inline u32_t can_generate_std_mask(const struct can_filter *filter)
|
||||
static inline u32_t can_generate_std_mask(const struct can_msg_filter *filter)
|
||||
{
|
||||
return (filter->std_id_mask << CAN_FIRX_STD_ID_POS) |
|
||||
(filter->rtr_mask << CAN_FIRX_STD_RTR_POS) |
|
||||
(1U << CAN_FIRX_STD_IDE_POS);
|
||||
}
|
||||
|
||||
static inline u32_t can_generate_ext_mask(const struct can_filter *filter)
|
||||
static inline u32_t can_generate_ext_mask(const struct can_msg_filter *filter)
|
||||
{
|
||||
return (filter->ext_id_mask << CAN_FIRX_EXT_EXT_ID_POS) |
|
||||
(filter->rtr_mask << CAN_FIRX_EXT_RTR_POS) |
|
||||
(1U << CAN_FIRX_EXT_IDE_POS);
|
||||
}
|
||||
|
||||
static inline u32_t can_generate_std_id(const struct can_filter *filter)
|
||||
static inline u32_t can_generate_std_id(const struct can_msg_filter *filter)
|
||||
{
|
||||
|
||||
return (filter->std_id << CAN_FIRX_STD_ID_POS) |
|
||||
|
@ -600,14 +600,14 @@ static inline u32_t can_generate_std_id(const struct can_filter *filter)
|
|||
|
||||
}
|
||||
|
||||
static inline u32_t can_generate_ext_id(const struct can_filter *filter)
|
||||
static inline u32_t can_generate_ext_id(const struct can_msg_filter *filter)
|
||||
{
|
||||
return (filter->ext_id << CAN_FIRX_EXT_EXT_ID_POS) |
|
||||
(filter->rtr << CAN_FIRX_EXT_RTR_POS) |
|
||||
(1U << CAN_FIRX_EXT_IDE_POS);
|
||||
}
|
||||
|
||||
static inline int can_stm32_set_filter(const struct can_filter *filter,
|
||||
static inline int can_stm32_set_filter(const struct can_msg_filter *filter,
|
||||
struct can_stm32_data *device_data,
|
||||
CAN_TypeDef *can,
|
||||
int *filter_index)
|
||||
|
@ -739,7 +739,7 @@ done:
|
|||
|
||||
|
||||
static inline int can_stm32_attach(struct device *dev, void *response_ptr,
|
||||
const struct can_filter *filter,
|
||||
const struct can_msg_filter *filter,
|
||||
int *filter_index)
|
||||
{
|
||||
const struct can_stm32_config *cfg = DEV_CFG(dev);
|
||||
|
@ -758,7 +758,7 @@ static inline int can_stm32_attach(struct device *dev, void *response_ptr,
|
|||
}
|
||||
|
||||
int can_stm32_attach_msgq(struct device *dev, struct k_msgq *msgq,
|
||||
const struct can_filter *filter)
|
||||
const struct can_msg_filter *filter)
|
||||
{
|
||||
int filter_nr;
|
||||
int filter_index;
|
||||
|
@ -772,7 +772,7 @@ int can_stm32_attach_msgq(struct device *dev, struct k_msgq *msgq,
|
|||
}
|
||||
|
||||
int can_stm32_attach_isr(struct device *dev, can_rx_callback_t isr,
|
||||
const struct can_filter *filter)
|
||||
const struct can_msg_filter *filter)
|
||||
{
|
||||
struct can_stm32_data *data = DEV_DATA(dev);
|
||||
int filter_nr;
|
||||
|
|
131
include/can.h
131
include/can.h
|
@ -33,6 +33,7 @@ extern "C" {
|
|||
#define CAN_STD_ID_MASK CAN_MAX_STD_ID
|
||||
#define CAN_EXT_ID_MASK (0x1FFFFFFF)
|
||||
#define CAN_MAX_DLC (8)
|
||||
#define CAN_MAX_DLEN 8
|
||||
|
||||
/* CAN_TX_* are the error flags from tx_callback and send.*/
|
||||
/** send successfully */
|
||||
|
@ -96,8 +97,49 @@ enum can_mode {
|
|||
CAN_SILENT_LOOPBACK_MODE
|
||||
};
|
||||
|
||||
/*
|
||||
* Controller Area Network Identifier structure for Linux compatibility.
|
||||
*
|
||||
* The fields in this type are:
|
||||
*
|
||||
* bit 0-28 : CAN identifier (11/29 bit)
|
||||
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
|
||||
* bit 30 : remote transmission request flag (1 = rtr frame)
|
||||
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
|
||||
*/
|
||||
typedef u32_t canid_t;
|
||||
|
||||
/**
|
||||
* @brief can message structure
|
||||
* @brief CAN frame structure that is compatible with Linux. This is mainly
|
||||
* used by Socket CAN code.
|
||||
*
|
||||
* @details Used to pass CAN messages from userspace to the socket CAN and vice
|
||||
* versa.
|
||||
*/
|
||||
struct can_frame {
|
||||
/** 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||
canid_t can_id;
|
||||
|
||||
/** The length of the message */
|
||||
u8_t can_dlc;
|
||||
|
||||
/** The message data */
|
||||
u8_t data[CAN_MAX_DLEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CAN filter that is compatible with Linux. This is mainly used by
|
||||
* Socket CAN code.
|
||||
*
|
||||
* @details A filter matches, when "received_can_id & mask == can_id & mask"
|
||||
*/
|
||||
struct can_filter {
|
||||
canid_t can_id;
|
||||
canid_t can_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CAN message structure
|
||||
*
|
||||
* Used to pass can messages from userspace to the driver and
|
||||
* from driver to userspace
|
||||
|
@ -127,7 +169,7 @@ struct can_msg {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* @brief can filter structure
|
||||
* @brief CAN filter structure
|
||||
*
|
||||
* Used to pass can identifier filter information to the driver.
|
||||
* rtr_mask and *_id_mask are used to mask bits of the rtr and id fields.
|
||||
|
@ -135,7 +177,7 @@ struct can_msg {
|
|||
* field don't care for the filter matching.
|
||||
*
|
||||
*/
|
||||
struct can_filter {
|
||||
struct can_msg_filter {
|
||||
/** Indicates the identifier type (standard or extended)
|
||||
* use can_ide enum for assignment
|
||||
*/
|
||||
|
@ -218,13 +260,14 @@ typedef int (*can_send_t)(struct device *dev, struct can_msg *msg,
|
|||
* *
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param msgq Pointer to the already initialized message queue.
|
||||
* @param filter Pointer to a can_filter structure defining the id filtering.
|
||||
* @param filter Pointer to a can_msg_filter structure defining the id
|
||||
* filtering.
|
||||
*
|
||||
* @retval filter id on success.
|
||||
* @retval CAN_NO_FREE_FILTER if there is no filter left.
|
||||
*/
|
||||
typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q,
|
||||
const struct can_filter *filter);
|
||||
const struct can_msg_filter *filter);
|
||||
|
||||
/**
|
||||
* @brief Attach an isr callback function to a single or group of identifiers.
|
||||
|
@ -238,13 +281,14 @@ typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q,
|
|||
* *
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param isr Callback function pointer.
|
||||
* @param filter Pointer to a can_filter structure defining the id filtering.
|
||||
* @param filter Pointer to a can_msg_filter structure defining the id
|
||||
* filtering.
|
||||
*
|
||||
* @retval filter id on success.
|
||||
* @retval CAN_NO_FREE_FILTER if there is no filter left.
|
||||
*/
|
||||
typedef int (*can_attach_isr_t)(struct device *dev, can_rx_callback_t isr,
|
||||
const struct can_filter *filter);
|
||||
const struct can_msg_filter *filter);
|
||||
|
||||
/**
|
||||
* @brief Detach an isr or message queue from the identifier filtering.
|
||||
|
@ -325,11 +369,11 @@ static inline int can_write(struct device *dev, u8_t *data, u8_t length,
|
|||
|
||||
|
||||
__syscall int can_attach_msgq(struct device *dev, struct k_msgq *msg_q,
|
||||
const struct can_filter *filter);
|
||||
const struct can_msg_filter *filter);
|
||||
|
||||
static inline int _impl_can_attach_msgq(struct device *dev,
|
||||
struct k_msgq *msg_q,
|
||||
const struct can_filter *filter)
|
||||
const struct can_msg_filter *filter)
|
||||
{
|
||||
const struct can_driver_api *api = dev->driver_api;
|
||||
|
||||
|
@ -338,10 +382,10 @@ static inline int _impl_can_attach_msgq(struct device *dev,
|
|||
|
||||
|
||||
__syscall int can_attach_isr(struct device *dev, can_rx_callback_t isr,
|
||||
const struct can_filter *filter);
|
||||
const struct can_msg_filter *filter);
|
||||
static inline int _impl_can_attach_isr(struct device *dev,
|
||||
can_rx_callback_t isr,
|
||||
const struct can_filter *filter)
|
||||
const struct can_msg_filter *filter)
|
||||
{
|
||||
const struct can_driver_api *api = dev->driver_api;
|
||||
|
||||
|
@ -370,6 +414,71 @@ static inline int _impl_can_configure(struct device *dev, enum can_mode mode,
|
|||
return api->configure(dev, mode, bitrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converter that translates betwen can_frame and can_msg structs.
|
||||
*
|
||||
* @param frame Pointer to can_frame struct.
|
||||
* @param msg Pointer to can_msg struct.
|
||||
*/
|
||||
static inline void can_copy_frame_to_msg(struct can_frame *frame,
|
||||
struct can_msg *msg)
|
||||
{
|
||||
msg->id_type = (frame->can_id & BIT(31)) >> 31;
|
||||
msg->rtr = (frame->can_id & BIT(30)) >> 30;
|
||||
msg->ext_id = frame->can_id & BIT_MASK(29);
|
||||
msg->dlc = frame->can_dlc;
|
||||
memcpy(msg->data, frame->data, sizeof(msg->data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converter that translates betwen can_msg and can_frame structs.
|
||||
*
|
||||
* @param msg Pointer to can_msg struct.
|
||||
* @param frame Pointer to can_frame struct.
|
||||
*/
|
||||
static inline void can_copy_msg_to_frame(struct can_msg *msg,
|
||||
struct can_frame *frame)
|
||||
{
|
||||
frame->can_id = (msg->id_type << 31) | (msg->rtr << 30) | msg->ext_id;
|
||||
frame->can_dlc = msg->dlc;
|
||||
memcpy(frame->data, msg->data, sizeof(frame->data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converter that translates betwen can_filter and can_msg_filter
|
||||
* structs.
|
||||
*
|
||||
* @param filter Pointer to can_filter struct.
|
||||
* @param msg_filter Pointer to can_msg_filter struct.
|
||||
*/
|
||||
static inline
|
||||
void can_copy_filter_to_msg_filter(struct can_filter *filter,
|
||||
struct can_msg_filter *msg_filter)
|
||||
{
|
||||
msg_filter->id_type = (filter->can_id & BIT(31)) >> 31;
|
||||
msg_filter->rtr = (filter->can_id & BIT(30)) >> 30;
|
||||
msg_filter->ext_id = filter->can_id & BIT_MASK(29);
|
||||
msg_filter->rtr_mask = (filter->can_mask & BIT(30)) >> 30;
|
||||
msg_filter->ext_id_mask = filter->can_mask & BIT_MASK(29);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converter that translates betwen can_msg_filter and can_filter
|
||||
* structs.
|
||||
*
|
||||
* @param msg_filter Pointer to can_msg_filter struct.
|
||||
* @param filter Pointer to can_filter struct.
|
||||
*/
|
||||
static inline
|
||||
void can_copy_msg_filter_to_filter(struct can_msg_filter *msg_filter,
|
||||
struct can_filter *filter)
|
||||
{
|
||||
filter->can_id = (msg_filter->id_type << 31) |
|
||||
(msg_filter->rtr << 30) | msg_filter->ext_id;
|
||||
filter->can_mask = (msg_filter->rtr_mask << 30) |
|
||||
(msg_filter->id_type << 31) | msg_filter->ext_id_mask;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -109,7 +109,7 @@ void tx_thread(void *can_dev_param, void *unused2, void *unused3)
|
|||
void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
|
||||
{
|
||||
struct can_msg msg;
|
||||
const struct can_filter filter = {
|
||||
const struct can_msg_filter filter = {
|
||||
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
.ext_id = STR_MSG_ID,
|
||||
|
@ -129,7 +129,7 @@ void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
|
|||
|
||||
void led_thread(void *msgq, void *can_dev_param, void *gpio_dev_param)
|
||||
{
|
||||
const struct can_filter filter = {
|
||||
const struct can_msg_filter filter = {
|
||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
.std_id = LED_MSG_ID,
|
||||
|
@ -181,7 +181,7 @@ void rx_button_isr(struct can_msg *msg)
|
|||
|
||||
void main(void)
|
||||
{
|
||||
const struct can_filter filter = {
|
||||
const struct can_msg_filter filter = {
|
||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
.std_id = BUTTON_MSG_ID,
|
||||
|
|
|
@ -90,7 +90,7 @@ static void rx(int fd)
|
|||
|
||||
static int setup_socket(void)
|
||||
{
|
||||
const struct can_filter filter = {
|
||||
const struct can_msg_filter filter = {
|
||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
.std_id = 0x1,
|
||||
|
|
Loading…
Reference in a new issue