0

私はマイクロコントローラーのプログラミングにかなり慣れていません。LPC1788 を使って数週間が経ちました。

私が最近抱えている問題の 1 つは、予想よりもずっと早くメモリ不足になることです。mallocできる連続したメモリのブロックの大きさをテストすることで、使用可能なメモリの量をテストしました。結果は972バイトです。割り当ては、アドレス 0x10000000 (このボードでは約 64kB である必要があるオンチップ SRAM の開始) から開始されます。

私が現在取り組んでいるプログラムは、LCD を利用してメッセージを表示できる単純なデバッガとして機能することを意図しています。新しいメッセージによって常に「追加」される 1 つの文字列があり、メッセージ全体が LCD に表示されます。画面のメッセージの長さが垂直方向の境界を超えると、最も古いメッセージ (一番上に近いメッセージ) が収まるまで削除されます。ただし、追加のメモリの割り当てを拒否する前に、約 7 つの追加メッセージしか追加できません。必要に応じて、プロジェクトの main.c はhttp://pastebin.com/bwUdpnD3でホストされます。

以前、threadX RTOS を使用して複数のスレッドを作成および実行するプロジェクトの作業も開始しました。そのプログラムにLCDの使用を含めようとしたとき、メモリも非常に限られていることがわかりました。LCD は SDRAM のベース アドレスから始まるすべてのピクセル データを格納しているように見えますが、それが私が使用している SRAM と同じかどうかはわかりません。

私が必要としているのは、LCD を利用しながら、複数のスレッドが機能したり、大きな文字列を格納したりできるように十分なメモリを割り当てる方法です。1 つの可能性としては、バッファーまたはその他のメモリー領域を使用することが考えられますが、その方法がよくわかりません。どんな助けでも大歓迎です。

tl;dr: LCD に大きな文字列を出力しようとすると、SRAM の割り当て可能なメモリがすぐに不足します。

編集 1: 変数 currMessage でメモリ リークが検出されました。現在は修正されていると思います:

strcpy(&trimMessage[1], &currMessage[trimIndex+1]);

// Frees up the memory allocated to currMessage from last iteration
// before assigning new memory.
free(currMessage);
currMessage = malloc((msgSize - trimIndex) * sizeof(char));
for(int i=0; i < msgSize - trimIndex; i++)
{
  currMessage[i] = trimMessage[i];
}

編集 2: メモリ リークの修正を実装しました。プログラムは今ではかなりうまく機能し、私はかなりばかげていると感じています。

4

1 に答える 1

1

組み込み環境で動的メモリ割り当てを使用する場合は、特にメモリに制約がある場合は注意が必要です。残された最大のホールが 972 バイトになるように、メモリ空間を非常に簡単に断片化してしまう可能性があります。

ヒープから割り当てる必要がある場合は、一度割り当ててから、静的バッファーとほぼ同じようにメモリにハングアップします。可能であれば、静的バッファを使用し、割り当てをまとめて回避してください。動的割り当てが必要な場合は、固定サイズのブロックに保つと断片化に役立ちます。

残念ながら、フラグメンテーションの問題を克服するには、多少のエンジニアリング作業が必要です。努力する価値はありますが、システムをより堅牢にします。

SRAM と SDRAM は同じではありません。私は threadX に精通しておらず、ボードにボード サポート パッケージ (BSP) があるかどうかもわかりませんが、一般的には SDRAM をセットアップする必要があります。つまり、ブート コードはメモリ コントローラーを初期化し、タイミングを設定してから、そのスペースを有効にする必要があります。ヒープの実装によっては、ヒープを動的に追加する必要があるか、またはヒープ空間が最終的に存在する場所 (SDRAM 空間) を指すようにコンパイルする必要があります。次に、実際にヒープを使用する前に、メモリ制御を構成およびアクティブ化する必要があります。

注意すべきもう 1 つのことは、実際には SRAM スペースからコードを実行している可能性があり、そのスペースの一部はプロセッサ例外テーブル用にも予約されています。そのスペース全体が利用できない可能性があり、たとえば、2 つの異なるアドレス (0x00000000 と 0x10000000) に存在する可能性があります。他の ARM9 プロセッサでは、これが一般的です。最初に 0x00000000 スペースにマップされるフラッシュからブートできます。次に、ブーターを SRAM にコピーし、SRAM をそのスペースにマップするために歌と踊りを行います。その時点で、Linux のようなものを起動できます。Linux は、0 で稼働しているテーブルを更新できることを期待しています。

ところで、投稿したコードにメモリリークがあるようです。つまり、 currentMessage は決して解放されません...新しいポインターで上書きされるだけです。これらのブロックは永久に失われます。

于 2012-08-31T09:31:24.560 に答える