From 891e36533b1e91a26f2afba0103c4f4e9f2bc170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 13 Dec 2023 18:38:06 +0100 Subject: [PATCH] CAN: implement new bus numbering scheme --- include/thingset/can.h | 65 ++++++++++++++-------- include/thingset/isotp_fast.h | 3 +- src/Kconfig.can | 16 ++++++ src/can.c | 61 +++++++++++--------- src/isotp_fast.c | 19 ++++--- src/isotp_fast_internal.h | 10 ++++ tests/can/src/main.c | 6 +- tests/isotp_fast/conformance/src/main.c | 28 +++++----- tests/isotp_fast/conformance/src/main.h | 5 +- tests/isotp_fast/conformance/testcase.yaml | 2 +- 10 files changed, 139 insertions(+), 76 deletions(-) diff --git a/include/thingset/can.h b/include/thingset/can.h index 1b06446..ce068d7 100644 --- a/include/thingset/can.h +++ b/include/thingset/can.h @@ -23,16 +23,15 @@ extern "C" { * * Channel-based messages using ISO-TP: * - * 28 26 25 24 23 16 15 8 7 0 - * +----------+-----+---------------+---------------+---------------+ - * | Priority | 0x0 | bus ID | target addr | source addr | - * +----------+-----+---------------+---------------+---------------+ + * 28 26 25 24 23 20 19 16 15 8 7 0 + * +----------+-----+---------+---------+---------------+---------------+ + * | Priority | 0x0 | tgt bus | src bus | target addr | source addr | + * +----------+-----+---------+---------+---------------+---------------+ * * Priority: 6 * - * Bus ID: - * Set to 218 (0xDA) by default as suggested by ISO-TP standard (ISO 15765-2) - * for normal fixed addressing with N_TAtype = physical. + * tgt bus: Bus number of the target node (default for single bus systems is 0x0) + * src bus: Bus number of the source node (default for single bus systems is 0x0) * * Control and report messages (always single-frame): * @@ -86,18 +85,27 @@ extern "C" { #define THINGSET_CAN_DATA_ID_GET(id) \ (((uint32_t)id & THINGSET_CAN_DATA_ID_MASK) >> THINGSET_CAN_DATA_ID_POS) -/* bus ID for request/response messages */ -#define THINGSET_CAN_BUS_ID_POS (16U) -#define THINGSET_CAN_BUS_ID_MASK (0xFF << THINGSET_CAN_BUS_ID_POS) -#define THINGSET_CAN_BUS_ID_SET(id) \ - (((uint32_t)id << THINGSET_CAN_BUS_ID_POS) & THINGSET_CAN_BUS_ID_MASK) -#define THINGSET_CAN_BUS_ID_GET(id) \ - (((uint32_t)id & THINGSET_CAN_BUS_ID_MASK) >> THINGSET_CAN_BUS_ID_POS) -#define THINGSET_CAN_BUS_ID_DEFAULT (0xDA) // 218, N_TAtype = physical +/* bus numbers for request/response messages */ +#define THINGSET_CAN_SOURCE_BUS_POS (16U) +#define THINGSET_CAN_SOURCE_BUS_MASK (0xF << THINGSET_CAN_SOURCE_BUS_POS) +#define THINGSET_CAN_SOURCE_BUS_SET(id) \ + (((uint32_t)id << THINGSET_CAN_SOURCE_BUS_POS) & THINGSET_CAN_SOURCE_BUS_MASK) +#define THINGSET_CAN_SOURCE_BUS_GET(id) \ + (((uint32_t)id & THINGSET_CAN_SOURCE_BUS_MASK) >> THINGSET_CAN_SOURCE_BUS_POS) +#define THINGSET_CAN_SOURCE_BUS_DEFAULT (0x0) +#define THINGSET_CAN_TARGET_BUS_POS (20U) +#define THINGSET_CAN_TARGET_BUS_MASK (0xF << THINGSET_CAN_TARGET_BUS_POS) +#define THINGSET_CAN_TARGET_BUS_SET(id) \ + (((uint32_t)id << THINGSET_CAN_TARGET_BUS_POS) & THINGSET_CAN_TARGET_BUS_MASK) +#define THINGSET_CAN_TARGET_BUS_GET(id) \ + (((uint32_t)id & THINGSET_CAN_TARGET_BUS_MASK) >> THINGSET_CAN_TARGET_BUS_POS) +#define THINGSET_CAN_TARGET_BUS_DEFAULT (0x0) /* random number for address discovery messages */ -#define THINGSET_CAN_RAND_SET THINGSET_CAN_BUS_ID_SET -#define THINGSET_CAN_RAND_GET THINGSET_CAN_BUS_ID_GET +#define THINGSET_CAN_RAND_POS (16U) +#define THINGSET_CAN_RAND_MASK (0xFF << THINGSET_CAN_RAND_POS) +#define THINGSET_CAN_RAND_SET(id) (((uint32_t)id << THINGSET_CAN_RAND_POS) & THINGSET_CAN_RAND_MASK) +#define THINGSET_CAN_RAND_GET(id) (((uint32_t)id & THINGSET_CAN_RAND_MASK) >> THINGSET_CAN_RAND_POS) /* message types */ #define THINGSET_CAN_TYPE_POS (24U) @@ -180,6 +188,7 @@ struct thingset_can thingset_can_report_rx_callback_t report_rx_cb; int64_t next_pub_time; uint8_t node_addr; + uint8_t bus_number; }; #ifdef CONFIG_THINGSET_CAN_MULTIPLE_INSTANCES @@ -191,12 +200,13 @@ struct thingset_can * @param rx_buf Buffer to store the message. * @param rx_buf_size Size of the buffer to store the message. * @param source_addr Pointer to store the node address the data was received from. + * @param source_bus Pointer to store the bus number the data was received from. * @param timeout Timeout to wait for a message from the node. * * @returns length of message or negative errno in case of error */ int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buf, size_t rx_buf_size, - uint8_t *source_addr, k_timeout_t timeout); + uint8_t *source_addr, uint8_t *source_bus, k_timeout_t timeout); #ifdef CONFIG_ISOTP_FAST /** @@ -206,6 +216,7 @@ int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buf, size * @param tx_buf Buffer containing the message. * @param tx_len Length of the message. * @param target_addr Target node address (8-bit value) to send the message to. + * @param target_bus Target bus number (4-bit value) to send the message to. * @param rsp_callback If a response is expected, this callback will be invoked, * either when it arrives or if a timeout or some other error occurs. * @param callback_arg User data for the callback. @@ -214,8 +225,9 @@ int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buf, size * @returns 0 for success or negative errno in case of error */ int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t tx_len, - uint8_t target_addr, thingset_can_response_callback_t rsp_callback, - void *callback_arg, k_timeout_t timeout); + uint8_t target_addr, uint8_t target_bus, + thingset_can_response_callback_t rsp_callback, void *callback_arg, + k_timeout_t timeout); #else /** * Send ThingSet message to other node @@ -224,11 +236,12 @@ int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t * @param tx_buf Buffer containing the message. * @param tx_len Length of the message. * @param target_addr Target node address (8-bit value) to send the message to. + * @param target_bus Target bus number (4-bit value) to send the message to. * * @returns 0 for success or negative errno in case of error */ int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t tx_len, - uint8_t target_addr); + uint8_t target_addr, uint8_t target_bus); /** * Process incoming ThingSet requests @@ -268,10 +281,12 @@ int thingset_can_set_report_rx_callback_inst(struct thingset_can *ts_can, * * @param ts_can Pointer to the thingset_can context. * @param can_dev Pointer to the CAN device that should be used. + * @param bus_number Assigned bus number of this CAN device. * * @returns 0 for success or negative errno in case of error */ -int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can_dev); +int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can_dev, + uint8_t bus_number); #else /* !CONFIG_THINGSET_CAN_MULTIPLE_INSTANCES */ @@ -282,10 +297,11 @@ int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can * @param tx_buf Buffer containing the message. * @param tx_len Length of the message. * @param target_addr Target node address (8-bit value) to send the message to. + * @param target_bus Target bus number (4-bit value) to send the message to. * * @returns 0 for success or negative errno in case of error */ -int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, +int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, uint8_t target_bus, thingset_can_response_callback_t rsp_callback, void *callback_arg, k_timeout_t timeout); #else @@ -295,10 +311,11 @@ int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, * @param tx_buf Buffer containing the message. * @param tx_len Length of the message. * @param target_addr Target node address (8-bit value) to send the message to. + * @param target_bus Target bus number (4-bit value) to send the message to. * * @returns 0 for success or negative errno in case of error */ -int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr); +int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, uint8_t target_bus); #endif /* CONFIG_ISOTP_FAST */ /** diff --git a/include/thingset/isotp_fast.h b/include/thingset/isotp_fast.h index 2e47e41..4effd7b 100644 --- a/include/thingset/isotp_fast.h +++ b/include/thingset/isotp_fast.h @@ -133,10 +133,11 @@ int isotp_fast_recv(struct isotp_fast_ctx *ctx, struct can_filter sender, uint8_ * @param target_addr The node ID identifying the recipient. This will be * combined with the sending address @ref my_addr on @ref * ctx to form the CAN ID on the message. + * @param target_bus Target bus number (4-bit value) to send the message to. * @param sent_cb_arg A pointer to data to be supplied to the callback * that will be invoked when the message is sent. * * @returns 0 on success. */ int isotp_fast_send(struct isotp_fast_ctx *ctx, const uint8_t *data, size_t len, - const uint8_t target_addr, void *sent_cb_arg); + const uint8_t target_addr, uint8_t target_bus, void *sent_cb_arg); diff --git a/src/Kconfig.can b/src/Kconfig.can index b66d350..42e49ec 100644 --- a/src/Kconfig.can +++ b/src/Kconfig.can @@ -68,12 +68,28 @@ config THINGSET_CAN_PACKETIZED_REPORTS_FRAME_TX_INTERVAL config THINGSET_CAN_MULTIPLE_INSTANCES bool "Support for multiple ThingSet CAN instances" + depends on ISOTP_FAST help If enabled, the CAN message processing does not happen in the background anymore. Instead, each instance has to be initialized for a dedicated CAN device and and messages have to be processed manually in application threads. + The bus numbering scheme in the CAN ID is not compatible with + the current Zephyr upstream ISO-TP implementation, so it depends + on ISOTP_FAST. + +config THINGSET_CAN_BUS_NUMBER + int "ThingSet CAN bus number" + depends on !THINGSET_CAN_MULTIPLE_INSTANCES + range 0 15 + default 0 + help + The bus number can be used to identify multiple CAN buses in one system. + It is used by gateways to forward messages between different buses. + + For a single bus system, the default bus number 0 should be used. + config THINGSET_CAN_RESPONSE_DELAY int "ThingSet CAN response delay" range 0 100 diff --git a/src/can.c b/src/can.c index c904c20..6d13f1a 100644 --- a/src/can.c +++ b/src/can.c @@ -345,7 +345,7 @@ void thingset_can_request_response_timeout_handler(struct k_timer *timer) } #else int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buffer, size_t rx_buf_size, - uint8_t *source_addr, k_timeout_t timeout) + uint8_t *source_addr, uint8_t *source_bus, k_timeout_t timeout) { int ret, rem_len, rx_len; struct net_buf *netbuf; @@ -390,7 +390,9 @@ int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buffer, s } else if (rx_len > 0 && rem_len == 0) { *source_addr = THINGSET_CAN_SOURCE_GET(ts_can->recv_ctx.rx_addr.ext_id); - LOG_DBG("ISO-TP received %d bytes from addr %d", rx_len, *source_addr); + *source_bus = THINGSET_CAN_SOURCE_BUS_GET(ts_can->recv_ctx.rx_addr.ext_id); + LOG_DBG("ISO-TP received %d bytes from addr 0x%X on bus 0x%X", rx_len, *source_addr, + *source_bus); return rx_len; } else if (rem_len == ISOTP_RECV_TIMEOUT) { @@ -404,8 +406,9 @@ int thingset_can_receive_inst(struct thingset_can *ts_can, uint8_t *rx_buffer, s #ifdef CONFIG_ISOTP_FAST int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t tx_len, - uint8_t target_addr, thingset_can_response_callback_t rsp_callback, - void *callback_arg, k_timeout_t timeout) + uint8_t target_addr, uint8_t target_bus, + thingset_can_response_callback_t rsp_callback, void *callback_arg, + k_timeout_t timeout) { if (!device_is_ready(ts_can->dev)) { return -ENODEV; @@ -422,16 +425,18 @@ int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t NULL); k_timer_start(&ts_can->request_response.timer, timeout, timeout); ts_can->request_response.can_id = THINGSET_CAN_TYPE_CHANNEL | THINGSET_CAN_PRIO_CHANNEL + | THINGSET_CAN_TARGET_BUS_SET(ts_can->bus_number) + | THINGSET_CAN_SOURCE_BUS_SET(target_bus) | THINGSET_CAN_TARGET_SET(ts_can->node_addr) | THINGSET_CAN_SOURCE_SET(target_addr); } - int ret = isotp_fast_send(&ts_can->ctx, tx_buf, tx_len, target_addr, ts_can); + int ret = isotp_fast_send(&ts_can->ctx, tx_buf, tx_len, target_addr, target_bus, ts_can); if (ret == ISOTP_N_OK) { return 0; } else { - LOG_ERR("Error sending data to addr %d: %d", target_addr, ret); + LOG_ERR("Error sending data to addr 0x%X: %d", target_addr, ret); return -EIO; } } @@ -459,9 +464,10 @@ void isotp_fast_recv_callback(struct net_buf *buffer, int rem_len, uint32_t can_ int tx_len = thingset_process_message(&ts, ts_can->rx_buffer, len, sbuf->data, sbuf->size); if (tx_len > 0) { - uint8_t target_id = (uint8_t)(can_id & 0xFF); - int err = thingset_can_send_inst(ts_can, sbuf->data, tx_len, target_id, NULL, NULL, - K_NO_WAIT); + uint8_t target_addr = THINGSET_CAN_SOURCE_GET(can_id); + uint8_t target_bus = THINGSET_CAN_SOURCE_BUS_GET(can_id); + int err = thingset_can_send_inst(ts_can, sbuf->data, tx_len, target_addr, + target_bus, NULL, NULL, K_NO_WAIT); if (err != 0) { k_sem_give(&sbuf->lock); } @@ -492,19 +498,21 @@ void isotp_fast_sent_callback(int result, void *arg) } #else int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t tx_len, - uint8_t target_addr) + uint8_t target_addr, uint8_t target_bus) { if (!device_is_ready(ts_can->dev)) { return -ENODEV; } - ts_can->tx_addr.ext_id = THINGSET_CAN_TYPE_CHANNEL | THINGSET_CAN_PRIO_CHANNEL - | THINGSET_CAN_TARGET_SET(target_addr) - | THINGSET_CAN_SOURCE_SET(ts_can->node_addr); + ts_can->tx_addr.ext_id = + THINGSET_CAN_TYPE_CHANNEL | THINGSET_CAN_PRIO_CHANNEL + | THINGSET_CAN_TARGET_BUS_SET(target_bus) | THINGSET_CAN_SOURCE_BUS_SET(ts_can->bus_number) + | THINGSET_CAN_TARGET_SET(target_addr) | THINGSET_CAN_SOURCE_SET(ts_can->node_addr); - ts_can->rx_addr.ext_id = THINGSET_CAN_TYPE_CHANNEL | THINGSET_CAN_PRIO_CHANNEL - | THINGSET_CAN_TARGET_SET(ts_can->node_addr) - | THINGSET_CAN_SOURCE_SET(target_addr); + ts_can->rx_addr.ext_id = + THINGSET_CAN_TYPE_CHANNEL | THINGSET_CAN_PRIO_CHANNEL + | THINGSET_CAN_TARGET_BUS_SET(ts_can->bus_number) | THINGSET_CAN_SOURCE_BUS_SET(target_bus) + | THINGSET_CAN_TARGET_SET(ts_can->node_addr) | THINGSET_CAN_SOURCE_SET(target_addr); int ret = isotp_send(&ts_can->send_ctx, ts_can->dev, tx_buf, tx_len, &ts_can->tx_addr, &ts_can->rx_addr, NULL, NULL); @@ -522,11 +530,12 @@ int thingset_can_process_inst(struct thingset_can *ts_can, k_timeout_t timeout) { struct shared_buffer *sbuf = thingset_sdk_shared_buffer(); uint8_t external_addr; + uint8_t external_bus; int tx_len, rx_len; int err; rx_len = thingset_can_receive_inst(ts_can, ts_can->rx_buffer, sizeof(ts_can->rx_buffer), - &external_addr, timeout); + &external_addr, &external_bus, timeout); if (rx_len == -EAGAIN) { return -EAGAIN; } @@ -554,7 +563,7 @@ int thingset_can_process_inst(struct thingset_can *ts_can, k_timeout_t timeout) k_sleep(K_MSEC(CONFIG_THINGSET_CAN_RESPONSE_DELAY)); if (tx_len > 0) { - err = thingset_can_send_inst(ts_can, sbuf->data, tx_len, external_addr); + err = thingset_can_send_inst(ts_can, sbuf->data, tx_len, external_addr, external_bus); if (err == -ENODEV) { LOG_ERR("CAN processing stopped because device not ready"); k_sem_give(&sbuf->lock); @@ -567,7 +576,8 @@ int thingset_can_process_inst(struct thingset_can *ts_can, k_timeout_t timeout) } #endif /* CONFIG_ISOTP_FAST */ -int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can_dev) +int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can_dev, + uint8_t bus_number) { struct can_frame tx_frame = { .flags = CAN_FRAME_IDE, @@ -592,6 +602,7 @@ int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can k_work_init_delayable(&ts_can->addr_claim_work, thingset_can_addr_claim_tx_handler); ts_can->dev = can_dev; + ts_can->bus_number = bus_number; /* set initial address (will be changed if already used on the bus) */ if (ts_can->node_addr < 1 || ts_can->node_addr > THINGSET_CAN_ADDR_MAX) { @@ -751,17 +762,17 @@ THINGSET_ADD_ITEM_UINT8(TS_ID_NET, TS_ID_NET_CAN_NODE_ADDR, "pCANNodeAddr", &ts_can_single.node_addr, THINGSET_ANY_RW, TS_SUBSET_NVM); #ifdef CONFIG_ISOTP_FAST -int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, +int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, uint8_t target_bus, thingset_can_response_callback_t rsp_callback, void *callback_arg, k_timeout_t timeout) { - return thingset_can_send_inst(&ts_can_single, tx_buf, tx_len, target_addr, rsp_callback, - callback_arg, timeout); + return thingset_can_send_inst(&ts_can_single, tx_buf, tx_len, target_addr, target_bus, + rsp_callback, callback_arg, timeout); } #else -int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr) +int thingset_can_send(uint8_t *tx_buf, size_t tx_len, uint8_t target_addr, uint8_t target_bus) { - return thingset_can_send_inst(&ts_can_single, tx_buf, tx_len, target_addr); + return thingset_can_send_inst(&ts_can_single, tx_buf, tx_len, target_addr, target_bus); } #endif /* CONFIG_ISOTP_FAST */ @@ -779,7 +790,7 @@ static void thingset_can_thread() { int err; - err = thingset_can_init_inst(&ts_can_single, can_dev); + err = thingset_can_init_inst(&ts_can_single, can_dev, CONFIG_THINGSET_CAN_BUS_NUMBER); if (err != 0) { LOG_ERR("Failed to init ThingSet CAN: %d", err); return; diff --git a/src/isotp_fast.c b/src/isotp_fast.c index 1311b5c..cd3d3bf 100644 --- a/src/isotp_fast.c +++ b/src/isotp_fast.c @@ -217,11 +217,13 @@ static void receive_can_tx(const struct device *dev, int error, void *arg) static void receive_send_fc(struct isotp_fast_recv_ctx *rctx, uint8_t fs) { + /* swap bus and address for FC frame */ struct can_frame frame = { .flags = CAN_FRAME_IDE | ((rctx->ctx->opts->flags & ISOTP_MSG_FDF) != 0 ? CAN_FRAME_FDF : 0), - .id = (rctx->rx_can_id & 0xFFFF0000) | ((rctx->rx_can_id & 0xFF00) >> 8) - | ((rctx->rx_can_id & 0xFF) << 8) + .id = (rctx->rx_can_id & 0xFF000000) | ((rctx->rx_can_id & 0x0000FF00) >> 8) + | ((rctx->rx_can_id & 0x000000FF) << 8) | ((rctx->rx_can_id & 0x000F0000) << 4) + | ((rctx->rx_can_id & 0x00F00000) >> 4) }; uint8_t *data = frame.data; uint8_t payload_len; @@ -616,8 +618,10 @@ static void can_rx_callback(const struct device *dev, struct can_frame *frame, v { struct isotp_fast_ctx *ctx = arg; int index = 0; - uint32_t can_id = - (frame->id & 0xFFFF0000) | ((frame->id & 0xFF00) >> 8) | ((frame->id & 0xFF) << 8); + uint32_t can_id = (frame->id & 0xFF000000) | ((frame->id & 0x0000FF00) >> 8) + | ((frame->id & 0x000000FF) << 8) | ((frame->id & 0x000F0000) << 4) + | ((frame->id & 0x00F00000) >> 4); + if ((frame->data[index++] & ISOTP_PCI_TYPE_MASK) == ISOTP_PCI_TYPE_FC) { LOG_DBG("Got flow control frame from %x", frame->id); /* inbound flow control for a message we are currently transmitting */ @@ -821,7 +825,7 @@ static inline void prepare_filter(struct can_filter *filter, uint32_t rx_can_id, const struct isotp_fast_opts *opts) { filter->id = rx_can_id; - filter->mask = ISOTP_FIXED_ADDR_RX_MASK; + filter->mask = 0x03F0FF00; /* fixed target bus and target address of any priority */ filter->flags = CAN_FILTER_DATA | CAN_FILTER_IDE | ((opts->flags & ISOTP_MSG_FDF) != 0 ? CAN_FILTER_FDF : 0); } @@ -990,9 +994,10 @@ int isotp_fast_recv(struct isotp_fast_ctx *ctx, struct can_filter sender, uint8_ #endif /* CONFIG_ISOTP_FAST_BLOCKING_RECEIVE */ int isotp_fast_send(struct isotp_fast_ctx *ctx, const uint8_t *data, size_t len, - const uint8_t target_addr, void *cb_arg) + const uint8_t target_addr, uint8_t target_bus, void *cb_arg) { - const uint32_t rx_can_id = (ctx->rx_can_id & 0xFFFF0000) + const uint32_t rx_can_id = (ctx->rx_can_id & 0xFF000000) | (target_bus << 20) + | (isotp_fast_get_target_bus(ctx->rx_can_id) << 16) | (isotp_fast_get_target_addr(ctx->rx_can_id)) | (target_addr << ISOTP_FIXED_ADDR_TA_POS); if (len <= (CAN_MAX_DLEN - ISOTP_FAST_SF_LEN_BYTE)) { diff --git a/src/isotp_fast_internal.h b/src/isotp_fast_internal.h index b1fe40c..fa27a40 100644 --- a/src/isotp_fast_internal.h +++ b/src/isotp_fast_internal.h @@ -94,3 +94,13 @@ static inline uint8_t isotp_fast_get_target_addr(uint32_t can_id) { return (uint8_t)((can_id & ISOTP_FIXED_ADDR_TA_MASK) >> ISOTP_FIXED_ADDR_TA_POS); } + +static inline uint8_t isotp_fast_get_source_bus(uint32_t can_id) +{ + return (uint8_t)((can_id & 0x000F0000) >> 16); +} + +static inline uint8_t isotp_fast_get_target_bus(uint32_t can_id) +{ + return (uint8_t)((can_id & 0x00F00000) >> 20); +} diff --git a/tests/can/src/main.c b/tests/can/src/main.c index 14839a1..bdde68b 100644 --- a/tests/can/src/main.c +++ b/tests/can/src/main.c @@ -86,9 +86,9 @@ ZTEST(thingset_can, test_send_request_to_node) zassert_false(err < 0, "adding rx filter failed: %d", err); #ifdef CONFIG_ISOTP_FAST - thingset_can_send(req_buf, sizeof(req_buf), 0xCC, NULL, NULL, TEST_RECEIVE_TIMEOUT); + thingset_can_send(req_buf, sizeof(req_buf), 0xCC, 0x0, NULL, NULL, TEST_RECEIVE_TIMEOUT); #else - thingset_can_send(req_buf, sizeof(req_buf), 0xCC); + thingset_can_send(req_buf, sizeof(req_buf), 0xCC, 0x0); #endif err = k_sem_take(&request_tx_sem, TEST_RECEIVE_TIMEOUT); @@ -111,7 +111,7 @@ ZTEST(thingset_can, test_request_response) zassert_equal(err, 0, "bind fail"); uint8_t msg[] = { 0x01, 0x1e }; - err = isotp_fast_send(&client_ctx, msg, sizeof(msg), 0x01, NULL); + err = isotp_fast_send(&client_ctx, msg, sizeof(msg), 0x01, 0x0, NULL); zassert_equal(err, 0, "send fail"); k_sem_take(&request_tx_sem, TEST_RECEIVE_TIMEOUT); diff --git a/tests/isotp_fast/conformance/src/main.c b/tests/isotp_fast/conformance/src/main.c index 16496dd..3161a22 100644 --- a/tests/isotp_fast/conformance/src/main.c +++ b/tests/isotp_fast/conformance/src/main.c @@ -40,7 +40,7 @@ static void send_sf(void) { int ret; - ret = isotp_fast_send(&ctx, random_data, DATA_SIZE_SF, rx_node_addr, NULL); + ret = isotp_fast_send(&ctx, random_data, DATA_SIZE_SF, rx_node_addr, rx_bus_id, NULL); zassert_equal(ret, 0, "Send returned %d", ret); } @@ -68,7 +68,7 @@ static void send_test_data(const uint8_t *data, size_t len) { int ret; - ret = isotp_fast_send(&ctx, data, len, rx_node_addr, INT_TO_POINTER(ISOTP_N_OK)); + ret = isotp_fast_send(&ctx, data, len, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_OK)); zassert_equal(ret, 0, "Send returned %d", ret); } @@ -254,8 +254,8 @@ ZTEST(isotp_fast_conformance, test_send_sf_fixed) filter_id = add_rx_msgq(tx_can_id, CAN_EXT_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", filter_id); - ret = - isotp_fast_send(&ctx, random_data, DATA_SIZE_SF, rx_node_addr, INT_TO_POINTER(ISOTP_N_OK)); + ret = isotp_fast_send(&ctx, random_data, DATA_SIZE_SF, rx_node_addr, rx_bus_id, + INT_TO_POINTER(ISOTP_N_OK)); zassert_equal(ret, 0, "Send returned %d", ret); check_frame_series(&des_frame, 1, &frame_msgq); @@ -487,7 +487,7 @@ ZTEST(isotp_fast_conformance, test_send_timeouts) /* Test timeout for first FC*/ k_sem_reset(&send_compl_sem); start_time = k_uptime_get_32(); - isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, + isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_TIMEOUT_BS)); ret = k_sem_take(&send_compl_sem, K_MSEC(BS_TIMEOUT_UPPER_MS)); time_diff = k_uptime_get_32() - start_time; @@ -496,7 +496,7 @@ ZTEST(isotp_fast_conformance, test_send_timeouts) /* Test timeout for consecutive FC frames */ k_sem_reset(&send_compl_sem); - ret = isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, + ret = isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_TIMEOUT_BS)); zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret); @@ -511,7 +511,7 @@ ZTEST(isotp_fast_conformance, test_send_timeouts) /* Test timeout reset with WAIT frame */ k_sem_reset(&send_compl_sem); - ret = isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, + ret = isotp_fast_send(&ctx, random_data, sizeof(random_data), rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_TIMEOUT_BS)); zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret); @@ -667,7 +667,7 @@ ZTEST(isotp_fast_conformance, test_sender_fc_errors) fc_frame.length = DATA_SIZE_FC; k_sem_reset(&send_compl_sem); - ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, + ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_INVALID_FS)); zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret); @@ -679,12 +679,12 @@ ZTEST(isotp_fast_conformance, test_sender_fc_errors) /* buffer overflow */ can_remove_rx_filter(can_dev, filter_id); - ret = isotp_fast_send(&ctx, random_data, 5 * 1024, rx_node_addr, NULL); + ret = isotp_fast_send(&ctx, random_data, 5 * 1024, rx_node_addr, rx_bus_id, NULL); zassert_equal(ret, ISOTP_N_BUFFER_OVERFLW, "Expected overflow but got %d", ret); filter_id = add_rx_msgq(tx_can_id, CAN_EXT_ID_MASK); k_sem_reset(&send_compl_sem); - ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, + ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_BUFFER_OVERFLW)); check_frame_series(&ff_frame, 1, &frame_msgq); @@ -695,7 +695,7 @@ ZTEST(isotp_fast_conformance, test_sender_fc_errors) /* wft overrun */ k_sem_reset(&send_compl_sem); - ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, + ret = isotp_fast_send(&ctx, random_data, DATA_SEND_LENGTH, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_WFT_OVRN)); check_frame_series(&ff_frame, 1, &frame_msgq); @@ -722,7 +722,8 @@ ZTEST(isotp_fast_conformance, test_sf_length) filter_id = add_rx_msgq(tx_can_id, CAN_EXT_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", filter_id); - ret = isotp_fast_send(&ctx, random_data, 7, rx_node_addr, INT_TO_POINTER(ISOTP_N_OK)); + ret = + isotp_fast_send(&ctx, random_data, 7, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_OK)); zassert_equal(ret, 0, "Send returned %d", ret); check_frame_series(&des_frame, 1, &frame_msgq); @@ -732,7 +733,8 @@ ZTEST(isotp_fast_conformance, test_sf_length) memcpy(&des_frame.data[2], random_data, DATA_SIZE_SF); des_frame.length = 9; - ret = isotp_fast_send(&ctx, random_data, 9, rx_node_addr, INT_TO_POINTER(ISOTP_N_OK)); + ret = + isotp_fast_send(&ctx, random_data, 9, rx_node_addr, rx_bus_id, INT_TO_POINTER(ISOTP_N_OK)); zassert_equal(ret, 0, "Send returned %d", ret); check_frame_series(&des_frame, 1, &frame_msgq); diff --git a/tests/isotp_fast/conformance/src/main.h b/tests/isotp_fast/conformance/src/main.h index b34757f..049a793 100644 --- a/tests/isotp_fast/conformance/src/main.h +++ b/tests/isotp_fast/conformance/src/main.h @@ -72,10 +72,11 @@ const struct isotp_fast_opts fc_opts = { #endif }; -const uint32_t rx_can_id = 0x18DA0201; -const uint32_t tx_can_id = 0x18DA0102; +const uint32_t rx_can_id = 0x180A0201; +const uint32_t tx_can_id = 0x18A00102; const uint8_t rx_node_addr = 0x01; +const uint8_t rx_bus_id = 0xA; const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); struct isotp_fast_ctx ctx; diff --git a/tests/isotp_fast/conformance/testcase.yaml b/tests/isotp_fast/conformance/testcase.yaml index cb6dfa6..f4f94d3 100644 --- a/tests/isotp_fast/conformance/testcase.yaml +++ b/tests/isotp_fast/conformance/testcase.yaml @@ -1,5 +1,5 @@ tests: - thingset_sdk.isotp_fast.conformance.sync.fd: + thingset_sdk.isotp_fast.conformance.sync: tags: - can - isotp