最近、組み込みソフトウェアで奇妙な動作に直面しています。
私が得たもの:ファイルサイズが大きすぎてマイクロコントローラーフラッシュから直接開始できないため、32ビットAVR32コントローラーを実行し、外部SDRAMからプログラムを開始します。物理メモリ マップにより、メモリ領域は次のように分割されます。
スタック (0x1000 から始まり、0xF000 の長さ) (< 0x1000 は MPU によって保護されます)
EBI SDRAM (0xD0000000 から始まり、0x00400000 の長さ)。
何が起こるか:残念ながら、再現できない例外が発生しました。与えられたスタック トレースを見ると、次のイベントが不規則に発生します。
名前: バス エラー データ フェッチ - イベント ソース: データ バス - ストアド リターン アドレス: 未完了の最初の命令
さらに、スタック ポインターには有効な値がありますが、例外が発生したアドレス (命令をフェッチするための最後のエントリ ポイント) はメモリ ニルヴァーナ (0x496e6372、0x5...、0x6.... 付近など) を指します。たぶん、これは「最初の未完了の指示」である必要があると思います。マニュアルが話しています。ただし、ソース コードの行は常に同じです。ポインターを介してデータ配列からメンバー関数にアクセスします。
if(mSomeArray[i])
{
mSomeArray[i]->someFunction(); <-- Crash
}
問題は、他のソース コードを追加または削除すると、イベントが消えて再び戻ることです。
考えたこと:何かが私の記憶 (マッピング) を壊しています。これにはどのような種類のエラーが考えられますか?
- バッファオーバーフロー?
- SDRAM コントローラがオフになる可能性があるため、一部のデータが失われます。それは不可能ではありませんが、むしろありそうもないことです
- スタックは十分に大きく、透かしで確認済みです
- データ バス レートと AVR クロックが正しく設定されている
これを解決する方法:もっと主張しますか? 残念ながら、これを AVRStudio でデバッグすることはできません。誰でもヒントやアイデアはありますか? それとも、明らかな何かが欠けていますか?
編集:
ユーザーからの言及されたアプローチ:
- 関数ポインタと配列エントリのアドレスをチェック
- スタック配列の上書き
- 正しく書き込まれていない割り込み
- 初期化されていないポインター
i
クラッシュ ケース経由でアレイ アクセスを確認する- 不正なメモリアクセスには例外ハンドラアドレスを使用
snprintf
の代わりに使用sprintf