[STM32] 指针使用不当,会造成很奇怪的问题,大家注意

[复制链接]
 楼主| haohaodee 发表于 2018-3-19 21:18 | 显示全部楼层 |阅读模式
本帖最后由 haohaodee 于 2018-3-24 09:06 编辑

最近一直在为这事烦恼,一直搞不定。楼主是用stm32做四轴飞行器飞控的,用的keil V5.23.0.0。
现象是程序中加一条处理降落模式的判断语句,飞机就由不加前的很稳变得飞的很颤抖了。具体如下:

很稳的代码:
float output = constrain_float(P_PID*err,-0.1f,0.1f) + constrain_float(I_PID*iterm,-0.1f,0.1f) + constrain_float(D_PID*dterm,-0.1f,0.1f) ;

修改后变得飞的颤抖的代码:
float output;
if(control_get_mode() == MODE_LAND){
  output = constrain_float(P_PID*err+I_PID*iterm+D_PID*dterm,-0.3f,0.3f);
}else{
  // 和上面的一样
  output = constrain_float(P_PID*err,-0.1f,0.1f) + constrain_float(I_PID*iterm,-0.1f,0.1f) + constrain_float(D_PID*dterm,-0.1f,0.1f) ;
}


control_get_mode() 函数具体为:
static uint8_t mode_ctrl = 0;
uint8_t control_get_mode()
{
  return mode_ctrl;
}


MODE_LAND为宏定义
#define MODE_LAND       3

如上所描述的,output的输出只有在MODE_LAND模式下才会与第一种情况不同,
但为什么飞机在其他模式下也变颤抖了呢?


我越来越怀疑是KEIL的BUG。




现在已经解决,原因是指针指向了被释放的栈,改了就好了。
多谢大家啦。


原标题为“keil有BUG?越来越疑惑,很简单的代码,实际效果差别很大”,未免大惊小怪,改为现在的标题以引起大家重视这种“误操作”。
 楼主| haohaodee 发表于 2018-3-19 21:23 | 显示全部楼层
keil的编译器有问题?
airwill 发表于 2018-3-19 21:37 | 显示全部楼层
我倒是不相信 Keil 编译器有这样简单的 BUG, 倒是担心是你自己的 bug.
mode_ctrl 在什么地方被意外地改掉了呢, 最好调试器捕捉一下
 楼主| haohaodee 发表于 2018-3-19 22:02 | 显示全部楼层
我用无线回传了数据,在if(control_get_mode() == MODE_LAND){}里加了一个log++,只要这里执行,log就会+1,实际是这个全局变量一直为0。
linqing171 发表于 2018-3-19 22:54 | 显示全部楼层
贴warning,贴 if(control_get_mode() == MODE_LAND)  这句代码对应的反汇编。
 楼主| haohaodee 发表于 2018-3-20 00:13 | 显示全部楼层
没有WARNING,反汇编如下:

