Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISO-TP: new ISO-TP implementation #7

Merged
merged 9 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
container: zephyrprojectrtos/ci:v0.26.2
container: zephyrprojectrtos/ci:v0.26.5
env:
CMAKE_PREFIX_PATH: /opt/toolchains
steps:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# folders generated by west
build
twister-out*

# editors
.vscode/*
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# This CMake file is picked by the Zephyr build system because it is defined
# as the module CMake entry point (see zephyr/module.yml).

add_subdirectory_ifdef(CONFIG_THINGSET_SDK src)
if (CONFIG_ISOTP_FAST OR CONFIG_THINGSET_SDK)
add_subdirectory(src)
endif()

zephyr_include_directories(include)
2 changes: 2 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright (c) The ThingSet Project Contributors
# SPDX-License-Identifier: Apache-2.0

rsource "src/Kconfig.isotp_fast"

menuconfig THINGSET_SDK
bool "ThingSet SDK"

Expand Down
61 changes: 60 additions & 1 deletion include/thingset/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#include <zephyr/canbus/isotp.h>
#include <zephyr/device.h>

#ifdef CONFIG_ISOTP_FAST
#include "isotp_fast.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -138,6 +142,19 @@ extern "C" {
*/
typedef void (*thingset_can_report_rx_callback_t)(uint16_t data_id, const uint8_t *value,
size_t value_len, uint8_t source_addr);
#ifdef CONFIG_ISOTP_FAST
typedef void (*thingset_can_response_callback_t)(uint8_t *data, size_t len, int result,
uint8_t sender_id, void *arg);

struct thingset_can_request_response
{
struct k_sem sem;
struct k_timer timer;
isotp_fast_can_id can_id;
thingset_can_response_callback_t callback;
void *cb_arg;
};
#endif /* CONFIG_ISOTP_FAST */

/**
* ThingSet CAN context storing all information required for one instance.
Expand All @@ -147,13 +164,20 @@ struct thingset_can
const struct device *dev;
struct k_work_delayable reporting_work;
struct k_work_delayable addr_claim_work;
#ifdef CONFIG_ISOTP_FAST
struct isotp_fast_ctx ctx;
#else
struct isotp_recv_ctx recv_ctx;
struct isotp_send_ctx send_ctx;
struct isotp_msg_id rx_addr;
struct isotp_msg_id tx_addr;
#endif
struct k_event events;
thingset_can_report_rx_callback_t report_rx_cb;
#ifdef CONFIG_ISOTP_FAST
struct thingset_can_request_response request_response;
#endif
uint8_t rx_buffer[CONFIG_THINGSET_CAN_RX_BUF_SIZE];
thingset_can_report_rx_callback_t report_rx_cb;
int64_t next_pub_time;
uint8_t node_addr;
};
Expand All @@ -174,6 +198,25 @@ struct thingset_can
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);

#ifdef CONFIG_ISOTP_FAST
/**
* Send ThingSet message to other node
*
* @param ts_can Pointer to the thingset_can context.
* @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 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.
* @param timeout Timeout to wait for a response.
*
* @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);
#else
/**
* Send ThingSet message to other node
*
Expand Down Expand Up @@ -205,6 +248,7 @@ int thingset_can_send_inst(struct thingset_can *ts_can, uint8_t *tx_buf, size_t
* @retval -EAGAIN in case of timeout
*/
int thingset_can_process_inst(struct thingset_can *ts_can, k_timeout_t timeout);
#endif /* CONFIG_ISOTP_FAST */

/**
* Set callback for received reports from other nodes
Expand All @@ -231,6 +275,20 @@ int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can

#else /* !CONFIG_THINGSET_CAN_MULTIPLE_INSTANCES */

#ifdef CONFIG_ISOTP_FAST
/**
* Send ThingSet message to other node
*
* @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.
*
* @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,
thingset_can_response_callback_t rsp_callback, void *callback_arg,
k_timeout_t timeout);
#else
/**
* Send ThingSet message to other node
*
Expand All @@ -241,6 +299,7 @@ int thingset_can_init_inst(struct thingset_can *ts_can, const struct device *can
* @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);
#endif /* CONFIG_ISOTP_FAST */

/**
* Set callback for received reports from other nodes
Expand Down
147 changes: 147 additions & 0 deletions include/thingset/isotp_fast.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright (c) 2023 Brill Power
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/canbus/isotp.h>

#ifndef ISOTP_MSG_FDF
#define ISOTP_MSG_FDF BIT(3)
#endif

/* Represents a sender or a receiver in an ISO-TP fixed addressing scheme */
typedef uint8_t isotp_fast_node_id;
/* ISO-TP message CAN ID */
typedef uint32_t isotp_fast_can_id;

/**
* Callback invoked when a message is received.
*
* @param buffer Pointer to a @ref net_buf. Call @ref net_buf_frags_len to
* obtain the length of the buffer, then @ref net_buf_linearize to copy the
* contents of the buffer into a local buffer.
* @param rem_len At present, this should always be zero. In future, this
* callback may be called repeatedly as a message's packets arrive to reduce
* the need to buffer an entire message in memory before it is dispatched
* to user code.
* @param can_id The CAN ID of the message that has been received.
* @param arg The value of @ref recv_cb_arg passed to @ref isotp_fast_bind.
*/
typedef void (*isotp_fast_recv_callback_t)(struct net_buf *buffer, int rem_len,
isotp_fast_can_id can_id, void *arg);

/**
* Callback invoked when an error occurs during message receiption.
*
* @param error The error code.
* @param can_id The CAN ID of the sender of the message, if available.
* @param arg The value of @ref recv_cb_arg passed to @ref isotp_fast_bind.
*/
typedef void (*isotp_fast_recv_error_callback_t)(int8_t error, isotp_fast_can_id can_id, void *arg);

