Skip to content

Commit f8a88cd

Browse files
henrikbrixandersencarlescufi
authored andcommitted
drivers: can: use flags fields for can_frame and can_filter structs
The can_frame and can_filter structs support a number of different flags (standard/extended CAN ID type, Remote Transmission Request, CAN-FD format, Bit Rate Switch, ...). Each of these flags is represented as a discrete bit in the given structure. This design pattern requires every user of these structs to initialize all of these flags to either 0 or 1, which does not scale well for future flag additions. Some of these flags have associated enumerations to be used for assignment, some do not. CAN drivers and protocols tend to rely on the logical value of the flag instead of using the enumeration, leading to a very fragile API. The enumerations are used inconsistently between the can_frame and can_filter structures, which further complicates the API. Instead, convert these flags to bitfields with separate flag definitions for the can_frame and can_filter structures. This API allows for future extensions without having to revisit existing users of the two structures. Furthermore, this allows driver to easily check for unsupported flags in the respective API calls. As this change leads to the "id_mask" field of the can_filter to be the only mask present in that structure, rename it to "mask" for simplicity. Fixes: zephyrproject-rtos#50776 Signed-off-by: Henrik Brix Andersen <[email protected]>
1 parent a9c7c58 commit f8a88cd

File tree

29 files changed

+662
-627
lines changed

29 files changed

+662
-627
lines changed

doc/hardware/peripherals/canbus/controller.rst

