Send multiple frames with Flexcan?

Status
Not open for further replies.

graner

New member
Hi, I'm about to do a project where I'm supposed to send encrypted data over CANbus. The CANbus is up and running, no problem so far. But my question is, is it possible to send 16 bytes divided in two or more frames without changing ID?

Anyone who knows and maybe can share some examples?

Best regards
 
Maybe this does what you want ?

https://en.wikipedia.org/wiki/ISO_15765-2

There is C code here (other repos exist but this one looks most developed - please let me know if you find a better one) :

https://github.com/Beatsleigher/isotp-c


In general, although you can send a stream of different CAN messages to the same ID, it's not the way CAN is supposed to work. Modern CAN interfaces (such as the one on teensy) have a FIFO mode that copes with this fairly well, but traditional CAN had only mailboxes for each used ID. If you didn't empty the mailbox quickly, you'd lose an intermediate value (and CAN's arbitration system makes short delays for some frames likely).

I have in the past implemented a streaming protocol over CAN that used a rotation of IDs to create a virtual FIFO in the receiver. It worked well and was more efficient than iso-tp (it uses the rotation as a sliding window) but it does require about 8 IDs in each direction. ISO-tp uses only a single ID.

Also note that you can send frames longer than 8 bytes using CAN-FD, if you are able to have hardware that supports it.
 
Depends if you actually follow the standard, or invent your own.
If you are connecting to something that is a "standard" then there isn't much I can do to help.
I usually treat CAN like serial, but with the ability to use additional priority IDs and using extended IDs.
I don't use the normal library either, I use my own, but it is only for Teensy 3.x, and a different MCU (that Paul isn't using on any of his boards, and beyond the scope of the question).

This is beyond the scope of the question as well, but worth mentioning:
I reserve the non-extended ID for firmware update. When it sees a packet there requesting a firmware update, it goes to updating.

What I use it for personally, is a reliable serial communication, with the ability to use only 3 wires, and TX/RX on a separate ID console data (debugging, etc).
I am able to talk to 8 other MCU (either between them or to the main host) as well as update software on any of them selectively.
I reserve CAN_SRC_8/CAN_DST_8 for the debug host ID. Debug IMHO isn't something that needs to be a high priority anyway, because of FIFOs.
I spread the message ID into something that is like an address to, an address from, then priorities and the additional function.
Here's the basic layout, which I will share, that has worked very well for me.

Code:
// source message bitmap -- each device has an address.
#define    CAN_SRC_0 (0x00000000u) // highest source priority
#define    CAN_SRC_1 (0x00000001u)
#define    CAN_SRC_2 (0x00000002u)
#define    CAN_SRC_3 (0x00000004u)
#define    CAN_SRC_4 (0x00000008u)
#define    CAN_SRC_5 (0x00000010u)
#define    CAN_SRC_6 (0x00000020u)
#define    CAN_SRC_7 (0x00000040u)
#define    CAN_SRC_8 (0x00000080u) // lowest source priority
#define CAN_SRC_DBUG (0x000000FFu) // rock bottom source, only for debugger

// source message priority.
#define SRC_MSG_PRI0 (0x00000000u) // highest priority
#define SRC_MSG_PRI1 (0x00000100u)
#define SRC_MSG_PRI2 (0x00000200u)
#define SRC_MSG_PRI3 (0x00000400u)
#define SRC_MSG_PRI4 (0x00000800u) // lowest priority
#define SRC_MSG_DBUG (0x00000F00u) // rock bottom priority, only for debug mess

// message types, 5 + one debug type
#define  MSG_IS_TYP0 (0x00000000u) // highest priority
#define  MSG_IS_TYP1 (0x00001000u)
#define  MSG_IS_TYP2 (0x00002000u)
#define  MSG_IS_TYP3 (0x00004000u)
#define  MSG_IS_TYP4 (0x00008000u) // lowest priority
#define  MSG_IS_DBUG (0x0000F000u) // rock bottom priority, only for debug mess

// Destination message bitmap -- each device has an address.
#define    CAN_DST_0 (0x00000000u) // highest destination priority
#define    CAN_DST_1 (0x00010000u)
#define    CAN_DST_2 (0x00020000u)
#define    CAN_DST_3 (0x00040000u)
#define    CAN_DST_4 (0x00080000u)
#define    CAN_DST_5 (0x00100000u)
#define    CAN_DST_6 (0x00200000u)
#define    CAN_DST_7 (0x00400000u)
#define    CAN_DST_8 (0x00800000u) // lowest destination priority
#define CAN_DST_DBUG (0x00FF0000u) // rock bottom destination, only to debugger

// destination message priority.
#define DST_MSG_PRI0 (0x00000000u) // highest priority
#define DST_MSG_PRI1 (0x01000000u)
#define DST_MSG_PRI2 (0x02000000u)
#define DST_MSG_PRI3 (0x04000000u)
#define DST_MSG_PRI4 (0x08000000u) // lowest priority
#define DST_MSG_DBUG (0x0F000000u) // rock bottom priority, debug only

// Message priority
#define DST_MSG_PRIH (0x00000000u) // highest priority
#define DST_MSG_PRIL (0x10000000u) // lowest priority

#define CAN_DEBUG_MESSAGE (SRC_MSG_DBUG | MSG_IS_DBUG | DST_MSG_DBUG | DST_MSG_PRIL)

#define RCV_DFLT (CAN_SRC_DBUG << 16) // Any message for us.
#define CAN_to_ME(FRAME_ID)  ((FRAME_ID & CAN_DST_DBUG) == RCV_DFLT)

#define CAN_FROM_DBG (CAN_SRC_DBUG | CAN_DEBUG_MESSAGE)
#define CAN_TO_DBG   (CAN_DST_DBUG | CAN_DEBUG_MESSAGE)

#define   CANHI_SRC (CAN_SRC_DBUG | DST_MSG_PRIH) // High priority message
#define   CANLO_SRC (CAN_SRC_DBUG | DST_MSG_PRIL) // Low priority message

#define   TOCANDBUG (CAN_SRC_DBUG | CAN_TO_DBG) // Debug message TO debugger
#define FROMCANDBUG(TARGET_DEST) (CAN_FROM_DBG | TARGET_DEST)


Frames are sent to one of two FIFOs. The first FIFO handles low priority, the second FIFO handles higher priority. When there is a free TX mailbox, higher priority is checked first, then the lower. In Flexcan hardware, it will send the message with the highest priority first.

ALL frames are received, even if not for us. These are decided and sorted in the frame handler.
I still SHOULD do filtering for it, but this works great for me at this time, even at 1mbit rates. This doesn't stress the CPU much, considering the latency between frames.
You do not need to sort out which one came in first: Flexcan does this already, as it has timestamps, and if priority is equal, it will send the message with the lower timestamp.


HTH :)
 
Status
Not open for further replies.
Back
Top