Table of Contents

Overview an History

CAN (Controller Area Network) is a serial bus standard, originally developed in the 1980 by Bosch, for connecting
electronic control units. CAN was specifically designed to be robust in electromagnetically noisy
environments (e.g. for use in broadcasting channel in cars) and can utilize a differential balanced line like RS-485.
Although initially created for automotive purposes (as a vehicle bus), nowadays it is used in many embedded control
applications (e.g., industrial automation and so on) that may be subject to noise.
The CAN data link layer protocol is standardized in ISO 11898-1 (2003).

CAN specific details

Supported bit rates reach up to 1 Mbit/s at network lengths below 40m (twisted pair). Decreasing the bit rate allows
longer network distances (e.g. 125 kbit/s at 500 m).

CAN features an automatic collision free transmission. A CAN message that is transmitted with highest priority
will win the arbitration, and the node transmitting the lower priority message will sense this, back off and wait upon
the next bargain to start a transmission.

Bit timing

Each node in a CAN network uses its own private clock which will not be transmitted to the other participants.
Rather the synchronization is done by dividing each bit of the frame into a number of segments:

Using CAN

Depending on the type of your FESTO SBOx-smartcamera your device is CAN-enabled .

The access to the CAN-hardware is provided by the mcp2515.ko.
The actual supported ioctl commands are found at can.h. If the ioctl is write or read/write (meaning output is returned to the calling process), the ioctl call returns the output of this function.

Here is a list of the most used ioctl commands

Typical initialization sequence

CAN Diagnosis

According to the used driver version some kind of CAN-message tracing and status information may be implemented.
To get the actual supported CAN driver features enter

~ $ dmesg
...
mcp2515 - 3.1.4-festo0 264 build Nov 29 2007 18:03:26
  CAN driver supports /proc/canstate status!!
  CAN driver supports /dev/canmsg0 message tracing
...
~ $

As shown above CAN message tracing AND status informations are supported.

CAN tracing

If message tracing is supported you can start to get information of transmitted and received CAN-messages directly from the driver.
This feature is EXTREMELY USEFUL because you don't need a CAN-analyzer for some quick checking if your CAN-hardware is really running or if you want to know the cycle time of some CAN-messages.
Even the used baudrate is of no matter for tracing.

~ $ cat /dev/canmsg0
   1136073142:220135 Status: OPEN
