当前位置: 首页 > news >正文

STM32 CAN通信自定义数据包多帧连发乱序问题

场景:

can标准帧中每一帧只能传输8字节,而应用中传输一包的内容往往超过8字节,因此需要把一个包拆成多个帧发送,接收端才把收到的多帧重新组装成一个完整的包


问题描述

在一问一答的两块板间通信,多帧连发是能够按照顺序发送的。但是,在一个主板和多个从板之间轮询一问一答的通信中,偶尔出现持续一段时间或者长时间无法通信的情况,特别高帧率发送的情况下,几乎无法通信。

原因分析:

抓取can总线数据发现不同板之间的帧相互交叉乱序,导致接收到的包因为乱序无法还原。但是不能保证多帧连续发送的话,就会导致无法还原包。如图,7E和E7之间为一包,但其出现乱序
在这里插入图片描述
发送过程大致为

  1. 把包根据8字节拆分为多个帧
  2. 调用发送函数HAL_CAN_AddTxMessage塞第一帧进发送邮箱,id为本设备ID
  3. can自动从邮箱里面取出该帧发送
  4. 发送完毕触发邮箱发送完毕中断,在中断里面再调用HAL_CAN_AddTxMessage塞下一帧进发送邮箱,ID为0,以最高优先级占用CAN总线,循环直到最后一帧
    以上过程按道理很快就可以连续发送,但是就是会出现不连续的情况。因为采用的轮询方式,很难保证其他can总线的设备不也在同时在竞争can总线,在发送完毕进入中断塞数据进邮箱的空隙,尽管ID号是0,但是在竞争总线的时刻,还在中断里面塞数据进邮箱,并未参与can总线竞争,就会被其他的设备竞争掉总线了,待填充完邮箱,因为ID号为0,其又可以占用can进行发送,就出现了本设备的帧和其他设备的帧交叉了。

解决方案:

其原因就是发送中出现时间停顿,让其他can设备有了可乘之机,因此保证多帧之间在上一帧发送完毕立马竞争总线进入下一帧发送就可以保证该包是连续发送的。以下是我的改进:

  1. 开启邮箱按照填写顺序发送(而不是根据邮箱ID优先级发送)
  2. 一包多帧的数据持续塞满三个邮箱,确保多帧发送过程中没有出现三个邮箱都出现空的情况
    在裸机的时候,其可以连续高帧率发送不出现乱帧,但是开启FREERTOS后,还会出现乱帧的情况,其原因是can的发送中断被freertos管理,需要把use freertos function关掉,使用裸机的中断,我把其优先级设为1.
    在这里插入图片描述
    但是!还是有但是!我的freertos任务多了以后,还是出现乱帧的情况,检查后发送,我的第一次填写邮箱是在代码里面进行的,也就是说我塞邮箱的过程中,freertos会打断我塞数据的过程,导致有概率不是连续塞数据进去邮箱的。如图,虽然我在代码调用的发送中断函数,但是其程序指针运行在psp下,而不是msp下,优先级就是普通的freerto任务,自然不能保证以高优先级连续塞数据进发送邮箱了。
    在这里插入图片描述
    改进为如下,分包好后,通过HAL_NVIC_SetPendingIRQ追加一个发送中断,其不会执行发送过程就可以直接触发发送中断,这下子没其他东西在打扰塞满发送邮箱了吧!
    在这里插入图片描述

总结:

经过测试,can总线每秒8000帧数据的情况下,有10%的错误率,检查后发现,顺序没乱,有些帧没能发送来就丢弃了,因为我设置的发送失败不重发。降低速率至6000,1%内的错误率,帧没发出现的数量大幅度下降,证明还是太快了。设置3000,0%错误率,为什么3000就是0%呢,看了一下can总线,发送我的每一包发送需要时间是1ms,一包大概3帧,也就是1s上限差不多是3000多帧。
在这里插入图片描述

相关文章:

  • Linux:Ubuntu实现远程登陆
  • 由走“贸工技”的联想联想到传统OEM,带给了自己那些思考?
  • ⑥【bitmap 】Redis数据类型: bitmap [使用手册]
  • Vue - Vue配置proxy代理,开发、测试、生产环境
  • cocos游戏引擎制作的滚动框地图防止误点操作的简单方法
  • C/C++ 使用API实现数据压缩与解压缩
  • 【好玩的 Docker 项目】搭建一个简洁的记事本 ——minimalist-web-notepad
  • Mac 最佳使用指南
  • Python 安装mysqlclient 错误 无法打开包括文件: “mysql.h”: 解决方法
  • 揭秘短信轰炸:原理实现与应对办法
  • Leetcode 2944. Minimum Number of Coins for Fruits
  • Lubuntu 23.10用户可使用LXQt 1.4桌面
  • torch.nn.batchnorm1d,torch.nn.batchnorm2d,torch.nn.LayerNorm解释:
  • 竞赛选题 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测
  • redis报错3
  • android图片蒙层
  • C# 免费离线人脸识别 2.0 Demo
  • chrome扩展demo1-小时钟
  • download使用浅析
  • echarts的各种常用效果展示
  • ES6 ...操作符
  • JavaScript 基本功--面试宝典
  • js学习笔记
  • laravel with 查询列表限制条数
  • Making An Indicator With Pure CSS
  • nginx 配置多 域名 + 多 https
  • passportjs 源码分析
  • Python进阶细节
  • vue 配置sass、scss全局变量
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 服务器之间,相同帐号,实现免密钥登录
  • 给第三方使用接口的 URL 签名实现
  • 构造函数(constructor)与原型链(prototype)关系
  • 精彩代码 vue.js
  • 前端面试之CSS3新特性
  • 微信小程序:实现悬浮返回和分享按钮
  • #include<初见C语言之指针(5)>
  • $NOIp2018$劝退记
  • (09)Hive——CTE 公共表达式
  • (2)STL算法之元素计数
  • (HAL库版)freeRTOS移植STMF103
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (第61天)多租户架构(CDB/PDB)
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (九十四)函数和二维数组
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net 中viewstate的原理和使用
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .net知识和学习方法系列(二十一)CLR-枚举
  • @angular/cli项目构建--Dynamic.Form
  • @ModelAttribute使用详解