How to control CAN transmit order on Jetson TX2?

CAN message sending/receiving is working in general but the order of transmitted messages is not in FIFO mode as expected and configured. This is a problem using CAN transport protocol (ISO 15765-2) strongly based on correct message order. I use a Jetson TX2 and do CAN communication using golang with brutella (“github.com/brutella/can”) based on socket CAN (and mttcan… of the Jetson SDK).

ENOBUFS is sporadically returned when I send a bunch of messages (~500) with high speed. This is handled with delays and retries.
The message order on real CAN bus is not in the order messages forwarded successfully to the socket CAN. There are often few messages sent very early (e.g. 30th, 31st, … message) which will be sent at the end of the bunch. At least exact the number of messages forwarded successfully to socket CAN appear also on CAN bus but in wrong order.

Is there are configuration to force strict FIFO mode on all layers (socket CAN and below)? Is there a known issue with the queuing on mttcan driver/hardware?

Info: The communication works fine if I use a simple delay on every message transmit. But this slows down communication and depends on CAN bus traffic.

Hi hans_juergen,

What are your current device-tree settings for mttcan?
Please give me data under mttcan@c310000 and mttcan@c320000.

Thanks,
Shubhi

Hello Shubhi,

I use can0. With dtc I read following values
(Jetson SDK defaults release # R32 (release), REVISION: 1.0, GCID: 14531094, BOARD: t186ref, EABI: aarch64, DATE: Wed Mar 13 07:41:08 UTC 2019):
mttcan@c310000 {
gpio_can_stb = <0x28 0x28 0x0>;
compatible = “nvidia,tegra186-mttcan”;
clocks = <0x10 0xd2 0x10 0xd3 0x10 0x214>;
resets = <0x10 0x3c>;
reg-names = “can-regs”, “glue-regs”, “msg-ram”;
clock-names = “can”, “can_host”, “pllaon”;
rx-config = <0x40 0x40 0x40>;
pll_source = “pllaon”;
mram-params = <0x0 0x10 0x10 0x8 0x8 0x8 0x10 0x10 0x10>;
status = “okay”;
interrupts = <0x0 0x28 0x4>;
phandle = <0x1e0>;
reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>;
gpio_can_en = <0x28 0x29 0x0>;
reset-names = “can”;
linux,phandle = <0x1e0>;
tx-config = <0x8 0x8 0x0 0x40>;
};
mttcan@c320000 {
gpio_can_stb = <0x28 0x2e 0x0>;
compatible = “nvidia,tegra186-mttcan”;
clocks = <0x10 0xd4 0x10 0xd5 0x10 0x214>;
resets = <0x10 0x3d>;
reg-names = “can-regs”, “glue-regs”, “msg-ram”;
clock-names = “can”, “can_host”, “pllaon”;
rx-config = <0x40 0x40 0x40>;
pll_source = “pllaon”;
mram-params = <0x0 0x10 0x10 0x8 0x8 0x8 0x10 0x10 0x10>;
status = “okay”;
interrupts = <0x0 0x2a 0x4>;
phandle = <0x1e1>;
reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>;
gpio_can_en = <0x28 0x2f 0x0>;
reset-names = “can”;
linux,phandle = <0x1e1>;
tx-config = <0x8 0x8 0x0 0x40>;
};

Here can0 statistics (bus-off/error-warn/error-pass is happens on device wakeup → this is no error):
27: 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 200
bitrate 500000 sample-point 0.800
tq 100 prop-seg 7 phase-seg1 8 phase-seg2 4 sjw 4
mttcan: tseg1 2…255 tseg2 0…127 sjw 1…127 brp 1…511 brp-inc 1
mttcan: dtseg1 1…31 dtseg2 0…15 dsjw 1…15 dbrp 1…15 dbrp-inc 1
clock 40000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
1 0 0 16 29 1 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
52384 6548 0 0 0 0
TX: bytes packets errors dropped carrier collsns
7721016 965127 0 0 0 0

Thank you and best regards
Jürgen

Hi,
Please change following params in DT and then check the message transfer:
mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>;
tx-config = <0x0 0x10 0x0 0x40>;

This change will use only fifo mode. Please check and let me know if this works.

Thanks,
Shubhi

Hello,

Thank you for the fast support!
Unfortunately I am not able to change the DT properly.
I tried to change according this instruction (even the file name seems to fit…): Linux Device Tree | How To Edit Device Tree at Run Time

The changes were applied: I can read the values with fdtget but they do not apply after reboot (reading: dtc -I fs /sys/firmware/devicetree/base, fdtget is still ok)

Because there is used a SD card for booting, I changed also the file after booting from native flash - there is no effect.

Sorry, thanks and best regards
Jürgen

Hi,
You can update dtb using:
$ sudo dtc -I dtb <DTB_FILE> -o test.dts
open test.dts and modify and save (sudo vi test.dts)
$ sudo dtc -I dts test.dts -O dtb -o <DTB_FILE>

make sure you update the correct dtb which is getting flashed, reflash the device to get changes.
Can you please tell me how are you flashing the device?

Thanks,
Shubhi

Hello,

the file /boot/tegra186-quill-p3310-1000-c03-00-base.dtb has already the changes (“dtc -I dtb … -o test.dts” creates the file test.dts including already the new changes).

The problem is that the new changes will not be applied. “dtc -I fs /sys/firmware/devicetree/base” reads the old values.

I flashed the board using the SDK-Manager. After that some modifications are applied (e.g. installing required tools). After that I copy the root file system to a SD card and adjust boot/extlinux/extlinux.conf to use mmcblk0p1 instead of mmcblk2p1. The file /etc/fstab will be added “/dev/mmcblk2p2 /config vfat dmask=027,fmask=137 0 1”.

After that booting from SD card is working.

Thanks, best regards
Jürgen

Hi juergen,

Reboot does not update dtb partition. To update, you need to copy updated dtb in Linux_for_Tegra/kernel/dtb location and reflash the device. Please try and let me know.

Thanks,
Shubhi

Hello Shubhi,

I have seen there is a new JetPack 4.2.1 available (we use 4.2 so far). The DT is already changed accordingly there. I have flashed this version and yes: It is working fine now!

Thank you very much!

Best Regards
Jürgen