drivers: can: deprecate the can_attach_workq() API call

Deprecate the can_attach_workq() API call.

This API is limited in its functionality (it does not work with
userspace, it uses one common buffer size for all work queue instances).

Similar functionality can easily be implemented using the
can_attach_msgq() API along with the generic triggered work API
(e.g. using k_work_poll_submit()).

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2021-12-16 12:23:30 +01:00 committed by Carles Cufí
parent d1ff466ceb
commit f92542ecf3
3 changed files with 73 additions and 99 deletions

View file

@ -207,9 +207,9 @@ Receiving
Frames are only received when they match a filter.
The following code snippets show how to receive frames by attaching filters.
Here we have an example for a receiving callback.
It is used for :c:func:`can_attach_isr` or :c:func:`can_attach_workq`.
The argument arg is passed when the filter is attached.
Here we have an example for a receiving callback as used for
:c:func:`can_attach_isr`. The argument arg is passed when the filter is
attached.
.. code-block:: C
@ -245,38 +245,6 @@ The filter for this example is configured to match the identifier 0x123 exactly.
LOG_ERR("Unable to attach isr [%d]", filter_id);
}
This example shows how to attach a callback from a work-queue.
In contrast to the :c:func:`can_attach_isr` function, here the callback is called from the
work-queue provided. In this case, it is the system work queue. Blocking is
generally allowed in the callback but could result in a frame backlog when it is
not limited. For the reason of a backlog, a ring-buffer is applied for every
attached filter. The size of this buffer can be adjusted in Kconfig.
This function is not yet callable from userspace context but will be in the
future.
The filter for this example is configured to match a filter range from
0x120 to x12f.
.. code-block:: C
const struct zcan_filter my_filter = {
.id_type = CAN_STANDARD_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.id = 0x120,
.rtr_mask = 1,
.id_mask = 0x7F0
};
struct zcan_work rx_work;
int filter_id;
const struct device *can_dev;
can_dev = device_get_binding("CAN_0");
filter_id = can_attach_workq(can_dev, &k_sys_work_q, &rx_work, callback_arg, callback_arg, &my_filter);
if (filter_id < 0) {
LOG_ERR("Unable to attach isr [%d]", filter_id);
}
Here an example for :c:func:`can_attach_msgq` is shown. With this function, it
is possible to receive frames synchronously. This function can be called from
userspace context.

View file

@ -70,7 +70,7 @@ config CAN_INIT_PRIORITY
so that it can start before the networking sub-system.
config CAN_WORKQ_FRAMES_BUF_CNT
int "Work queue buffer frame count"
int "Work queue buffer frame count (DEPRECATED)"
default 4
range 1 65534
help

View file

