天天看點

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

目錄

    • TX2, Xavier NX, Xavier CAN特性
    • TX2, Xavier NX, Xavier 載闆引出位置
    • CAN收發器
    • NVIDIA CAN Driver
    • Xavier CAN 引腳配置
    • Jetson CAN 設定
    • 設定開機運作
    • 檢視連接配接狀态
    • CANFD注意事項
    • 檢視接收
    • CAN濾波器計算
    • 發送
    • 微信公衆号

TX2, Xavier NX, Xavier CAN特性

參考 Jetson_TX2_Series_Module_DataSheet_v1.6.pdf, TX2 CAN特性:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用
Jetson Xavier/XavierNX/TX2 CANFD 配置使用

參考 JetsonXavierNXDatasheet_v1.6.pdf, Xavier NX CAN特性:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用
Jetson Xavier/XavierNX/TX2 CANFD 配置使用

參考 Jetson_AGX_Xavier_Series_Datasheet_DS09654001_v1.2.pdf, Xavier CAN特性:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

TX2, Xavier NX, Xavier 載闆引出位置

參考nv_JetsonTX2_Developer_Kit_Carrier_Board_Specification.pdf

TX2, 有兩路CAN, 官方載闆上通過

[J26] Secondary Exp Header

引出:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用
Jetson Xavier/XavierNX/TX2 CANFD 配置使用

參考Jetson_Xavier_NX_DevKit_Carrier_Board_Specification_v1.0.pdf

Xavier NX, 有1路CAN, 官方載闆通過

[J17] Optional CAN Bus Header

引出, 需要自己拿烙鐵焊出來:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用
Jetson Xavier/XavierNX/TX2 CANFD 配置使用

參考Jetson_AGX_Xavier_Developer_Kit_Carrier_Board_Specification_SP-09778-001_v2.1.pdf

Xavier, 有兩路CAN, 官方載闆通過

[J30] 40-Pin Expansion Header

引出:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用
Jetson Xavier/XavierNX/TX2 CANFD 配置使用

1腳位置為載闆上靠近訓示燈的引腳.

CAN收發器

核心闆和載闆出來都是3.3V CMOS電平, 需要連接配接相應的CAN收發器, 并且接上120Ω終端電阻.

用CANFD的話, 要注意選擇支援CANFD的收發器, 如常用的NXP的TJA1044GT, 可以到5Mbit/s, 如果需要8Mbit/s, 或者更高速率, 需要更換相應的CAN收發器或者相應縮短線束長度.

NVIDIA CAN Driver

參考 NVIDIA DRIVE OS 5.1 Linux SDK – CAN Driver:

  • 關于标準CAN位速率隻能在 125K / 250K / 500K / 1Mbps 中4選1:

    125000(125 Kbps), 250000(250 Kbps), 500000(500 Kbps) and 1000000(1Mbps) are supported bitrates for Tegra MTTCAN driver. Any other bitrate is not validated on Tegra MTTCAN driver. Only 500000 (500 Kbps) bitrate is supported for Tegra MTTCAN-IVC. Other bitrates are not enabled on Tegra MTTCAN-IVC driver out of box. Details are available in the SPE documentation.

  • 關于CANFD, 仲裁段位速率參考上面的4選1, 資料段位速率隻能在 1M / 2Mbps中2選1, 還要CAN收發器也支援CANFD:

    For dbitrate support, iproute package version 2.4.0.0 or later is required. Additionally, the maximum dbitrate support depends on PHY chip on platform. Consult the PHY datasheet to identify and obtain the maximum allowed data bitrate. dbitrate 1000000 (1 Mbps) and 2000000 (2 Mbps) are supported data bitrates. Any other dbitrate is not validated on TegraMTTCAN driver.

  • 文章中也說明了

    MTTCAN

    的用法, 有興趣一定要去看

Xavier CAN 引腳配置

如果是TX2和Xavier NX, 跳過此小節.

不同于TX2和Xavier NX, Xavier是個例外, 它的兩路CAN剛好在40Pin擴充口上, 預設是IO, 需要先配置CAN:

