TX2/Linux でのコマンドと C プログラムの送受信例

このブログでは、先人の作品について詳しく言及しています。

TX2/LinuxでのCANバスの受信と送信を詳しく解説!

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

Linux CANプログラミングの詳細な説明

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

CAN の使用は 6 つのステップに要約できます。

0. テストする前に、テスト ツール can-utils をダウンロードしてインストールすることをお勧めします。

sudo apt-get install can-utils

1. 缶デバイスドライバーをロードします。

sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

2. ボーレートを設定します(ここでは有効にしたりオンにしたりすることはできないことに注意してください)

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

RTNETLINK が「デバイスまたはリソースがビジー状態である」と応答した場合は、次のコマンドを使用する必要があります。

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

閉じる。

3. ループバック モードに設定します (テストする必要があるため、ループバック テストは外部 can ドライバーと 120 オームの抵抗なしで実行できます。can0 デバイスを使用します)

sudo ip link set can0 type can loopback on

周辺機器を使用する場合、この手順は省略できます。

4. 缶デバイスの電源を入れます。

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

5. 送受信:

送信:

cansend can0 123#abcdabcd

cansend はコマンド、can0 はパラメータ、123 は ID、# セパレータ、abcdabcd は送信データです。

受信: 受信するには別の端末を開く必要があります

candump can0

candump はコマンド、can0 はデバイスを示すパラメータであり、このコマンドはブロックされており、常に受信を待ちます。

6. 缶デバイスの電源を切ります。

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

上記のテストを tx2 で短時間で実行しました。しかし、制御の知識を持った技術者の制御ニーズには応えられず、受信と送信を実現するプログラムを作成する必要があります。使用されるプログラム例:

2 つの c ファイル: 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;
}

実際の測定でも送受信を実現できます。

他のデバイスとの通信のために、TX2 は CAN 経由でウィンドウ 7 と通信します。TX2 は CAN 変換チップに外部接続され、ウィンドウは直接接続に USB から CAN デバイスを使用します (直接接続が可能です。USB から CAN コンバータにはすでに 120 が含まれています)オーム抵抗器, ここを参照してください, したがって、一致する抵抗器がないという問題について心配する必要はありません). 缶デバイスの電源を入れた後、プログラムを使用して送受信しました. 午後テストした後, 何もありませんでした問題。

おすすめ

転載: blog.csdn.net/weixin_41579872/article/details/119426097
おすすめ