Receiving and sending commands and C program examples of can bus under TX2/Linux

This blog makes in-depth reference to the works of predecessors:

Detailed explanation of reception and transmission of can bus under TX2/Linux!

https://blog.csdn.net/hhlenergystory/article/details/81976069

Detailed explanation of Linux CAN programming

https://blog.csdn.net/ppdyhappy/article/details/79458458

Using CAN can be summarized into 6 steps:

0. Before testing, it is best to download and install the testing tool can-utils.

sudo apt-get install can-utils

1. Load the can device driver:

sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

2. Set the baud rate (note that can cannot be enabled or turned on here)

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

If RTNETLINK answers: Device or resource busy occurs, you need to use the command

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

to close;

3. Set to loopback mode (because it needs to be tested, loopback testing can be done without external can driver and 120 ohm resistor, use can0 device)

sudo ip link set can0 type can loopback on

If using peripherals, this step can be omitted.

4. Turn on the can device:

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

5. Send and receive:

send:

cansend can0 123#abcdabcd

cansend is the command, can0 is the parameter, 123 is the ID, # separator, abcdabcd is the sending data.

Receiving: Receiving requires opening another terminal

candump can0

candump is a command, can0 is a parameter, indicating which device. This command is blocking and will always wait for reception.

6. Turn off the can device.

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

I ran the above test on tx2 in a short time. However, it does not meet the control needs of technicians with a background in control, so they need to write a program to achieve reception and transmission. Example program used:

Two c files: 1.can_send.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main()
{
	int s,nbytes;
	struct sockaddr_can addr;
	struct ifreq ifr;
	struct can_frame frame[2]={
   
   {0}};
	s=socket(PF_CAN,SOCK_RAW,CAN_RAW);
	strcpy(ifr.ifr_name,"can0");
	ioctl(s,SIOCGIFINDEX,&ifr);
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
	bind(s,(struct sockaddr*)&addr,sizeof(addr));
	setsockopt(s,SOL_CAN_RAW,CAN_RAW_FILTER,NULL,0);
	
	frame[0].can_id = 0x11;
	frame[0].can_dlc =1;
	frame[0].data[0]= 'Y';
	frame[1].can_id = 0x11;//0x33;
	frame[1].can_dlc =1;
	frame[1].data[0]= 'N';
	while(1)
	{
		nbytes = write(s, &frame[0], sizeof(frame[0]));
		printf("nbytes=%d\n",nbytes);
		if(nbytes != sizeof(frame[0]))
		{
			printf("Send Error frame[0]\n!");
			break; //发送错误,退出
		}
		sleep(1);
		nbytes = write(s, &frame[1], sizeof(frame[1]));
		if(nbytes != sizeof(frame[1]))
		{
			printf("Send Error frame[1]\n!");
			break;
		}
		sleep(1);
	}
	close(s);
	return 0;
}

2.can_receive.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main()
{
	int s, nbytes;
	struct sockaddr_can addr;
	struct ifreq ifr;
	struct can_frame frame;
	struct can_filter rfilter[1];
	s = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字
	strcpy(ifr.ifr_name, "can0" );
	ioctl(s, SIOCGIFINDEX, &ifr); //指定 can0 设备
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
	bind(s, (struct sockaddr *)&addr, sizeof(addr)); //将套接字与 can0 绑定
	//定义接收规则,只接收表示符等于 0x11 的报文
	rfilter[0].can_id = 0x11;
	rfilter[0].can_mask = CAN_SFF_MASK;
	//设置过滤规则
	setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
	while(1)
	{
		nbytes = read(s, &frame, sizeof(frame));
		//接收报文//显示报文
		if(nbytes > 0)
		{
			printf("ID=0x%X DLC=%d data[0]=0x%X\n",frame.can_id,frame.can_dlc,frame.data[0]);
		//printf(“ID=0x%X DLC=%d data[0]=0x%X\n”, frame.can_id,	frame.can_dlc, frame.data[0]);
		}
	}
	close(s);
	return 0;
}

The actual measurement can also realize sending and receiving.

For communication with other devices, TX2 communicates with window 7 via CAN. TX2 is externally connected to a CAN conversion chip, and window uses a USB to CAN device for direct connection (direct connection is possible. The USB to CAN conversion already includes a 120 ohm resistor, see here , so you don’t have to worry about the problem of not having matching resistors). After turning on the can device, I used the program to send and receive. After testing it for an afternoon, there was no problem.

Guess you like

Origin blog.csdn.net/weixin_41579872/article/details/119426097