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

Implement system functions as callbacks #22

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 12 additions & 3 deletions README.mkd
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand Down Expand Up @@ -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) {

Expand Down
71 changes: 43 additions & 28 deletions isotp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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), link->user_data);
#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
Expand All @@ -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), link->user_data);
#else
ret = isotp_user_send_can(id,
ret = link->isotp_user_send_can(id,
message.as.data_array.ptr,
link->send_size + 1);
#endif
Expand All @@ -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), link->user_data);
if (ISOTP_RET_OK == ret) {
link->send_offset += sizeof(message.as.first_frame.data);
link->send_sn = 1;
Expand Down Expand Up @@ -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), link->user_data);
#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
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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 *user_data),
void (*isotp_user_debug)(const char* message, ...),
void *user_data
) {
memset(link, 0, sizeof(*link));
link->receive_status = ISOTP_RECEIVE_STATUS_IDLE;
link->send_status = ISOTP_SEND_STATUS_IDLE;
Expand All @@ -461,7 +472,11 @@ 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;
link->user_data = user_data;

return;
}

Expand All @@ -475,15 +490,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) {
Expand All @@ -495,7 +510,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;
}
Expand All @@ -505,7 +520,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;
}
Expand Down
27 changes: 23 additions & 4 deletions isotp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -54,6 +53,13 @@ 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, 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;

/**
Expand All @@ -65,10 +71,23 @@ 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.
* @param isotp_user_debug A pointer to user data passed to the user implemented callback functions.
*/
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 *user_data),
void (*isotp_user_debug)(const char* message, ...),
void *user_data
);

/**
* @brief Polling function; call this function periodically to handle timeouts, send consecutive frames, etc.
Expand Down
16 changes: 0 additions & 16 deletions isotp_user.h

This file was deleted.