sudo /opt/nvidia/jetson-io/jetson-io.py 
           

按上下鍵選擇

Configure 40-pin expansion header

:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

按上下鍵和Enter鍵選擇can0, can1, 然後Back:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

選擇

Save and reboot to reconfig pins

:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

Jetson CAN 設定

由于CANFD的配置也能正常接收CAN, 是以直接配置成CANFD, 寫個腳本

canfd.sh

:

#!/bin/sh

sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

sudo ip link set down can0
sudo ip link set can0 type can bitrate 500000 sample-point 0.8 dbitrate 2000000 dsample-point 0.75 fd on restart-ms 100
# sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on
sudo ip link set up can0 mtu 72
sudo ifconfig can0 txqueuelen 1000

sudo ip link set down can1
sudo ip link set can1 type can bitrate 500000 sample-point 0.8 dbitrate 2000000 dsample-point 0.75 fd on restart-ms 100
# sudo ip link set can1 type can bitrate 500000 dbitrate 2000000 fd on
sudo ip link set up can1 mtu 72
sudo ifconfig can1 txqueuelen 1000
           

詳細可檢視 Linux核心文檔can.txt:

  • restart-ms 100

    設定總線 bus-off 時延時100ms自動重新開機
  • bitrate 500000 sample-point 0.8

    , 核心中設定

    CONFIG_CAN_CALC_BITTIMING=y

    可以自動計算位時間(bit-timing)
  • mtu 72

    , MTU是資料鍊路層的概念, MTU限制的是資料鍊路層的payload,也就是上層協定的大小. CANFD預設最大就是72, 這種情況下CANFD的最大有效使用率=64/72≈88.88%, 參考以太網中的MTU 什麼是MTU?為什麼MTU值普遍都是1500?, Linux CAN核心文檔:
The length of the two CAN(FD) frame structures define the maximum transfer
  unit (MTU) of the CAN(FD) network interface and skbuff data length. Two
  definitions are specified for CAN specific MTUs in include/linux/can.h :

  #define CAN_MTU   (sizeof(struct can_frame))   == 16  => 'legacy' CAN frame
  #define CANFD_MTU (sizeof(struct canfd_frame)) == 72  => CAN FD frame
           

權重限運作:

sudo chmod 777 canfd.sh
sudo ./canfd.sh
           

注意Xavier NX隻有1路CAN, TX2和Xavier是兩路CAN.

這個設定關機或者重新開機就失效了, 可以用下面的方法設定開機運作.

ip link set can

的設定選項可以用

ip link set can0 type can help

檢視:

