2

このトピックは非常に漠然としていることを理解しています....それで説明しようと思います。

IAR Workbench でプロジェクトに取り組んでいます。単純な if ステートメントなどの新しい機能を追加すると、コード構造全体が壊れてしまうところまで来ました。コードは正常にコンパイルされ、8051 デバイスに正常にダウンロードされますが、コードの起動シーケンスの途中で接続が失われます。スタック オーバーフローが発生しているようです。デバッガーを一時停止すると、XdataStack と IdataStack の値が低く (50% 未満)、レポートするスタック オーバーフローがないことがわかります。

実際、問題の原因となっているコードは、アプリケーションによって呼び出されることさえありません。

これは、コード内にある debug #define 定数を有効にするとさらに明白になります。これを有効にすると、より多くの文字列定数が uart デバッグ用のコードに組み込まれます。

私が実行した別のテストは、既に存在する関数で 100 文字の配列を作成することでした。

char hello[100];
memset(hello, 0x00, 100);

そして、これもコードを壊しているようです。

このデバイス (フラッシュ サイズが 128Kb の CC2540) がいっぱいになっていないかどうかを確認するために、確認すべきメモリ領域があるかどうか疑問に思っていました。

IAR では、次のことを確認できます。

  • IDATA
  • XDATA
  • SFR
  • 論理コード
  • コード
  • データ
  • Pdata

私のプロジェクト構成に関する限り:

スタックサイズ:

  • IDATA: 0xC0
  • PDATA: 0x00
  • XDATA: 0x280

ヒープ サイズ:

  • XDATA: 0xFF
  • ファー: 0xFFF
  • Far22: 0xFFF ヒュージ: 0xFFF
4

1 に答える 1

0

スタック オーバーフローが発生しているようです。

8051 ではスタックがあまり使用されないため、これはほとんどありません。効果的な間接アドレス指定モードがない場合、ほとんどの場合、戻りアドレス (MCU によって自動的に管理される) と保存されたレジスタ (ほとんどが ISR 内) を保持することに制限されます。

私が実行した別のテストは、既に存在する関数で 100 文字の配列を作成することでした [...] そして、これもコードを壊しているようです。

あなたのコードは基本的に同等です: f() { static char hello[100]; ... }コンパイラがこれらの「ローカル」変数のすべてをオーバーレイで管理するため、これらの 100 バイトはf()が実行されている場合にのみ安全に使用できます。f()これは、 の実行中に呼び出される可能性のある関数をコンパイラが認識できる場合にのみ機能します。コンパイラによるコール ツリーの分析が間違っていると、ローカル変数 (レジスタに渡すには引数が多すぎる関数への引数を含む) が予期しない方法で上書きされます。

main()コンパイラは、すべての ISR を独立した呼び出しツリーのルートと見なせるほどスマートである必要があります。計算されたジャンプ、関数ポインターを介した呼び出し、RTOS の「タスク」などの概念によって簡単にだまされます。たとえば、関数ポインターを使用する場合、ポインターを介して関数呼び出しから呼び出される可能性のあるすべての関数を (おそらくリンカー オプションとして) コンパイラーに通知する必要があります。

于 2014-02-24T16:19:03.470 に答える