CAN总线基础和在linux下使用实战

CAN总线基础和在linux下使用实战

CAN 是Controller Area Network 的缩写
有CANH和CANL两线,即差分信号通信。当然设备芯片还会有电源和地等线。
在总线空闲时,所有的单元都可开始发送消息(多主控制)。
最先访问总线的单元可获得发送权(CSMA/CA 方式)。
多个单元同时开始发送时,发送高优先级 ID 消息的单元可获得发送权。
没有目标地址和源地址的概念,只有标识符,根据标识符决定优先级,根据表示符,设备自己判断是否接收给上层,让上层处理。即消息是广播的形式。
两个以上的单元同时开始发送消息时,对各消息ID 的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。这个是与CAN总线中,多个电平同时出现时,显式电平为最终值这个机理有关。所以,设备一边发送,一遍检查总线的实际值,即可知道是否有别的设备在同时发送了。这种不算出错误,而是算仲裁是否取胜。 后面CRC检验错误等,才是错误。
标准格式有11 个位的标识符(Identifier: 以下称ID),扩展格式有29 个位的ID。
通信是通过以下5 种类型的帧进行的。 数据帧、 遥控帧、错误帧、 过载帧、 帧间隔

作为驱动开发人员,应该了解,总线协议哪些部分是硬件实现的,哪些部分是软件实现的。
数据帧的数据内容和遥控帧的数据内容,应该是软件填入,并由硬件进行协助处理。错误帧、过载帧、帧间隔,这种东西,应该是硬件直接处理,只是可能会转换为一个中断控制器的一个status来通知上层软件逻辑,出现某些问题。

对于linux软件来说,CAN host controller驱动会把硬件收到的CAN数据组织为struct can_frame 。
linux内核代码来看
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags /
__u8 can_dlc; / frame payload length in byte (0 … CAN_MAX_DLEN) /
__u8 data[CAN_MAX_DLEN] attribute((aligned(8)));
};
can_id就是表示符字段,并含CAN_ID + EFF/RTR/ERR flags
例如imx6的flexcan的驱动,在can_id上也指明了一些错误信息给上层使用。通过can_id的标记位指明。具体看flexcan的代码。
/

Controller Area Network Identifier structure
bit 0-28 : CAN identifier (11/29 bit)
bit 29 : error message frame flag (0 = data frame, 1 = error message)
bit 30 : remote transmission request flag (1 = rtr frame)
bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
即linux重新定义了canid,这个与can总线上的格式不同,但意义类似。而且提供了filter机制,让应用层的socket只是关心某些canframe的包。注意,其他操作系统,实现方式可能不同。
使用CAN分析仪,安装驱动,并使用CANTest工具,
选择好设备和can通道后,并设置频率后,即可接收和发送。

CANH接CANH,CANL接CANL

此CANTest工具运行后,并设置速率为500KHz

另外一侧,即设备侧,linux中运行
ip link set can0 down
ip link set can0 up type can bitrate 500000
即设置为500KHz。
然后运行
cansend can0 1F334455#11223355
linux上发送上面的数据,#之前是can id,#号之后是数据。CANTest上,就会收到并显示。

linux设备侧,运行candump -l any,0:0,#FFFFFFFF,然后CANTest上发送数据。
然后candump会告诉你保存到哪个文件,你即可
cat这个文件看到内容。

linux侧的can使用介绍,具体可以看Documentation/networking/can.txt

linux CAN应用开发涉及的api:参考candump和cansend的代码
struct sockaddr_can addr;
struct iovec iov;
struct msghdr msg;
struct cmsghdr cmsg;
struct can_filter
rfilter;
can_err_mask_t err_mask;
struct canfd_frame frame;
struct ifreq ifr;
socket(PF_CAN, SOCK_RAW, CAN_RAW);
ioctl(s[i], SIOCGIFINDEX, &ifr)
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_ERR_FILTER,&err_mask, sizeof(err_mask)); //根据需要
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,&join_filter, sizeof(join_filter)) //根据需要
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FILTER,rfilter, numfilter sizeof(struct can_filter)); //根据需要, 设置filter,过滤某些CAN_ID的数据
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on)); //根据需要
bind(s[i], (struct sockaddr
)&addr, sizeof(addr))
select(s[currmax-1]+1, &rdfs, NULL, NULL, timeout_current)
recvmsg(s[i], &msg, 0); //或者recv()
close(s[i]);
ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);
ioctl(s, SIOCGIFMTU, &ifr)
bind(s, (struct sockaddr *)&addr, sizeof(addr)
write(s, &frame, required_mtu)

由于linux暴露给上层的CAN网络设备只支持
socket(PF_CAN, SOCK_RAW, CAN_RAW);
而android上层使用的是java,所以需要native层的service把此种socket转为另外的tcp或者udp或者进程间通信机制的socket才能发给java上层。

具体请参考我的免费的linux各种驱动开发课程如下:
https://edu.51cto.com/course/17138.html

另外我的相关培训视频请看:
欢迎观看我发布的各个课程: https://edu.51cto.com/lecturer/8896847.html

原文地址:https://blog.51cto.com/8906847/2367906

时间: 2024-11-13 11:02:12

CAN总线基础和在linux下使用实战的相关文章

spi总线注意事项和linux下使用实战

spi总线注意事项和linux下使用实战 spi一般是4线(CS.MISO.MOSI.SCK)或者3线(MISO和MOSI线合并),当然这里忽略了设备芯片的电源.地等其他线.一条spi总线上只有一个master,slave根据片选情况可以有多个,但同一时间只能有一个工作.通过片选cs信号来区分.这里只关心spi总线的外设,所以不用像spi host controller驱动及内核spi_bus_type那样关心很多spi的细节.具体协议参见<SPI_motorola_specification.

[Linux基础环境/软件]Linux下安装mysql

我是使用免安装的包mysql-5.5.28-linux2.6-x86_64.tar.gz(在http://dev.mysql.com/downloads/可以下载到最新的包)的.直接解压,然后配置,初始化数据库,启动即可. 安装步骤有: 解压和建立软链: 配置文件和配置参数: 初始化数据库: 启动和关闭: 建立数据库用户和授权. 1. 解压和建立软链: #tar xzvf mysql-5.5.28-linux2.6-x86_64.tar.gz #在/usr/local目录下 #ln -s mys

Linux入门基础教程之Linux下软件安装

Linux入门基础教程之Linux下软件安装 一.在线安装: sudo apt-get install 即可安装 如果在安装完后无法用Tab键补全命令,可以执行: source ~/.zshrc APT(Advanced Packaging Tool), 包括apt-get, apt-cache, apt-cdrom等工具,APT可以自动下载,配置,安装二进制或者源代码格式的软件包,因此简化了Unix系统上管理软件的过程,Ubuntu是Debian的发行版.Debian使用的包管理工具是dpkg

i2c总线注意事项和在linux下使用实战

i2c总线注意事项和在linux下使用实战 仔细阅读上图中的下部分文字. 注意你的i2c_msg发送方式,决定了是否有pause. 注意图中,什么叫sr. 注意图上说的什么样的才是真i2c协议 i2c设备驱动涉及的linux i2c api:参见include/linux/i2c.hi2c_transfer()i2c_master_send().i2c_master_recv ()i2c_smbus_xfer()struct i2c_driverstruct i2c_clienti2c_get_

【夯实PHP基础系列】linux下yum安装PHP APC

Alternative PHP Cache(可选PHP缓存),依赖于 PECL扩展库 用源码方式安装,直接yum就行了:首先要安装apc的依赖包:yum install php-pear php-devel httpd-devel pcre-devel gcc make 然后使用pecl安装apc:pecl install apc 添加apc扩展到配置文件:echo "extension=apc.so" > /etc/php.d/apc.ini 最后记得重启服务器:service

Linux基础教程 linux下cat 命令使用详解

cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件]... 2.命令功能: 兄弟连Linux培训 小编,来讲一下cat主要的三大功能: 1.一次显示整个文件:cat filename 2.从键盘创建一个文件:cat > filename 只能创建新文件,不能编辑已有文件. 3.将几个文件合并为一个文件:cat file1 file2 > file

postgreSql基础命令及linux下postgreSql命令

转自:http://blog.csdn.net/qpengyanting123/article/details/7497556 (1)用户实用程序:  createdb 创建一个新的PostgreSQL的数据库(和SQL语句:CREATE DATABASE 相同)  createuser 创建一个新的PostgreSQL的用户(和SQL语句:CREATE USER 相同)  dropdb 删除数据库  dropuser 删除用户  pg_dump 将PostgreSQL数据库导出到一个脚本文件 

springboot:基础学习一 linux下后台启动springboot项目

我们知道启动springboot的项目有三种方式: 运行主方法启动 使用命令 mvn spring-boot:run”在命令行启动该应用 运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行. 我们在开发的时候,通常会使用前两种,而在部署的时候往往会使用第三种.但是,我们在使用java -jar来运行的时候,并非后台运行. 下面我们来说说服务器上如何后台启动springboot项目.实际上,实现的方法有很多种,这里就列两

linux下NFS实战

系统环境 系统平台:CentOS release 6.8 (Final) NFS Server IP:172.16.55.6 防火墙关闭 SELinux=disabled 安装NFS程序包 1.查看系统是否已经安装 [[email protected] vsftpd]$ yum list nfs-utils 已加载插件:fastestmirror, security Loading mirror speeds from cached hostfile 已安装的软件包 nfs-utils.x86_