Skip to content

Commit 58f3ae5

Browse files
jukkarnashif
authored andcommitted
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>
1 parent c2d5e7b commit 58f3ae5

File tree

4 files changed

+132
-23
lines changed

4 files changed

+132
-23
lines changed

drivers/can/stm32_can.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -578,36 +578,36 @@ static inline void can_stm32_set_mode_scale(enum can_filter_type filter_type,
578578
*scale_reg |= scale_reg_bit;
579579
}
580580

581-
static inline u32_t can_generate_std_mask(const struct can_filter *filter)
581+
static inline u32_t can_generate_std_mask(const struct can_msg_filter *filter)
582582
{
583583
return (filter->std_id_mask << CAN_FIRX_STD_ID_POS) |
584584
(filter->rtr_mask << CAN_FIRX_STD_RTR_POS) |
585585
(1U << CAN_FIRX_STD_IDE_POS);
586586
}
587587

588-
static inline u32_t can_generate_ext_mask(const struct can_filter *filter)
588+
static inline u32_t can_generate_ext_mask(const struct can_msg_filter *filter)
589589
{
590590
return (filter->ext_id_mask << CAN_FIRX_EXT_EXT_ID_POS) |
591591
(filter->rtr_mask << CAN_FIRX_EXT_RTR_POS) |
592592
(1U << CAN_FIRX_EXT_IDE_POS);
593593
}
594594

595-
static inline u32_t can_generate_std_id(const struct can_filter *filter)
595+
static inline u32_t can_generate_std_id(const struct can_msg_filter *filter)
596596
{
597597

598598
return (filter->std_id << CAN_FIRX_STD_ID_POS) |
599599
(filter->rtr << CAN_FIRX_STD_RTR_POS);
600600

601601
}
602602

603-
static inline u32_t can_generate_ext_id(const struct can_filter *filter)
603+
static inline u32_t can_generate_ext_id(const struct can_msg_filter *filter)
604604
{
605605
return (filter->ext_id << CAN_FIRX_EXT_EXT_ID_POS) |
606606
(filter->rtr << CAN_FIRX_EXT_RTR_POS) |
607607
(1U << CAN_FIRX_EXT_IDE_POS);
608608
}
609609

