CAN

The HAL interface to CANbus driver should be the one described in ISO11898 to form a normalized layer between layer 2 and layer 3. The original CAN standard describes layer 1 and layer 2 with a 8 byte payload, 11 or 29 bid ID, RTR flag, a DLC and a CRC. At this level this is the only things that interest us, so we create a fixed primitive for this purpose to send and receive.

The hardware CAN interface usually contain a queue, but we need to add queues of our own both ways to enable the user application some freedom. To support that we need to know the age of a message, so we insert a 16 bit ms counter. Age under 1 ms is not of interest in this context.

 CAN Message Struct

  • 29 bit ID
  • 1 bit Ext flag =1 for 29 bit, 0 for 11 bit ID.
  • 1 bit RTR flag
  • 1 spare bit to align the above on 32 bits
  •  4 bit DLC (Data Length Code). Indicate bytes used on payload.
  • 4 flag bits indicating status
  • 8 spare bits for flags/status.
  • 16 bit ToI (Time of Insertion) in ms.
  • 8 byte p

That is a total of 16 bytes per message. We will set the queues to 50 each way by default. That means we use 800 byte x 2 per CAN port for queues.

The struct is called “LSDU” in CAN documentation, but our content is extended so we call it CANLayer2Primitive for simplicity.

The interface should contain a classic Init, Send, Receive, Open, Close and even mechanism to indicate message, error etc.

Event’s are happenings in our system where one task need to signal another. This is handled by the RTOS so we simply call RTOS::SignalTask(…) with event id’s provided during setup.

Init Initialize CAN port and wire to an actual CAN driver port. Will set default communication parameters.
Open Open a communication port with selected bitrate.
Send Send a message.
Receive Receive a message.
Close Close a port.
SetEventID Set event ID’s used (Receive and Error)

 This is a draft!