
Software Filtering
struct can_filter filter[1];/* Rule: Can receive data frame with ID 0x200 and error frame */
filter[0].can_mask = CAN_SFF_MASK;filter[0].can_id = 0x200 & CAN_SFF_MASK;filter[0].can_mask |= CAN_EFF_FLAG;
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter))){perror("setsockopt failed");exit(EXIT_FAILURE);}
The software configuration can be checked in the system:
root@host:/root# ls /proc/net/can/rcvlist_all rcvlist_err rcvlist_inv reset_statsrcvlist_eff rcvlist_fil rcvlist_sff stats
root@host:/root# cat /proc/net/can/rcvlist_filreceive list 'rx_fil': (any: no entry) (can0: no entry) device can_id can_mask function userdata matches ident can1 200 800007ff 0000000095327ce0 00000000674196b1 0 raw (can2: no entry)


The hardware filtering method is implemented in the driver: drivers/net/can/rockchip/rockchip_canfd.c, specific code:
static int rockchip_canfd_start(struct net_device *ndev){ ...... rockchip_canfd_write(rcan, CAN_INT_MASK, 0);
/* RECEIVING FILTER, accept all */ rockchip_canfd_write(rcan, CAN_IDCODE, 0); rockchip_canfd_write(rcan, CAN_IDMASK, CAN_RX_FILTER_MASK); rockchip_canfd_write(rcan, CAN_IDCODE0, 0); rockchip_canfd_write(rcan, CAN_IDMASK0, CAN_RX_FILTER_MASK); rockchip_canfd_write(rcan, CAN_IDCODE1, 0); rockchip_canfd_write(rcan, CAN_IDMASK1, CAN_RX_FILTER_MASK); rockchip_canfd_write(rcan, CAN_IDCODE2, 0); rockchip_canfd_write(rcan, CAN_IDMASK2, CAN_RX_FILTER_MASK); rockchip_canfd_write(rcan, CAN_IDCODE3, 0); rockchip_canfd_write(rcan, CAN_IDMASK3, CAN_RX_FILTER_MASK); rockchip_canfd_write(rcan, CAN_IDCODE4, 0); rockchip_canfd_write(rcan, CAN_IDMASK4, CAN_RX_FILTER_MASK); ......}
root@host:/root# ip link set can1 type can bitrate 1000000root@host:/root# ip link set can1 uproot@host:/root# candump can1 &# only receive frames with ID 0x123, not controlled by a switchroot@host:/root# io -4 0xfe58003c 0x123root@host:/root# io -4 0xfe580040 0x0# only receive frames with ID 0x124, need switch controlroot@host:/root# io -4 0xfe580120 0x124root@host:/root# io -4 0xfe580124 0x0root@host:/root# io -4 0xfe58011c 0x1

The default sending queue for the system CAN: txqueuelen:10, for wired network ports this value is 1000. A smaller value results in stronger real-time performance.
During large data sending, the write function often returns abnormally, mainly because of insufficient memory in the system sending queue. The following command can be used to increase the sending queue:
root@host:/root# ip link set txqueuelen 500 dev can1
Insufficient receiving queue is reflected in incomplete data obtained from read, mostly because the data skb has already been provided to the receiver queue, but the application is unable to retrieve it in time, leading to final filling of all available memory size, and data is updated to the wrong location in the queue.
root@host:/root# echo 1000000 > /proc/sys/net/core/rmem_maxroot@host:/root# echo 1000000 > /proc/sys/net/core/rmem_default


For more past articles, please click “ Read the original ”.




