之前手中的Xavier一直用老版本的Jetpack, 最近换上较新的 Jetpack 4.6 以后, MTTCAN 配置发生了变化, CAN时钟默认为低功耗设置(没使能PLLAON), CAN工作不正常, 现象如下:
ip -details -statistics link show can0
也看不出波特率设置的问题归根到底, 实际的时钟/波特率不对了. 可以用 下面的命令检验
#!/bin/sh
sudo cat /sys/kernel/debug/bpmp/debug/clk/can1/parent
sudo cat /sys/kernel/debug/bpmp/debug/clk/can2/parent
结果:
osc
或者 pll_c
都不正常pll_aon
pll_c
, 运行 sudo modprobe can, sudo modprobe can_raw, sudo modprobe mttcan
后应变为 pll_aon
需要进行修改的地方(T194平台, 适用于Xavier和Xavier NX):
bpmp
里面给can
附加pllaon
时钟源pinmux
修改(因为默认是gpio
, 不是can
, 同以前)clocks-init
去掉CAN的低功耗设置, 把CAN的时钟放出来mttcan@c310000
, mttcan@c320000
里附上 pllaon
时钟或许可以回到以前 38.4MHz, 但还是建议就按最新的 pllaon
来, 官方说法更准确了, 默认 50MHz. (虽然CANFD最好主时钟是 80MHz/120MHz, 这样采样点算起来更精确, 但这里 50MHz 误差也不算大, 正常用没问题)
改用 pllaon
时钟, 配置 tdc_offset
后, CANFD更猛了, 测试CANFD 5Mbps 没有问题, 更高由于手头的收发器限制没有测试.
可参考:
# 要使用的dtb
# Linux_for_Tegra/bootloader/t186ref/tegra194-a02-bpmp-p2888-a04.dtb
cd Linux_for_Tegra/bootloader/t186ref
# 使用dtc反编译出dts
dtc -I dtb -O dts -o tegra194-a02-bpmp-p2888-a04.dts tegra194-a02-bpmp-p2888-a04.dtb
################################################
# 默认的
# clock@can1 {
# allow_fractional_divider = <0x01>;
# allowed-parents = <0x121 0x5b 0x13a>;
# clk-id = <0x09>;
# };
# clock@can2 {
# allow_fractional_divider = <0x01>;
# allowed-parents = <0x121 0x5b 0x13a>;
# clk-id = <0x0b>;
# };
################################################
# 时钟源的解释
# Linux_for_Tegra/source/public/hardware/nvidia/soc/t19x/kernel-include/dt-bindings/clock/tegra194-clock.h
# #define TEGRA194_CLK_CLK_32K 289U //0x121, 32K input clock provided by PMIC
# #define TEGRA194_CLK_OSC 91U //0x5b, input from Tegra's XTAL_IN
# #define TEGRA194_CLK_PLLC 314U //0x13a, PLL controlled by CLK_RST_CONTROLLER_PLLC_BASE
# #define TEGRA194_CLK_PLLAON 94U //0x5e, PLL controlled by CLK_RST_CONTROLLER_PLLAON_BASE for use by IP blocks in the AON domain
################################################
# 修改为 (参考下图)
# allowed-parents 增加 0x5e, 也就是 PLLAON 时钟
clock@can1 {
allow_fractional_divider = <0x01>;
allowed-parents = <0x121 0x5b 0x13a 0x5e>;
clk-id = <0x09>;
};
clock@can2 {
allow_fractional_divider = <0x01>;
allowed-parents = <0x121 0x5b 0x13a 0x5e>;
clk-id = <0x0b>;
};
################################################
# 再把dts编译回dtb
dtc -I dts -O dtb -o tegra194-a02-bpmp-p2888-a04.dtb tegra194-a02-bpmp-p2888-a04.dts
# 改动完后进入Recovery模式, 单独刷写 bpmp-fw-dtb 分区
# 最后需要显示 *** The [bpmp-fw-dtb] has been updated successfully. ***
cd Linux_for_Tegra
cp bootloader/t186ref/BCT/tegra194-mb1-bct-ratchet-p2888-0000-p2822-0000.cfg bootloader
sudo ./flash.sh -k bpmp-fw-dtb jetson-xavier mmcblk0p1
# 如果不刷 bpmp-fw-dtb 分区, modprobe 的时候会报下面的错误
# [ 32.386287] mttcan c310000.mttcan: unable to set CAN_CLK parent
# [ 32.402724] mttcan c310000.mttcan: probe failed
# [ 32.425253] mttcan c320000.mttcan: unable to set CAN_CLK parent
# [ 32.450769] mttcan c320000.mttcan: probe failed
改动如下所示
Xavier默认的是GPIO, 要改成CAN功能, 下面三种配置方法任选其一即可
适用于开发者, 直接修改下面的cfg文件, 如下
# Linux_for_Tegra/bootloader/t186ref/BCT/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
# 默认
# pinmux.0x0c303000 = 0x0000c055; # can1_dout_paa0: rsvd1, pull-down, tristate-enable, input-enable
# pinmux.0x0c303008 = 0x0000c055; # can1_din_paa1: rsvd1, pull-down, tristate-enable, input-enable
# pinmux.0x0c303010 = 0x0000c059; # can0_dout_paa2: rsvd1, pull-up, tristate-enable, input-enable
# pinmux.0x0c303018 = 0x0000c059; # can0_din_paa3: rsvd1, pull-up, tristate-enable, input-enable
# 修改为
pinmux.0x0c303000 = 0x0000c400; # can1_dout_paa0: rsvd1, pull-down, tristate-enable, input-enable
pinmux.0x0c303008 = 0x0000c458; # can1_din_paa1: rsvd1, pull-down, tristate-enable, input-enable
pinmux.0x0c303010 = 0x0000c400; # can0_dout_paa2: rsvd1, pull-up, tristate-enable, input-enable
pinmux.0x0c303018 = 0x0000c458; # can0_din_paa3: rsvd1, pull-up, tristate-enable, input-enable
# 可以删除上面的
# pinmux.0x0c303000 = 0x00000000; # GPIO can1_dout_paa0
# pinmux.0x0c303008 = 0x00000000; # GPIO can1_din_paa1
# pinmux.0x0c303010 = 0x00000000; # GPIO can0_dout_paa2
# pinmux.0x0c303018 = 0x00000000; # GPIO can0_din_paa3
如图所示
后面也改动完后, 重新替换设备树
(系统开机后), 用户空间 sudo /opt/nvidia/jetson-io/jetson-io.py
, 选中can0, can1, 保存重启, 只需修改一次
直接在can的配置脚本最上方(还在sudo modprobe can
之前), 用busybox修改, 如下
# sudo apt install busybox
sudo busybox devmem 0x0c303000 32 0x0000C400
sudo busybox devmem 0x0c303008 32 0x0000C458
sudo busybox devmem 0x0c303010 32 0x0000C400
sudo busybox devmem 0x0c303018 32 0x0000C458
三种方法任选其一即可, 检验
sudo busybox devmem 0x0c303000 # 0x0000C400
sudo busybox devmem 0x0c303008 # 0x0000C458
sudo busybox devmem 0x0c303010 # 0x0000C400
sudo busybox devmem 0x0c303018 # 0x0000C458
Jetpack 4.6 默认的CAN驱动之所以不正常, 就是因为时钟默认被关小黑屋了, 美其名曰低功耗, 省电
# Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
clocks-init {
compatible = "nvidia,clocks-config";
status = "okay";
disable {
clocks = <&aon_clks TEGRA194_CLK_PLLAON>,
<&bpmp_clks TEGRA194_CLK_CAN1>,
<&bpmp_clks TEGRA194_CLK_CAN2>;
};
};
现在既然要用CAN, 自然要把时钟给放出来
# Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
clocks-init {
compatible = "nvidia,clocks-config";
status = "okay";
disable {
// clocks = <&aon_clks TEGRA194_CLK_PLLAON>,
// <&bpmp_clks TEGRA194_CLK_CAN1>,
// <&bpmp_clks TEGRA194_CLK_CAN2>;
};
};
如图所示
还是上面那个文件, 默认这两个节点只有 status = "okay"
, 附上 pllaon 时钟
# Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
mttcan@c310000 {
status = "okay";
pll_source = "pllaon";
clocks = <&bpmp_clks TEGRA194_CLK_CAN1_CORE>,
<&bpmp_clks TEGRA194_CLK_CAN1_HOST>,
<&bpmp_clks TEGRA194_CLK_CAN1>,
<&bpmp_clks TEGRA194_CLK_PLLAON>;
clock-names = "can_core", "can_host","can","pllaon";
};
mttcan@c320000 {
status = "okay";
pll_source = "pllaon";
clocks = <&bpmp_clks TEGRA194_CLK_CAN2_CORE>,
<&bpmp_clks TEGRA194_CLK_CAN2_HOST>,
<&bpmp_clks TEGRA194_CLK_CAN2>,
<&bpmp_clks TEGRA194_CLK_PLLAON>;
clock-names = "can_core", "can_host","can","pllaon";
};
# 可参考 Linux_for_Tegra/source/public/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc/tegra194-soc-can.dtsi
如图所示
改好后, 编译, 替换 设备树 内核 后重启
之前做过 STM32H7 / TC397 的CANFD的, 应该对TDC不陌生, 这个上高速率CANFD必须设置的, 不然会罢工(busoff)
官方说法, Xavier 的 CANFD速率最高能怼到15Mbps, 不过高速率需要设置TDCR (Transmission Delay Compensation Register), modprobe 以后, ip link 之前, 切换到 root, 把这个写进去
echo 0x600 > /sys/devices/c310000.mttcan/net/can0/tdc_offset
echo 0x600 > /sys/devices/c320000.mttcan/net/can1/tdc_offset
如果不设置, CAN没问题, 但是CANFD上到如5Mbps, 并且发送数据时, dmesg里会疯狂打印
[11746.995166] mttcan c310000.mttcan can0: entered error warning state
[11746.995307] mttcan c310000.mttcan can0: entered error passive state
[11746.995451] mttcan c310000.mttcan can0: entered bus off state
大概情况就这样了, 下面汇总下设置脚本
板子上贴的CANFD收发器为 TJA1042T/3
, 只能到 5Mbps, 这里就设置成5M.
以 [email protected], [email protected]
的 CANFD
为例, 设置脚本 5M_canfd.sh
:
#!/bin/sh
# sudo busybox devmem 0x0c303000 32 0x0000C400
# sudo busybox devmem 0x0c303008 32 0x0000C458
# sudo busybox devmem 0x0c303010 32 0x0000C400
# sudo busybox devmem 0x0c303018 32 0x0000C458
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan
sudo sh -c 'echo 0x600 > /sys/devices/c310000.mttcan/net/can0/tdc_offset'
sudo sh -c 'echo 0x600 > /sys/devices/c320000.mttcan/net/can1/tdc_offset'
sudo ip link set down can0
sudo ip link set can0 type can bitrate 500000 sample-point 0.8 dbitrate 5000000 dsample-point 0.8 fd on restart-ms 100
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 5000000 dsample-point 0.8 fd on restart-ms 100
sudo ip link set up can1 mtu 72
sudo ifconfig can1 txqueuelen 1000
运行完上面的脚本后, 我们先来检验一下配置生效了没有
# 检查CAN的主时钟是否是 pll_aon, 如果是 pll_c 或 osc, 是不对的
# 注意 bpmp 里面编号是 can1 can2
$ sudo cat /sys/kernel/debug/bpmp/debug/clk/can1/parent
pll_aon
$ sudo cat /sys/kernel/debug/bpmp/debug/clk/can2/parent
pll_aon
# sudo cat /sys/kernel/debug/bpmp/debug/clk/can1/pto_counter
# sudo cat /sys/kernel/debug/bpmp/debug/clk/can2/pto_counter
# 199989248
# 检查TDC是否配置成功
# 用户空间里面编号变成了 can0 can1
$ sudo cat /sys/devices/c310000.mttcan/net/can0/tdc_offset
tdc_offset=0x600, DBTP.tdc=1
$ sudo cat /sys/devices/c320000.mttcan/net/can1/tdc_offset
tdc_offset=0x600, DBTP.tdc=1
# 可以看到时钟 50MHz, 500K, 2M, 数据段采样点只能是 0.7, 0.8 这样, 没有0.75, 0.875, 不影响用
$ sudo ip -d -s link show can0
8: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP 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 500000 sample-point 0.800
tq 20 prop-seg 39 phase-seg1 40 phase-seg2 20 sjw 1
mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
dbitrate 5000000 dsample-point 0.800
dtq 20 dprop-seg 3 dphase-seg1 4 dphase-seg2 2 dsjw 1
mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
clock 50000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
0 0 0 0 0 0
TX: bytes packets errors dropped carrier collsns
16 2 0 0 0 0
连接外部CANFD分析仪:
Xavier 发送测试
cansend can1 123#11.22.33.44.55.66.77.88
cansend can1 12345678#11.22.33.44.55.66.77.99
cansend can1 321##0.11.22.33.44.55.66.77.88
cansend can1 321##0.11.22.33.44.55.66.77.88.99
cansend can1 321##1.11.22.33.44.55.66.77.88.99
cansend can1 321##2.11.22.33.44.55.66.77.88.99
cansend can1 321##3.11.22.33.44.55.66.77.88.99
cansend can1 12345678##3.11.22.33.44.55.66.77.88.\
12.22.33.44.55.66.77.88.\
13.22.33.44.55.66.77.88.\
14.22.33.44.55.66.77.88.\
15.22.33.44.55.66.77.88.\
16.22.33.44.55.66.77.88.\
17.22.33.44.55.66.77.88.\
18.22.33.44.55.66.77.88
如图
Xavier接收测试
$ candump -ta -x can1
(1650347819.045906) can1 RX - - 12345678 [8] 11 22 33 44 55 66 77 88
(1650347819.046337) can1 RX - - 123 [8] 11 22 33 44 55 66 77 88
(1650347819.046799) can1 RX - - 321 [08] 11 22 33 44 55 66 77 88
(1650347819.047107) can1 RX B - 321 [12] 11 22 33 44 55 66 77 88 99 00 00 00
(1650347819.047558) can1 RX B - 12345679 [64] 11 22 33 44 55 66 77 88 99 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(1650347819.048017) can1 RX - - 321 [12] 11 22 33 44 55 66 77 88 99 00 00 00
如图
欢迎扫描二维码关注微信公众号, 及时获取最新文章: