花卉网 — 您身边的花草养护与盆景制作专家!关注花草乐让生活,温暖如花。

你的串口数据通过检查了吗?

时间:2021-10-06 01:15编辑:admin来源:ror体育当前位置:主页 > ror体育花语大全 > 勿忘我花语 >
本文摘要:上篇文章先容了串口吸收遇到的互斥锁释放问题,今天说说串口数据帧检盘问题。你是否会对吸收的数据举行检查?如果不举行检查会发生什么?我们知道一帧数据中,每个部门都有各自的寄义,甚至有些部门可能在某些数据帧中不存在,好比数据域部门,我们需要凭据长度信息来判断数据域部门是否存在。可是你能保证你所吸收的数据都是准确的吗?你能确保在事情情况下不会因为种种滋扰导致数据长度信息由 0x05 酿成 0x85(最高位翻转)吗?,如果泛起了会导致什么结果?

ror体育

上篇文章先容了串口吸收遇到的互斥锁释放问题,今天说说串口数据帧检盘问题。你是否会对吸收的数据举行检查?如果不举行检查会发生什么?我们知道一帧数据中,每个部门都有各自的寄义,甚至有些部门可能在某些数据帧中不存在,好比数据域部门,我们需要凭据长度信息来判断数据域部门是否存在。可是你能保证你所吸收的数据都是准确的吗?你能确保在事情情况下不会因为种种滋扰导致数据长度信息由 0x05 酿成 0x85(最高位翻转)吗?,如果泛起了会导致什么结果?假设你接纳 RXNE 中断方式来一个、一个字节的吸收数据,分析如下:因为是单字节吸收数据,所以你需要把所有吸收的数据当成数据流,凭据帧头信息来确定帧的开始,一旦确定帧头信息之后,你就可以凭据接下来的一系列数据保证一帧数据的竣事,同时开始新帧的吸收……初看这个吸收流程没有问题,可是真的如此吗?可是就像前面所说,你能保证你的数据没有问题吗?如果说你吸收到一个长度信息,原来是 0x05,可是最终吸收的数据是 0x85,这就意味着你接下来的数据域的长度是 0x85,凭据你的吸收流程,你需要再吸收 0x85 个字节之后,才气判断校验字节是否正确。

可能你会说,虽然你的长度信息由 0x05 酿成了 0x85,之后吸收校验历程肯定是失败的,那么这帧数据就会被吸收法式抛弃,从而导致吸收法式进入重新寻找帧头的流程,这个历程不是挺正常的吗?按理说上述异常情况是能被吸收流程处置惩罚掉的。那么首先确认一点,上述异常能被吸收流程处置惩罚吗?谜底是能!既然上述异常是能被吸收状态机处置惩罚的,那么还会有什么问题?问题就出在这个错误数据自己!因为你是凭据错误数据来决议接下来需要吸收几多数据,而一般来说,吸收缓存巨细设置为最大帧的长度,那么就泛起一个问题,你的缓存够你吸收 0x85 个字节吗?如果说你开发的吸收缓存空间很大,足够吸收这么多数据,那么就算遇上以上情况,也是没有任何问题,可是万一你比力节约资源,缓存不够大会泛起什么情况?这就涉及到内存分配问题:你的串口缓存一般在 Data 区域,一旦你吸收的数据超出了你开发的空间,那么一定导致缓存空间溢出!那么缓存空间溢出会导致什么危害?我们通过上图可以知道,一旦缓存溢出,一定导致该缓存周围的数据泛起异常(数据被窜改),如果你的其它代码恰好需要这个数据作为重要参考,而你在使用的时候又没有对这个数据的有效性举行检查,那么可能导致另一个灾难性结果,而这个结果又导致了其他结果,从而导致雪崩效应。

而你修复这个 bug 时,你以为修复了,但你只修复了外貌,真正内在 bug 还存在!所以,千万别太相信内存中的数据,每一个数据的输入都要举行严格检查,这个数据可以错误,可是不能导致法式瓦解!所以千万别写能窜改别人数据的代码,这是很危险的事情,也是很难明决的 bug,因为你不知道它会在什么时候窜改那里的数据!再如果你的吸收缓存放在栈中了呢(稍微有 C 语言知识的法式员都不会把串口吸收缓存放在栈中,但鱼鹰偏偏遇到过这种代码,而为相识决这个 bug 整整花了一星期,这还是在 bug 复现率高的情况下)?凭据前面的图可知,栈一般存放在高地址,而且一般栈生长偏向为向低地址生长。如果泛起上述情况(吸收的数据大于开发的栈缓存空间)会发生什么?栈帧被破坏!灰色部门因为吸收的数据太多,导致原本存在的栈数据被串口的吸收的数据修改了(注意窜改的数据可能不是一连的,因为每一次进入时,开发的那部门栈空间可能都不在同一个地址),如果这个数据是生存返回寄存器 LR 的,那么一定导致返回错误,极可能触发 HardFault 中断!那么有什么措施解决栈被破坏的问题?最有效的方式鱼鹰以为是使用 ITM,如果无法在线调试,可以实验 DMA 循环传输 PC 指针值(可是如何获得这个值?究竟这个寄存器自己是没有地址观点的)到一块内存中,这样就可以获得最后正常执行的代码地址,从而定位错误代码的位置。如果单片机不支持这些功效呢?鱼鹰现有的知识体系似乎无法解决,只能佛系调 bug 了(看和 bug 之间的缘分),囧。

