news 2026/7/3 7:10:41

瑞芯微RV1126B开发板(EASY-EAI-PI2) CAN

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
瑞芯微RV1126B开发板(EASY-EAI-PI2) CAN

1.CAN简介

使用Socket CAN的主要目的就是为用户空间的应用程序提供基于Linux网络层的套接字接口。与广为人知的TCP/IP协议以及以太网不同,CAN总线没有类似以太网的MAC层地址,只能用于广播。CAN ID仅仅用来进行总线的仲裁。因此CAN ID在总线上必须是唯一的。当设计一个CAN-ECU(Electronic Control Unit 电子控制单元)网络的时候,CAN报文ID可以映射到具体的ECU。因此CAN报文ID可以当作发送源的地址来使用。

1.1开发板的CAN资源

1.2硬件连接

通常由CPU出来的CAN信号是TTL信号,并不是差分信号。因此需要一个CAN TTL信号转CAN差分信号的模块。其具体的接线图如下所示。

2.快速上手

2.1开发环境准备

如果您初次阅读此文档,请阅读《入门指南/开发环境准备/Easy-Eai编译环境准备与更新》,并按照其相关的操作,进行编译环境的部署

在PC端Ubuntu系统中执行run脚本,进入EASY-EAI编译环境,具体如下所示。

cd ~/develop_environment ./run.sh 2204

2.2源码下载以及例程编译

首先,在虚拟机后台终端,执行以下命令,创建外设单例源码管理目录:

cd /opt mkdir -p EASY-EAI-PI2/demo

首先,到【百度网盘】上下载相关的单例程序:

链接:https://pan.baidu.com/s/1ORJrMeW-bOJ6g_lPiNG6mw?pwd=1234

提取码:1234

比如把单例程序下载到:此电脑\D:\BaiduNetdisk (无规定,用户可自主选择),如下图所示。

再将下载好的单例复制进入虚拟机的文件系统,过程如下图所示。

最后,进入到对应的例程目录执行编译操作,具体命令如下所示:

cd EASY-EAI-PI2/demo/11_CAN ./build.sh

注:

* 由于依赖库部署在板卡上,因此交叉编译过程中必须保持/mnt挂载。

编译成功后,会生成2个demo,一个是发送端:test-can_send,另一个是接收端:test-can_reception。并会自动部署到开发板的/userdata/目录中。

* 此例程需要2个板卡做收发测试,所以2个板卡都需要重复上述操作。

2.3例程运行

通过串口调试ssh调试,进入板卡后台,定位到例程部署的位置,如下所示:

cd /userdata

首先在一台板卡上运行发送端,运行命令如下:

sudo ./test-can-send

然后【再在另外一台】板卡上,运行接收端,运行命令如下:

cd /userdata sudo ./test-can-reception

【接收端】执行效果如下所示。

API的详细说明,以及API的调用(本例程源码),详细信息见下方说明。

3.CAN操作API说明

3.1创建socketcan套接字操作

创建socketcan套接字操作函数原型如下所示。

int socket(int domain, int type, int protocol);

具体介绍如下所示。

3.2指定本地网络接口地址操作

指定本地网络接口地址函数原型如下所示。

int ioctl(int fd, unsigned long request, ...);

具体介绍如下所示。

3.3绑定地址结构操作

绑定地址结构函数原型如下所示。

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

具体介绍如下所示。

3.4设置CAN过滤器操作

设置CAN过滤器操作函数原型如下所示。

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

3.5CAN定义报文格式操作

CAN定义报文格式如下所示。

4.CAN通信例程

【发送端】例程源码为11_CAN/test-can_send/main.c,操作流程如下。

【接收端】例程源码为11_CAN/test-can_send/main.c,操作流程如下。

参考例程如下所示。

发送端例程:

