发新帖我要提问
123
返回列表
打印
[MCU]

真诚求助,求建议,奇怪的问题

[复制链接]
楼主: haohaodee
手机看帖
扫描二维码
随时随地手机跟帖
41
haohaodee|  楼主 | 2018-3-31 14:41 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
苏山人家 发表于 2018-3-31 12:25
如果使用动态申请强烈建议自己封装一下,保证不可重入还有内存释放后NULL
下面已经给你写好代码了,一定要用 ...

void *MALLOC(size_t size)()里的p指针是局部变量吧,能够return回去吗

使用特权

评论回复
42
苏山人家| | 2018-3-31 15:23 | 只看该作者
haohaodee 发表于 2018-3-31 14:41
void *MALLOC(size_t size)()里的p指针是局部变量吧,能够return回去吗

申请的是全局的,这只是指针值的返回,没问题

使用特权

评论回复
43
苏山人家| | 2018-3-31 15:29 | 只看该作者
haohaodee 发表于 2018-3-31 14:38
1. 我先保证局部变量都赋初值。
2. 中断里面确认没有内存申请,但有memcpy,把中断接收到的数据copy出来, ...

想到的只有这些了,没有代码也都没法排查。
还有就是尽量减少全局变量,不得已用全局也要用static限制在文件内。

使用特权

评论回复
评论
haohaodee 2018-3-31 16:04 回复TA
现在是static的 
44
haohaodee|  楼主 | 2018-3-31 16:06 | 只看该作者
是不是我把295的反汇编和296的反汇编对比分析,然后结合程序仿真,能够找出哪里指针操作错误了,哪里发生了未预料的错误导致飞行效果发生了很大的变化?这样的话也好排查啊。

使用特权

评论回复
45
haohaodee|  楼主 | 2018-3-31 16:07 | 只看该作者
楼上的思路成不。。。

使用特权

评论回复
46
haohaodee|  楼主 | 2018-3-31 17:30 | 只看该作者
真的好急啊,好几周专门搞这个了。。。还是没有头绪

使用特权

评论回复
47
linqing171| | 2018-3-31 23:21 | 只看该作者
抖动是不是仅在驱动信号计算出错的时候才会发生?
要把所有故障模式的故障树画出来。然后找测试点,测试中间信号。
粗略看了一下你上面列的,好像都没有什么问题。

使用特权

评论回复
48
haohaodee|  楼主 | 2018-4-1 20:41 | 只看该作者
本帖最后由 haohaodee 于 2018-4-1 21:00 编辑
linqing171 发表于 2018-3-31 23:21
抖动是不是仅在驱动信号计算出错的时候才会发生?
要把所有故障模式的故障树画出来。然后找测试点,测试中 ...

我抓取了所以的数据,还是没分析出来。

很可能是堆栈的使用远远超过我的预计,所以我加了点stack,根本没解决。
现在问题是,怎样知道程序使用到的最大堆栈空间。

register window 的 MSP 吗?怎么计算?
另外,如果真是栈空间超了,可以解释发生的现象吗?

我把栈改到最大了,还是一样的表现。。。

堆栈.PNG (36.51 KB )

堆栈.PNG

使用特权

评论回复
49
linqing171| | 2018-4-1 21:53 | 只看该作者
haohaodee 发表于 2018-4-1 20:41
我抓取了所以的数据,还是没分析出来。

很可能是堆栈的使用远远超过我的预计,所以我加了点stack,根本没 ...

加个nop只会导致flash变化,ram不会变的,无论保存局部变量的stack还是malloc用的heap。

使用特权

评论回复
评论
haohaodee 2018-4-2 17:50 回复TA
@linqing171 :你也说了,加nop只会引起flash中存储位置的变化,你说业务代码有问题,可能的问题会有什么 
haohaodee 2018-4-2 17:49 回复TA
@linqing171 :只要改动代码,就可能引起变化,如给局部变量赋0值或者不赋值,都会引起稳或者不稳。所以非常奇怪! 
haohaodee 2018-4-2 17:47 回复TA
@linqing171 :用记录的数据离线计算,和记录的结果完全一样;陀螺仪我换了另一个型号的,还是同样的表现。所以现在非常奇怪!! 
haohaodee 2018-4-2 17:46 回复TA
@linqing171 :我今天又把所有的数据记录了,我最下层的控制只有一个err=k*(sp-gyro),sp赋值为0,只有陀螺仪是变量,我记录了所有的计算,然后用记录的 
linqing171 2018-4-2 14:05 回复TA
@haohaodee :首先怀疑自己的业务代码的问题,从距离发生抖动最近的路上调试。keil本身的bug极少,去年我报告了当时beta版本的一个,几天就修修复了。 
haohaodee 2018-4-2 00:17 回复TA
全工程我没用过函数指针,所以应该不会是指针的问题,如果keil,arm没问题,那就是驱动库了,里面可能有函数指针,只有函数指针用错才会导致flas... 
haohaodee 2018-4-2 00:15 回复TA
是啊 
50
haohaodee|  楼主 | 2018-4-2 18:03 | 只看该作者
本帖最后由 haohaodee 于 2018-4-2 18:28 编辑

引起姿态抖动的是姿态控制,姿态控制我现在只隔离成如下两行代码:

