NVIDIA Xavier CAN

文章目录

 

前言

Nvidia Xavier GPIO 输入输出 中断 PWM
NVIDIA Xavier UART
前面几节总结了GPIO, UART相关的操作, 本节总结一下NVIDIA Xavier的CAN, 作为本周的小结. Xavier的40-Pin扩展口引出了两路CAN, 具体引脚为:

引脚CAN
29CAN0_DIN
31CAN0_DOUT
33CAN1_DOUT
37CAN1_DIN

如果接上CAN收发器(别忘了120Ω终端电阻), 如下图所示:
在这里插入图片描述
图出自 https://elinux.org/Jetson/AGX_Xavier_CAN.

Jetson/AGX Xavier CAN

Jetson/AGX Xavier CAN 是权威的资料, 文中指出, 为了和树莓派40-Pin引脚兼容, CAN的相应引脚默认配置为GPIO功能, 使用CAN功能需要两步:

  • 更新Pinmux
  • 安装(挂载)内核模块, 配置接口以使能CAN

通过这两步使能CAN后, 再进行诸如 Socket CAN 的编程.

更新Pinmux方法1

嫌麻烦的直接跳到下一小节方法2.

上小节链接中给出的更新Pinmux的方法是通过Jetson_AGX_Devkit_Pinmux_Configuration_Template.xlsm文件配置后自动生成, 改动大致有:

diff --git a/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg b/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
index df43561..c61e80d 100644
--- a/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
+++ b/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
@@ -322,10 +322,10 @@ pinmux.0x0243d010 = 0x00000059; # spi1_cs0_pz6: rsvd1, pull-up, tristate-enable,
 pinmux.0x0243d050 = 0x00000059; # spi1_cs1_pz7: rsvd1, pull-up, tristate-enable, input-enable, lpdr-disable
 pinmux.0x0c301010 = 0x00000059; # safe_state_pee0: rsvd1, pull-up, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable
 pinmux.0x0c301038 = 0x00000058; # power_on_pee4: rsvd0, pull-up, tristate-enable, input-enable, lpdr-disable
-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.0x0c303020 = 0x0000c000; # can0_stb_paa4: rsvd0, tristate-disable, input-disable
 pinmux.0x0c303028 = 0x0000c000; # can0_en_paa5: rsvd0, tristate-disable, input-disable
 pinmux.0x0c303030 = 0x0000c058; # can0_wake_paa6: rsvd0, pull-up, tristate-enable, input-enable

自动生成的pinmux配置文件放到主机的Jetpack里面, 路径是: $JETPACK_ROOT/Xavier/Linux_for_Tegra/bootloader/t186ref/BCT, 然后开始刷机:

$ cd $JETPACK_ROOT/Xavier/Linux_for_Tegra/
$ sudo ./flash.sh jetson-xavier mmcblk0p1

更新Pinmux方法2

https://github.com/hmxf/can_xavier, 这里使用busybox中的devmem工具配置:

# 安装busybox, 需要里面的devmem工具
sudo apt install busybox

# pinmux.0x0c303000 and pinmux.0x0c303008 are for CAN1
# pinmux.0x0c303010 and pinmux.0x0c303018 are for CAN0
# 检查当前的寄存器值
sudo busybox devmem 0x0c303000	# 0x0000C055
sudo busybox devmem 0x0c303008	# 0x0000C055
sudo busybox devmem 0x0c303010	# 0x0000C059
sudo busybox devmem 0x0c303018	# 0x0000C059

# 用devmem修改寄存器
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

挂载CAN控制器

寄存器改好了, 该挂载了, 使用modprobe:

sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

# 检查挂载
lsmod

与下面操作似乎等效:

# Load prebuilt but not loaded drivers(Please modify path if system has been updated)
sudo insmod /lib/modules/4.9.108-tegra/kernel/net/can/can.ko
sudo insmod /lib/modules/4.9.108-tegra/kernel/net/can/can-raw.ko
sudo insmod /lib/modules/4.9.108-tegra/kernel/net/can/can-bcm.ko
sudo insmod /lib/modules/4.9.108-tegra/kernel/net/can/can-gw.ko
sudo insmod /lib/modules/4.9.108-tegra/kernel/drivers/net/can/can-dev.ko
sudo insmod /lib/modules/4.9.108-tegra/kernel/drivers/net/can/mttcan/native/mttcan.ko

下面是挂载后, 用lsmod检查的情况:

