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 */
|
||||
#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)
|
||||
{
|
||||
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
|
||||
* 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,
|
||||
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,
|
||||
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