3.9 KiB
CAN
CAN(Controller Area Network),这是一种常见的实时通信协议,用于在汽车、工业自动化、机器人和其他领域中进行高速、可靠的数据通信。
关于CAN的重要概念:
-
多主多从架构: CAN通信是多主多从的通信架构,多个设备可以同时传输和接收数据,从而实现高效的分布式通信。
-
帧格式: CAN通信使用帧格式来传输数据。基本帧由标识符、数据、控制位和CRC(循环冗余校验)组成。
-
标识符: 每个CAN帧都有一个唯一的标识符,用于标识消息的类型和优先级。标识符由11位或29位组成,决定了消息的优先级。
-
数据率: CAN支持多种数据传输率,例如125 Kbps、500 Kbps、1 Mbps等,您可以根据需要进行选择。
-
冲突检测: CAN使用CSMA/CR(Carrier Sense Multiple Access / Collision Resolution)机制来检测和解决数据冲突。
-
错误检测和纠正: CAN使用CRC来检测错误,并且具有一些错误纠正的能力,确保可靠的数据传输。
-
广播和单播: CAN支持广播消息,使得所有设备都能收到消息。同时,也支持通过标识符进行单播,只有特定设备会接收消息。
-
应用领域: CAN通信广泛应用于汽车内部网络、工业自动化、航空航天、机器人和医疗设备等领域。
CAN 在 linux 被抽象成了一个网络设备,所以对 CAN 总线的编程被称为SocketCAN.
在linux 中使用can 首先要设置can的通信速率,然后开启can总线
# 查看 CAN 接口
sudo ip link list
# 设置 CAN 接口速率为 500000
sudo ip link set can0 type can bitrate 500000
# 开启 CAN 接口
sudo ip link set up can0
# 关闭 CAN 接口
sudo ip link set down can0
为了展示 CAN 编程,创建一个虚拟的 CAN 总线.
sudo modprobe can
sudo modprobe can_raw
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
sudo ip link show vcan0
然后在 C 程序中读写 CAN 总线.
#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)) == -1)
{
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)) == -1)
{
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;
}
可以使用 candump 实用程序在 vcan0 接口上分析数据包,该实用程序是 SocketCAN can-utils 包的一部分。 如果没有安装 can-utils,可以使用下面的命令安装.
sudo apt install can-utils
首先在一个终端中运行命令:
candump vcan0
然后另起一个终端编译运行上述程序,然后就能在 运行 candump 命令的终端看到:
vcan0 123 [2] 11 22
看完信息可以按 ctrl + c 结束 candump 程序的运行.
在编译上述程序时可以在 M5Stack_Linux_Libs 的 examples/linux_can 目录下编译并运行.
# 克隆仓库
git clone https://github.com/M5STACK/M5Stack_Linux_Libs.git
# 进入目录
cd M5Stack_Linux_Libs/examples/linux_can
# 编译
scons
推荐:
https://zhuanlan.zhihu.com/p/470681140?utm_id=0