From 4317251eb8c8788a9f92cf6b30754e5fec616399 Mon Sep 17 00:00:00 2001 From: driftregion <20824939+driftregion@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:45:36 +0800 Subject: [PATCH 1/3] implement system functions as callbacks #14 --- isotp.c | 68 +++++++++++++++++++++++++++++++--------------------- isotp.h | 25 +++++++++++++++---- isotp_user.h | 16 ------------- 3 files changed, 62 insertions(+), 47 deletions(-) delete mode 100644 isotp_user.h diff --git a/isotp.c b/isotp.c index 6b5b825..c193f1c 100644 --- a/isotp.c +++ b/isotp.c @@ -47,9 +47,9 @@ static int isotp_send_flow_control(IsoTpLink* link, uint8_t flow_status, uint8_t /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.flow_control.reserve, 0, sizeof(message.as.flow_control.reserve)); - ret = isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); #else - ret = isotp_user_send_can(link->send_arbitration_id, + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, 3); #endif @@ -73,9 +73,9 @@ static int isotp_send_single_frame(IsoTpLink* link, uint32_t id) { /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.single_frame.data + link->send_size, 0, sizeof(message.as.single_frame.data) - link->send_size); - ret = isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); #else - ret = isotp_user_send_can(id, + ret = link->isotp_user_send_can(id, message.as.data_array.ptr, link->send_size + 1); #endif @@ -98,7 +98,7 @@ static int isotp_send_first_frame(IsoTpLink* link, uint32_t id) { (void) memcpy(message.as.first_frame.data, link->send_buffer, sizeof(message.as.first_frame.data)); /* send message */ - ret = isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); if (ISOTP_RET_OK == ret) { link->send_offset += sizeof(message.as.first_frame.data); link->send_sn = 1; @@ -128,9 +128,9 @@ static int isotp_send_consecutive_frame(IsoTpLink* link) { /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.consecutive_frame.data + data_length, 0, sizeof(message.as.consecutive_frame.data) - data_length); - ret = isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); #else - ret = isotp_user_send_can(link->send_arbitration_id, + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, data_length + 1); #endif @@ -147,7 +147,7 @@ static int isotp_send_consecutive_frame(IsoTpLink* link) { static int isotp_receive_single_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len) { /* check data length */ if ((0 == message->as.single_frame.SF_DL) || (message->as.single_frame.SF_DL > (len - 1))) { - isotp_user_debug("Single-frame length too small."); + link->isotp_user_debug("Single-frame length too small."); return ISOTP_RET_LENGTH; } @@ -162,7 +162,7 @@ static int isotp_receive_first_frame(IsoTpLink *link, IsoTpCanMessage *message, uint16_t payload_length; if (8 != len) { - isotp_user_debug("First frame should be 8 bytes in length."); + link->isotp_user_debug("First frame should be 8 bytes in length."); return ISOTP_RET_LENGTH; } @@ -172,12 +172,12 @@ static int isotp_receive_first_frame(IsoTpLink *link, IsoTpCanMessage *message, /* should not use multiple frame transmition */ if (payload_length <= 7) { - isotp_user_debug("Should not use multiple frame transmission."); + link->isotp_user_debug("Should not use multiple frame transmission."); return ISOTP_RET_LENGTH; } if (payload_length > link->receive_buf_size) { - isotp_user_debug("Multi-frame response too large for receiving buffer."); + link->isotp_user_debug("Multi-frame response too large for receiving buffer."); return ISOTP_RET_OVERFLOW; } @@ -204,7 +204,7 @@ static int isotp_receive_consecutive_frame(IsoTpLink *link, IsoTpCanMessage *mes remaining_bytes = sizeof(message->as.consecutive_frame.data); } if (remaining_bytes > len - 1) { - isotp_user_debug("Consecutive frame too short."); + link->isotp_user_debug("Consecutive frame too short."); return ISOTP_RET_LENGTH; } @@ -222,7 +222,7 @@ static int isotp_receive_consecutive_frame(IsoTpLink *link, IsoTpCanMessage *mes static int isotp_receive_flow_control_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len) { /* check message length */ if (len < 3) { - isotp_user_debug("Flow control frame too short."); + link->isotp_user_debug("Flow control frame too short."); return ISOTP_RET_LENGTH; } @@ -241,19 +241,19 @@ int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], ui int ret; if (link == 0x0) { - isotp_user_debug("Link is null!"); + link->isotp_user_debug("Link is null!"); return ISOTP_RET_ERROR; } if (size > link->send_buf_size) { - isotp_user_debug("Message size too large. Increase ISO_TP_MAX_MESSAGE_SIZE to set a larger buffer\n"); + link->isotp_user_debug("Message size too large. Increase ISO_TP_MAX_MESSAGE_SIZE to set a larger buffer\n"); char message[128]; sprintf(&message[0], "Attempted to send %d bytes; max size is %d!\n", size, link->send_buf_size); return ISOTP_RET_OVERFLOW; } if (ISOTP_SEND_STATUS_INPROGRESS == link->send_status) { - isotp_user_debug("Abort previous message, transmission in progress.\n"); + link->isotp_user_debug("Abort previous message, transmission in progress.\n"); return ISOTP_RET_INPROGRESS; } @@ -274,8 +274,8 @@ int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], ui link->send_bs_remain = 0; link->send_st_min = 0; link->send_wtf_count = 0; - link->send_timer_st = isotp_user_get_ms(); - link->send_timer_bs = isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; + link->send_timer_st = link->isotp_user_get_ms(); + link->send_timer_bs = link->isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; link->send_protocol_result = ISOTP_PROTOCOL_RESULT_OK; link->send_status = ISOTP_SEND_STATUS_INPROGRESS; } @@ -343,7 +343,7 @@ void isotp_on_can_message(IsoTpLink *link, uint8_t *data, uint8_t len) { link->receive_bs_count = ISO_TP_DEFAULT_BLOCK_SIZE; isotp_send_flow_control(link, PCI_FLOW_STATUS_CONTINUE, link->receive_bs_count, ISO_TP_DEFAULT_ST_MIN); /* refresh timer cs */ - link->receive_timer_cr = isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; + link->receive_timer_cr = link->isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; } break; @@ -368,7 +368,7 @@ void isotp_on_can_message(IsoTpLink *link, uint8_t *data, uint8_t len) { /* if success */ if (ISOTP_RET_OK == ret) { /* refresh timer cs */ - link->receive_timer_cr = isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; + link->receive_timer_cr = link->isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; /* receive finished */ if (link->receive_offset >= link->receive_size) { @@ -395,7 +395,7 @@ void isotp_on_can_message(IsoTpLink *link, uint8_t *data, uint8_t len) { if (ISOTP_RET_OK == ret) { /* refresh bs timer */ - link->send_timer_bs = isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; + link->send_timer_bs = link->isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; /* overflow */ if (PCI_FLOW_STATUS_OVERFLOW == message.as.flow_control.FS) { @@ -452,7 +452,18 @@ int isotp_receive(IsoTpLink *link, uint8_t *payload, const uint16_t payload_size return ISOTP_RET_OK; } -void isotp_init_link(IsoTpLink *link, uint32_t sendid, uint8_t *sendbuf, uint16_t sendbufsize, uint8_t *recvbuf, uint16_t recvbufsize) { +void isotp_init_link( + IsoTpLink *link, + uint32_t sendid, + uint8_t *sendbuf, + uint16_t sendbufsize, + uint8_t *recvbuf, + uint16_t recvbufsize, + uint32_t (*isotp_user_get_ms)(void), + int (*isotp_user_send_can)(const uint32_t arbitration_id, + const uint8_t* data, const uint8_t size), + void (*isotp_user_debug)(const char* message, ...) + ) { memset(link, 0, sizeof(*link)); link->receive_status = ISOTP_RECEIVE_STATUS_IDLE; link->send_status = ISOTP_SEND_STATUS_IDLE; @@ -461,6 +472,9 @@ void isotp_init_link(IsoTpLink *link, uint32_t sendid, uint8_t *sendbuf, uint16_ link->send_buf_size = sendbufsize; link->receive_buffer = recvbuf; link->receive_buf_size = recvbufsize; + link->isotp_user_get_ms = isotp_user_get_ms; + link->isotp_user_send_can = isotp_user_send_can; + link->isotp_user_debug = isotp_user_debug; return; } @@ -475,15 +489,15 @@ void isotp_poll(IsoTpLink *link) { if (/* send data if bs_remain is invalid or bs_remain large than zero */ (ISOTP_INVALID_BS == link->send_bs_remain || link->send_bs_remain > 0) && /* and if st_min is zero or go beyond interval time */ - (0 == link->send_st_min || (0 != link->send_st_min && IsoTpTimeAfter(isotp_user_get_ms(), link->send_timer_st)))) { + (0 == link->send_st_min || (0 != link->send_st_min && IsoTpTimeAfter(link->isotp_user_get_ms(), link->send_timer_st)))) { ret = isotp_send_consecutive_frame(link); if (ISOTP_RET_OK == ret) { if (ISOTP_INVALID_BS != link->send_bs_remain) { link->send_bs_remain -= 1; } - link->send_timer_bs = isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; - link->send_timer_st = isotp_user_get_ms() + link->send_st_min; + link->send_timer_bs = link->isotp_user_get_ms() + ISO_TP_DEFAULT_RESPONSE_TIMEOUT; + link->send_timer_st = link->isotp_user_get_ms() + link->send_st_min; /* check if send finish */ if (link->send_offset >= link->send_size) { @@ -495,7 +509,7 @@ void isotp_poll(IsoTpLink *link) { } /* check timeout */ - if (IsoTpTimeAfter(isotp_user_get_ms(), link->send_timer_bs)) { + if (IsoTpTimeAfter(link->isotp_user_get_ms(), link->send_timer_bs)) { link->send_protocol_result = ISOTP_PROTOCOL_RESULT_TIMEOUT_BS; link->send_status = ISOTP_SEND_STATUS_ERROR; } @@ -505,7 +519,7 @@ void isotp_poll(IsoTpLink *link) { if (ISOTP_RECEIVE_STATUS_INPROGRESS == link->receive_status) { /* check timeout */ - if (IsoTpTimeAfter(isotp_user_get_ms(), link->receive_timer_cr)) { + if (IsoTpTimeAfter(link->isotp_user_get_ms(), link->receive_timer_cr)) { link->receive_protocol_result = ISOTP_PROTOCOL_RESULT_TIMEOUT_CR; link->receive_status = ISOTP_RECEIVE_STATUS_IDLE; } diff --git a/isotp.h b/isotp.h index c7b6253..36f2642 100644 --- a/isotp.h +++ b/isotp.h @@ -12,7 +12,6 @@ extern "C" { #include "isotp_defines.h" #include "isotp_config.h" -#include "isotp_user.h" /** * @brief Struct containing the data for linking an application to a CAN instance. @@ -54,6 +53,12 @@ typedef struct IsoTpLink { end at receive FC */ int receive_protocol_result; uint8_t receive_status; + + /* user implemented callback functions */ + uint32_t (*isotp_user_get_ms)(void); /* get millisecond */ + int (*isotp_user_send_can)(const uint32_t arbitration_id, + const uint8_t* data, const uint8_t size); /* send can message. should return ISOTP_RET_OK when success. */ + void (*isotp_user_debug)(const char* message, ...); /* print debug message */ } IsoTpLink; /** @@ -65,10 +70,22 @@ typedef struct IsoTpLink { * @param sendbufsize The size of the buffer area. * @param recvbuf A pointer to an area in memory which can be used as a buffer for data to be received. * @param recvbufsize The size of the buffer area. + * @param isotp_user_get_ms A pointer to a function which returns the current time as milliseconds. + * @param isotp_user_send_can A pointer to a function which sends a can message. should return ISOTP_RET_OK when success. + * @param isotp_user_debug A pointer to a function which prints a debug message. */ -void isotp_init_link(IsoTpLink *link, uint32_t sendid, - uint8_t *sendbuf, uint16_t sendbufsize, - uint8_t *recvbuf, uint16_t recvbufsize); +void isotp_init_link( + IsoTpLink *link, + uint32_t sendid, + uint8_t *sendbuf, + uint16_t sendbufsize, + uint8_t *recvbuf, + uint16_t recvbufsize, + uint32_t (*isotp_user_get_ms)(void), + int (*isotp_user_send_can)(const uint32_t arbitration_id, + const uint8_t* data, const uint8_t size), + void (*isotp_user_debug)(const char* message, ...) + ); /** * @brief Polling function; call this function periodically to handle timeouts, send consecutive frames, etc. diff --git a/isotp_user.h b/isotp_user.h deleted file mode 100644 index f99bccc..0000000 --- a/isotp_user.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ISOTP_USER_H__ -#define __ISOTP_USER_H__ - -/* user implemented, print debug message */ -void isotp_user_debug(const char* message, ...); - -/* user implemented, send can message. should return ISOTP_RET_OK when success. -*/ -int isotp_user_send_can(const uint32_t arbitration_id, - const uint8_t* data, const uint8_t size); - -/* user implemented, get millisecond */ -uint32_t isotp_user_get_ms(void); - -#endif // __ISOTP_H__ - From 59dc573a944a2661df6cda42c22edf5cfe53931b Mon Sep 17 00:00:00 2001 From: driftregion <20824939+driftregion@users.noreply.github.com> Date: Thu, 17 Feb 2022 14:02:13 +0800 Subject: [PATCH 2/3] update README.mkd --- README.mkd | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.mkd b/README.mkd index 40b2517..4cc5093 100644 --- a/README.mkd +++ b/README.mkd @@ -61,7 +61,10 @@ You can use isotp-c in the following way: /* Initialize link, 0x7TT is the CAN ID you send with */ isotp_init_link(&g_link, 0x7TT, g_isotpSendBuf, sizeof(g_isotpSendBuf), - g_isotpRecvBuf, sizeof(g_isotpRecvBuf)); + g_isotpRecvBuf, sizeof(g_isotpRecvBuf), + isotp_user_get_ms, + isotp_user_send_can, + isotp_user_debug); while(1) { @@ -128,10 +131,16 @@ If you need handle functional addressing, you must use two separate links, one f /* Initialize link, 0x7TT is the CAN ID you send with */ isotp_init_link(&g_phylink, 0x7TT, g_isotpPhySendBuf, sizeof(g_isotpPhySendBuf), - g_isotpPhyRecvBuf, sizeof(g_isotpPhyRecvBuf)); + g_isotpPhyRecvBuf, sizeof(g_isotpPhyRecvBuf), + isotp_user_get_ms, + isotp_user_send_can, + isotp_user_debug); isotp_init_link(&g_funclink, 0x7TT, g_isotpFuncSendBuf, sizeof(g_isotpFuncSendBuf), - g_isotpFuncRecvBuf, sizeof(g_isotpFuncRecvBuf)); + g_isotpFuncRecvBuf, sizeof(g_isotpFuncRecvBuf), + isotp_user_get_ms, + isotp_user_send_can, + isotp_user_debug); while(1) { From 27379492110d8ae1aaf7e4ca94cf65b31a2192b9 Mon Sep 17 00:00:00 2001 From: Nick James Kirkby <20824939+driftregion@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:10:22 -0700 Subject: [PATCH 3/3] add user_data argument to send_can --- isotp.c | 19 ++++++++++--------- isotp.h | 12 +++++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/isotp.c b/isotp.c index c193f1c..737911c 100644 --- a/isotp.c +++ b/isotp.c @@ -47,7 +47,7 @@ static int isotp_send_flow_control(IsoTpLink* link, uint8_t flow_status, uint8_t /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.flow_control.reserve, 0, sizeof(message.as.flow_control.reserve)); - ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message), link->user_data); #else ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, @@ -73,7 +73,7 @@ static int isotp_send_single_frame(IsoTpLink* link, uint32_t id) { /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.single_frame.data + link->send_size, 0, sizeof(message.as.single_frame.data) - link->send_size); - ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message), link->user_data); #else ret = link->isotp_user_send_can(id, message.as.data_array.ptr, @@ -98,7 +98,7 @@ static int isotp_send_first_frame(IsoTpLink* link, uint32_t id) { (void) memcpy(message.as.first_frame.data, link->send_buffer, sizeof(message.as.first_frame.data)); /* send message */ - ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message), link->user_data); if (ISOTP_RET_OK == ret) { link->send_offset += sizeof(message.as.first_frame.data); link->send_sn = 1; @@ -128,7 +128,7 @@ static int isotp_send_consecutive_frame(IsoTpLink* link) { /* send message */ #ifdef ISO_TP_FRAME_PADDING (void) memset(message.as.consecutive_frame.data + data_length, 0, sizeof(message.as.consecutive_frame.data) - data_length); - ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message)); + ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message), link->user_data); #else ret = link->isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, @@ -459,10 +459,10 @@ void isotp_init_link( uint16_t sendbufsize, uint8_t *recvbuf, uint16_t recvbufsize, - uint32_t (*isotp_user_get_ms)(void), - int (*isotp_user_send_can)(const uint32_t arbitration_id, - const uint8_t* data, const uint8_t size), - void (*isotp_user_debug)(const char* message, ...) + uint32_t (*isotp_user_get_ms)(void), + int (*isotp_user_send_can)(const uint32_t arbitration_id, const uint8_t* data, const uint8_t size, void *user_data), + void (*isotp_user_debug)(const char* message, ...), + void *user_data ) { memset(link, 0, sizeof(*link)); link->receive_status = ISOTP_RECEIVE_STATUS_IDLE; @@ -475,7 +475,8 @@ void isotp_init_link( link->isotp_user_get_ms = isotp_user_get_ms; link->isotp_user_send_can = isotp_user_send_can; link->isotp_user_debug = isotp_user_debug; - + link->user_data = user_data; + return; } diff --git a/isotp.h b/isotp.h index 36f2642..65171f3 100644 --- a/isotp.h +++ b/isotp.h @@ -57,8 +57,9 @@ typedef struct IsoTpLink { /* user implemented callback functions */ uint32_t (*isotp_user_get_ms)(void); /* get millisecond */ int (*isotp_user_send_can)(const uint32_t arbitration_id, - const uint8_t* data, const uint8_t size); /* send can message. should return ISOTP_RET_OK when success. */ + const uint8_t* data, const uint8_t size, void *user_data); /* send can message. should return ISOTP_RET_OK when success. */ void (*isotp_user_debug)(const char* message, ...); /* print debug message */ + void* user_data; /* user data */ } IsoTpLink; /** @@ -73,6 +74,7 @@ typedef struct IsoTpLink { * @param isotp_user_get_ms A pointer to a function which returns the current time as milliseconds. * @param isotp_user_send_can A pointer to a function which sends a can message. should return ISOTP_RET_OK when success. * @param isotp_user_debug A pointer to a function which prints a debug message. + * @param isotp_user_debug A pointer to user data passed to the user implemented callback functions. */ void isotp_init_link( IsoTpLink *link, @@ -81,10 +83,10 @@ void isotp_init_link( uint16_t sendbufsize, uint8_t *recvbuf, uint16_t recvbufsize, - uint32_t (*isotp_user_get_ms)(void), - int (*isotp_user_send_can)(const uint32_t arbitration_id, - const uint8_t* data, const uint8_t size), - void (*isotp_user_debug)(const char* message, ...) + uint32_t (*isotp_user_get_ms)(void), + int (*isotp_user_send_can)(const uint32_t arbitration_id, const uint8_t* data, const uint8_t size, void *user_data), + void (*isotp_user_debug)(const char* message, ...), + void *user_data ); /**