CAN總線調(diào)試時(shí),根據(jù)數(shù)據(jù)的重要性,接收端可以專注于接收重要消息,提高效率。CAN報(bào)文幀是用一個(gè)標(biāo)識(shí)符或一系列標(biāo)識(shí)符來過濾的??梢允褂肅AN總線軟件和芯片硬件過濾規(guī)則實(shí)現(xiàn)過濾功能。
?軟件過濾
struct can_filter filter[1];/* 規(guī)則:可以接收ID為0x200數(shù)據(jù)幀和錯(cuò)誤幀 */
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);}
軟件的配置可以在系統(tǒng)中檢查:
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)
此處rcvlist_*為CAN協(xié)議中的接收器:struct receiver,包含軟件的過濾規(guī)則。
?硬件過濾芯片手冊(cè):
硬件過濾方式在驅(qū)動(dòng):drivers/net/can/rockchip/rockchip_canfd.c 中實(shí)現(xiàn),具體代碼:
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); ......}
從以上代碼可以看出,每次執(zhí)行CAN軟件都會(huì)重新配置CAN控制器寄存器不過濾任何數(shù)據(jù)。通過2個(gè)寄存器來實(shí)現(xiàn)硬件過濾:CAN_IDCODEn、CAN_RX_FILTER_MASK
RK3568 CAN控制器有6個(gè)過濾器,其中第一個(gè)過濾器默認(rèn)使能,不受開關(guān)控制,其余過濾器需要使能對(duì)應(yīng)的過濾器。可以在can軟件運(yùn)行時(shí),再去配置硬件過濾方式,如:
root@host:/root# ip link set can1 type can bitrate 1000000root@host:/root# ip link set can1 uproot@host:/root# candump can1 只接收0x123 id的幀,不受開關(guān)控制root@host:/root# io -4 0xfe58003c 0x123root@host:/root# io -4 0xfe580040 0x0# 只接收0x124 id的幀,需開關(guān)控制root@host:/root# io -4 0xfe580120 0x124root@host:/root# io -4 0xfe580124 0x0root@host:/root# io -4 0xfe58011c 0x1
?系統(tǒng)優(yōu)化1. 發(fā)送異常返回
系統(tǒng)CAN默認(rèn)發(fā)送隊(duì)列:txqueuelen:10,有線網(wǎng)口該數(shù)值為1000。更小的數(shù)值,實(shí)時(shí)性更強(qiáng)。
在大量數(shù)據(jù)發(fā)送時(shí),write函數(shù)經(jīng)常異常返回,大部分原因是由于系統(tǒng)發(fā)送隊(duì)列內(nèi)存不足,可以使用以下指令增大發(fā)送隊(duì)列:
root@host:/root# ip link set txqueuelen 500 dev can1
2. 接收數(shù)據(jù)丟失
接收隊(duì)列不足表現(xiàn)在read得到的數(shù)據(jù)不全,大部分情況為數(shù)據(jù)skb已經(jīng)提供到receiver 隊(duì)列中,但是應(yīng)用來不及取出,導(dǎo)致最終占滿所有可支配的內(nèi)存大小,數(shù)據(jù)更新到了隊(duì)列中錯(cuò)誤的位置。
可使用以下指令調(diào)整接收隊(duì)列大?。?/p>
root@host:/root# echo 1000000 > /proc/sys/net/core/rmem_maxroot@host:/root# echo 1000000 > /proc/sys/net/core/rmem_default
Coral-EVa為致遠(yuǎn)電子推出的Coral3568配套評(píng)估底板,同樣功能強(qiáng)大,接口豐富。Coral-EVa評(píng)估底板采用適配器供電,更方便實(shí)驗(yàn)室和研發(fā)辦公室使用,HDMI、DP、USB、CAN、RS485、RS232、TTL UART、3.5mm四線耳麥接口、Micro SD卡槽、SATA、M.2、LVDS LCD、MIPI_DSI、MIPI-CSI、RTC時(shí)鐘、蜂鳴器等功能一應(yīng)俱全。
-
CAN
+關(guān)注
關(guān)注
57文章
2694瀏覽量
463149 -
硬件
+關(guān)注
關(guān)注
11文章
3211瀏覽量
66063 -
軟件
+關(guān)注
關(guān)注
69文章
4699瀏覽量
87088
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論