困扰一周的奇葩bug:重复相似代码多,导致单片机程序跑飞

今天是个好日子,困扰一周的bug终于解决了,迫不及待将这个奇葩问题分享给各位朋友~

硬件环境:

国产MCU:华大HC32L130

问题描述:

最近做一款基于Modbus协议的三通道温度采集模块,程序设计是移植之前验证过的两通道温度、压力采集模块的程序,完成后,三通道温度采集程序可正常运行。

最后需要对三通道温度采集模块添加二次校准算法功能,新功能写好后,也可正常采集和通信,但是使用IAP功能时,flash扇区擦除失败,无法跳转到升级程序,且程序跑飞。

问题分析和解决:

尝试1:修改新增加的二次校准算法功能程序。

将二次校准算法功能屏蔽,升级程序可正常使用,估计是这里的问题,进行修改:变量定义、指针地址、内存管理等一系列操作下来,问题没有解决。

此时我的排查侧重点是数据内存或者地址溢出方面。

尝试2:查看flash配置是否存在问题。

既然是flash扇区擦除失败,会不是是配置存在问题?通过查看寄存器,修改时隙间隔等方面,还是无法解决问题,主要是之前运行一直没问题,排除这点。

那么会不会新添加的二次校准算法功能和已经存在的功能冲突呢?或者是使用的全局结构体变量有问题?

尝试3:整体研读项目代码,重点排查二次校准算法功能中全局变量、全局结构体变量的使用。

并没有变量使用不合理或者逻辑错误的地方。

尝试4:按照功能模块屏蔽代码,是否是程序中某部分功能与二次校准算法功能程序冲突。

通过一点点屏蔽程序,发现在二次校准算法功能程序正常运行前提下,屏蔽主循环的Modbus显示功能、Modbus配置UART功能、传感器GPIO配置等多个部分均可正常使用IAP功能。

通过仔细分析,这些功能模块中变量定义和使用均不存在问题,此时心态很郁闷了,这些模块功能基本没有关联。

尝试5:通过修改某个功能模块代码,是否可使程序正常运行。

此时项目整体功能是不存在逻辑问题和bug的,是否可以通过将以上那些存在未知冲突故障的代码换种写法,让程序正常运行呢?

经过了一系列操作和尝试,将主循环的Modbus显示功能代码换种更简洁的写法,程序可以完美运行~

