STM32之一种双通路CAN总线消息备份冗余处理方法(十三)

news2025/1/10 8:53:17

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

注:位时间tBit=1s/500kbps=2000ns/bit;晶振时钟周期T=1s/8MHz=125ns。

2.CAN网络消息ID组成

CAN总线通讯采用CAN2.0B标准的扩展帧格式,29位标识符组成定义见表2。不遵循此规范的ID为非法指令,终端节点应予以丢弃或上报异常。总线上各节点单机在处理相应的消息时,采用:“消息代号(D26~D22)”+“消息源设备(D21~D16)”+“消息目的(D15~D10)”三者结合的方式来判断是否该类型的消息。

D28~D27

D26~D22

D21~D16

D15~D10

D9~D8

D7~D0

消息优先级类型

消息代号

消息源

设备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

bool,unsigned char

表示bool型逻辑变量

2

单字节有符号整数

I8

char

表示-128~+127的整数

3

单字节无符号整数

U8

unsigned char

表示0~255的整数,或者ASCII字符

4

双字节有符号整数

I16

short

表示-32768~+32767的整数

5

双字节无符号整数

U16

unsigned short

表示0~65535的整数

6

四字节有符号整数

I32

int

表示-2147483648~2147483647的整数

7

四字节无符号整数

U32

unsigned int

表示0~4294967295的整数

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个空闲邮箱(Freelevel=1)将一帧CAN数据填充进去,将此空闲邮箱状态设置为繁忙(Freelevel=0),并设置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的D10~D15是否与本设备节点编号一致来过滤无关消息。各节点单机必须对CAN总线节点信息进行过滤处理,只响应与本节点相关信息。

10.节点CAN消息冗余过滤机制

为保证CAN总线消息可靠性,部分CAN数据帧采用了双总线通道(CAN1总线和CAN1总线)同时发送的策略,各节点单机在接收CAN消息数据时,需要过滤以上冗余信息,具体过滤机制建议如下:

  1. 对于来自不同总线通道(CAN1总线、CAN2总线)且ID相同(这里指除了总线编号(D9~D8)之外的ID信息)进行冗余过滤;
  2. 过滤时间门限建议设置为8ms,即8ms内的相同消息只取一条;
  3. 对于同一总线通道的CAN消息不进行过滤;
  4. 过滤后的有效CAN消息才进入接收队列进行后续处理。

5.工程化实现

上面给出的一种双通路CAN总线消息备份冗余处理方法,实现思路及过程已讲述清楚,这里给出其C语言工程化实现的关键代码,详细工程代码见文末链接处。

//消息滤波处理结构
typedef struct
{
    CAN_EXT_ID    	ID[MAX_ID_CHECK_LIST];   		// 消息ID
    unsigned 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.res&STD_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.ListIndex+1) >= MAX_ID_CHECK_LIST)?0:RecvIDList.ListIndex+1;
			RecvIDList.ID[RecvIDList.ListIndex].id = ID.id;
			RecvIDList.RecvTime[RecvIDList.ListIndex] = g_1msTick;
		}
	}	
	return bRet;
}

总结

下面提供的代码,基于STM32F407ZGT芯片编写,可直接在原子开发板上运行,也可运行在各工程项目上,但需要注意各接口以及相应的引脚应和原子开发板上保持一致。

相应的代码链接:单片机STM32F407-Case程序代码例程-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2274251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内网穿透的应用-Ubuntu本地Docker部署Leantime项目管理工具随时随地在线管理项目

文章目录 前言1.关于Leantime2.本地部署Leantime3.Leantime简单实用4.安装内网穿透5.配置Leantime公网地址6. 配置固定公网地址 前言 本文主要介绍如何在本地Linux系统使用Docker部署Leantime&#xff0c;并结合cpolar内网穿透工具轻松实现随时随地查看浏览器页面&#xff0c;…

VulnHub-Acid(1/100)

参考链接&#xff1a; ​​​​​​​【VulnHub】Acid靶场复盘-CSDN博客 靶场渗透&#xff08;二&#xff09;——Acid渗透_ambassador 靶场渗透-CSDN博客 网络安全从0到0.5之Acid靶机实战渗透测试 | CN-SEC 中文网 Vulnhub靶场渗透练习(四) Acid - 紅人 - 博客园 红日团队…

HTML5实现好看的端午节网页源码

HTML5实现好看的端午节网页源码 前言一、设计来源1.1 网站首页界面1.2 登录注册界面1.3 端午节由来界面1.4 端午节习俗界面1.5 端午节文化界面1.6 端午节美食界面1.7 端午节故事界面1.8 端午节民谣界面1.9 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 H…

git merge与rebase区别以及实际应用

在 Git 中&#xff0c;merge 和 rebase 是两种将分支的更改合并到一起的常用方法。虽然它们都可以实现类似的目标&#xff0c;但它们的工作方式和效果有所不同。 1. Git Merge 定义&#xff1a;git merge 是将两个分支的历史合并在一起的一种操作。当你执行 git merge 时&…

Matlab APP Designer

我想给聚类的代码加一个图形化界面&#xff0c;需要输入一些数据和一些参数并输出聚类后的图像和一些评价指标的值。 gpt说 可以用 app designer 界面元素设计 在 设计视图 中直接拖动即可 如图1&#xff0c;我拖进去一个 按钮 &#xff0c;图2 红色部分 出现一行 Button 图…

PyCharm 引用其他路径下的文件报错 ModuleNotFound 或报红

PyCharm 中引用其他路径下的文件提示 ModuleNotFound&#xff0c;将被引用目录添加到系统路径&#xff1a; # # 获取当前目录 dir_path os.path.dirname(os.path.realpath(__file__)) # # 获取上级目录 parent_dir_path os.path.abspath(os.path.join(dir_path, os.pardir))…