610-
static inline int can_stm32_set_filter(const struct can_filter *filter,
610+
static inline int can_stm32_set_filter(const struct can_msg_filter *filter,
611611
struct can_stm32_data *device_data,
612612
CAN_TypeDef *can,
613613
int *filter_index)
@@ -739,7 +739,7 @@ static inline int can_stm32_set_filter(const struct can_filter *filter,
739739

740740

741741
static inline int can_stm32_attach(struct device *dev, void *response_ptr,
742-
const struct can_filter *filter,
742+
const struct can_msg_filter *filter,
743743
int *filter_index)
744744
{
745745
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,
758758
}
759759

760760
int can_stm32_attach_msgq(struct device *dev, struct k_msgq *msgq,
761-
const struct can_filter *filter)
761+
const struct can_msg_filter *filter)
762762
{
763763
int filter_nr;
764764
int filter_index;
@@ -772,7 +772,7 @@ int can_stm32_attach_msgq(struct device *dev, struct k_msgq *msgq,
772772
}
773773

774774
int can_stm32_attach_isr(struct device *dev, can_rx_callback_t isr,
775-
const struct can_filter *filter)
775+
const struct can_msg_filter *filter)
776776
{
777777
struct can_stm32_data *data = DEV_DATA(dev);
778778
int filter_nr;

include/can.h

Lines changed: 120 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern "C" {
3333
#define CAN_STD_ID_MASK CAN_MAX_STD_ID
3434
#define CAN_EXT_ID_MASK (0x1FFFFFFF)
3535
#define CAN_MAX_DLC (8)
36+
#define CAN_MAX_DLEN 8
3637

3738
/* CAN_TX_* are the error flags from tx_callback and send.*/
3839
/** send successfully */
@@ -96,8 +97,49 @@ enum can_mode {
9697
CAN_SILENT_LOOPBACK_MODE
9798
};
9899

100+
/*
101+
* Controller Area Network Identifier structure for Linux compatibility.
102+
*
103+
* The fields in this type are:
104+
*
105+
* bit 0-28 : CAN identifier (11/29 bit)
106+
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
107+
* bit 30 : remote transmission request flag (1 = rtr frame)
108+
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
109+
*/
110+
typedef u32_t canid_t;
111+
112+
/**
113+
* @brief CAN frame structure that is compatible with Linux. This is mainly
114+
* used by Socket CAN code.
115+
*
116+
* @details Used to pass CAN messages from userspace to the socket CAN and vice
117+
* versa.
118+
*/
119+
struct can_frame {
120+
/** 32 bit CAN_ID + EFF/RTR/ERR flags */
121+
canid_t can_id;
122+
123+
/** The length of the message */
124+
u8_t can_dlc;
125+
126+
/** The message data */
127+
u8_t data[CAN_MAX_DLEN];
128+
};
129+
99130
/**
100-
* @brief can message structure
131+
* @brief CAN filter that is compatible with Linux. This is mainly used by
132+
* Socket CAN code.
133+
*
134+
* @details A filter matches, when "received_can_id & mask == can_id & mask"
135+
*/
136+
struct can_filter {
137+
canid_t can_id;
138+
canid_t can_mask;
139+
};
140+
141+
/**
142+
* @brief CAN message structure
101143
*
102144
* Used to pass can messages from userspace to the driver and
103145
* from driver to userspace
@@ -127,15 +169,15 @@ struct can_msg {
127169
} __packed;
128170

129171
/**
130-
* @brief can filter structure
172+
* @brief CAN filter structure
131173
*
132174
* Used to pass can identifier filter information to the driver.
133175
* rtr_mask and *_id_mask are used to mask bits of the rtr and id fields.
134176
* If the mask bit is 0, the value of the corresponding bit in the id or rtr
135177
* field don't care for the filter matching.
136178
*
137179
*/
138-
struct can_filter {
180+
struct can_msg_filter {
139181
/** Indicates the identifier type (standard or extended)
140182
* use can_ide enum for assignment
141183
*/
@@ -218,13 +260,14 @@ typedef int (*can_send_t)(struct device *dev, struct can_msg *msg,
218260
* *
219261
* @param dev Pointer to the device structure for the driver instance.
220262
* @param msgq Pointer to the already initialized message queue.
221-
* @param filter Pointer to a can_filter structure defining the id filtering.
263+
* @param filter Pointer to a can_msg_filter structure defining the id
264+
* filtering.
222265
*
223266
* @retval filter id on success.
224267
* @retval CAN_NO_FREE_FILTER if there is no filter left.
225268
*/
226269
typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q,
227-
const struct can_filter *filter);
270+
const struct can_msg_filter *filter);
228271

229272
/**
230273
* @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,
238281
* *
239282
* @param dev Pointer to the device structure for the driver instance.
240283
* @param isr Callback function pointer.
241-
* @param filter Pointer to a can_filter structure defining the id filtering.
284+
* @param filter Pointer to a can_msg_filter structure defining the id
285+
* filtering.
242286
*
243287
* @retval filter id on success.
244288
* @retval CAN_NO_FREE_FILTER if there is no filter left.
245289
*/
246290
typedef int (*can_attach_isr_t)(struct device *dev, can_rx_callback_t isr,
247-
const struct can_filter *filter);
291+
const struct can_msg_filter *filter);
248292

249293
/**
250294
* @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,
325369

326370

327371
__syscall int can_attach_msgq(struct device *dev, struct k_msgq *msg_q,
328-
const struct can_filter *filter);
372+
const struct can_msg_filter *filter);
329373

330374
static inline int _impl_can_attach_msgq(struct device *dev,
331375
struct k_msgq *msg_q,
332-
const struct can_filter *filter)
376+
const struct can_msg_filter *filter)
333377
{
334378
const struct can_driver_api *api = dev->driver_api;
335379

@@ -338,10 +382,10 @@ static inline int _impl_can_attach_msgq(struct device *dev,
338382

339383

340384
__syscall int can_attach_isr(struct device *dev, can_rx_callback_t isr,
341-
const struct can_filter *filter);
385+
const struct can_msg_filter *filter);
342386
static inline int _impl_can_attach_isr(struct device *dev,
343387
can_rx_callback_t isr,
344-
const struct can_filter *filter)
388+
const struct can_msg_filter *filter)
345389
{
346390
const struct can_driver_api *api = dev->driver_api;
347391

@@ -370,6 +414,71 @@ static inline int _impl_can_configure(struct device *dev, enum can_mode mode,
370414
return api->configure(dev, mode, bitrate);
371415
}
372416

417+
/**
418+
* @brief Converter that translates betwen can_frame and can_msg structs.
419+
*
420+
* @param frame Pointer to can_frame struct.
421+
* @param msg Pointer to can_msg struct.
422+
*/
423+
static inline void can_copy_frame_to_msg(struct can_frame *frame,
424+
struct can_msg *msg)
425+
{
426+
msg->id_type = (frame->can_id & BIT(31)) >> 31;
427+
msg->rtr = (frame->can_id & BIT(30)) >> 30;
428+
msg->ext_id = frame->can_id & BIT_MASK(29);
429+
msg->dlc = frame->can_dlc;
430+
memcpy(msg->data, frame->data, sizeof(msg->data));
431+
}
432+
433+
/**
434+
* @brief Converter that translates betwen can_msg and can_frame structs.
435+
*
436+
* @param msg Pointer to can_msg struct.
437+
* @param frame Pointer to can_frame struct.
438+
*/
439+
static inline void can_copy_msg_to_frame(struct can_msg *msg,
440+
struct can_frame *frame)
441+
{
442+
frame->can_id = (msg->id_type << 31) | (msg->rtr << 30) | msg->ext_id;
443+
frame->can_dlc = msg->dlc;
444+
memcpy(frame->data, msg->data, sizeof(frame->data));
445+
}
446+
447+
/**
448+
* @brief Converter that translates betwen can_filter and can_msg_filter
449+
* structs.
450+
*
451+
* @param filter Pointer to can_filter struct.
452+
* @param msg_filter Pointer to can_msg_filter struct.
453+
*/
454+
static inline
455+
void can_copy_filter_to_msg_filter(struct can_filter *filter,
456+
struct can_msg_filter *msg_filter)
457+
{
458+
msg_filter->id_type = (filter->can_id & BIT(31)) >> 31;
459+
msg_filter->rtr = (filter->can_id & BIT(30)) >> 30;
460+
msg_filter->ext_id = filter->can_id & BIT_MASK(29);
461+
msg_filter->rtr_mask = (filter->can_mask & BIT(30)) >> 30;
462+
msg_filter->ext_id_mask = filter->can_mask & BIT_MASK(29);
463+
}
464+
465+
/**
466+
* @brief Converter that translates betwen can_msg_filter and can_filter
467+
* structs.
468+
*
469+
* @param msg_filter Pointer to can_msg_filter struct.
470+
* @param filter Pointer to can_filter struct.
471+
*/
472+
static inline
473+
void can_copy_msg_filter_to_filter(struct can_msg_filter *msg_filter,
474+
struct can_filter *filter)
475+
{
476+
filter->can_id = (msg_filter->id_type << 31) |
477+
(msg_filter->rtr << 30) | msg_filter->ext_id;
478+
filter->can_mask = (msg_filter->rtr_mask << 30) |
479+
(msg_filter->id_type << 31) | msg_filter->ext_id_mask;
480+
}
481+
373482
#ifdef __cplusplus
374483
}
375484
#endif

samples/drivers/CAN/src/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void tx_thread(void *can_dev_param, void *unused2, void *unused3)
109109
void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
110110
{
111111
struct can_msg msg;
112-
const struct can_filter filter = {
112+
const struct can_msg_filter filter = {
113113
.id_type = CAN_EXTENDED_IDENTIFIER,
114114
.rtr = CAN_DATAFRAME,
115115
.ext_id = STR_MSG_ID,
@@ -129,7 +129,7 @@ void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
129129

130130
void led_thread(void *msgq, void *can_dev_param, void *gpio_dev_param)
131131
{
132-
const struct can_filter filter = {
132+
const struct can_msg_filter filter = {
133133
.id_type = CAN_STANDARD_IDENTIFIER,
134134
.rtr = CAN_DATAFRAME,
135135
.std_id = LED_MSG_ID,
@@ -181,7 +181,7 @@ void rx_button_isr(struct can_msg *msg)
181181

182182
void main(void)
183183
{
184-
const struct can_filter filter = {
184+
const struct can_msg_filter filter = {
185185
.id_type = CAN_STANDARD_IDENTIFIER,
186186
.rtr = CAN_DATAFRAME,
187187
.std_id = BUTTON_MSG_ID,

samples/net/sockets/can/src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static void rx(int fd)
9090

9191
static int setup_socket(void)
9292
{
93-
const struct can_filter filter = {
93+
const struct can_msg_filter filter = {
9494
.id_type = CAN_STANDARD_IDENTIFIER,
9595
.rtr = CAN_DATAFRAME,
9696
.std_id = 0x1,

0 commit comments

Comments
 (0)