原程序如下所示:

  1. if(nModbusCalRegs[Modbus_RegCalChan-Modbus_RegCalChan] == TEMP1_CHANNEL_ID)

  2. {

  3. ///< 初始化温度传感器:校准量程、零点偏移、灵敏度、零点偏移系数和灵敏度偏移系数

  4. nModbusCalRegs[Modbus_CalChanIndex] = strDeviceParamSave.temp1_range;

  5. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp1_bias1, 4);

  6. ntemp = (uint16_t) ltemp;

  7. nModbusCalRegs[Modbus_CalZeroIndex] = ntemp;

  8. ntemp = (uint16_t) (ltemp >> 16);

  9. nModbusCalRegs[Modbus_CalZeroIndex+1] = ntemp;

  10. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp1_kate1, 4);

  11. ntemp = (uint16_t) ltemp;

  12. nModbusCalRegs[Modbus_CalKateIndex] = ntemp;

  13. ntemp = (uint16_t) (ltemp >> 16);

  14. nModbusCalRegs[Modbus_CalKateIndex+1] = ntemp;

  15. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp1_bias2, 4);

  16. ntemp = (uint16_t) ltemp;

  17. nModbusCalRegs[Modbus_CalKZeroIndex] = ntemp;

  18. ntemp = (uint16_t) (ltemp >> 16);

  19. nModbusCalRegs[Modbus_CalKZeroIndex+1] = ntemp;

  20. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp1_kate2, 4);

  21. ntemp = (uint16_t) ltemp;

  22. nModbusCalRegs[Modbus_CalKSensiIndex] = ntemp;

  23. ntemp = (uint16_t) (ltemp >> 16);

  24. nModbusCalRegs[Modbus_CalKSensiIndex+1] = ntemp;

  25. }

  26. else if(nModbusCalRegs[Modbus_RegCalChan-Modbus_RegCalChan] == TEMP2_CHANNEL_ID)

  27. {

  28. ///< 初始化温度传感器:校准量程、零点偏移、灵敏度、零点偏移系数和灵敏度偏移系数

  29. nModbusCalRegs[Modbus_CalChanIndex] = strDeviceParamSave.temp2_range;

  30. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp2_bias1, 4);

  31. ntemp = (uint16_t) ltemp;

  32. nModbusCalRegs[Modbus_CalZeroIndex] = ntemp;

  33. ntemp = (uint16_t) (ltemp >> 16);

  34. nModbusCalRegs[Modbus_CalZeroIndex+1] = ntemp;

  35. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp2_kate1, 4);

  36. ntemp = (uint16_t) ltemp;

  37. nModbusCalRegs[Modbus_CalKateIndex] = ntemp;

  38. ntemp = (uint16_t) (ltemp >> 16);

  39. nModbusCalRegs[Modbus_CalKateIndex+1] = ntemp;

  40. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp2_bias2, 4);

  41. ntemp = (uint16_t) ltemp;

  42. nModbusCalRegs[Modbus_CalKZeroIndex] = ntemp;

  43. ntemp = (uint16_t) (ltemp >> 16);

  44. nModbusCalRegs[Modbus_CalKZeroIndex+1] = ntemp;

  45. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp2_kate2, 4);

  46. ntemp = (uint16_t) ltemp;

  47. nModbusCalRegs[Modbus_CalKSensiIndex] = ntemp;

  48. ntemp = (uint16_t) (ltemp >> 16);

  49. nModbusCalRegs[Modbus_CalKSensiIndex+1] = ntemp;

  50. }

  51. else if(nModbusCalRegs[Modbus_RegCalChan-Modbus_RegCalChan] == TEMP3_CHANNEL_ID)

  52. {

  53. ///< 初始化温度传感器:校准量程、零点偏移、灵敏度、零点偏移系数和灵敏度偏移系数

  54. nModbusCalRegs[Modbus_CalChanIndex] = strDeviceParamSave.temp3_range;

  55. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp3_bias1, 4);

  56. ntemp = (uint16_t) ltemp;

  57. nModbusCalRegs[Modbus_CalZeroIndex] = ntemp;

  58. ntemp = (uint16_t) (ltemp >> 16);

  59. nModbusCalRegs[Modbus_CalZeroIndex+1] = ntemp;

  60. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp3_kate1, 4);

  61. ntemp = (uint16_t) ltemp;

  62. nModbusCalRegs[Modbus_CalKateIndex] = ntemp;

  63. ntemp = (uint16_t) (ltemp >> 16);

  64. nModbusCalRegs[Modbus_CalKateIndex+1] = ntemp;

  65. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp3_bias2, 4);

  66. ntemp = (uint16_t) ltemp;

  67. nModbusCalRegs[Modbus_CalKZeroIndex] = ntemp;

  68. ntemp = (uint16_t) (ltemp >> 16);

  69. nModbusCalRegs[Modbus_CalKZeroIndex+1] = ntemp;

  70. memcpy((uint8_t *) &ltemp,(uint8_t *) &strDeviceParamSave.temp3_kate2, 4);

  71. ntemp = (uint16_t) ltemp;

  72. nModbusCalRegs[Modbus_CalKSensiIndex] = ntemp;

  73. ntemp = (uint16_t) (ltemp >> 16);

  74. nModbusCalRegs[Modbus_CalKSensiIndex+1] = ntemp;

  75. }

  76. else

  77. {

  78. nModbusCalRegs[Modbus_CalChanIndex] = 0;

  79. nModbusCalRegs[Modbus_CalZeroIndex] = 0;

  80. nModbusCalRegs[Modbus_CalZeroIndex+1] = 0;

  81. nModbusCalRegs[Modbus_CalKateIndex] = 0;

  82. nModbusCalRegs[Modbus_CalKateIndex+1] = 0;

  83. nModbusCalRegs[Modbus_CalKZeroIndex] = 0;

  84. nModbusCalRegs[Modbus_CalKZeroIndex+1] = 0;

  85. nModbusCalRegs[Modbus_CalKSensiIndex] = 0;

  86. nModbusCalRegs[Modbus_CalKSensiIndex+1] = 0;

  87. }

。。。。。。。。。。。。。。。。。

版权原因,完整文章,请参考如下:困扰一周的奇葩bug:重复相似代码多,导致单片机程序跑飞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值