+4-10
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ a mailbox. When a transmitting mailbox is assigned, sending cannot be canceled.
152152
.. code-block:: C
153153
154154
struct can_frame frame = {
155-
.id_type = CAN_STANDARD_IDENTIFIER,
156-
.rtr = CAN_DATAFRAME,
155+
.flags = 0,
157156
.id = 0x123,
158157
.dlc = 8,
159158
.data = {1,2,3,4,5,6,7,8}
@@ -187,8 +186,7 @@ occurred. It does not block until the message is sent like the example above.
187186
int send_function(const struct device *can_dev)
188187
{
189188
struct can_frame frame = {
190-
.id_type = CAN_EXTENDED_IDENTIFIER,
191-
.rtr = CAN_DATAFRAME,
189+
.flags = CAN_FRAME_IDE,
192190
.id = 0x1234567,
193191
.dlc = 2
194192
};
@@ -227,10 +225,8 @@ The filter for this example is configured to match the identifier 0x123 exactly.
227225
.. code-block:: C
228226
229227
const struct can_filter my_filter = {
230-
.id_type = CAN_STANDARD_IDENTIFIER,
231-
.rtr = CAN_DATAFRAME,
228+
.flags = CAN_FILTER_DATA,
232229
.id = 0x123,
233-
.rtr_mask = 1,
234230
.id_mask = CAN_STD_ID_MASK
235231
};
236232
int filter_id;
@@ -252,10 +248,8 @@ The filter for this example is configured to match the extended identifier
252248
.. code-block:: C
253249
254250
const struct can_filter my_filter = {
255-
.id_type = CAN_EXTENDED_IDENTIFIER,
256-
.rtr = CAN_DATAFRAME,
251+
.flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
257252
.id = 0x1234567,
258-
.rtr_mask = 1,
259253
.id_mask = CAN_EXT_ID_MASK
260254
};
261255
CAN_MSGQ_DEFINE(my_can_msgq, 2);

drivers/can/can_handlers.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ static inline int z_vrfy_can_set_bitrate_data(const struct device *dev,
129129

130130
#endif /* CONFIG_CAN_FD_MODE */
131131

132-
static inline int z_vrfy_can_get_max_filters(const struct device *dev, enum can_ide id_type)
132+
static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide)
133133
{
134134
/* Optional API function */
135135
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
136136

137-
return z_impl_can_get_max_filters(dev, id_type);
137+
return z_impl_can_get_max_filters(dev, ide);
138138
}
139139
#include <syscalls/can_get_max_filters_mrsh.c>
140140

drivers/can/can_loopback.c

+37-20
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ struct can_loopback_filter {
3333
struct can_loopback_data {
3434
struct can_loopback_filter filters[CONFIG_CAN_MAX_FILTER];
3535
struct k_mutex mtx;
36-
bool loopback;
3736
struct k_msgq tx_msgq;
3837
char msgq_buffer[CONFIG_CAN_LOOPBACK_TX_MSGQ_SIZE * sizeof(struct can_loopback_frame)];
3938
struct k_thread tx_thread_data;
4039
bool started;
40+
bool loopback;
41+
#ifdef CONFIG_CAN_FD_MODE
42+
bool fd;
43+
#endif /* CONFIG_CAN_FD_MODE */
4144

4245
K_KERNEL_STACK_MEMBER(tx_thread_stack,
4346
CONFIG_CAN_LOOPBACK_TX_THREAD_STACK_SIZE);
@@ -51,9 +54,8 @@ static void dispatch_frame(const struct device *dev,
5154

5255
LOG_DBG("Receiving %d bytes. Id: 0x%x, ID type: %s %s",
5356
frame->dlc, frame->id,
54-
frame->id_type == CAN_STANDARD_IDENTIFIER ?
55-
"standard" : "extended",
56-
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
57+
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
58+
(frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
5759

5860
filter->rx_cb(dev, &frame_tmp, filter->cb_arg);
5961
}
@@ -99,15 +101,29 @@ static int can_loopback_send(const struct device *dev,
99101

100102
LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
101103
frame->dlc, dev->name, frame->id,
102-
frame->id_type == CAN_STANDARD_IDENTIFIER ?
103-
"standard" : "extended",
104-
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
104+
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
105+
(frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
105106

106107
#ifdef CONFIG_CAN_FD_MODE
107-
if (frame->fd != 0) {
108+
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR |
109+
CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0) {
110+
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
111+
return -ENOTSUP;
112+
}
113+
114+
if ((frame->flags & CAN_FRAME_FDF) != 0) {
115+
if (!data->fd) {
116+
return -ENOTSUP;
117+
}
118+
108119
max_dlc = CANFD_MAX_DLC;
109120
}
110-
#endif /* CONFIG_CAN_FD_MODE */
121+
#else /* CONFIG_CAN_FD_MODE */
122+
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
123+
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
124+
return -ENOTSUP;
125+
}
126+
#endif /* !CONFIG_CAN_FD_MODE */
111127

112128
if (frame->dlc > max_dlc) {
113129
LOG_ERR("DLC of %d exceeds maximum (%d)", frame->dlc, max_dlc);
@@ -150,14 +166,12 @@ static int can_loopback_add_rx_filter(const struct device *dev, can_rx_callback_
150166
struct can_loopback_filter *loopback_filter;
151167
int filter_id;
152168

153-
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
154-
filter->id_mask);
155-
LOG_DBG("Filter type: %s ID %s mask",
156-
filter->id_type == CAN_STANDARD_IDENTIFIER ?
157-
"standard" : "extended",
158-
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) ||
159-
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ?
160-
"with" : "without");
169+
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, filter->mask);
170+
171+
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
172+
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
173+
return -ENOTSUP;
174+
}
161175

162176
k_mutex_lock(&data->mtx, K_FOREVER);
163177
filter_id = get_free_filter(data->filters);
@@ -242,14 +256,17 @@ static int can_loopback_set_mode(const struct device *dev, can_mode_t mode)
242256
LOG_ERR("unsupported mode: 0x%08x", mode);
243257
return -ENOTSUP;
244258
}
259+
260+
data->fd = (mode & CAN_MODE_FD) != 0;
245261
#else
246262
if ((mode & ~(CAN_MODE_LOOPBACK)) != 0) {
247263
LOG_ERR("unsupported mode: 0x%08x", mode);
248264
return -ENOTSUP;
249265
}
250266
#endif /* CONFIG_CAN_FD_MODE */
251267

252-
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0 ? 1 : 0;
268+
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0;
269+
253270
return 0;
254271
}
255272

@@ -335,9 +352,9 @@ static int can_loopback_get_core_clock(const struct device *dev, uint32_t *rate)
335352
return 0;
336353
}
337354

338-
static int can_loopback_get_max_filters(const struct device *dev, enum can_ide id_type)
355+
static int can_loopback_get_max_filters(const struct device *dev, bool ide)
339356
{
340-
ARG_UNUSED(id_type);
357+
ARG_UNUSED(ide);
341358

342359
return CONFIG_CAN_MAX_FILTER;
343360
}

0 commit comments

Comments
 (0)