xavier@xavier-c:~$ lsmod
Module                  Size  Used by
mttcan                 66187  0
can_dev                13306  1 mttcan
can_raw                10388  3
can                    46600  1 can_raw
fuse                  103841  3
zram                   26166  7
overlay                48691  0
hid_logitech_hidpp     22721  0
hid_logitech_dj        13813  0
nvgpu                1569917  20
bluedroid_pm           13912  0
ip_tables              19441  0
x_tables               28951  1 ip_tables

配置CAN接口

挂载好了, 还需要配置一些波特率之类的参数:

配置为1Mbps的标准CAN

sudo ip link set can0 type can bitrate 1000000
sudo ip link set can1 type can bitrate 1000000

或者配置为仲裁段500k, 数据段2M的的CANFD:

sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on
sudo ip link set can1 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on

如果没有外面的CAN收发器, 不要慌, 配置为回环模式:

sudo ip link set can0 type can bitrate 1000000 loopback on
sudo ip link set can1 type can bitrate 1000000 loopback on

然后找根杜邦线短接CAN1的TX和RX, CAN0的TX和RX, 照样可以测试收发. 如图所示(不建议这么做, 为防止烧坏IO, 可以串联一个数K的电阻进行限流):
在这里插入图片描述

打开或关闭CAN

打开CAN控制器:

sudo ip link set up can0
sudo ip link set up can1

# 检查
ifconfig

# 或者静态检查
ip -details -statistics link show can0 
ip -details -statistics link show can1

# 或者简写版的
ip -s -d link show can0
ip -s -d link show can1

使用ifconfig检查的效果如图:
在这里插入图片描述
关闭CAN控制器:

sudo ip link set down can0
sudo ip link set down can1

# 检查
ifconfig	# 关闭的话里面就没有can0, can1了

建议每次配置上小节的参数前都先关闭, 然后配置, 最后重新打开!!!

CAN收发

可以使用 can-utils 进行简单的收发测试, 先安装:

sudo apt install can-utils

发送:

# 123是十六进制帧ID, #后面是8字节十六进制数, 可以用.相隔也可以不用
cansend can0 123#99.95.42.07.2B.96.66.6E
cansend can1 123#99.95.42.07.2B.96.66.6E

# 随机发送
cangen -v can0
cangen -v can1

发送数据的格式(均为十六进制, 3字节是标准帧, 8字节是扩展帧, #跟标准数据帧, #R跟遥控帧, ##跟CANFD帧):

<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.

接收:

candump can0
candump can1

收的数据格式如下, can_x, can_id, [data_dlc], data:

xavier@xavier-c:~$ candump can1
  can1  123   [8]  99 95 42 07 2B 96 66 6E
  can1  123   [8]  99 95 42 07 2B 96 66 6E

小结Xavier CAN配置

以CAN1 配置为500kbps, 回环模式为例:

# 安装busybox, 需要里面的devmem工具
sudo apt install busybox

# 用devmem修改寄存器
sudo busybox devmem 0x0c303000 32 0x0000C400
sudo busybox devmem 0x0c303008 32 0x0000C458
sudo busybox devmem 0x0c303010 32 0x0000C400
sudo busybox devmem 0x0c303018 32 0x0000C458

# 安装CAN控制器并加载驱动程序
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

# 配置前先关闭
sudo ip link set down can1

# 配置CAN为回环模式, 用线短接CAN的TX和RX即可测试, 不用CAN收发器
sudo ip link set can1 type can bitrate 500000 loopback on
# sudo ip link set can1 type can bitrate 500000

# 启动CAN
sudo ip link set up can1

# 打开一个接收终端用于CAN接收
candump can1

# 再打开一个接收终端用于CAN发送
cansend can1 A234567F#99.95.42.07.2B.96.66.6E

需要说明的是, CAN1我测试通过了, CAN0出不来数据, 可能哪里没有配好, 慢慢来吧…

上电加载

需要说明的是, 上面的配置一断电就没了, 是的, 寄存器, lsmodifconfig里面都没了.

如果想开机直接配好, 就把这些写到脚本里, 开机加载就好了, 具体可以参考 Enabling CAN on Nvidia Jetson Xavier Developer Kit. 这里就不赘述了.

SocketCAN 和 can-utils

可参考SocketCAN, 这里引用一段代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

int
main(void)
{
	int s;
	int nbytes;
	struct sockaddr_can addr;
	struct can_frame frame;
	struct ifreq ifr;

	const char *ifname = "vcan0";

	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("Error while opening socket");
		return -1;
	}

	strcpy(ifr.ifr_name, ifname);
	ioctl(s, SIOCGIFINDEX, &ifr);
	
	addr.can_family  = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	printf("%s at index %d\n", ifname, ifr.ifr_ifindex);

	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("Error in socket bind");
		return -2;
	}

	frame.can_id  = 0x123;
	frame.can_dlc = 2;
	frame.data[0] = 0x11;
	frame.data[1] = 0x22;

	nbytes = write(s, &frame, sizeof(struct can_frame));

	printf("Wrote %d bytes\n", nbytes);
	
	return 0;
}

