收藏官网首页
查看: 21234|回复: 3

[经验分享] rbRead()中的一个BUG,大家注意

3

主题

6

帖子

70

积分

注册会员

Rank: 2

积分
70
跳转到指定楼层
楼主
发表于 2017-4-5 11:47:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
rdRead()函数中的代码

  1. if (rb->rbHead < rb->rbTail)
  2. {
  3.     copySz = min(count, rbCanRead(rb));
  4.     memcpy(data, rb->rbHead, copySz);
  5.     rb->rbHead += copySz;
  6.     return copySz;
  7. }
复制代码
其中copySz=min...编译后汇编如下:

  1.    121:         copySz = min(count, rbCanRead(rb));
  2. 0x080054FA 4620      MOV      r0,r4
  3. 0x080054FC F7FFFFB4  BL.W     rbCanRead (0x08005468)
  4. 0x08005500 42B0      CMP      r0,r6
  5. 0x08005502 D901      BLS      0x08005508
  6. 0x08005504 4630      MOV      r0,r6
  7. 0x08005506 E002      B        0x0800550E
  8. 0x08005508 4620      MOV      r0,r4
  9. 0x0800550A F7FFFFAD  BL.W     rbCanRead (0x08005468)
  10. 0x0800550E 4605      MOV      r5,r0
复制代码
此语句在下面这种情况时会出现漏读一个数据。
执行此条C语句之前,count=1,rbCanRead(rb)返回为1。
然后PC指针会执行到0x0800550A,如果此时又有一个数据接收到(通过rbWrite()填充到循环缓冲区)。
这时0x0800550A语句执行会返回为2,导致送给copySz的值为2。
复制了两个数据至data指针。
而在gizProtocolGetOnePacket()中调用传递的是读1个数据。这样就丢了一个数据了。
而且会影响&tmpData的下一个地址的数据。

3

主题

6

帖子

70

积分

注册会员

Rank: 2

积分
70
沙发
 楼主| 发表于 2017-4-5 11:50:23 | 只看该作者
我的解决方法:
修改gizwits_protocol.h中的min宏定义
  1. #define min(a, b) (a)<(b)?(a):(b)                   ///< 获取最小值
复制代码
改为
  1. #define min(a, b) (a)<=(b)?(a):(b)                   ///< 获取最小值
复制代码

1

主题

30

帖子

374

积分

中级会员

Rank: 3Rank: 3

积分
374
地板
发表于 2017-4-5 14:57:25 | 只看该作者
哇! C语言转化汇编 YYY
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表