TX 1136073142:222277 ID=0x080 [no data]
TX 1136076695:877487 ID=0x011 [0xec 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
RX 1136076695:878493 ID=0x077 [0xec 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
TX 1136076695:977476 ID=0x011 [0xed 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
RX 1136076695:978444 ID=0x077 [0xed 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
TX 1136076696:077467 ID=0x011 [0xee 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
RX 1136076696:078434 ID=0x077 [0xee 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
TX 1136076696:177455 ID=0x011 [0xef 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
RX 1136076696:178461 ID=0x077 [0xef 0x0e 0x00 0x00 0x00 0x00 0x00 0x00]
TX 1136076825:459306 ID=0x022 [0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00]
   1136076825:459373 Error: TX_RETRY
   1136076825:459421 Error: TX_RETRY
   1136076825:459527 Error: TX_ERR EFLAG( TXWAR )
TX 1136076825:559261 ID=0x022 [0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00]
   1136076825:559408 Error: ERR_PASSIVE TX_RETRY EFLAG( TXEP TXWAR )
   1136076825:559448 Error: TX_ERR
TX 1136076825:659341 ID=0x022 [0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00]
   1136076825:659420 Error: TX_RETRY
   1136076825:659470 Error: TX_RETRY
   1136076825:659521 Error: TX_ERR
TX 1136076825:759329 ID=0x022 [0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00]
   1136076825:759442 Error: BUS_OFF TX_RETRY EFLAG( TXBO )
   1136076825:760879 Error: TX_RETRY
   1136076825:760934 Error: TX_ERR
TX 1136076825:859329 ID=0x022 [0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00]
   1136076825:859420 Error: TX_RETRY
   1136076825:859470 Status: TX_PEND
   1136076825:860120 Status: IOC_RESET
   1136076825:865247 Status: CLOSE
Column Value + Description
1 RX … received CAN message
TX … transmitted CAN message
<SPACES> … error/status message
2 time in microseconds(1e-6)
i.e. 1136073142:222277 should be interpreted as 1136079142 seconds and 222277 microseconds since 1970
3 ID= source or destination id according to type of message (3-digit for SID (i.e. ID=0×080) and 8-digit for EID)
Error: in case of any detected error
Status: driver relevant status information
4 ID=
transmitted/received data (if no data is transmitted/received [no data] will be displayed)

Error:
type of error
IRQ_FLOOD 
RXB_FULL
BUS_OFF
ERR_PASSIVE
BUF_OVERFLOW
TX_RETRY
TX_ERR
TX_MLOA
RX_ERR

IRQ_FLOOD … too many CAN interrupts ⇒ CAN-ISR overload
RXB_FULL… device drivers receive buffer is full ⇒ lost received message
BUS_OFF … chip state changed to bus off ⇒ no message receive/transmit possible
ERR_PASSIVE … chip's state changed to error passive mode ⇒ no active error frames sent
BUF_OVERFLOW … chip's receive buffer already occupied ⇒ tried to put message into other receive buffer
TX_RETRY … message could not be transmitted (no acknowledge from destination) so it will be retried
TX_ERR … retry count for message to be transmitted exceeded ⇒ last tx-message got lost!!
TX_MLOA… lost bus arbitration during transmit (each lost arbitration counts as a retry!!)
RX_ERR… chip's info about erroneous receive

also the errorflags of the EFLAG-register of the CAN-chip will be displayed

EFLAG( RX0OVR RX1OVR TXBO TXEP RXEP TXWAR RXWAR )

EFLAG( RX0OVR ) … chip's receive buffer 0 was full ⇒ message put into receive buffer 1
EFLAG( TXBO ) … transmit error counter reached 255 ⇒ chip set to bus off
EFLAG( TXEP RXEP ) … CAN chip is now in the state error passive, set when TEC or REC is equal or greater than 128
EFLAG( TXWAR RXWAR ) … set when transmit or receive Error counter is equal or greater than 96

Status:

TX_PEND
IOC_RESET
OPEN
CLOSE

TX_PEND… driver keeps message(s) inside queue (may occur after change NORMAL→CONFIG mode, use CAN_IOC_RESET to reset)
IOC_RESET… CAN_IOC_RESET has been executed deleting any TX or RX messages at the driver's buffers
OPEN… device has been opened
CLOSE… device has been closed

Remember you can use grep to filter the messages as shown below

CAN status information

~ $ cat /proc/canstate
Baudrate : 1000000 bits/sec
Sampling : 1 sample(s) (PRSEG=2 PHSEG1=5 PHSEG2=2)
Max Retry: 10
CANCTRL[0xXF]  0x88
CANSTAT[0x0e]  0x80: OPMOD 0x4 ICOD 0x0
CANINTE[0x2b]  0xff
CANINTF[0x2c]  0x0
TXB0CTRL[0x30] 0x0
TXB1CTRL[0x40] 0x0
TXB2CTRL[0x50] 0x0
RXB0CTRL[0x60] 0x26
RXB1CTRL[0x70] 0x20
Receive filter
  Mask Rx0[0x20-23] 0xff e3 ff ff: s[0x7ff] e[0xffff]
    Filter 0[0x00-03] 0x00 00 00 00: 0x0 0x0 (S)
    Filter 1[0x04-07] 0x00 00 00 00: 0x0 0x0 (S)
  Mask Rx1[0x24-27] 0xff e3 ff ff: s[0x7ff] e[0xffff]
    Filter 2[0x08-0B] 0x00 00 00 00: 0x0 0x0 (S)
    Filter 3[0x10-13] 0x00 00 00 00: 0x0 0x0 (S)
    Filter 4[0x14-17] 0x00 00 00 00: 0x0 0x0 (S)
    Filter 5[0x18-1B] 0x00 00 00 00: 0x0 0x0 (S)
TEC[0x1C]  0x0
REC[0x1D]  0x0
EFLG[0x2D] 0x0
IRQ  2 enabled: YES
CAN status    : 0x0
CAN RX status : 0x0
TX queue size : 64
TX queue : 0 msg - 0(0) full - max 0(0) msg
RX buffer: 0 msg - 0(0) full - max 0(0) msg
RX queue : 0 msg - 0(0) full - max 0(0) msg
Spin locks:
    spi      : not locked
    tx_queue : not locked
    tx       : not locked
    rx_buffer: not locked
    rx_queue : not locked
*intf_table[ 0] = 00 nr=0
 intf_table[ 1] = 00 nr=0
 intf_table[ 2] = 00 nr=0
 intf_table[ 3] = 00 nr=0
 intf_table[ 4] = 00 nr=0
 intf_table[ 5] = 00 nr=0
 intf_table[ 6] = 00 nr=0
 intf_table[ 7] = 00 nr=0
 intf_table[ 8] = 00 nr=0
 intf_table[ 9] = 00 nr=0
 intf_table[10] = 00 nr=0
 intf_table[11] = 00 nr=0
 intf_table[12] = 00 nr=0
 intf_table[13] = 00 nr=0
 intf_table[14] = 00 nr=0
 intf_table[15] = 00 nr=0
wr_msg_cnt : 0
tx_msg_cnt : 0
tx0_pending: 0
tx0_retry  : 0
tx0_MLOA   : 0 (max 0)
GPLR0: 03059026
GPDR0: fb83ffdc
GRER0: 00600001
GFER0: 00000002
GEDR0: 00000000
ICPR : 00000000
ICLR : 00000000
ICMR : 06400700
/dev/canmsg0 trace queue overflows: 0
Statistics
  irq           : 0
  txb1 irq flag : 0
  txb2 irq flag : 0
  bus off       : 0
  TX_0 sent     : 0
  TX_0 lost     : 0
  TX_0 lost arb : 0
  TX_0 max retry: 0
  RX received   : 0
  RX error      : 0
~ $

Example

Some simple examples for CAN usage can be found → here