赞
踩
【摘要】由于大陆ARS408毫米波雷达以及底盘控制均采用CAN通信,Xavier的40-Pin扩展引脚包含两路CAN控制器,因此本篇介绍CAN的相关配置以及使用SoketCAN进行报文的收发。
JETPACK_ROOT/Xavier/Linux_for_Tegra/bootloader/t186ref/BCT/
# 法1 $JETPACK_ROOT/Xavier/Linux_for_Tegra/bootloader/t186ref/BCT/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg ***************************************************************************************************************** # 法2 # 安装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
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan
# 检查挂载
lsmod
# 配置波特率为500000 sudo ip link set can0 type can bitrate 1000000 sudo ip link set can1 type can bitrate 1000000 # 启动CAN sudo ip link set up can0 sudo ip link set up can1 # 检查配置 ifconfig # 关闭CAN sudo ip link set down can0 sudo ip link set down can1 # 检查 ifconfig # 关闭的话里面就没有can0, can1了
# 安装
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
# 接收数据
candump can0
candump can1
echo ">>> Reconfigure the four regs for CAN controllers' pins" echo ">> ----------original regs data----------" sudo busybox devmem 0x0c303000 sudo busybox devmem 0x0c303008 sudo busybox devmem 0x0c303010 sudo busybox devmem 0x0c303018 echo ">> ----------Modified regs data----------" 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 sudo busybox devmem 0x0c303008 sudo busybox devmem 0x0c303010 sudo busybox devmem 0x0c303018 echo ">>> ----------Mount CAN controllers and load the drivers----------" sudo modprobe can sudo modprobe can_raw sudo modprobe mttcan echo ">>> ----------Set Baud rate----------" 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 echo ">>> ----------Enable CAN----------" sudo ip link set up can0 sudo ip link set up can1
int socket(int domain, int type, int protocol);
是socket函数的原型,这是一个通用的网络编程函数,用于创建套接字并指定通信协议,参数分别为:协议集、socket类型、传输协议(0会缺省),返回一个文件描述符。在SocketCAN中,我们使用socket函数创建用于CAN总线通信的套接字,需要指定PF_CAN协议族和CAN_RAW套接字类型。PF_CAN是对于原始socket协议系列的补充,同时,使用了一种特殊的CAN_RAW套接字类型#include <iostream> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> #include <linux/can.h> #include <linux/can/raw.h> int main() { // 创建Socket,采用AF_CAN协议 int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (sock == -1) std::cerr << "Failed to create SocketCAN socket." << std::endl; // 设置CAN接口名称,配置CAN地址信息 struct sockaddr_can addr; struct ifreq ifr; std::strcpy(ifr.ifr_name, "can0"); // 替换为实际的CAN接口名称 if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) { std::cerr << "Failed to get CAN interface index." << std::endl; close(sock); } addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; // 绑定CAN地址 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { std::cerr << "Failed to bind SocketCAN socket." << std::endl; close(sock); } // 发送CAN报文 struct can_frame frame; frame.can_id = 0x123; // CAN标识符 frame.can_dlc = 8; // 数据长度 std::memset(frame.data, 0, sizeof(frame.data)); // 数据内容 if (write(sock, &frame, sizeof(frame)) == -1) { std::cerr << "Failed to send CAN frame." << std::endl; close(sock); } // 接收CAN报文 struct can_frame frame; ssize_t nbytes = read(sock, &frame, sizeof(frame)); if (nbytes < 0) { std::cerr << "Failed to receive CAN frame." << std::endl; close(sock); } else if (nbytes < sizeof(struct can_frame)) { std::cerr << "Incomplete CAN frame received." << std::endl; close(sock); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。