0

CAN 送信のセットアップ中に、ポインターが破損しています (有効な 0x00000bd0 から、RAM の範囲外の 0x84520000 に変化します)。ポインターも CAN アクティビティとは無関係です。破損の理由は、union64 がポインターのアドレスに上書きされるためです。この union64 は (ASF からの) CANIF オブジェクトに属しています。ソースコードでは、次の場所で破損が発生します。

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 の後の 32 ビット整数はポインター 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 に答える