linux-can里有很多示例, 可以去扒拉:
在这里插入图片描述

python-can

是的, 这个很重要, 贴出文档链接: https://python-can.readthedocs.io/en/stable/index.html
引用一个示例代码:

#!/usr/bin/env python
# coding: utf-8

"""
This example shows how sending a single message works.
"""

from __future__ import print_function

import can


def send_one():

    # this uses the default configuration (for example from the config file)
    # see https://python-can.readthedocs.io/en/stable/configuration.html
    bus = can.interface.Bus()

    # Using specific buses works similar:
    # bus = can.interface.Bus(bustype='socketcan', channel='vcan0', bitrate=250000)
    # bus = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
    # bus = can.interface.Bus(bustype='ixxat', channel=0, bitrate=250000)
    # bus = can.interface.Bus(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)
    # ...

    msg = can.Message(
        arbitration_id=0xC0FFEE, data=[0, 25, 0, 1, 3, 1, 4, 1], is_extended_id=True
    )

    try:
        bus.send(msg)
        print("Message sent on {}".format(bus.channel_info))
    except can.CanError:
        print("Message NOT sent")


if __name__ == "__main__":
    send_one()

各种工具或者模块很实用:

CAN Interface Modules:
SocketCAN
Kvaser’s CANLIB
CAN over Serial
CAN over Serial / SLCAN
IXXAT Virtual CAN Interface
PCAN Basic API
USB2CAN Interface
NI-CAN
isCAN
NEOVI Interface
Vector
Virtual
CANalyst-II
SYSTEC interface
USB-CAN Analyzer

一些参考链接

hmxf/can_xavier
Enabling CAN on Nvidia Jetson Xavier Developer Kit
在Nvidia Jetson Xavier开发者套件上启用CAN总线
Nvidia Jetson Xavier与树莓派3b+进行can通讯

微信公众号

欢迎扫描二维码关注本人微信公众号, 及时获取或者发送给我最新消息:
在这里插入图片描述

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
NVIDIA Xavier NX是一款强大的嵌入式AI计算模块,可以广泛应用于无人驾驶、工业自动化、智能摄像头等领域。下面是关于NVIDIA Xavier NX产品手册的回答: 产品手册概述了Xavier NX的技术规格、功能特性以及应用场景。首先介绍了Xavier NX的硬件组成,它采用了高性能的NVIDIA Volta GPU和六核心Carmel ARM v8.2 64位CPU,配备了8GB LPDDR4x内存和16GB eMMC闪存。这些硬件配置使得Xavier NX具备了强大的计算能力和存储能力,可以处理高度复杂的机器学习和深度学习任务。 此外,产品手册还详细介绍了Xavier NX的软件支持。它可以运行NVIDIA的JetPack SDK和TensorRT推理引擎,这使得开发者可以轻松构建和部署高效的AI模型。手册对于如何设置和启动Xavier NX提供了详细的指导,还介绍了如何使用TensorRT加速AI推理和深度学习模型的优化技巧。此外,手册还包含了开发者工具和开发环境的介绍,帮助开发者更好地利用Xavier NX进行软件开发和调试。 产品手册还重点强调了Xavier NX在无人驾驶、工业自动化和智能摄像头等领域的应用优势。它通过提供高度可靠性和低功耗的计算能力,为这些领域中的各种复杂任务提供了强力支持。不仅如此,Xavier NX还具备丰富的扩展性,支持多种传感器和接口,可以轻松与其他设备集成。 总的来说,NVIDIA Xavier NX产品手册提供了全面而详细的关于Xavier NX的介绍和应用指南。它不仅让用户了解到Xavier NX的硬件和软件特性,还帮助用户充分利用其强大的AI计算能力,实现在各个领域的应用创新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值