希望没有在这里创建一个重复的主题是我的怀疑:
我正在使用Atmel Xmega处理器,我正在使用AtmelStudio(gcc),我必须通过类似于此的情况通过设备发送内存区域:
volatile unsigned char *areatobetransferred;
void afunction (unsigned int someint)
{
unsigned int otherint;
otherint=(someint<<8) | (someint>>8); //used to swap lobyte and hibyte
otherfunction ((volatile unsigned char *)&otherint);
}
void otherfunction (volatile unsigned char * pointedarea)
{
areatobetransferred=pointedarea;
bytestosend=2;
StartSenderInterrupt();
}
ISR (SenderInterrupt)
{
deviceport=*areatobetransferred;
if (length<bytestosend)
{areatobetransferred++;
bytestosend++;}
else StopSenderInterrupt();
}
现在,我的问题是,虽然当我从另一个模块调用此例程时,我得到了正确的行为,但在另一个模块中,我无法获得正确的结果。 具体来说,在ISR中,除了将局部变量“otherint”的正确值作为指针传递之外,我得到的只是垃圾,除非我将局部变量声明为静态。 如果我将其读入调用例程并进入中断服务程序,则指针值绝对正确,而指向的值仅在调用例程“功能”中正确。 更深入地看,我看到如果将局部变量声明为非静态,则将其分配在堆栈上,位于ram的远端(应该是),而如果声明为static,则将其放置在公羊空间。
没有调试工具和汇编程序知识不足,我假设: - 当我声明一个局部变量时,它的值被保留,而且只有当我进入它的范围时 - 如果我调用其他例程,或者在中断的情况下(如我的情况),我有指向我的局部变量的指针存储我的变量所在的正确位置但是现在该地址的内容最终会被其他数据覆盖,这就是为什么我只是垃圾。 - 如果我将变量声明为静态,它被分配一次,它的值和位置永远不会通过ISR或调用其他例程来改变,所以我总是读取正确的值。
最后,我认为这只是运气问题,它在另一个模块上按预期工作:如果我发展我的项目或我改变“那个”特定的东西,我认为它也会在那里开始失败。
我的猜测是否正确?
由于
答案 0 :(得分:1)
您的ISR正在尝试访问areatobetransferred
,这是(间接)设置在ISR之外的&otherint
。但是,otherint
位于afunction
的堆栈上。因此,如果在调用ISR之前afunction
退出,则otherint
的值将变为未定义。这就是为什么让它静态起作用的原因。作为替代方案,当ISR完成时,它malloc()
和free()
。