5

I am using flexcan driver on an embedded linux and I have C program controling can messages. In my C program I need to check the state of the can bus e.g. buss-off or error-active. I can use linux command like ip -details -statistics link show can0 with following result:

2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0 
    can state *ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 100 
          bitrate 250000 sample-point 0.866 
          tq 266 prop-seg 6 phase-seg1 6 phase-seg2 2 sjw 1
          flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
          clock 30000000
          re-started bus-errors arbit-lost error-warn error-pass bus-off
          31594      0          0          7686       25577      33258     
    RX: bytes  packets  errors  dropped overrun mcast   
    5784560    723230   0       1       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    157896     19742    0       33269   0       0       

How can I get that can state ERROR-ACTIVE in my C program? Also I can see in the flex can driver there are some registers that can be used to see the state but I don't know how to include these values in my program also. registers like FLEXCAN_ESR_BOFF_INT contains the values that I need.

Yasushi Shoji
  • 4,028
  • 1
  • 26
  • 47
PHA
  • 1,588
  • 5
  • 18
  • 37

1 Answers1

5

You can setup your socket to return CAN errors as messages.

As described in Network Problem Notifications the CAN interface driver can generate so called Error Message Frames that can optionally be passed to the user application in the same way as other CAN frames. The possible errors are divided into different error classes that may be filtered using the appropriate error mask. To register for every possible error condition CAN_ERR_MASK can be used as value for the error mask. The values for the error mask are defined in linux/can/error.h

can_err_mask_t err_mask = ( CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF );

setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
           &err_mask, sizeof(err_mask));

See kernel documentation for more information.

Update

Take a look at libsocketcan and the routine can_get_state.

yegorich
  • 4,653
  • 3
  • 31
  • 37
  • 1
    @1113139 sorry that's not really clear to me. The doc says that in that case, we are receiving an Error Frame similar to any other frame. Well ok, but what is the frame content?? What about can_get_state? do you regularly pulling it or do call it when you are receiving an Error Frame? And again, how to distinguish an Error Frame? – fralbo Apr 06 '20 at 07:55
  • Agree with @fralbo: and the can_get_state call isn't appropriate. I'm not going to be checking for can state every time I poll the canbus, especially since CAN error frames are synthesized specifically to avoid having to do so. – MB. Nov 02 '20 at 11:50
  • 1
    @fralbo have you tried to check the CAN frame flags for `CAN_ERR_FLAG`? See `include/uapi/linux/can/error.h` for the content of the error frame. – yegorich Nov 02 '20 at 15:25