@ -74,12 +74,6 @@ extern "C" {
#endif
#endif /* CONFIG_CANFD_MAX_DLC */
/**
* Allow including drivers/can.h even if CONFIG_CAN is not selected.
*/
#ifndef CONFIG_CAN_WORKQ_FRAMES_BUF_CNT
#define CONFIG_CAN_WORKQ_FRAMES_BUF_CNT 4
#endif
/** @endcond */
/** @} */
@ -293,30 +287,6 @@ typedef void (*can_state_change_isr_t)(enum can_state state, struct can_bus_err_
* For internal driver use only, skip these in public documentation.
*/
/**
* @brief CAN frame buffer structure
*
* Used internally by @a zcan_work struct
*/
struct can_frame_buffer {
struct zcan_frame buf[CONFIG_CAN_WORKQ_FRAMES_BUF_CNT];
uint16_t head;
uint16_t tail;
};
/**
* @brief CAN work structure
*
* Used to attach a work queue to a filter.
*/
struct zcan_work {
struct k_work work_item;
struct k_work_q *work_queue;
struct can_frame_buffer buf;
can_rx_callback_t cb;
void *cb_arg;
};
/**
* @typedef can_set_timing_t
* @brief Callback API upon setting CAN bus timing
@ -741,37 +711,6 @@ static inline int can_attach_isr(const struct device *dev, can_rx_callback_t cal
return api->attach_isr(dev, callback, user_data, filter);
}
/**
* @brief Attach a CAN work queue with a given CAN filter
*
* Attach a work queue to CAN identifiers specified by a filter. Whenever a
* frame matching the filter is received by the CAN controller, the frame is
* pushed to the buffer of the @a zcan_work structure and the work element is
* put in the workqueue.
*
* If a frame matches more than one attached filter, the priority of the match
* is hardware dependent.
*
* The same CAN work queue can be attached to more than one filter.
*
* @note The work queue must be initialized before and the caller must have
* appropriate permissions on it.
*
* @param dev Pointer to the device structure for the driver instance.
* @param work_q Pointer to the already initialized @a zcan_work queue.
* @param work Pointer to a @a zcan_work structure, which will be initialized.
* @param callback This function is called by the work queue whenever a frame
* matching the filter is received.
* @param user_data User data to pass to callback function.
* @param filter Pointer to a @a zcan_filter structure defining the filter.
*
* @retval filter_id on success.
* @retval -ENOSPC if there are no free filters.
*/
int can_attach_workq(const struct device *dev, struct k_work_q *work_q,
struct zcan_work *work, can_rx_callback_t callback, void *user_data,
const struct zcan_filter *filter);
/**
* @brief Statically define and initialize a CAN RX message queue.
*
@ -809,10 +748,10 @@ __syscall int can_attach_msgq(const struct device *dev, struct k_msgq *msg_q,
const struct zcan_filter *filter);
/**
* @brief Detach an ISR, CAN work queue, or CAN message queue RX filter
* @brief Detach an ISR or CAN message queue RX filter
*
* This routine detaches an CAN RX filter based on the filter ID returned by @a
* can_attach_isr(), @a can_attach_workq(), or @a can_attach_msgq().
* can_attach_isr() or @a can_attach_msgq().
*
* @param dev Pointer to the device structure for the driver instance.
* @param filter_id Filter ID
@ -1167,6 +1106,73 @@ __deprecated static inline int can_configure(const struct device *dev, enum can_
return can_set_mode(dev, mode);
}
/**
* Allow including drivers/can.h even if CONFIG_CAN is not selected.
*/
#ifndef CONFIG_CAN_WORKQ_FRAMES_BUF_CNT
#define CONFIG_CAN_WORKQ_FRAMES_BUF_CNT 4
#endif
/**
* @brief CAN frame buffer structure
*
* Used internally by @a zcan_work struct
*/
struct can_frame_buffer {
struct zcan_frame buf[CONFIG_CAN_WORKQ_FRAMES_BUF_CNT];
uint16_t head;
uint16_t tail;
};
/**
* @brief CAN work structure
*
* Used to attach a work queue to a filter.
*/
struct zcan_work {
struct k_work work_item;
struct k_work_q *work_queue;
struct can_frame_buffer buf;
can_rx_callback_t cb;
void *cb_arg;
};
/**
* @brief Attach a CAN work queue with a given CAN filter
*
* Attach a work queue to CAN identifiers specified by a filter. Whenever a
* frame matching the filter is received by the CAN controller, the frame is
* pushed to the buffer of the @a zcan_work structure and the work element is
* put in the workqueue.
*
* If a frame matches more than one attached filter, the priority of the match
* is hardware dependent.
*
* The same CAN work queue can be attached to more than one filter.
*
* @see @a can_detach()
*
* @note The work queue must be initialized before and the caller must have
* appropriate permissions on it.
*
* @warning This function is deprecated. Use @a can_attach_msgq() along with @a
* k_work_poll_submit() instead.
*
* @param dev Pointer to the device structure for the driver instance.
* @param work_q Pointer to the already initialized @a zcan_work queue.
* @param work Pointer to a @a zcan_work structure, which will be initialized.
* @param callback This function is called by the work queue whenever a frame
* matching the filter is received.
* @param user_data User data to pass to callback function.
* @param filter Pointer to a @a zcan_filter structure defining the filter.
*
* @retval filter_id on success.
* @retval -ENOSPC if there are no free filters.
*/
__deprecated int can_attach_workq(const struct device *dev, struct k_work_q *work_q,
struct zcan_work *work, can_rx_callback_t callback,
void *user_data, const struct zcan_filter *filter);
/** @endcond */
/**