0

在设置 CAN 传输期间,指针被损坏(它从有效的 0x00000bd0 变为超出我的 RAM 范围的 0x84520000)。该指针也与 CAN 活动无关。损坏的原因是,在指针的地址上写入了 union64。这个 union64 属于 CANIF 对象(来自 ASF),在源代码中损坏发生在这里:

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(如屏幕截图所示)。

腐败前的记忆

损坏后的内存

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

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

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

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

1 回答 1

0

在行中:

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

CANIF_mob_get_ptr_data是一个产生结构指针的宏,根据文档定义为:

#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是无效的,后续的赋值也会失败。

即使解析的地址无效,在没有任何类型的硬件内存保护的情况下,这种访问的典型效果是“包装”地址,使其解析为非确定性的真实地址——从而破坏不相关的内存。

于 2017-04-13T12:35:58.447 回答