一级做网站视频教学,品牌开发者应掌握的技能,wordpress 汽车租赁,wordpress 显示加载时间STM32F407 系列文章 - Dual-CANBus-ProMethod#xff08;十三#xff09; 目录
前言
一、现状分析
二、解决思路
1.应用场景网络结构图
2.数据发送流程
3.数据接收流程
4.用到的模块
1.CAN网络速率及时间片分配
2.CAN网络消息ID组成
3.设备节点定义
4.数据格式说明…STM32F407 系列文章 - Dual-CANBus-ProMethod十三 目录
前言
一、现状分析
二、解决思路
1.应用场景网络结构图
2.数据发送流程
3.数据接收流程
4.用到的模块
1.CAN网络速率及时间片分配
2.CAN网络消息ID组成
3.设备节点定义
4.数据格式说明
5.消息格式说明
6.FIFO队列
7.CAN发送流程
8.CAN接收流程
9.节点CAN消息冗余过滤原则
10.节点CAN消息冗余过滤机制
总结 前言
在一些对系统可靠性要求很高的应用中、或者传输环境较差的场景下如何保证CAN总线组网通信中数据传输无缺损或者缺损率极低是本文章主要解决的问题。 一、现状分析
在一些重要系统应用中如飞行器、航天航空等环境经常需要使用CAN总线来传输数据传输过程中有可能受空间干扰或电源波动等原因会导致某一帧数据信息缺损、错乱或者丢失。
现有技术主要是从硬件电路的可靠性出发在节点接收端和发送端电路上增加对CAN电路的保护如电源上增加滤波、隔离电路在数字通信接口增加隔离电路增强电路稳定性。这种方式在节点单一、传输环境简单、数据信息少量的情况下CAN总线传输的过程中比较可靠有效。但是涉及到传输环境复杂、数据量较大的情况下时就缺乏一种保护措施来保证数据传输的可靠性。
本文给出一种方式采用双通路CAN总线冗余消息处理来传输数据通过在CAN消息的发送端增加缓存机制和进行冗余备份在接收端采用查重过滤机制来完成对数据信息处理。
二、解决思路
1.应用场景网络结构图 网络结构图中节点表示各单机设备各节点设备通过CAN总线网络组网采用CAN1和CAN2双总线组网机制。本文以一些重要场合为实施应用场景通过CAN总线线缆网对各节点设备ID分配采用互斥性设计需保持其唯一性。各节点与各节点之间通过CAN通讯协议以实现对各节点之间的信息通讯与控制。
CAN总线是一个广播通用通道各类信息均在总线上传输为了避免无关信息对各执行节点产生干扰各节点单机必须对CAN总线节点信息进行过滤处理只响应与本节点相关信息。单机节点在收到控制信息后无论信息来自哪条总线首先确认是否为重复信息如果不是重复信息则执行动作。
2.数据发送流程
设备节点发送CAN信息处理过程 如下图所示。 某节点需要向外发送CAN消息时将发送的CAN消息先存入CAN1和CAN2消息FIFO队列中然后在主函数main()中设置while()循环通过不间断查询方式判断CAN发送邮箱是否有空闲的CAN发送邮箱有3个且每个邮箱只能装一个报文。若有空邮箱则划出一条CAN消息从FIFO队列中出栈进入CAN发送邮箱中等待发送若发送邮箱都被占用则等待下一次主循环判断CAN发送邮箱是否有空闲。设置每个邮箱优先级相同消息依次发送发送成功后将当前被占用的邮箱置空等待接收CAN信息此时CAN消息已发送CAN1和CAN2总线上发送失败后不设置丢弃此信息邮箱被继续占用等待下一次发送即CAN总线上负载率不高时。
解释说明将某节点向外发送CAN的消息先存入FIFO队列中这个是对于大系统即节点设备较多或数据量较大的情况下必须使用的为防止某时刻CAN总线上负载率高时CAN消息丢失对于简单系统2、3个节点设备或少数据量的不需要存入FIFO缓存队列中直接放入CAN发送邮箱使用。
3.数据接收流程
设备节点接收CAN信息处理过程 如下图所示。 总线上有数据时设备节点通过CAN接收中断触发接收到有效报文被存储在3级邮箱深度的FIFO中。只要接收到有效报文时接收回调函数会被调用应用程序通过读取FIFO输出邮箱来读取FIFO中最先收到的报文等这个读完之后才能读下一个报文。读取报文数据时通过判断CAN句柄指针地址判断是CAN1地址区接受的数据还是CAN2。然后对读取到的报文数据进行解析和检查是否是新消息防止CAN1、CAN2总线上的重复消息避免二次执行对收到数据ID与缓存队列2中的数据ID依次进行对别当前收到的数据ID的时间点与缓存队列2中的数据ID时间戳在8毫秒内且二者ID相同则认为时重复消息当丢弃此消息若收到数据ID的时间点与缓存队列2中数据ID时间戳大于8毫秒或者二者ID不相同时则认为时新消息当把此消息放入缓存队列1作消息预处理使用同时此消息ID和此消息时间戳放入缓存队列2作判重使用。
解释说明接收邮箱FIFO完全由硬件来管理从而节省了CPU的处理负荷简化了软件并保证了数据的一致性。8毫秒内判断是否为新消息此8毫秒规定是基于系统CAN总线上最短发数周期和线路延时。
4.用到的模块
为实现上述流程图所用到的模块有。
1.CAN网络速率及时间片分配
为保证总线为负载较低总线速率设定为500Kbps要求各单机节点的时钟晶振为8MHz的整数倍时间片分配方案如下表所示。 位速率 每位时间片数 时间片分配 同步段 传播段相位缓冲段1 相位缓冲段2 500Kbps 10 1 5 4 注位时间tBit1s/500kbps2000ns/bit晶振时钟周期T1s/8MHz125ns。
2.CAN网络消息ID组成
CAN总线通讯采用CAN2.0B标准的扩展帧格式29位标识符组成定义见表2。不遵循此规范的ID为非法指令终端节点应予以丢弃或上报异常。总线上各节点单机在处理相应的消息时采用“消息代号D26D22”“消息源设备D21D16”“消息目的D15D10”三者结合的方式来判断是否该类型的消息。 D28D27 D26D22 D21D16 D15D10 D9D8 D7D0 消息优先级类型 消息代号 消息源 设备ID 消息目的设备ID 用于传输的总线编号 可用于传输数据或数据帧内编号 00-重要控制 01-一般控制 10-重要测试 11-一般测试 0~31 由总线协议确定 0~63 由实际终端节点情况确定 0~63 由实际终端节点情况确定 00-CAN1 01-CAN2 0~255 由待传输的数据量决定
3.设备节点定义
CAN1总线和CAN2总线内部设备节点的ID分配采用互斥性设计需保持其唯一性。节点ID定义见下表。 ID 设备含义 000001 (1) 设备节点1 000010 (2) 设备节点2 000011 (3) 设备节点3 … …
4.数据格式说明
协议消息组织与传输以字节为单位进行在多字节传输时CAN总线先发送低字节后发送高字节例如如发送0x12AB则先发送0xAB再发送0x12。在每个字节8个bit中则先发送高位再发送低位。
字节号定义 位序号定义 消息内各数据类型如下表所示。 序号 数据类型对照 本文 标注 对应C/C语言32位机器 用途 1 布尔型 BOOL boolunsigned char 表示bool型逻辑变量 2 单字节有符号整数 I8 char 表示-128127的整数 3 单字节无符号整数 U8 unsigned char 表示0255的整数或者ASCII字符 4 双字节有符号整数 I16 short 表示-3276832767的整数 5 双字节无符号整数 U16 unsigned short 表示065535的整数 6 四字节有符号整数 I32 int 表示-21474836482147483647的整数 7 四字节无符号整数 U32 unsigned int 表示04294967295的整数 8 单精度浮点数 F32 float IEEE-754标准 9 双精度浮点数 F64 double IEEE-754标准
5.消息格式说明
CAN消息根据待传输的有效数据长度由一个或多个CAN总线数据帧完成传输。组成一条消息的不同数据帧拥有相同的消息代号数据帧编号从0开始依次增长。消息说明的格式如下表所示。 消息名称 消息格式说明 版 本 版本号 信 源 信息发送方 信 宿 信息接收方 消息优先级 紧急控制、一般测试等 消息代号 节点间通信的唯一消息代号 数据长度 实际使用的字节数 总线网络 传输时使用的总线网络 发送频率 发送周期或事件条件 转发情况 明确是否转发 消息ID 总线数据帧的标识符二进制和十六进制形式 数据内容信息 帧序号 名 称 数据类型 长度 值域 含义 0~255 数据内容名称 int、float等类型 字节数 取值范围 数据的物理意义 附 注 1.所有的总线消息均依据此格式进行规定和说明 2.有数据内容以字节为基本单位并遵循约定的存储方式。
6.FIFO队列
队列是一种先进先出FIFO的线性表它只允许在表的一端插入元素另一端删除元素。其中允许插入的一端称为队尾rear允许删除的一端称为队头front。a[1]为队头元素a[5]为队尾元素。最早进入队列的元素也会最早出来只有当最先进入队列的元素都出来以后后进入的元素才能退出。循环FIFO队列示意图如下。 7.CAN发送流程
主程序查询到发送邮箱有空闲状态的选择1个空闲邮箱Freelevel1将一帧CAN数据填充进去将此空闲邮箱状态设置为繁忙Freelevel0并设置CAN数据长度和发送数据位然后将此邮箱请求预定此处每个邮箱优先级相同邮箱被预定发送后等待总线空闲发送成功后邮箱置空若发送失败返回预定发送。整个CAN发送流程如下图所示。 注CAN发送流程图中实线表示单个邮箱执行流程可强制执行和发送失败处虚线表示程序可设置而未设置执行。
8.CAN接收流程
CAN接收到的有效报文被存储在3级邮箱深度的FIFO中。CAN接收流程为FIFO为空时收到有效报文存入邮箱1存入FIFO的一个邮箱这个由硬件控制我们不需要理会收到有效报文存入邮箱2收到有效报文存入邮箱3在收到有效报文时溢出。这个流程里面我们没有考虑从FIFO读出报文的情况实际情况是我们必须在FIFO溢出之前读出至少1个报文否则下个报文到来将导致FIFO溢出从而出现报文丢失。每读出1个报文相应的邮箱就置空直到FIFO空。CAN接收流程如下图所示。 9.节点CAN消息冗余过滤原则
在整个CAN总线网络中通过CAN总线设备节点的标识符过滤功能利用消息帧ID的D10D15是否与本设备节点编号一致来过滤无关消息。各节点单机必须对CAN总线节点信息进行过滤处理只响应与本节点相关信息。
10.节点CAN消息冗余过滤机制
为保证CAN总线消息可靠性部分CAN数据帧采用了双总线通道CAN1总线和CAN1总线同时发送的策略各节点单机在接收CAN消息数据时需要过滤以上冗余信息具体过滤机制建议如下
对于来自不同总线通道CAN1总线、CAN2总线且ID相同这里指除了总线编号D9D8之外的ID信息进行冗余过滤过滤时间门限建议设置为8ms即8ms内的相同消息只取一条对于同一总线通道的CAN消息不进行过滤过滤后的有效CAN消息才进入接收队列进行后续处理。
5.工程化实现
上面给出的一种双通路CAN总线消息备份冗余处理方法实现思路及过程已讲述清楚这里给出其C语言工程化实现的关键代码详细工程代码见文末链接处。
//消息滤波处理结构
typedef struct
{CAN_EXT_ID ID[MAX_ID_CHECK_LIST]; // 消息IDunsigned int RecvTime[MAX_ID_CHECK_LIST]; // 收到的时间unsigned char ListIndex;
}CAN_Msgs_Recv_Time;
static CAN_Msgs_Recv_Time RecvIDList {0};
/*** brief 检查是新消息 还是两条总线上重发的消息此函数在中断处使用* param CAN_EXT_ID: CAN帧的扩展ID定义* retval 无*/
//
uint8_t Is_New_CAN_Msg(CAN_EXT_ID ID)
{uint8_t bRet 1; // 新消息//if((ID.s.resSTD_CAN_MSG) ! STD_CAN_MSG) // 仅对扩展帧进行重复帧筛选{for(int i 0; i MAX_ID_CHECK_LIST; i){// 两个消息ID相同 且接收的时间间隔小于8ms则认为是重复消息if((ID_IGNORE_CAN_BUS(RecvIDList.ID[i].id) ID_IGNORE_CAN_BUS(ID.id)) (g_1msTick - RecvIDList.RecvTime[i]) 8) {//仅屏蔽不同总线的can消息if(RecvIDList.ID[i].s.res ! ID.s.res) {bRet 0;break;}}}// 新消息 写入队列if(bRet 1) {RecvIDList.ListIndex ((RecvIDList.ListIndex1) MAX_ID_CHECK_LIST)?0:RecvIDList.ListIndex1;RecvIDList.ID[RecvIDList.ListIndex].id ID.id;RecvIDList.RecvTime[RecvIDList.ListIndex] g_1msTick;}} return bRet;
} 总结
下面提供的代码基于STM32F407ZGT芯片编写可直接在原子开发板上运行也可运行在各工程项目上但需要注意各接口以及相应的引脚应和原子开发板上保持一致。
相应的代码链接单片机STM32F407-Case程序代码例程-CSDN文库