我正在用C编写回调函数。它用于初始化I2C传感器,并在每个(分相)配置步骤结束时调用;在第9次通话后,设备几乎可以使用了。
该功能的基本思想是:
void callback(void)
{
static uint8_t calls = 0;
if (++calls == 9) {
// Finalise device setup (literally a single line of code)
}
}
我的问题是上面的if语句永远不会被输入,尽管函数被调用了9次。
我的函数的(dis)汇编代码似乎是理智的(除了subi . 0xFF
一个增量的技巧,尽管包含了inc
指令):
00000a4c <callback>:
a4c: 80 91 9e 02 lds r24, 0x029E
a50: 8f 5f subi r24, 0xFF ; 255
a52: 80 93 9e 02 sts 0x029E, r24
a56: 89 30 cpi r24, 0x09 ; 9
a58: 09 f0 breq .+2 ; 0xa5c <callback+0x10>
a5a: 08 95 ret
a5c: 2e e1 ldi r18, 0x1E ; 30
a5e: 35 e0 ldi r19, 0x05 ; 5
a60: 41 e0 ldi r20, 0x01 ; 1
a62: 60 e0 ldi r22, 0x00 ; 0
a64: 84 e7 ldi r24, 0x74 ; 116
a66: 0c 94 c7 02 jmp 0x58e ; 0x58e <twi_set_register>
我正在为Atmel AVR芯片编写代码,因此使用avr-gcc进行编译。我没有有意义的代码调试功能(我无法访问JTAG程序员,并且该函数在任何情况下都是异步/分离阶段; USART打印太慢了。)
但是,我可以访问逻辑分析器,并且能够通过在代码中放置while (1) ;
语句来确定许多内容:
if (calls == 0) { while (1) ; }
,则不会挂起if (calls) { while(1) ; }
,它就不会挂起我完全不知所措。
有没有人对可能导致这种情况的原因有什么建议,甚至是我可以采取的新调试步骤?
答案 0 :(得分:4)
我最终找到了错误的原因;另一个子系统作为第一次调用回调函数的副作用而中断,这意味着没有其他调用成功。
这解释了我看到的行为:
我能够通过使用一些GPIO引脚作为调试切换来解决这个问题,从而跟踪调用通过TWI接口进行的调用。
感谢帮助人员。这并不是原来提出的问题的答案,但它已经解决了,所以这就是:)
答案 1 :(得分:2)
对于你说的我只能想到3种可能性:1)你假设在每次I2C通信时调用函数是不正确的,2)你的程序在一些不相关的函数中有一个错误(可能是内存泄漏)导致变量调用损坏。或者3)两个或多个线程同时调用您的函数,调用以不同于预期的方式递增,使用&gt; 而不是 == < / strong>,如果这样可以解决问题,那么你就是在一个多线程的环境中运行,而你却没有知道。
你需要一个准确的方法来知道调用的确切值,如果你没有调试器并且没有输出文本的方法,你唯一要留下的就是玩是时间。我不知道你编译器,但我确信它包含一些有用的计时功能,所以我要做的就是在增加10 +调用秒之前循环,然后再增加10 +调用秒,例如:
sleep(1000*(10+calls));
++calls;
sleep(1000*(10+calls));
if(calls>8){
// your actual code
}
我会(手中的天文台)预计第一次通话时延迟(10 + 0加10 + 1)= 21秒,第二次通话时延迟23秒,第三次通话则延迟25,依此类推。这样我可以确定调用的值从0开始,然后逐渐增加到9。
此外,你必须测试你不期望的东西,所以不要这样做:
++calls;
if (calls==0) while (1);
这样做:
++calls;
if (calls==1) while (1);
如果您的程序挂起,那么可以确定调用的值正好是1,而不是零的任何值。如果计算一个有效的I2C通信并且程序挂起,则从0到1的转换正确完成,因此请相应地更改挂起语句:
++calls;
if (calls==2) while (1);
同样,如果在程序挂起之前计算2个有效的I2C通信,则表示从1到2的转换是正确的,依此类推。
另一个建议,试试这个:
uint8_t Times(void){
static uint8_t calls = 0;
return ++calls;
}
void callback(void){
if (Times()>8) {
// Your actual code
}
}
而且:
void callback(void){
static uint8_t calls = 0;
if (calls++>7) {
// some code.
}
}
希望这有帮助。