int channel[2];
channel[0] = k*(sp[0]-gyro[0]);  // gyro 是陀螺仪数据,k是常数,sp[0]和sp[1]都赋值为0
channel[1] = k*(sp[1]-gyro[1]);

然后把channel值输出给pwm.

然后在while(1)前增加nop就会有很抖动和很稳两种截然不同的效果。
当然,很稳定的版本烧到哪台飞机都是稳定的,抖动的烧到哪台飞机都是抖动的。

我记录了上面涉及到的所有数据,然后离线计算复查,发现计算过程完全没有问题,但是输出channel确实变化很大。

如果抖动了,我不在前面加nop,而是把int channel[2] = {0};就OK了。当然,如果改了别的地方抖动了,再把赋初值去掉,就又不抖动了。

这个完全无法解释了嘛!目前可以确定就是跟代码在flash中的位置有关系,一旦位置稍微一动,效果就会完全不一样。
是如何造成效果完全不一样的,追踪上面两个式子,也完全没错,至少计算没错,不会变成1+2=5,常量值没有被改变,唯一的变量是陀螺仪,换别的陀螺仪,别的型号的陀螺仪,飞机表现都一样。

所以真正奇怪了。




使用特权

评论回复
51
haohaodee|  楼主 | 2018-4-2 18:29 | 只看该作者
苏山人家 发表于 2018-3-31 15:29
想到的只有这些了,没有代码也都没法排查。
还有就是尽量减少全局变量,不得已用全局也要用static限制在 ...

为什么局部变量必须赋初值?

使用特权

评论回复
52
linqing171| | 2018-4-2 21:43 | 只看该作者
haohaodee 发表于 2018-4-2 18:03
引起姿态抖动的是姿态控制,姿态控制我现在只隔离成如下两行代码:

int channel[2];

抖和不抖的时候 channel 的结果值都确认没有问题? 如果channel确认没有问题,那么问题就在后的pwm。
在8051里面sp是关键字吧。这个数**算是不是要检测溢出?

你的烧写mcu  flash的程序,有没有往特定的flash地址写入流水号的功能?
MCU换过吗?会是一个MCU的flash被你完的寿命有问题了吗?

使用特权

评论回复
53
haohaodee|  楼主 | 2018-4-2 22:27 | 只看该作者
linqing171 发表于 2018-4-2 21:43
抖和不抖的时候 channel 的结果值都确认没有问题? 如果channel确认没有问题,那么问题就在后的pwm。
在8 ...

抖动的版本,陀螺仪和channel的跳动都很比稳的大,很难说是抖动引起陀螺仪数值变大还是陀螺仪数值有问题,造成抖动。

有往特定的地址写一些参数,这个地址在flash的后面,程序远没到那里呢。读出来全是FFFF。
换过其他的MCU,同样的表现。

使用特权

评论回复
评论
苏山人家 2018-4-3 09:38 回复TA
channel和陀螺抖动都很大,然后这两还是线性关系,所以肯定就是陀螺的毛病啊,你看看你的代码是不是在读陀螺的时候时序,变量什么的没有处理好 
54
haohaodee|  楼主 | 2018-4-2 22:32 | 只看该作者
本帖最后由 haohaodee 于 2018-4-2 22:39 编辑

另外,怎样看程序最大用了多少栈,MSP吗,比如RAM是0x20000000到0x20004FFF,开了8k的栈,则栈的地址是0x20003000到0x20002FFF。
对吗?但是我看.map文件,好像是顺序排列的,data,bss,heap,stack,比如heap到0x20001666,则栈是0x20001666到0x20003666。

我觉得地址应该是0x20001666到0x20003666,但是由3666向1666扩展。

使用特权

评论回复
55
苏山人家| | 2018-4-3 09:32 | 只看该作者
haohaodee 发表于 2018-4-2 18:29
为什么局部变量必须赋初值?

因为局部变量是从栈里面获取的,其值是不确定的

使用特权

评论回复
评论
haohaodee 2018-4-3 21:43 回复TA
恩 是的,明白的 
56
苏山人家| | 2018-4-3 09:40 | 只看该作者
haohaodee 发表于 2018-4-2 22:32
另外,怎样看程序最大用了多少栈,MSP吗,比如RAM是0x20000000到0x20004FFF,开了8k的栈,则栈的地址是0x20 ...

你是什么芯片啊,keil有个.s的引导文件里面由设置堆栈大小的,keil堆栈是顺序分配的,剩下的就是给全局留着的

使用特权

评论回复
57
一路向北lm| | 2018-4-3 11:05 | 只看该作者
没操作系统的话,只能一步一步的检查了,慢慢调试吧,这个过程也是你收货与成长的过程。

使用特权

评论回复
58
haohaodee|  楼主 | 2018-4-5 21:18 | 只看该作者
一路向北lm 发表于 2018-4-3 11:05
没操作系统的话,只能一步一步的检查了,慢慢调试吧,这个过程也是你收货与成长的过程。 ...

是啊,翻了个底朝天,解了一些可能的BUG.

使用特权

评论回复
59
haohaodee|  楼主 | 2018-4-5 21:22 | 只看该作者
感谢大家,我想应该是已经解了,PWM的一个结构体成员没有初始化。。。所以pwm出问题了。。。

感谢大家,谢谢大家的关注,在这两个帖子中,大家给了很多的帮助,我自己得到了很大的成长,再次感谢大家。

使用特权

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

本版积分规则