NVIDIA Xavier CAN
文章目錄
前言
Nvidia Xavier GPIO 輸入輸出 中斷 PWM
NVIDIA Xavier UART
前面幾節總結了GPIO, UART相關的操作, 本節總結一下NVIDIA Xavier的CAN, 作為本週的小結. Xavier的40-Pin擴充套件口引出了兩路CAN, 具體引腳為:
引腳 | CAN |
---|---|
29 | CAN0_DIN |
31 | CAN0_DOUT |
33 | CAN1_DOUT |
37 | CAN1_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出不來資料, 可能哪裡沒有配好, 慢慢來吧…
上電載入
需要說明的是, 上面的配置一斷電就沒了, 是的, 暫存器, lsmod
, ifconfig
裡面都沒了.
如果想開機直接配好, 就把這些寫到指令碼里, 開機載入就好了, 具體可以參考 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通訊
微信公眾號
歡迎掃描二維碼關注本人微信公眾號, 及時獲取或者傳送給我最新訊息:
相關文章
- Nvidia AGX Xavier Jetson 開機配置
- 『NVIDIA』JETSON XAVIER NX DEVELOPER KIT學習筆記Developer筆記
- 【nvidia jetson xavier】 Deepstream Yolov3示例模型執行YOLO模型
- Jetson Xavier NX 試玩 (二)
- 新品釋出 | 飛凌 AI邊緣計算終端FCU3001來了!基於NVIDIA Jetson Xavier NX設計AI
- Jetson AGX Xavier/Ubuntu安裝QTUbuntuQT
- CAN_NM
- CAN協議協議
- why you can be in netherland
- CAN過濾器過濾器
- Jetson AGX Xavier ROS下呼叫USB單目攝像頭ROS
- Only AI Flow Can Do!AI
- 在Linux上使用CANLinux
- CAN匯流排分析儀工具-CAN轉USB智慧協議轉換器協議
- 計算CAN波特率
- C# kvaser can 通訊C#
- Can匯流排介紹
- STM32——CAN通訊
- npm A complete log of this run can be found inNPM
- TypeError: can‘t concat str to bytesError
- Can't open file: (errno: 24)
- markevery can control which dots to be plotted
- conda的nvidia頻道
- 如何配置 CAN 轉 PN 閘道器實現與 can 裝置的連線
- nvidia顯示設定不可用 nvidia沒有顯示設定
- nvidia控制皮膚怎麼調 nvidia控制皮膚怎麼設定
- 完美解決stack Error: Can‘t find Python executable “python“, you can set the PYTHON env variable.ErrorPython
- linux nvidia驅動錯誤--NVRM: This PCI I/O region assigned to your NVIDIA device is invalidLinuxVRdev
- 【已解決】報錯 NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driverAI
- [LeetCode] 3011. Find if Array Can Be SortedLeetCode
- 協議CAN&報文&仲裁協議
- Mongoose can't update timestampGo
- CAN匯流排原理_學習
- DSP28377S_CAN通訊
- Supervisor 解決 can't find command *
- How can I add a site title refiner
- Ubuntu安裝nvidia-dockerUbuntuDocker
- Containerd 配置使用 Nvidia container runtimeAI