drivers: can: provide default callback to can_send() if NULL
Provide a default, internal callback to CAN controller drivers implementation of can_send() if no callback was provided by the caller. This allows for simplifying the CAN driver implementations of can_send() as these no longer need special handling for callback/no callback operation. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
97feeb48d4
commit
d6fc3f6596
2 changed files with 41 additions and 9 deletions
|
@ -17,6 +17,44 @@ LOG_MODULE_REGISTER(can_common, CONFIG_CAN_LOG_LEVEL);
|
||||||
/* CAN sync segment is always one time quantum */
|
/* CAN sync segment is always one time quantum */
|
||||||
#define CAN_SYNC_SEG 1
|
#define CAN_SYNC_SEG 1
|
||||||
|
|
||||||
|
struct can_tx_default_cb_ctx {
|
||||||
|
struct k_sem done;
|
||||||
|
int status;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void can_tx_default_cb(const struct device *dev, int error, void *user_data)
|
||||||
|
{
|
||||||
|
struct can_tx_default_cb_ctx *ctx = user_data;
|
||||||
|
|
||||||
|
ctx->status = error;
|
||||||
|
k_sem_give(&ctx->done);
|
||||||
|
}
|
||||||
|
|
||||||
|
int z_impl_can_send(const struct device *dev, const struct can_frame *frame,
|
||||||
|
k_timeout_t timeout, can_tx_callback_t callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (callback == NULL) {
|
||||||
|
struct can_tx_default_cb_ctx ctx;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
k_sem_init(&ctx.done, 0, 1);
|
||||||
|
|
||||||
|
err = api->send(dev, frame, timeout, can_tx_default_cb, &ctx);
|
||||||
|
if (err != 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_sem_take(&ctx.done, K_FOREVER);
|
||||||
|
|
||||||
|
return ctx.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->send(dev, frame, timeout, callback, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void can_msgq_put(const struct device *dev, struct can_frame *frame, void *user_data)
|
static void can_msgq_put(const struct device *dev, struct can_frame *frame, void *user_data)
|
||||||
{
|
{
|
||||||
struct k_msgq *msgq = (struct k_msgq *)user_data;
|
struct k_msgq *msgq = (struct k_msgq *)user_data;
|
||||||
|
|
|
@ -348,6 +348,9 @@ typedef int (*can_set_mode_t)(const struct device *dev, can_mode_t mode);
|
||||||
/**
|
/**
|
||||||
* @brief Callback API upon sending a CAN frame
|
* @brief Callback API upon sending a CAN frame
|
||||||
* See @a can_send() for argument description
|
* See @a can_send() for argument description
|
||||||
|
*
|
||||||
|
* @note From a driver perspective `callback` will never be `NULL` as a default callback will be
|
||||||
|
* provided if none is provided by the caller. This allows for simplifying the driver handling.
|
||||||
*/
|
*/
|
||||||
typedef int (*can_send_t)(const struct device *dev,
|
typedef int (*can_send_t)(const struct device *dev,
|
||||||
const struct can_frame *frame,
|
const struct can_frame *frame,
|
||||||
|
@ -1095,15 +1098,6 @@ __syscall int can_send(const struct device *dev, const struct can_frame *frame,
|
||||||
k_timeout_t timeout, can_tx_callback_t callback,
|
k_timeout_t timeout, can_tx_callback_t callback,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
static inline int z_impl_can_send(const struct device *dev, const struct can_frame *frame,
|
|
||||||
k_timeout_t timeout, can_tx_callback_t callback,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
|
|
||||||
|
|
||||||
return api->send(dev, frame, timeout, callback, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue