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

  

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

  

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

  

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

  

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

  

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

  

对于linux软件来说,主机控制器可以驱动会把硬件收到的可以数据组织为struct can_frame。
linux内核代码来看
struct can_frame {
canid_t can_id;/* 32位CAN_ID + EFF/RTR/错国旗/
__u8 can_dlc;/帧载荷长度字节(0…CAN_MAX_DLEN)/
__u8数据(CAN_MAX_DLEN)属性((对齐(8)));
};
can_id就是表示符字段,并含can_id + EFF RTR/错国旗
例如imx6的flexcan的驱动,在can_id上也指明了一些错误信息给上层使用。通过can_id的标记位指明。具体看flexcan的代码。
/

  


控制器区域网络标识符结构0-28:可以标识符(11/29位)
29:错误消息帧标记(0=数据帧,1=错误消息)
30:远程传输请求标志(1=rtr帧)
31:帧格式标记(0=标准11位,1=扩展29位)
*/
即linux重新定义了犬科动物,这个与总能线上的格式不同,但意义类似。而且提供了过滤机制,让应用层的套接字只是关心某些canframe的包。注意,其他操作系统,实现方式可能不同。
使用可分析仪,安装驱动,并使用斜面工具,
选择好设备和可以通道后,并设置频率后,即可接收和发送。

  

CANH接CANH, CANL接CANL

  

此斜面工具运行后,并设置速率为500千赫

  

另外一侧,即设备侧,linux中运行

ip ip链路群can0下来链接设置can0类型可以500000比特率
即设置为500 khz。
然后运行
cansend can0 1 f334455 # 11223355
linux上发送上面的数据,#之前是可以id, #号之后是数据.CANTest上,就会收到并显示。

  

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

  

linux侧的可以使用介绍,具体可以看文档/网络/can.txt

  

linux可以应用开发涉及的api:参考candump和cansend的代码
struct sockaddr_can addr;
struct iovec iov;
struct msghdr味精;
struct cmsghdr cmsg;
struct can_filter
rfilter;
can_err_mask_t err_mask;
struct canfd_frame框架;
struct ifreq仪表;
插座(PF_CAN, SOCK_RAW CAN_RAW);
ioctl (s[我],SIOCGIFINDEX,及仪表)
setsockopt (s[我],SOL_CAN_RAW、CAN_RAW_ERR_FILTER, err_mask, sizeof (err_mask));//根据需要
setsockopt (s[我],SOL_CAN_RAW、CAN_RAW_JOIN_FILTERS, join_filter, sizeof (join_filter))//根据需要
setsockopt (s[我],SOL_CAN_RAW、CAN_RAW_FILTER rfilter, numfilter sizeof (struct can_filter));//根据需要,设置过滤器,过滤某些CAN_ID的数据
setsockopt (s[我],SOL_CAN_RAW、CAN_RAW_FD_FRAMES, canfd_on, sizeof (canfd_on));//根据需要
绑定(s(我),(struct sockaddr
), addr, sizeof (addr))
选择(s [currmax-1] + 1), rdfs,空,空,timeout_current)

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