Skip to content

Commit

Permalink
CAN: Rework multi-frame reports to include MF type
Browse files Browse the repository at this point in the history
  • Loading branch information
martinjaeger committed Mar 6, 2024
1 parent 22b5e7f commit 278a1cc
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 25 deletions.
30 changes: 15 additions & 15 deletions include/thingset/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ extern "C" {
*
* Multi-frame reports:
*
* 28 26 25 24 23 20 19 16 15 13 12 11 8 7 0
* +----------+-----+-----+---------+------+-----+------+-------------+
* | Priority | 0x1 | res | src bus | msg# | end | seq# | source addr |
* +----------+-----+-----+---------+------+-----+------+-------------+
* 28 26 25 24 23 20 19 16 15 14 13 12 11 8 7 0
* +----------+-----+-----+---------+------+---------+------+-------------+
* | Priority | 0x1 | res | src bus | msg# | MF type | seq# | source addr |
* +----------+-----+-----+---------+------+---------+------+-------------+
*
* Priority: 5 or 7
* msg#: Wrapping message counter from 0 to 7
* end: End of message flag
* msg#: Wrapping message counter from 0 to 3
* MF type: 0: first frame, 1: consecutive frame, 2: last frame, 3: single frame
* seq#: Wrapping sequence counter from 0 to 15
* src bus and res: Either source bus or bridge number
*
Expand Down Expand Up @@ -108,21 +108,21 @@ extern "C" {
#define THINGSET_CAN_DATA_ID_GET(id) \
(((uint32_t)id & THINGSET_CAN_DATA_ID_MASK) >> THINGSET_CAN_DATA_ID_POS)

/* message number, end flag and sequence number for multi-frame reports */
/* message number, type and sequence number for multi-frame reports */
#define THINGSET_CAN_SEQ_NO_POS (8U)
#define THINGSET_CAN_SEQ_NO_MASK (0xF << THINGSET_CAN_SEQ_NO_POS)
#define THINGSET_CAN_SEQ_NO_SET(no) \
(((uint32_t)no << THINGSET_CAN_SEQ_NO_POS) & THINGSET_CAN_SEQ_NO_MASK)
#define THINGSET_CAN_SEQ_NO_GET(id) \
(((uint32_t)id & THINGSET_CAN_SEQ_NO_MASK) >> THINGSET_CAN_SEQ_NO_POS)
#define THINGSET_CAN_END_FLAG_POS (12U)
#define THINGSET_CAN_END_FLAG_MASK (0x1 << THINGSET_CAN_END_FLAG_POS)
#define THINGSET_CAN_END_FLAG_SET(val) \
(((uint32_t)val << THINGSET_CAN_END_FLAG_POS) & THINGSET_CAN_END_FLAG_MASK)
#define THINGSET_CAN_END_FLAG_GET(id) \
(((uint32_t)id & THINGSET_CAN_END_FLAG_MASK) >> THINGSET_CAN_END_FLAG_POS)
#define THINGSET_CAN_MSG_NO_POS (13U)
#define THINGSET_CAN_MSG_NO_MASK (0x7 << THINGSET_CAN_MSG_NO_POS)
#define THINGSET_CAN_MF_TYPE_POS (12U)
#define THINGSET_CAN_MF_TYPE_MASK (0x3 << THINGSET_CAN_MF_TYPE_POS)
#define THINGSET_CAN_MF_TYPE_FIRST (0U << THINGSET_CAN_MF_TYPE_POS)
#define THINGSET_CAN_MF_TYPE_CONSEC (1U << THINGSET_CAN_MF_TYPE_POS)
#define THINGSET_CAN_MF_TYPE_LAST (2U << THINGSET_CAN_MF_TYPE_POS)
#define THINGSET_CAN_MF_TYPE_SINGLE (3U << THINGSET_CAN_MF_TYPE_POS)
#define THINGSET_CAN_MSG_NO_POS (14U)
#define THINGSET_CAN_MSG_NO_MASK (0x3 << THINGSET_CAN_MSG_NO_POS)
#define THINGSET_CAN_MSG_NO_SET(no) \
(((uint32_t)no << THINGSET_CAN_MSG_NO_POS) & THINGSET_CAN_MSG_NO_MASK)
#define THINGSET_CAN_MSG_NO_GET(id) \
Expand Down
28 changes: 24 additions & 4 deletions src/can.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ static const struct isotp_fast_opts fc_opts = {
struct thingset_can_rx_context
{
uint8_t src_addr;
uint8_t msg;
uint8_t seq;
bool started;
};

NET_BUF_POOL_DEFINE(thingset_can_rx_buffer_pool, CONFIG_THINGSET_CAN_REPORT_RX_NUM_BUFFERS,
Expand Down Expand Up @@ -193,12 +195,25 @@ static void thingset_can_report_rx_cb(const struct device *dev, struct can_frame
{
struct thingset_can *ts_can = user_data;
uint8_t source_addr = THINGSET_CAN_SOURCE_GET(frame->id);
uint8_t msg_no = THINGSET_CAN_MSG_NO_GET(frame->id);
uint8_t seq = THINGSET_CAN_SEQ_NO_GET(frame->id);

struct net_buf *buffer = thingset_can_get_rx_buf(source_addr);
if (buffer != NULL) {
struct thingset_can_rx_context *context =
(struct thingset_can_rx_context *)buffer->user_data;

if ((frame->id & THINGSET_CAN_MF_TYPE_MASK) == THINGSET_CAN_MF_TYPE_SINGLE
|| (frame->id & THINGSET_CAN_MF_TYPE_MASK) == THINGSET_CAN_MF_TYPE_FIRST)
{
context->msg = msg_no;
}
else if (context->msg != msg_no) {
LOG_WRN("Out-of-message frame received");
thingset_can_free_rx_buf(buffer);
return;
}

if ((context->seq & 0xF) == seq) {
int chunk_len = can_dlc_to_bytes(frame->dlc);
if (buffer->len + chunk_len > buffer->size) {
Expand All @@ -209,7 +224,9 @@ static void thingset_can_report_rx_cb(const struct device *dev, struct can_frame
uint8_t *buf = net_buf_add(buffer, chunk_len);
LOG_DBG("Reassembling %d bytes from ID 0x%08X", chunk_len, frame->id);
memcpy(buf, frame->data, chunk_len);
if (THINGSET_CAN_END_FLAG_GET(frame->id) != 0) {
if ((frame->id & THINGSET_CAN_MF_TYPE_MASK) == THINGSET_CAN_MF_TYPE_SINGLE
|| (frame->id & THINGSET_CAN_MF_TYPE_MASK) == THINGSET_CAN_MF_TYPE_LAST)
{
LOG_DBG("Finished; dispatching %d bytes from node %x", buffer->len, source_addr);
ts_can->report_rx_cb(buffer->data, buffer->len, source_addr);
thingset_can_free_rx_buf(buffer);
Expand All @@ -218,8 +235,8 @@ static void thingset_can_report_rx_cb(const struct device *dev, struct can_frame
context->seq++;
}
else {
/* out-of-sequence message received, so free the buffer */
LOG_WRN("Out-of-sequence message received");
/* out-of-sequence frame received, so free the buffer */
LOG_WRN("Out-of-sequence frame received");
thingset_can_free_rx_buf(buffer);
}
}
Expand Down Expand Up @@ -257,16 +274,19 @@ int thingset_can_send_report_inst(struct thingset_can *ts_can, const char *path,
};

do {
uint32_t mf_type;
if (len - pos > CAN_MAX_DLEN) {
chunk_len = CAN_MAX_DLEN;
mf_type = (pos == 0) ? THINGSET_CAN_MF_TYPE_FIRST : THINGSET_CAN_MF_TYPE_CONSEC;
}
else {
chunk_len = len - pos;
end = true;
mf_type = (pos == 0) ? THINGSET_CAN_MF_TYPE_SINGLE : THINGSET_CAN_MF_TYPE_LAST;
}
memcpy(frame.data, tx_buf->data + pos, chunk_len);
frame.id = THINGSET_CAN_PRIO_REPORT_LOW | THINGSET_CAN_TYPE_MF_REPORT
| THINGSET_CAN_MSG_NO_SET(ts_can->msg_no) | THINGSET_CAN_END_FLAG_SET(end)
| THINGSET_CAN_MSG_NO_SET(ts_can->msg_no) | mf_type
| THINGSET_CAN_SEQ_NO_SET(seq) | THINGSET_CAN_SOURCE_SET(ts_can->node_addr);
frame.dlc = can_bytes_to_dlc(chunk_len);
if (end && IS_ENABLED(CONFIG_CAN_FD_MODE)) {
Expand Down
2 changes: 1 addition & 1 deletion tests/can/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ CONFIG_ZTEST_NEW_API=y
CONFIG_ZTEST_SUMMARY=n

# enable click-able absolute paths in assert messages
#CONFIG_BUILD_OUTPUT_STRIP_PATHS=n
CONFIG_BUILD_OUTPUT_STRIP_PATHS=n
16 changes: 11 additions & 5 deletions tests/can/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ ZTEST(thingset_can, test_receive_packetized_report)

struct can_frame report_frames[] = {
{
.id = 0x1D000002, /* node with address 0x02, seq 0x0, msg 0x0 */
.id = 0x1D000002, /* msg 0x0, first frame, seq 0x0 */
.flags = CAN_FRAME_IDE,
.data = { 0x1F, 0x19, 0x12, 0x34, 0x6B, 0x68, 0x65, 0x6C },
.dlc = 8,
},
{
.id = 0x1D001102, /* node with address 0x02, seq 0x1, msg 0x0, end = true */
.id = 0x1D002102, /* msg 0x0, last frame, seq 0x1 */
.flags = CAN_FRAME_IDE,
.data = { 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64 },
.dlc = 8,
Expand Down Expand Up @@ -171,13 +171,19 @@ ZTEST(thingset_can, test_send_packetized_report)

for (uint32_t seq = 0; seq * CAN_MAX_DLEN < strlen(report_exp); seq++) {
int missing_len = strlen(report_exp) - seq * CAN_MAX_DLEN;
uint32_t end = missing_len <= CAN_MAX_DLEN ? 0x00001000 : 0;
uint32_t mf_type;
if (missing_len > CAN_MAX_DLEN) {
mf_type = (seq == 0) ? 0x00000000 : 0x00001000;
}
else {
mf_type = (seq == 0) ? 0x00003000 : 0x00002000;
}
err = k_msgq_get(&report_packets_msgq, &rx_frame, K_MSEC(100));
zassert_equal(err, 0, "receiving CAN frame %d timed out", seq);
zassert_equal(rx_frame.id, 0x1d000001 | ((msg_no & 0x7) << 13) | end | (seq << 8),
zassert_equal(rx_frame.id, 0x1d000001 | ((msg_no & 0x3) << 14) | mf_type | (seq << 8),
"CAN ID 0x%x for seq %d of msg %d not correct", rx_frame.id, seq, msg_no);
zassert_mem_equal(rx_frame.data, report_exp + seq * CAN_MAX_DLEN,
end ? missing_len : CAN_MAX_DLEN);
MIN(missing_len, CAN_MAX_DLEN));
}
}

Expand Down

0 comments on commit 278a1cc

Please sign in to comment.