参考:

  1. 解决:cannot execute binary filelink
  2. Linux中查看文件是什么类型的三种办法link
  3. fatal error: libusb.h: No such file or directorylink
  4. GCC编译过程与动态链接库和静态链接库link
  5. Linux 要如何查看系统架构link
  6. adb下载安装及使用link

正文:

/xxx/黑芝麻/BST_A1000_linux_driver_程序员开发指南 目录下《BST-A1000-Linux-Driver-程序员开发指南-v1.2.1.pdf》文档中的 SocketCAN编程部分有明确的过程:

  1. 复制文档中的代码实例,放在docker的宿主机里
    can_send.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>


#define CAN0 "can0"
#define CAN0_CONFIG "ip link set can0 up type can \
    tq 50 prop-seg 8 phase-seg1 6 phase-seg2 5 sjw 2 \
    dtq 10 dprop-seg 8 dphase-seg1 6 dphase-seg2 5 dsjw 2 fd on"
#define CAN0_DOWN "ip link set can0 down"
#define CANFD_TEST_LEN 64

int main(int argv, char **argc)
{
	struct sockaddr_can addr;
	struct ifreq ifr;
	struct canfd_frame frame;
	int enable_canfd = 1;
	int i = 0, nbytes;
	int s;

	system(CAN0_DOWN);
	system(CAN0_CONFIG);

	/* init socket */
	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0){
		perror("socket");
		return -1;
	}

	strcpy(ifr.ifr_name, CAN0);
	ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);
	if(!ifr.ifr_ifindex){
		perror("if_nametoindex");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	if(ioctl(s, SIOCGIFINDEX, &ifr) < 0){
		perror("SIOCGIFINDEX");
		return -1;
	}

	if(setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd))){
		printf("error when enableing CANFD support\n");
		return -1;
	}
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0){
		perror("bind");
		return -1;
	}
	/* send data */
	frame.can_id = 0x666;
	for(i = 0; i < CANFD_TEST_LEN; i++){
		frame.data[i] = i;
	}
	frame.len = CANFD_TEST_LEN;

	nbytes = sizeof(frame);
	if (write(s, &frame, nbytes) != nbytes) {
		perror("write");
	}
	close(s);
	return 0;
}

can_recv.c

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


#define CAN1 "can1"
#define CAN1_CONFIG "ip link set can1 up type can \
	tq 50 prop-seg 8 phase-seg1 6 phase-seg2 5 sjw 2 \
	dtq 10 dprop-seg 8 dphase-seg1 6 dphase-seg2 5 dsjw 2 fd on"
#define CAN1_DOWN "ip link set can1 down"
#define CANFD_TEST_DLC 64

int main(int argv, char **argc)
{
	struct sockaddr_can addr;
	struct ifreq ifr;
	struct canfd_frame frame;
	int enable_canfd = 1;
	int i = 0, nbytes = 0;
	int s;
	system(CAN1_DOWN);
	system(CAN1_CONFIG);
	/* init socket */
	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0){
		perror("socket");
		return -1;
	}
	strcpy(ifr.ifr_name, CAN1);
	ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);
	if(!ifr.ifr_ifindex){
		perror("if_nametoindex");
		return -1;
	}
	memset(&addr, 0, sizeof(addr));
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	if(ioctl(s, SIOCGIFINDEX, &ifr) < 0){
		perror("SIOCGIFINDEX");
		return -1;
	}

	if(setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd))){
		printf("error when enableing CANFD support\n");
		return -1;
	}
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0){
		perror("bind");
		return -1;
	}
	
	/* receive data */
	nbytes = read(s, &frame, sizeof(frame));
	if(nbytes > 0){
		printf("ID=0x%X DLC=%d DATA : ", frame.can_id, frame.len);
		for(i = 0; i < frame.len; i++){
			printf("0x%x ", frame.data[i]);
		}
		printf("\n");
	}
	close(s);
	return 0;
}

  1. docker宿主机的文件传送到docker环境里
sudo docker cp file <容器 ID>:/dir
sudo docker cp can_recv.c  cbdf19c95fb2:/home/canfd_demo
sudo docker cp can_send.c  cbdf19c95fb2:/home/canfd_demo
  1. 在docker环境里编译
    查看docker环境的架构:
# uname -m
x86_64

BST A1000板子的架构:

# adb shell
# uname -m
aarch64

架构不一样,得交叉编译
查看 /xxx/黑芝麻/BST-OS SDK_用户指南 下的文档《BST-OS-SDK用户指南-v1.2.1.pdf》中的 编译工具链介绍 部分:

# which aarch64-bst-linux-gcc
/opt/bstos/1.1.1.3/sysroots/x86_64-bstsdk-linux/usr/bin/aarch64-bst-linux/aarch64-bst-linux-gcc

然后执行 改变环境变量 的可执行文件:

# cd /opt/bstos/1.1.1.3/
# ls
environment-setup-aarch64-bst-linux                         sysroots
environment-setup-armv7at2hf-neon-bstmllib32-linux-gnueabi  version-aarch64-bst-linux
site-config-aarch64-bst-linux                               version-armv7at2hf-neon-bstmllib32-linux-gnueabi
site-config-armv7at2hf-neon-bstmllib32-linux-gnueabi
# chmod +x environment-setup-aarch64-bst-linux
# ./environment-setup-aarch64-bst-linux

最后编译代码:

#cd /home/canfd_demo/
# aarch64-bst-linux-gcc can_recv.c -o can_recv --sysroot=/opt/bstos/1.1.1.3/sysroots/aarch64-bst-linux/
# aarch64-bst-linux-gcc can_send.c -o can_send --sysroot=/opt/bstos/1.1.1.3/sysroots/aarch64-bst-linux/
  1. 把编译好的可执行文件传送到BST A1000板子里
    用一根USB信号线连接docker宿主机和BST A1000板子的USB2.0 FOR SOC B端口,另外一根信号线连接docker宿主机和BST A1000板子的 USB2.0 DEBUG FOR SOA A + SOC B + TC397 端口,putty 连接 /dev/ttyUSB1 串口,然后宿主机docker环境外面执行
adb kill-server

避免docker宿主机的adb服务与docker容器中的有冲突,然后:

adb push can_send /home/root/test
adb push can_recv /home/root/test
  1. 在BST A1000板子里执行可执行文件
    可以在docker环境里 adb shell 进入BST A1000板子里
    从BST A1000板子shell里退出到docker环境里用 exit
adb shell
cd /home/root/test
chmod +x can_recv can_send
./can_recv &
./can_send

大功告成!!!

Logo

开源、云原生的融合云平台

更多推荐