打印
[STM32]

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

[复制链接]
7281|80
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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。

使用特权

评论回复
5
linqing171| | 2018-3-19 22:54 | 只看该作者
贴warning,贴 if(control_get_mode() == MODE_LAND)  这句代码对应的反汇编。

使用特权

评论回复
6
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

使用特权

评论回复
7
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

使用特权

评论回复
8
xyz549040622| | 2018-3-20 06:34 | 只看该作者
优化模式调的不一样吗?MDK哪来的那么多bug

使用特权

评论回复
9
arm86| | 2018-3-20 08:28 | 只看该作者
可以试试将 mode_ctrl  的 static 改为 volatile

使用特权

评论回复
10
ayb_ice| | 2018-3-20 08:34 | 只看该作者
本帖最后由 ayb_ice 于 2018-3-20 08:36 编辑

这么简单的语句,不可能是KEIL BUG
极有可能是其它地方的问题,只是这种情况下容易触发故障罢了,因为执行时间的变化,
或这样的语句导致其它代码的位置发生了变化

使用特权

评论回复
11
haohaodee|  楼主 | 2018-3-20 09:11 | 只看该作者
xyz549040622 发表于 2018-3-20 06:34
优化模式调的不一样吗?MDK哪来的那么多bug

优化模式一样的设置

使用特权

评论回复
12
haohaodee|  楼主 | 2018-3-20 09:12 | 只看该作者
ayb_ice 发表于 2018-3-20 08:34
这么简单的语句,不可能是KEIL BUG
极有可能是其它地方的问题,只是这种情况下容易触发故障罢了,因为执行 ...

确实可能是导致其他代码的位置发生了变化,怎么排查,有没有建议啊

使用特权

评论回复
13
ayb_ice| | 2018-3-20 09:15 | 只看该作者
haohaodee 发表于 2018-3-20 09:12
确实可能是导致其他代码的位置发生了变化,怎么排查,有没有建议啊

只能大胆怀疑,小心求证

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

使用特权

评论回复
14
haohaodee|  楼主 | 2018-3-20 09:19 | 只看该作者
arm86 发表于 2018-3-20 08:28
可以试试将 mode_ctrl  的 static 改为 volatile

改了试了,还是不行

使用特权

评论回复
15
haohaodee|  楼主 | 2018-3-20 09:29 | 只看该作者
ayb_ice 发表于 2018-3-20 09:15
只能大胆怀疑,小心求证

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

全工程只有三个warnig,就是三个定义了但没有用到的变量

使用特权

评论回复
16
ayb_ice| | 2018-3-20 09:30 | 只看该作者
haohaodee 发表于 2018-3-20 09:29
全工程只有三个warnig,就是三个定义了但没有用到的变量

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

之前虽然越界了,但可能影响不明显,现在代码发生变化,可能影响了重要的变量

使用特权

评论回复
17
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


各位仁兄帮分析一下,不尽感谢。

使用特权

评论回复
18
七颗咖啡豆| | 2018-3-20 10:56 | 只看该作者
不用看了,肯定是哪里指针或者数组越界

使用特权

评论回复
19
haohaodee|  楼主 | 2018-3-20 10:58 | 只看该作者
七颗咖啡豆 发表于 2018-3-20 10:56
不用看了,肯定是哪里指针或者数组越界

可能是,我有一个卡尔曼的函数,注释掉就没问题了

使用特权

评论回复
20
ayb_ice| | 2018-3-20 11:27 | 只看该作者
haohaodee 发表于 2018-3-20 10:58
可能是,我有一个卡尔曼的函数,注释掉就没问题了

也可能堆栈出问题了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

80

帖子

0

粉丝