Files

139 lines
4.4 KiB
Markdown
Raw Permalink Normal View History

2024-04-10 12:21:46 +08:00
# CAN
2024-05-27 16:58:34 +08:00
CAN (Controller Area Network) is a common real-time communication protocol used for high-speed, reliable data communication in automotive, industrial automation, robotics, and other fields.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
Key concepts regarding CAN:
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
1. **Multi-master, Multi-slave Architecture:** CAN communication follows a multi-master, multi-slave architecture where multiple devices can simultaneously transmit and receive data, enabling efficient distributed communication.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
2. **Frame Format:** CAN communication uses a frame format to transmit data. A basic frame consists of an identifier, data, control bits, and CRC (Cyclic Redundancy Check).
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
3. **Identifier:** Each CAN frame has a unique identifier used to specify the type and priority of the message. The identifier is either 11 bits or 29 bits in length, which determines the message priority.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
4. **Data Rate:** CAN supports various data transmission rates, such as 125 Kbps, 500 Kbps, and 1 Mbps. You can choose the rate according to your needs.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
5. **Collision Detection:** CAN uses the CSMA/CR (Carrier Sense Multiple Access / Collision Resolution) mechanism to detect and resolve data collisions.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
6. **Error Detection and Correction:** CAN employs CRC to detect errors and has some error correction capabilities to ensure reliable data transmission.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
7. **Broadcast and Unicast:** CAN supports broadcast messages, allowing all devices to receive the message. It also supports unicast through identifiers, where only specific devices will receive the message.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
8. **Application Areas:** CAN communication is widely used in automotive internal networks, industrial automation, aerospace, robotics, and medical devices, among other fields.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
CAN has been abstracted as a network device in Linux, so programming for the CAN bus is referred to as [SocketCAN](https://en.wikipedia.org/wiki/SocketCAN).
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
In Linux, to use CAN, you first need to set the communication baud rate for CAN, and then enable the CAN bus.
2024-04-10 12:21:46 +08:00
```bash
2024-05-27 16:58:34 +08:00
# View CAN interface.
2024-04-10 12:21:46 +08:00
sudo ip link list
2024-05-27 16:58:34 +08:00
# Set the CAN interface speed to 500000.
2024-04-10 12:21:46 +08:00
sudo ip link set can0 type can bitrate 500000
2024-05-27 16:58:34 +08:00
# Activate the CAN interface.
2024-04-10 12:21:46 +08:00
sudo ip link set up can0
2024-05-27 16:58:34 +08:00
# Disable the CAN interface.
2024-04-10 12:21:46 +08:00
sudo ip link set down can0
```
2024-05-27 16:58:34 +08:00
To demonstrate CAN programming, create a virtual CAN bus.
2024-04-10 12:21:46 +08:00
```bash
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
```
2024-05-27 16:58:34 +08:00
Then read and write the CAN bus in a C program.
2024-04-10 12:21:46 +08:00
``` C
#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;
}
```
2024-05-27 16:58:34 +08:00
You can analyze packets on the vcan0 interface using the candump utility, which is part of the SocketCAN can-utils package.
If can-utils is not installed, you can use the following command to install it.
2024-04-10 12:21:46 +08:00
``` bsah
sudo apt install can-utils
```
2024-05-27 16:58:34 +08:00
First, run the command in a terminal:
2024-04-10 12:21:46 +08:00
``` bash
candump vcan0
```
2024-05-27 16:58:34 +08:00
Then, start another terminal to compile and run the above program, and you will be able to see in the terminal where the candump command is running:
2024-04-10 12:21:46 +08:00
``` bash
vcan0 123 [2] 11 22
```
2024-05-27 16:58:34 +08:00
After viewing the information, you can press `ctrl + c` to terminate the candump program.
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
When compiling the above program, you can compile and run it in the examples/linux_can directory of [M5Stack_Linux_Libs]().
2024-04-10 12:21:46 +08:00
``` bash
2024-05-27 16:58:34 +08:00
# Clone repository
2024-04-10 12:21:46 +08:00
git clone https://github.com/M5STACK/M5Stack_Linux_Libs.git
2024-05-27 16:58:34 +08:00
# Enter directory
2024-04-10 12:21:46 +08:00
cd M5Stack_Linux_Libs/examples/linux_can
2024-05-27 16:58:34 +08:00
# Compile
2024-04-26 09:45:12 +08:00
scons
2024-04-10 12:21:46 +08:00
2024-05-27 16:58:34 +08:00
#Quote
# https://zhuanlan.zhihu.com/p/470681140?utm_id=0
2024-04-10 12:21:46 +08:00
```