drivers: can: Extend can_send with void *arg and pass it to the isr cb
This commit extends the CAN api can_send function by an argument that is passed to the isr callback. With this extension it is possible to distinguish between sent masseges when they use the same callback. Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
This commit is contained in:
parent
1b93522304
commit
b3b43b8921
10 changed files with 85 additions and 30 deletions
|
@ -15,7 +15,7 @@ Z_SYSCALL_HANDLER(can_configure, dev, mode, bitrate) {
|
|||
(u32_t)bitrate);
|
||||
}
|
||||
|
||||
Z_SYSCALL_HANDLER(can_send, dev, msg, timeout, callback_isr) {
|
||||
Z_SYSCALL_HANDLER(can_send, dev, msg, timeout, callback_isr, callback_arg) {
|
||||
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, send));
|
||||
|
||||
|
@ -26,9 +26,12 @@ Z_SYSCALL_HANDLER(can_send, dev, msg, timeout, callback_isr) {
|
|||
Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback_isr == 0,
|
||||
"callbacks may not be set from user mode"));
|
||||
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)callback_arg, sizeof(void *)));
|
||||
|
||||
return z_impl_can_send((struct device *)dev,
|
||||
(const struct zcan_frame *)msg,
|
||||
(s32_t)timeout, (can_tx_callback_t) callback_isr);
|
||||
(s32_t)timeout, (can_tx_callback_t) callback_isr,
|
||||
(void *)callback_arg);
|
||||
}
|
||||
|
||||
Z_SYSCALL_HANDLER(can_attach_msgq, dev, msgq, filter) {
|
||||
|
|
|
@ -266,7 +266,7 @@ static int mcp2515_configure(struct device *dev, enum can_mode mode,
|
|||
}
|
||||
|
||||
static int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
|
||||
s32_t timeout, can_tx_callback_t callback)
|
||||
s32_t timeout, can_tx_callback_t callback, void *callback_arg)
|
||||
{
|
||||
struct mcp2515_data *dev_data = DEV_DATA(dev);
|
||||
u8_t tx_idx = 0U;
|
||||
|
@ -295,6 +295,7 @@ static int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
|
|||
}
|
||||
|
||||
dev_data->tx_cb[tx_idx].cb = callback;
|
||||
dev_data->tx_cb[tx_idx].cb_arg = callback_arg;
|
||||
|
||||
addr_tx_ctrl = MCP2515_ADDR_TXB0CTRL +
|
||||
(tx_idx * MCP2515_ADDR_OFFSET_FRAME2FRAME);
|
||||
|
@ -432,7 +433,7 @@ static void mcp2515_tx_done(struct device *dev, u8_t tx_idx)
|
|||
if (dev_data->tx_cb[tx_idx].cb == NULL) {
|
||||
k_sem_give(&dev_data->tx_cb[tx_idx].sem);
|
||||
} else {
|
||||
dev_data->tx_cb[tx_idx].cb(0);
|
||||
dev_data->tx_cb[tx_idx].cb(0, dev_data->tx_cb[tx_idx].cb_arg);
|
||||
}
|
||||
|
||||
k_mutex_lock(&dev_data->tx_mutex, K_FOREVER);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
struct mcp2515_tx_cb {
|
||||
struct k_sem sem;
|
||||
can_tx_callback_t cb;
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
struct mcp2515_data {
|
||||
|
|
|
@ -43,10 +43,12 @@ static inline void socket_can_iface_init(struct net_if *iface)
|
|||
LOG_DBG("Init CAN interface %p dev %p", iface, dev);
|
||||
}
|
||||
|
||||
static inline void tx_irq_callback(u32_t error_flags)
|
||||
static inline void tx_irq_callback(u32_t error_flags, void *arg)
|
||||
{
|
||||
char *caller_str = (char *)arg;
|
||||
if (error_flags) {
|
||||
LOG_DBG("Callback! error-code: %d", error_flags);
|
||||
LOG_DBG("TX error from %s! error-code: %d",
|
||||
caller_str, error_flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +64,7 @@ static inline int socket_can_send(struct device *dev, struct net_pkt *pkt)
|
|||
|
||||
ret = can_send(socket_context->can_dev,
|
||||
(struct zcan_frame *)pkt->frags->data,
|
||||
SEND_TIMEOUT, tx_irq_callback);
|
||||
SEND_TIMEOUT, tx_irq_callback, "socket_can_send");
|
||||
if (ret) {
|
||||
LOG_DBG("Cannot send socket CAN msg (%d)", ret);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ static const u8_t reg_demand[] = {2, 1, 4, 2};
|
|||
static void can_stm32_signal_tx_complete(struct can_mailbox *mb)
|
||||
{
|
||||
if (mb->tx_callback) {
|
||||
mb->tx_callback(mb->error_flags);
|
||||
mb->tx_callback(mb->error_flags, mb->callback_arg);
|
||||
} else {
|
||||
k_sem_give(&mb->tx_int_sem);
|
||||
}
|
||||
|
@ -300,11 +300,8 @@ static int can_stm32_init(struct device *dev)
|
|||
data->mb2.tx_callback = NULL;
|
||||
|
||||
data->filter_usage = (1ULL << CAN_MAX_NUMBER_OF_FILTERS) - 1ULL;
|
||||
(void)memset(data->rx_response, 0,
|
||||
sizeof(void *) * CONFIG_CAN_MAX_FILTER);
|
||||
(void)memset(data->cb_arg, 0,
|
||||
sizeof(void *) * CONFIG_CAN_MAX_FILTER);
|
||||
data->response_type = 0U;
|
||||
(void)memset(data->rx_cb, 0, sizeof(data->rx_cb));
|
||||
(void)memset(data->cb_arg, 0, sizeof(data->cb_arg));
|
||||
|
||||
clock = device_get_binding(STM32_CLOCK_CONTROL_NAME);
|
||||
__ASSERT_NO_MSG(clock);
|
||||
|
@ -327,7 +324,7 @@ static int can_stm32_init(struct device *dev)
|
|||
}
|
||||
|
||||
int can_stm32_send(struct device *dev, const struct zcan_frame *msg,
|
||||
s32_t timeout, can_tx_callback_t callback)
|
||||
s32_t timeout, can_tx_callback_t callback, void *callback_arg)
|
||||
{
|
||||
const struct can_stm32_config *cfg = DEV_CFG(dev);
|
||||
struct can_stm32_data *data = DEV_DATA(dev);
|
||||
|
@ -383,6 +380,7 @@ int can_stm32_send(struct device *dev, const struct zcan_frame *msg,
|
|||
}
|
||||
|
||||
mb->tx_callback = callback;
|
||||
mb->callback_arg = callback_arg;
|
||||
k_sem_reset(&mb->tx_int_sem);
|
||||
|
||||
/* mailbix identifier register setup */
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
CAN_BANK_IN_32BIT_MODE(can, bank))
|
||||
struct can_mailbox {
|
||||
can_tx_callback_t tx_callback;
|
||||
void *callback_arg;
|
||||
struct k_sem tx_int_sem;
|
||||
u32_t error_flags;
|
||||
};
|
||||
|
|
|
@ -210,8 +210,9 @@ struct zcan_filter {
|
|||
* @brief Define the application callback handler function signature
|
||||
*
|
||||
* @param error_flags status of the performed send operation
|
||||
* @param arg argument that was passed when the message was sent
|
||||
*/
|
||||
typedef void (*can_tx_callback_t)(u32_t error_flags);
|
||||
typedef void (*can_tx_callback_t)(u32_t error_flags, void *arg);
|
||||
|
||||
/**
|
||||
* @typedef can_rx_callback_t
|
||||
|
@ -227,7 +228,8 @@ typedef int (*can_configure_t)(struct device *dev, enum can_mode mode,
|
|||
u32_t bitrate);
|
||||
|
||||
typedef int (*can_send_t)(struct device *dev, const struct zcan_frame *msg,
|
||||
s32_t timeout, can_tx_callback_t callback_isr);
|
||||
s32_t timeout, can_tx_callback_t callback_isr,
|
||||
void *callback_arg);
|
||||
|
||||
|
||||
typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q,
|
||||
|
@ -260,21 +262,24 @@ struct can_driver_api {
|
|||
* occurred. If NULL, this function is blocking until
|
||||
* message is sent. This must be NULL if called from user
|
||||
* mode.
|
||||
* @param callback_arg This will be passed whenever the isr is called.
|
||||
*
|
||||
* @retval 0 If successful.
|
||||
* @retval CAN_TX_* on failure.
|
||||
*/
|
||||
__syscall int can_send(struct device *dev, const struct zcan_frame *msg,
|
||||
s32_t timeout, can_tx_callback_t callback_isr);
|
||||
s32_t timeout, can_tx_callback_t callback_isr,
|
||||
void *callback_arg);
|
||||
|
||||
static inline int z_impl_can_send(struct device *dev,
|
||||
const struct zcan_frame *msg,
|
||||
s32_t timeout, can_tx_callback_t callback_isr)
|
||||
s32_t timeout, can_tx_callback_t callback_isr,
|
||||
void *callback_arg)
|
||||
{
|
||||
const struct can_driver_api *api =
|
||||
(const struct can_driver_api *)dev->driver_api;
|
||||
|
||||
return api->send(dev, msg, timeout, callback_isr);
|
||||
return api->send(dev, msg, timeout, callback_isr, callback_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -318,7 +323,7 @@ static inline int can_write(struct device *dev, const u8_t *data, u8_t length,
|
|||
msg.rtr = rtr;
|
||||
memcpy(msg.data, data, length);
|
||||
|
||||
return can_send(dev, &msg, timeout, NULL);
|
||||
return can_send(dev, &msg, timeout, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,10 +36,12 @@ static struct gpio_callback gpio_cb;
|
|||
CAN_DEFINE_MSGQ(led_msgq, 2);
|
||||
CAN_DEFINE_MSGQ(str_msgq, 5);
|
||||
|
||||
void tx_irq_callback(u32_t error_flags)
|
||||
void tx_irq_callback(u32_t error_flags, void *arg)
|
||||
{
|
||||
char *sender = (char *)arg;
|
||||
if (error_flags) {
|
||||
printk("Callback! error-code: %d\n", error_flags);
|
||||
printk("Callback! error-code: %d\nSender: %s\n",
|
||||
error_flags, sender);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +66,7 @@ void send_string(char *string, struct device *can_dev)
|
|||
str_len -= msg.dlc;
|
||||
memcpy(msg.data, string, msg.dlc);
|
||||
string += msg.dlc;
|
||||
can_send(can_dev, &msg, 10, tx_irq_callback);
|
||||
can_send(can_dev, &msg, 10, tx_irq_callback, "send_string");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,8 +100,8 @@ void tx_thread(void *can_dev_param, void *unused2, void *unused3)
|
|||
msg.data[0] = toggle;
|
||||
msg_button_cnt.data[0] = button_press_cnt & 0xFF;
|
||||
msg_button_cnt.data[1] = (button_press_cnt >> 8) & 0xFF;
|
||||
can_send(can_dev, &msg, 10, tx_irq_callback);
|
||||
can_send(can_dev, &msg_button_cnt, 10, NULL);
|
||||
can_send(can_dev, &msg, 10, tx_irq_callback, "LED msg");
|
||||
can_send(can_dev, &msg_button_cnt, 10, NULL, "Button count");
|
||||
if (toggle == SET_LED) {
|
||||
send_string("String sent over CAN\n", can_dev);
|
||||
}
|
||||
|
@ -109,6 +111,7 @@ void tx_thread(void *can_dev_param, void *unused2, void *unused3)
|
|||
void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
|
||||
{
|
||||
struct zcan_frame msg;
|
||||
int filter_id;
|
||||
const struct zcan_filter filter = {
|
||||
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
|
@ -118,7 +121,8 @@ void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
|
|||
};
|
||||
struct device *can_dev = can_dev_param;
|
||||
|
||||
can_attach_msgq(can_dev, msgq, &filter);
|
||||
filter_id = can_attach_msgq(can_dev, msgq, &filter);
|
||||
printk("filter id: %d\n", filter_id);
|
||||
|
||||
while (1) {
|
||||
k_msgq_get((struct k_msgq *)msgq, &msg, K_FOREVER);
|
||||
|
|
|
@ -141,9 +141,32 @@ static inline void check_msg(struct zcan_frame *msg1, struct zcan_frame *msg2,
|
|||
zassert_equal(cmp_res, 0, "Received data differ");
|
||||
}
|
||||
|
||||
static void tx_isr(u32_t error_flags)
|
||||
static void tx_std_isr(u32_t error_flags, void *arg)
|
||||
{
|
||||
struct zcan_frame *msg = (struct zcan_frame *)arg;
|
||||
|
||||
zassert_equal(msg->std_id, TEST_CAN_STD_ID, "Arg does not match");
|
||||
}
|
||||
|
||||
static void tx_std_masked_isr(u32_t error_flags, void *arg)
|
||||
{
|
||||
struct zcan_frame *msg = (struct zcan_frame *)arg;
|
||||
|
||||
zassert_equal(msg->std_id, TEST_CAN_STD_MASK_ID, "Arg does not match");
|
||||
}
|
||||
|
||||
static void tx_ext_isr(u32_t error_flags, void *arg)
|
||||
{
|
||||
struct zcan_frame *msg = (struct zcan_frame *)arg;
|
||||
|
||||
zassert_equal(msg->ext_id, TEST_CAN_EXT_ID, "Arg does not match");
|
||||
}
|
||||
|
||||
static void tx_ext_masked_isr(u32_t error_flags, void *arg)
|
||||
{
|
||||
struct zcan_frame *msg = (struct zcan_frame *)arg;
|
||||
|
||||
zassert_equal(msg->ext_id, TEST_CAN_EXT_MASK_ID, "Arg does not match");
|
||||
}
|
||||
|
||||
static void rx_std_isr(struct zcan_frame *msg, void *arg)
|
||||
|
@ -178,7 +201,7 @@ static void send_test_msg(struct device *can_dev, struct zcan_frame *msg)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT, NULL);
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT, NULL, NULL);
|
||||
zassert_not_equal(ret, CAN_TX_ARB_LOST,
|
||||
"Arbitration though in loopback mode");
|
||||
zassert_equal(ret, CAN_TX_OK, "Can't send a message. Err: %d", ret);
|
||||
|
@ -188,7 +211,24 @@ static void send_test_msg_nowait(struct device *can_dev, struct zcan_frame *msg)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT, tx_isr);
|
||||
if (msg->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
if (msg->std_id == TEST_CAN_STD_ID) {
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT,
|
||||
tx_std_isr, msg);
|
||||
} else {
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT,
|
||||
tx_std_masked_isr, msg);
|
||||
}
|
||||
} else {
|
||||
if (msg->ext_id == TEST_CAN_EXT_ID) {
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT,
|
||||
tx_ext_isr, msg);
|
||||
} else {
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT,
|
||||
tx_ext_masked_isr, msg);
|
||||
}
|
||||
}
|
||||
|
||||
zassert_not_equal(ret, CAN_TX_ARB_LOST,
|
||||
"Arbitration though in loopback mode");
|
||||
zassert_equal(ret, CAN_TX_OK, "Can't send a message. Err: %d", ret);
|
||||
|
|
|
@ -115,7 +115,7 @@ static void send_test_msg(struct device *can_dev, struct zcan_frame *msg)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT, NULL);
|
||||
ret = can_send(can_dev, msg, TEST_SEND_TIMEOUT, NULL, NULL);
|
||||
zassert_not_equal(ret, CAN_TX_ARB_LOST,
|
||||
"Arbitration though in loopback mode");
|
||||
zassert_equal(ret, CAN_TX_OK, "Can't send a message. Err: %d", ret);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue