2017-04-13 48 views
0

在CAN传输的设置过程中,指针被损坏(它从有效的0x00000bd0变为超出我的RAM范围的0x84520000)。指针也与CAN活动无关。腐败的原因是,union64写在指针的地址上。这union64属于(从ASF)的CANIF对象,源代码中的腐败发生在这里:Atmelstudio UC3C AVR32 - 内存中错误位置的框架对象?

void CAN_SendMsg_KMS(uint64_t msg) 
{ 
    CANIF_mob_get_ptr_data(ACTIVECHANNEL,0)->data = (Union64)msg; 
    AVR32_CANIF.channel[ACTIVECHANNEL].mober = 1<<0; 
} 

我的问题是,为什么对“数据”存储在同一地址作为我的指针分配呢? 或者这是一个错误的结论?

在下面的截图中,第一个是在执行函数之前,最后一个是在执行后立即执行。 “msg”的内容是0x8452000000000000。 被损坏的指针A的内容应该是0x00000bd0,因为它在损坏发生之前。 指针A之后的32Bit整数是指针B,指针B指向指针A,因此其未损坏的内容因此是0x00000004(如屏幕截图所示)。

Memory before corruption

Memory after corruption

我不知道这是一个有用的信息: 根据数据表的CANIF寄存器内存地址0xFFFD1C00。

更新: 这是破坏指针汇编级代码:

// CANIF_mob_get_ptr_data(ACTIVECHANNEL,0) - >数据=(Union64)MSG;

80006AC8 mov R8, -189440   
80006ACC ld.w R9, R8[8]   
80006ACE st.d R9[8], R5 
+0

在汇编级单步调用。你确定你的目标支持64位整数吗? – unwind

+0

看看更新,st.d是一个64位的汇编操作。看起来好像一切都好。有两个32位移动寄存器,然后一个64位写入。但它毕竟是错误的位置。 – anyone

+0

工会演员在一开始就失败了使用工会的目的。使用:'CANIF_mob_get_ptr_data(ACTIVECHANNEL,0) - > data.u64 = msg;' - 不是一个解决方案,只是一个评论。 – Clifford

回答

0

在行:

CANIF_mob_get_ptr_data(ACTIVECHANNEL,0)->data = (Union64)msg; 

CANIF_mob_get_ptr_data是产生一个结构指针的宏,根据documentation所定义:

#define CANIF_mob_get_ptr_data(ch, mob) ((can_msg_t *)(CANIF_SIZE_OF_CANIF_MSG*mob+CANIF_get_ram_add(ch))) 

反过来宏CANIF_get_ram_add是返回一个宏包含在CAN接口寄存器中的地址CANRAMB

#define CANIF_get_ram_add(ch) (AVR32_CANIF.channel[ch].canramb) 

因此,如果AVR32_CANIF_CANRAMB先前未被初始化或不正确初始化,则返回的指针CANIF_mob_get_ptr_data将无效,并且后续分配将失败。

即使解析地址是无效的,在没有任何类型的硬件内存保护的情况下,这种访问的典型效果是“包装”地址,以便它解析为非确定性实际地址 - 所以破坏无关的记忆。