/* 将CAN1波特率设置为500000 bps */ #define ip_cmd_set_can_params "ip link set can1 type can bitrate 500000 triple-sampling on" /* 打开CAN1 */ #define ip_cmd_open "ifconfig can1 up" /* 关闭CAN1 */ #define ip_cmd_close "ifconfig can1 down" int main() { int fd, nbytes; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame[2] = {{0}}; system(ip_cmd_close); system(ip_cmd_set_can_params); system(ip_cmd_open); fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);//创建套接字 strcpy(ifr.ifr_name, "can0" ); ioctl(fd, SIOCGIFINDEX, &ifr); //指定 can1 设备 addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(fd, (struct sockaddr *)&addr, sizeof(addr));//将套接字与 can1 绑定 //禁用过滤规则,本进程不接收报文,只负责发送 setsockopt(fd, 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 = 0x22; frame[1]. can_dlc = 1; frame[1].data[0] = 'N'; //循环发送两个报文 while(1) { nbytes = write(fd, &frame[0], sizeof(frame[0])); //发送 frame[0] printf("write ret:%d",nbytes); if(nbytes != sizeof(frame[0])) { printf("Send Error frame[0]\n!"); break; //发送错误,退出 } sleep(1); nbytes = write(fd, &frame[1], sizeof(frame[1])); //发送 frame[1] if(nbytes != sizeof(frame[1])) { printf("Send Error frame[1]\n!"); break; } sleep(1); } close(fd); return 0; }

接收端例程:

/* 将CAN1波特率设置为500000 bps */ #define ip_cmd_set_can_params "ip link set can1 type can bitrate 500000 triple-sampling on" /* 打开CAN1 */ #define ip_cmd_open "ifconfig can1 up" /* 关闭CAN01*/ #define ip_cmd_close "ifconfig can1 down" int main() { int fd, nbytes; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; struct can_filter rfilter[1]; system(ip_cmd_close); system(ip_cmd_set_can_params); system(ip_cmd_open); fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字 strcpy(ifr.ifr_name, "can1" ); ioctl(fd, SIOCGIFINDEX, &ifr); //指定 can1 设备 addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(fd, (struct sockaddr *)&addr, sizeof(addr)); //将套接字与 can1 绑定 //定义接收规则,只接收表示符等于 0x11 的报文 rfilter[0].can_id = 0x11; rfilter[0].can_mask = CAN_SFF_MASK; //设置过滤规则 setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); while(1) { nbytes = read(fd, &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]); } } close(fd); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 7:08:38

聚氨酯复合板的生产特点与应用前景分析

聚氨酯复合板在建筑行业的使用逐渐增多,展现出良好的节能保温性能。生产过程中,先进的自动化流水线除了提高了生产效率,也确保了产品质量的稳定性。该材料在欧美等发达国家的普及率已达80%,而中国市场仍具备较大的发展空间。凭借多…

作者头像 李华
网站建设 2026/7/3 7:10:07

【IDE终极选型指南】:20年资深架构师亲测IntelliJ IDEA与VS Code在Java/TS全栈开发中的真实性能差距(附基准测试数据)

更多请点击: https://kaifayun.com 第一章:IDE终极选型的底层逻辑与认知重构 开发者常将IDE视为“写代码的工具”,却忽视其本质是**工程化认知系统的外延接口**。选型决策若仅基于语法高亮、插件数量或启动速度,便如同用尺子丈量…

作者头像 李华
网站建设 2026/6/27 10:20:00

GBase 8s数据库安装后核查简介

南大通用GBase 8s数据库(gbase database)安装完成后:别忘了"验货"。1、查看数据库状态onstat -正常输出:On-Line -- Up 00:12:45 -- 3378128 Kbytes2、连接数据库dbaccess sysmaster -总结:选对方式&#xf…

作者头像 李华
网站建设 2026/6/27 10:17:42

PyQt examples:15个示例带你入门桌面应用开发

文章目录PyQt examples:15个示例带你入门桌面应用开发PyQt examples:15个示例带你入门桌面应用开发 PyQt examples 是一个桌面应用开发示例合集,目前获得 2,571 Star。 这个仓库由 Michael Herrmann 维护,包含 15 个独立的 PyQt …

作者头像 李华
网站建设 2026/6/27 10:16:00

You-Get:一条命令下载网页视频和图片

文章目录You-Get:一条命令下载网页视频和图片You-Get:一条命令下载网页视频和图片 GitHub 上有个命令行工具,Star 数超过 5.6 万: You-Get 是一个 Python 写的命令行下载工具,用来从网页上抓取视频、音频和图片。 它…

作者头像 李华