$ ip link set can0 type can help
Usage: ip link set DEVICE type can
        [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
        [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
          phase-seg2 PHASE-SEG2 [ sjw SJW ] ]

        [ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |
        [ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1
          dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]

        [ loopback { on | off } ]
        [ listen-only { on | off } ]
        [ triple-sampling { on | off } ]
        [ one-shot { on | off } ]
        [ berr-reporting { on | off } ]
        [ fd { on | off } ]
        [ fd-non-iso { on | off } ]
        [ presume-ack { on | off } ]

        [ restart-ms TIME-MS ]
        [ restart ]

        [ termination { 0..65535 } ]

        Where: BITRATE  := { 1..1000000 }
                  SAMPLE-POINT  := { 0.000..0.999 }
                  TQ            := { NUMBER }
                  PROP-SEG      := { 1..8 }
                  PHASE-SEG1    := { 1..8 }
                  PHASE-SEG2    := { 1..8 }
                  SJW           := { 1..4 }
                  RESTART-MS    := { 0 | NUMBER }
           

設定開機運作

以Xavier為例(TX2不一樣), 把上面的

canfd.sh

放到指定位置:

sudo cp canfd.sh /usr/local/
           

編寫service檔案:

cd /etc/systemd/system
sudo vi canfd.service
           

填入以下内容:

[Unit]
Description=Canfd

[Service]
ExecStart=/usr/local/canfd.sh start

[Install]
WantedBy=multi-user.target
           

寫入後運作:

sudo systemctl daemon-reload 
sudo systemctl enable canfd.service
sudo systemctl start canfd.service
           

檢視log:

journalctl -u canfd.service
           

如果報下面的錯誤:

2月 18 13:14:43 systemd[1]: Started Canfd.
2月 18 13:14:43 systemd[9629]: canfd.service: Failed to execute command: Exec format error
2月 18 13:14:43 systemd[9629]: canfd.service: Failed at step EXEC spawning /usr/local/canfd.sh: Exec format error
2月 18 13:14:43 systemd[1]: canfd.service: Main process exited, code=exited, status=203/EXEC
2月 18 13:14:43 systemd[1]: canfd.service: Failed with result 'exit-code'.
           

是因為

canfd.sh

中開頭沒有加入

#!/bin/sh

.

log的正常情況是:

2月 18 14:27:42 systemd[1]: Started Canfd.
2月 18 14:27:42 sudo[16347]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/sbin/modprobe can
2月 18 14:27:42 sudo[16347]: pam_unix(sudo:session): session opened for user root by (uid=0)
2月 18 14:27:42 sudo[16347]: pam_unix(sudo:session): session closed for user root
           

檢視連接配接狀态

可以

ifconfig

檢視:

$ ifconfig
can0: flags=193<UP,RUNNING,NOARP>  mtu 72
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 12411  bytes 788080 (788.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 68  

can1: flags=193<UP,RUNNING,NOARP>  mtu 72
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 12295  bytes 786432 (786.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 76  bytes 1216 (1.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 69  
           

或者用更詳細的

ip -details -statistics link show

檢視:

ip -details -statistics link show can0

: <<'COMMENT'
$ ip -details -statistics link show can0
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
    link/can  promiscuity 0 
    can <FD> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 100 
          bitrate 498701 sample-point 0.792 
          tq 26 prop-seg 30 phase-seg1 30 phase-seg2 16 sjw 1
          mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
          dbitrate 2021052 dsample-point 0.736 
          dtq 26 dprop-seg 6 dphase-seg1 7 dphase-seg2 5 dsjw 1
          mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
          clock 38400000
          re-started bus-errors arbit-lost error-warn error-pass bus-off
          0          0          0          4          42         0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 
    RX: bytes  packets  errors  dropped overrun mcast   
    731184     11522    0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0  
COMMENT 
           

序列槽也列印出了波特率的誤差:

[ 2051.260844] mttcan c310000.mttcan can0: bitrate error 0.2%
[ 2051.261015] mttcan c310000.mttcan can0: bitrate error 1.0%
[ 2051.334326] mttcan c320000.mttcan can1: bitrate error 0.2%
[ 2051.334484] mttcan c320000.mttcan can1: bitrate error 1.0%
           

CANFD注意事項

CANFD傳輸存在3種方式:

  • 一 CAN幀: Standard CAN frame (transmit and receive)
  • 二 CANFD長幀發送, 長幀和快速幀接收: CAN FD long frame in transmit and CAN FD long and fast frame in receive
  • 三 CANFD長快幀收發

差別是 BRS (BitRateSwitch)位, 以 仲裁段500kbps + 資料段2Mbps 為例:

  • 第一種方式就是500K, 最多8位元組;
  • 第二種方式

    BRS位設定為Off

    , 發送最多64位元組@500Kbps, 接收可以64位元組@2Mbps
  • 第三種方式

    BRS位設定為On

    發送和接收都可以 仲裁段500kbps, 資料段64位元組傳輸在2Mbps.

可以從 CAN FD Explained - A Simple Intro (2021) 中的配圖形象的看出來:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

在CAN FD+BRS通訊中使用NI-XNET出現錯誤或不正确的幀 這篇文章指出:

CANFD所有節點的采樣點必須比對,因為資料位速率通常遠高于标準位速率。如果标準位速率采樣點與另一個節點不比對,則在發射機的采樣點和接收機的采樣點之間的重疊期間,許多資料位可能會提前發送或者錯誤地傳輸。

采樣點一般設定再

0.75~0.8

之間.

前兩種方式由于通信速率還是500Kbps, 是以影響不大, 第三種方式中存在速率的變化, 一定要確定裝置的采樣點一緻. 如果不一緻典型的就是收不到CANFD消息, 發送時調試序列槽報

mttcan can0: entered error warning state

.

重新看下上面的:

$ ip link set can0 type can help
Usage: ip link set DEVICE type can
        [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
        [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
          phase-seg2 PHASE-SEG2 [ sjw SJW ] ]

        [ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |
        [ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1
          dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]
           

我們可以設定

波特率+采樣點

, 或者設定

tq prop-seg phase-seg1 phase-seg2 sjw

等參數, 2選1, 上面選的是前一個

sudo ip link set can0 type can bitrate 500000 sample-point 0.8 dbitrate 2000000 dsample-point 0.75 fd on restart-ms 100

, 最後自動計算的結果:

$ ip -details -statistics link show can0
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
    link/can  promiscuity 0 
    can <FD> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 100 
          bitrate 498701 sample-point 0.792 
          tq 26 prop-seg 30 phase-seg1 30 phase-seg2 16 sjw 1
          mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
          dbitrate 2021052 dsample-point 0.736 
          dtq 26 dprop-seg 6 dphase-seg1 7 dphase-seg2 5 dsjw 1
          mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
          clock 38400000
          re-started bus-errors arbit-lost error-warn error-pass bus-off
          0          0          0          4          42         0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 
    RX: bytes  packets  errors  dropped overrun mcast   
    1696048    26598    0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0  
           

可以看出:

  • 時鐘源clock 38400000Hz => 38.4MHz, 這個還是比較奇葩的, 可能時鐘樹沒有設定好, 一般是40MHz.
  • sample-point = (prop-seg + phase-seg1 + 1) / (prop-seg + phase-seg1 + phase-seg2 + 1) = 61 / 77 ≈ 0.792

  • dsample-point = (dprop-seg + dphase-seg1 + 1) / (dprop-seg + dphase-seg1 + dphase-seg2 + 1) = 14 / 19 ≈ 0.7368

  • bitrate = clock / (prop-seg + phase-seg1 + phase-seg2 + 1) = 38400000 / 77 ≈ 498,701.2

  • dbitrate = clock / (dprop-seg + dphase-seg1 + dphase-seg2 + 1) = 38400000 / 19 ≈ 2,021,052.6

  • 主時鐘源可能是

    tq * clock = 26 * 38.4M = 998.4M ≈ 1GHz

    , 未查證, 有錯誤請指正.
  • sjw

    常用的有

    1

    或者等于

    phase-seg2

    .

檢視接收

安裝can-utils:

sudo apt install can-utils
           

先來看candump的用法:

$ candump
candump - dump CAN bus traffic.

Usage: candump [options] <CAN interface>+
  (use CTRL-C to terminate candump)

Options:
         -t <type>   (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)
         -H          (read hardware timestamps instead of system timestamps)
         -c          (increment color mode level)
         -i          (binary output - may exceed 80 chars/line)
         -a          (enable additional ASCII output)
         -S          (swap byte order in printed CAN data[] - marked with '`' )
         -s <level>  (silent mode - 0: off (default) 1: animation 2: silent)
         -b <can>    (bridge mode - send received frames to <can>)
         -B <can>    (bridge mode - like '-b' with disabled loopback)
         -u <usecs>  (delay bridge forwarding by <usecs> microseconds)
         -l          (log CAN-frames into file. Sets '-s 2' by default)
         -L          (use log file format on stdout)
         -n <count>  (terminate after receiption of <count> CAN frames)
         -r <size>   (set socket receive buffer to <size>)
         -D          (Don't exit if a "detected" can device goes down.
         -d          (monitor dropped CAN frames)
         -e          (dump CAN error frames in human-readable format)
         -x          (print extra message infos, rx/tx brs esi)
         -T <msecs>  (terminate after <msecs> without any reception)

Up to 16 CAN interfaces with optional filter sets can be specified
on the commandline in the form: <ifname>[,filter]*

Filters:
 Comma separated filters can be specified for each given CAN interface.
<can_id>:<can_mask>
        (matches when <received_can_id> & mask == can_id & mask)
<can_id>~<can_mask>
        (matches when <received_can_id> & mask != can_id & mask)
#<error_mask>
        (set error frame filter, see include/linux/can/error.h)
[j|J]
        (join the given CAN filters - logical AND semantic)

CAN IDs, masks and data content are given and expected in hexadecimal values.
When can_id and can_mask are both 8 digits, they are assumed to be 29 bit EFF.
Without any given filter all data frames are received ('0:0' default filter).

Use interface name 'any' to receive from all CAN interfaces.

Examples:
candump -c -c -ta can0,123:7FF,400:700,#000000FF can2,400~7F0 can3 can8

candump -l any,0~0,#FFFFFFFF
        (log only error frames but no(!) data frames)
candump -l any,0:0,#FFFFFFFF
        (log error frames and also all data frames)
candump vcan2,92345678:DFFFFFFF
        (match only for extended CAN ID 12345678)
candump vcan2,123:7FF
        (matches CAN ID 123 - including EFF and RTR frames)
candump vcan2,123:C00007FF
        (matches CAN ID 123 - only SFF and non-RTR frames)
           

使用

candump can0

檢視接收, 64位元組的CANFD接收正常:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

或者寫到檔案裡面:

candump can0 >1.dat

添加參數訓示間隔時間, BRS位(顯示B或-), ESI(ErrorStateIndicator)位(顯示E或-),

candump -td -x can0

:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

CAN濾波器計算

從上面可知,

candump

濾波設定方法為

<can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)

.

常見的CAN軟體都附帶有濾波器計算軟體, 如周立功的

ZCANPRO

軟體安裝目錄下的

filter.exe

:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

或者搜CAN濾波器計算就出來的這個軟體:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

candump can0,91A2B3C0:7

, 這樣就能濾出來

0x12345678

這一幀.

或者更簡單的, 因為掩碼位為1比較, 為0忽略, 我們就全比較

candump can0,12345678:1FFFFFFF

, 如果再加上一個标準幀如

0x123

, 就是

candump can0,12345678:1FFFFFFF,123:7FF

Jetson Xavier/XavierNX/TX2 CANFD 配置使用

發送

先來看cansend的用法:

$ cansend
Usage: cansend - simple command line tool to send CAN-frames via CAN_RAW sockets.
Usage: cansend <device> <can_frame>.
<can_frame>:
 <can_id>#{R|data}          for CAN 2.0 frames
 <can_id>##<flags>{data}    for CAN FD frames

<can_id>:
 can have 3 (SFF) or 8 (EFF) hex chars
{data}:
 has 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
<flags>:
 a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

Examples:
  5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311
  1F334455#1122334455667788 / 123#R for remote transmission request.
           

寫個CANFD發送的腳本

can_trans.sh

:

#!/bin/sh

while true; do
    cansend can0 18FF0001##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
    #cansend can0 12345678##0.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
    #cansend can0 12345678##0.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
    sleep 0.1
done
           

其中:

  • ##後跟

    <flags>

    :

    a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

  • ##後跟0是上面的第二種發送方式, BRS不使能, 後面01開始才是資料, 以500Kbps傳輸64位元組
  • ##後跟3是使能BRS和SEI位, 真正的CANFD用這個, 仲裁段500Kbps, 資料段2Mbps傳輸64位元組

權重限發送:

sudo chmod 777 can_trans.sh
sudo ./can_trans.sh
           

微信公衆号

歡迎掃描二維碼關注本人微信公衆号, 及時擷取或者發送給我最新消息:

Jetson Xavier/XavierNX/TX2 CANFD 配置使用