前面说了由于外部事情情况导致数据长度信息错误从而泛起数组溢出这种情况,如果说你保证事情情况很是好,不行能泛起这种滋扰,是否还会泛起问题?固然会!前面分析了外在原因,现在分析内在原因,你的吸收法式能保证实时吸收发送端发送过来的数据吗?如果不实时吸收数据会泛起什么问题?我们知道,一个系统一般都有许多中断需要处置惩罚,如果说你的吸收法式的中断优先级不是最高的,那么很可能泛起吸收法式无法实时吸收的情况,即 RXNE 中断来暂时,因更高优先级中断需要处置惩罚,而且处置惩罚时间较长,那么就会泛起当前吸收的字节因为没有吸收完成而被后续的数据冲掉,即泛起 ORE(溢堕落误)。这样会导致什么问题?数据域信息(也可能是校验值等数据)当成了长度信息(为什么只讨论长度,而不讨论功效字之类的数据,岂非他们不会泛起 ORE 的情况吗?),这样一来,如果这个数据很大,吸收法式就会以为接下来还需要吸收许多数据才气完成一帧的吸收,导致结果和前面分析的数据滋扰一样严重。

那么接纳 RXNE 吸收方式时该怎么解决这种问题?检查长度信息的合理性,只要长度信息不会导致缓存溢出即可。可是上面的解决方案会导致什么问题?因为你的法式设计问题(接纳 RXNE 吸收导致不能实时处置惩罚),使得原本能吸收的数据无法实时处置惩罚(DMA 可以实时处置惩罚),最终使恰当前这一帧数据无法正常吸收(如果错误的长度信息够大的话,另有可能接下来许多帧数据都无法吸收),这你能接受吗?可是接纳 DMA 为什么就不会有上述问题,除了 DMA 能自动吸收数据提高效率之外,另有一点就是它不凭据吸收的数据来判断接下来还需要吸收几多数据,而是凭据设定的吸收数据长度来吸收的(如果加入 IDLE 中断,可以提前竣事吸收事情),这就制止了上述的缓存溢出和吸收不实时问题。最后再分析上述吸收的另一个问题,那就是一帧数据中可能泛起没有数据域的情况,这种情况该怎么处置惩罚?只要凭据长度信息离开处置惩罚即可。如果差池没有数据域的情况离开处置惩罚,那么你吸收的下一个数据直接就是校验值,而你的吸收流程却认为这是数据域的数据,一定导致校验失败。

现在总结使用 RXNE 方式吸收的几个问题:1. 缓存溢出。缓存溢出有两种可能,第一种就是情况滋扰导致长度信息堕落,从而泛起缓存溢出情况;第二种情况就是因为吸收不实时,导致数据错位,如果恰好是长度信息错误,而且这个长度信息太大,而你的代码未对长度举行检查,那么也会泛起缓存溢出 bug,而这种 bug 一旦泛起,很难发现。所以在代码中对数据的合理性检查是很是有须要的一件事。

2. 中断实时处置惩罚。如果中断不实时处置惩罚,会导致数据错位,轻则丢失至少一帧数据,重则缓存溢出!3. 状态机是否需要吸收数据部门。

由于数据帧有可能没有数据域的情况,所以必须区别处置惩罚,保证代码吸收的准确性,否则有可能把校验值当成数据了,这样一定无法通过校验,这一帧数据一定会丢失!下集精彩,串口空闲与通信量,喜欢的话,就来关注鱼鹰吧!。


本文关键词:ror体育官网,你的,串口,数据,通过,检查,了,吗,上篇,文章

本文来源:ror体育-www.zrsdtj.com

上一篇:充满质疑?不相信中医药的疗效?那你该好悦目看这篇文章

下一篇:没有了

养花知识本月排行

养花知识精选

养花知识推荐