【HarmonyOS NEXT】鸿蒙应用点9图的处理(draw9patch)

【HarmonyOS NEXT】鸿蒙应用点9图的处理&#xff08;draw9patch&#xff09; 一、前言&#xff1a; 首先在鸿蒙中是不支持安卓 .9图的图片直接使用。只有类似拉伸的处理方案&#xff0c;鸿蒙提供的Image组件有与点九图相同功能的API设置。 可以通过设置resizable属性来设置R…

SOLID原则学习,开闭原则

文章目录 1. 定义2. 开闭原则的详细解释3. 实现开闭原则的方法4. 总结 1. 定义 开闭原则&#xff08;Open-Closed Principle&#xff0c;OCP&#xff09;是面向对象设计中的五大原则&#xff08;SOLID&#xff09;之一&#xff0c;由Bertrand Meyer提出。开闭原则的核心思想是…

【Vue3中使用crypto-js】crypto-js加密解密用法

目录 1、安装crypto2、创建crypto.js文件3、在main.js主文件中进行引用4、页面中进行使用5、实现效果展示6、加密模式解析以及iv参数使用 1、安装crypto npm install crypto-js 如果是在Typescript版本需要再安装 npm install --save types/crypto-js2、创建crypto.js文件 注…

跨界融合:人工智能与区块链如何重新定义数据安全?

引言&#xff1a;数据安全的挑战与现状 在信息化驱动的数字化时代&#xff0c;数据已成为企业和个人最重要的资产之一。然而&#xff0c;随着网络技术的逐步优化和数据量的爆发式增长&#xff0c;数据安全问题也愈变突出。 数据安全现状&#xff1a;– 数据泄露驱动相关事件驱…

简单易用的PDF工具箱

软件介绍 PDF24 Creator是一款简单易用的PDF工具箱&#xff0c;而且完全免费&#xff0c;没有任何功能限制。既可以访问官网在线使用各种PDF工具&#xff0c;也可以下载软件离线使用各种PDF工具。 软件功能 1、PDF转换 支持将多种文件格式&#xff08;Word、PowerPoint、Exc…

低秩信息收集_0109

系列博客目录 文章目录 系列博客目录LoRA: Low-Rank Adaptation of Large Language Models传统模型适配的局限性&#xff1a;尽管研究界致力于通过添加适配器层或优化输入层激活来提高模型适配效率&#xff0c;这些方法在大型模型和延迟敏感的环境中存在局限。适配器层尽管参数…

C语言与ASCII码应用之简单加密

加密是什么&#xff1f;什么是加密通话&#xff1f;用人话说就是一句有含义的话&#xff0c;经过一定的特殊规则把里面的每个字按照这个规则进行改变&#xff0c;但是这个规则只有你和你想让知道这条信息的人知道 今天我们来用ASCII码编写一个简单加密与解密的程序&#xff0c…

国产3D CAD将逐步取代国外软件

在工业软件的关键领域&#xff0c;计算机辅助设计&#xff08;CAD&#xff09;软件对于制造业的重要性不言而喻。近年来&#xff0c;国产 CAD 的发展态势迅猛&#xff0c;展现出巨大的潜力与机遇&#xff0c;正逐步改变着 CAD 市场长期由国外软件主导的格局。 国产CAD发展现状 …

【Linux网络编程】第二十二弹---深入理解 I/O 多路转接之 epoll:系统调用、工作原理、代码演示及应用场景

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、I/O 多路转接之 epoll 1.1、epoll 初识 1.2、epoll 的相关系统调用 1.2.1、epoll_create 1.2.2、epol…

品牌账号矩阵如何打造?来抄作业

在讲究全域营销的当下&#xff0c;目前企业都在各自搭建品牌矩阵号&#xff0c;以提升自己在不同渠道上的影响力。虽然不同平台之间有诸多细节值得深究&#xff0c;但也不妨碍我们先了解如何搭建品牌矩阵。接下来&#xff0c;就让我们一同来了解下该如何搭建。 一、一个主账号 …

备考蓝桥杯:数据结构概念浅谈

目录 1数据结构的概念 什么是数据结构: 为什么要有数据结构 2.数据结构的三个组成要素 1.逻辑结构 2.存储结构 3.数据运算 3。算法好坏的度量&#xff08;时间复杂度和空间复杂度&#xff09; 时间复杂度计算 最优和平均和最差时间复杂度 计算时间复杂度例子 空间复…

scala代码打包配置(maven)

目录 mavenpom.xml打包配置项&#xff08;非完整版&#xff0c;仅含打包的内容< build>&#xff09;pom.xml完整示例&#xff08;需要修改参数&#xff09;效果说明 maven 最主要的方式还是maven进行打包&#xff0c;也好进行配置项的管理 以下为pom文件&#xff08;不要…

用于 EV 牵引电机的先进冷却技术

电动汽车牵引电机的冷却挑战 热管理的重要性 有效的热管理在电动汽车 &#xff08;EV&#xff09; 设计中至关重要&#xff0c;尤其是在牵引电机方面。这些电机将电能转化为机械运动&#xff0c;对车辆的整体性能和效率至关重要。 管理它们的热量至关重要&#xff0c;不仅可以…

课题推荐——基于GPS的无人机自主着陆系统设计

关于“基于GPS的无人机自主着陆系统设计”的详细展开&#xff0c;包括项目背景、具体内容、实施步骤和创新点。如需帮助&#xff0c;或有导航、定位滤波相关的代码定制需求&#xff0c;请点击文末卡片联系作者 文章目录 项目背景具体内容实施步骤相关例程MATLAB例程python例程 …