296:         if(control_get_mode() == MODE_LAND){
0x08006562 F001F9F1  BL.W     control_get_mode (0x08007948)
0x08006566 2803      CMP      r0,#0x03
0x08006568 D11D      BNE      0x080065A6
 楼主| haohaodee 发表于 2018-3-20 00:15 | 显示全部楼层
我找了另一台电脑的KEIL编译,相同的有if(control_get_mode() == MODE_LAND)这一句,但飞机飞稳了,反汇编如下:

297:         if(control_get_mode() == MODE_LAND){
0x0800655E F001F9F1  BL.W     control_get_mode (0x08007944)
0x08006562 2803      CMP      r0,#0x03
0x08006564 D11D      BNE      0x080065A2
xyz549040622 发表于 2018-3-20 06:34 来自手机 | 显示全部楼层
优化模式调的不一样吗?MDK哪来的那么多bug
arm86 发表于 2018-3-20 08:28 | 显示全部楼层
可以试试将 mode_ctrl  的 static 改为 volatile
ayb_ice 发表于 2018-3-20 08:34 | 显示全部楼层
本帖最后由 ayb_ice 于 2018-3-20 08:36 编辑

这么简单的语句,不可能是KEIL BUG
极有可能是其它地方的问题,只是这种情况下容易触发故障罢了,因为执行时间的变化,
或这样的语句导致其它代码的位置发生了变化
 楼主| haohaodee 发表于 2018-3-20 09:11 | 显示全部楼层
xyz549040622 发表于 2018-3-20 06:34
优化模式调的不一样吗?MDK哪来的那么多bug

优化模式一样的设置
 楼主| haohaodee 发表于 2018-3-20 09:12 | 显示全部楼层
ayb_ice 发表于 2018-3-20 08:34
这么简单的语句,不可能是KEIL BUG
极有可能是其它地方的问题,只是这种情况下容易触发故障罢了,因为执行 ...

确实可能是导致其他代码的位置发生了变化,怎么排查,有没有建议啊
ayb_ice 发表于 2018-3-20 09:15 | 显示全部楼层
haohaodee 发表于 2018-3-20 09:12
确实可能是导致其他代码的位置发生了变化,怎么排查,有没有建议啊

只能大胆怀疑,小心求证

多测试,找规律,多记录,打印相关信息,特别是怀疑的地方

 楼主| haohaodee 发表于 2018-3-20 09:19 | 显示全部楼层
arm86 发表于 2018-3-20 08:28
可以试试将 mode_ctrl  的 static 改为 volatile

改了试了,还是不行
 楼主| haohaodee 发表于 2018-3-20 09:29 | 显示全部楼层
ayb_ice 发表于 2018-3-20 09:15
只能大胆怀疑,小心求证

多测试,找规律,多记录,打印相关信息,特别是怀疑的地方

全工程只有三个warnig,就是三个定义了但没有用到的变量
ayb_ice 发表于 2018-3-20 09:30 | 显示全部楼层
haohaodee 发表于 2018-3-20 09:29
全工程只有三个warnig,就是三个定义了但没有用到的变量

有可能是指针或数组越界了,

之前虽然越界了,但可能影响不明显,现在代码发生变化,可能影响了重要的变量
 楼主| haohaodee 发表于 2018-3-20 10:14 | 显示全部楼层
本帖最后由 haohaodee 于 2018-3-20 14:50 编辑

现在尝试把if(control_get_mode() == MODE_LAND){ }中的内容注释掉,飞机飞的没问题。也就是判断语句没问题,而是里面的内容会引起问题。

具体如下:


if(){}中的注释与否,就会引起问题。

没有注释前的反汇编:
   297:         if(control_get_mode() == MODE_LAND){
0x08006562 F001F9F1  BL.W     control_get_mode (0x08007948)
0x08006566 2803      CMP      r0,#0x03
0x08006568 D11D      BNE      0x080065A6

0x0800656A 4863      LDR      r0,[pc,#396]  ; @0x080066F8
0x0800656C 9909      LDR      r1,[sp,#0x24]
0x0800656E F7F9FE65  BL.W     __aeabi_fmul (0x0800023C)
0x08006572 9004      STR      r0,[sp,#0x10]
0x08006574 485D      LDR      r0,[pc,#372]  ; @0x080066EC
0x08006576 6881      LDR      r1,[r0,#0x08]
0x08006578 4860      LDR      r0,[pc,#384]  ; @0x080066FC
0x0800657A F7F9FE5F  BL.W     __aeabi_fmul (0x0800023C)
0x0800657E 4659      MOV      r1,r11
0x08006580 9002      STR      r0,[sp,#0x08]
0x08006582 485F      LDR      r0,[pc,#380]  ; @0x08006700
0x08006584 F7F9FE5A  BL.W     __aeabi_fmul (0x0800023C)
0x08006588 9001      STR      r0,[sp,#0x04]
0x0800658A 9902      LDR      r1,[sp,#0x08]
0x0800658C F7F9FDFE  BL.W     __aeabi_fadd (0x0800018C)
0x08006590 9003      STR      r0,[sp,#0x0C]
0x08006592 9904      LDR      r1,[sp,#0x10]
0x08006594 F7F9FE4C  BL.W     __aeabi_fsub (0x08000230)
0x08006598 4A58      LDR      r2,[pc,#352]  ; @0x080066FC
0x0800659A 495A      LDR      r1,[pc,#360]  ; @0x08006704
0x0800659C 9005      STR      r0,[sp,#0x14]
0x0800659E F7FFFEF9  BL.W     constrain_float (0x08006394)
0x080065A2 9008      STR      r0,[sp,#0x20]
0x080065A4 E026      B        0x080065F4


注释之后就没问题了,反汇编如下:
  297:         if(control_get_mode() == MODE_LAND){
0x08006562 F001F9D1  BL.W     control_get_mode (0x08007908)
0x08006566 2803      CMP      r0,#0x03
0x08006568 D026      BEQ      0x080065B8


各位仁兄帮分析一下,不尽感谢。
七颗咖啡豆 发表于 2018-3-20 10:56 | 显示全部楼层
不用看了,肯定是哪里指针或者数组越界
 楼主| haohaodee 发表于 2018-3-20 10:58 | 显示全部楼层
七颗咖啡豆 发表于 2018-3-20 10:56
不用看了,肯定是哪里指针或者数组越界

可能是,我有一个卡尔曼的函数,注释掉就没问题了
ayb_ice 发表于 2018-3-20 11:27 | 显示全部楼层
haohaodee 发表于 2018-3-20 10:58
可能是,我有一个卡尔曼的函数,注释掉就没问题了

也可能堆栈出问题了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

80

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

3

主题

80

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部