/**
* Callback invoked when a message has been sent.
*
* @param result If non-zero, an error has occurred.
* @param arg The value of @ref sent_cb_arg passed to @ref isotp_fast_send.
*/
typedef void (*isotp_fast_send_callback_t)(int result, void *arg);

/**
* Options pertaining to the bound context.
*/
struct isotp_fast_opts
{
uint8_t bs; /**< Block size. Number of CF PDUs before next CF is sent */
uint8_t stmin; /**< Minimum separation time. Min time between frames */
uint8_t flags;
};

/**
* General ISO-TP fast context object.
*/
struct isotp_fast_ctx
{
/** list of currently in-flight send contexts */
sys_slist_t isotp_send_ctx_list;
/** list of currently in-flight receive contexts */
sys_slist_t isotp_recv_ctx_list;
/** The CAN device to which the context is bound via @ref isotp_fast_bind */
const struct device *can_dev;
/** Identifies the CAN filter which filters incoming messages */
int filter_id;
/** Pointer to context options described above */
const struct isotp_fast_opts *opts;
/** Callback that is invoked when a message is received */
isotp_fast_recv_callback_t recv_callback;
/** Pointer to user-supplied data to be passed to @ref recv_callback */
void *recv_cb_arg;
/** Callback that is invoked when a receive error occurs */
isotp_fast_recv_error_callback_t recv_error_callback;
/** Callback that is invoked when a message is sent */
isotp_fast_send_callback_t sent_callback;
/** CAN ID of this node, used in both transmission and receipt of messages */
isotp_fast_can_id rx_can_id;
#ifdef CONFIG_ISOTP_FAST_BLOCKING_RECEIVE
sys_slist_t wait_recv_list;
#endif
};

/**
* Binds the supplied ISO-TP context to the supplied CAN device. Messages
* addressed to the given address (@ref my_addr) will be delivered to user
* code by invoking the supplied callback, @ref recv_callback.
*
* @param ctx A pointer to the general ISO-TP context
* @param can_dev The CAN device to which the context should be bound
* @param rx_can_id The address to listen on for incoming messages. When
* transmitting messages, the target address byte will be
* used as the source address byte.
* @param opts A pointer to an options structure, @ref isotp_fast_opts
* @param recv_callback A callback that is invoked when a message is received
* @param recv_cb_arg A pointer to data to be supplied to @ref recv_callback
* @param recv_error_callback A callback that is invoked when an error occurs.
* @param sent_callback A callback that is invoked when a message is sent
*
* @returns 0 on success, otherwise an error code < 0.
*/
int isotp_fast_bind(struct isotp_fast_ctx *ctx, const struct device *can_dev,
const isotp_fast_can_id rx_can_id, const struct isotp_fast_opts *opts,
isotp_fast_recv_callback_t recv_callback, void *recv_cb_arg,
isotp_fast_recv_error_callback_t recv_error_callback,
isotp_fast_send_callback_t sent_callback);

/**
* Unbinds the supplied ISO-TP context. Removes the CAN filter if it was
* successfully set.
*
* @param ctx A pointer to the context to unbind
*
* @returns 0 on success.
*/
int isotp_fast_unbind(struct isotp_fast_ctx *ctx);

#ifdef CONFIG_ISOTP_FAST_BLOCKING_RECEIVE
int isotp_fast_recv(struct isotp_fast_ctx *ctx, struct can_filter sender, uint8_t *buf, size_t size,
k_timeout_t timeout);
#endif

/**
* Send a message to a given recipient. If the message fits within a
* CAN frame, it will be sent synchronously. If not, it will be sent
* asynchronously.
*
* @param ctx The bound context on which the message should be sent
* @param data A pointer to the data containing the message to send
* @param len The length of the data in @ref data
* @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 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 isotp_fast_node_id target_addr, void *sent_cb_arg);
6 changes: 4 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright (c) The ThingSet Project Contributors
# SPDX-License-Identifier: Apache-2.0

target_sources(app PRIVATE sdk.c)
target_sources(app PRIVATE packetizer.c)
target_sources_ifdef(CONFIG_ISOTP_FAST app PRIVATE isotp_fast.c)

target_sources_ifdef(CONFIG_THINGSET_SDK app PRIVATE sdk.c)
target_sources_ifdef(CONFIG_THINGSET_SDK app PRIVATE packetizer.c)

target_sources_ifdef(CONFIG_THINGSET_AUTH app PRIVATE auth.c)
target_sources_ifdef(CONFIG_THINGSET_BLE app PRIVATE ble.c)
Expand Down
41 changes: 41 additions & 0 deletions src/Kconfig.isotp_fast
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
menuconfig ISOTP_FAST
bool "New ISO-TP context"
depends on CAN
depends on ISOTP
select EVENTS

if ISOTP_FAST

config ISOTP_FAST_RX_MAX_PACKET_COUNT
int "Max packets for ISO-TP reception"
default 8
help
Max number of packets expected in a single ISO-TP message.

config ISOTP_FAST_RX_BUF_COUNT
int "Max number of RX buffers"
default 4
help
This broadly implies the max number of simultaneous receptions.

config ISOTP_FAST_TX_BUF_COUNT
int "Max number of TX buffers"
default 4
help
This broadly implies the max number of simultaneous transmissions.

config ISOTP_FAST_PER_FRAME_DISPATCH
bool "Per-frame dispatch"
default false
help
Whether to invoke the receive callback on receipt of every frame

config ISOTP_FAST_BLOCKING_RECEIVE
bool "Blocking receive"
default false
depends on !ISOTP_FAST_PER_FRAME_DISPATCH
help
Whether to make blocking receive functionality available
to ease migration from the old API.

endif
Loading