オペレーティング システムのソース コードをカスタマイズする方法 - FreeRTOS のメモリ管理モジュールを ARMV8 ベアチップに移植する

オペレーティング システムのソース コードをトリミングする方法

この記事の要件シナリオは、標準ライブラリが実装されていないプロセッサ IP のメモリ管理モジュールを移植すること、つまり、ベアチップの C 標準ライブラリにmalloc()および関数を展開することです。free()

具体的な方法は、オペレーティング システムのメモリ管理コンポーネントから必要なソース コードを切り出し、ターゲット プロセッサの開発環境 (SDK/IDE/CMAKE プロジェクトのサブディレクトリ) に適合させることです。

1 要件の決定 - メモリ管理/ヒープ管理を理解する

1.1 C 標準ライブラリのメモリ管理スキーム

C 標準ライブラリは、C プログラムでの動的なメモリ割り当ておよび解放操作のための一連のメモリ管理関数を提供します。これらの関数には主に、malloc、calloc、realloc、free が含まれます。

malloc 関数: malloc 関数は、指定されたサイズのメモリ ブロックを割り当て、メモリ ブロックへのポインタを返すために使用されます。その関数プロトタイプは次のとおりです。

void* malloc(size_t size);

割り当てられるメモリ空間のサイズ (バイト単位) を示すパラメータ サイズを受け入れます。malloc 関数は、ヒープ メモリ内に連続したメモリ ブロックを割り当て、メモリ ブロックの開始アドレスへのポインタを返します。

calloc 関数: calloc 関数は、指定された数とサイズのメモリ ブロックを割り当てるためにも使用され、メモリ ブロックへのポインタを返します。malloc とは異なり、calloc は割り当てられたメモリ ブロック内のすべてのバイトを 0 に初期化します。その関数プロトタイプは次のとおりです。

void* calloc(size_t num, size_t size);

num パラメータは割り当てる必要がある要素の数を示し、size パラメータは各要素のサイズ (バイト単位) を示します。calloc 関数は、ヒープ メモリ内にサイズ num * size のメモリ ブロックを割り当て、メモリ ブロックの開始アドレスへのポインタを返します。

realloc 関数: realloc 関数は、以前に割り当てられたメモリ ブロックのサイズを変更するために使用されます。その関数プロトタイプは次のとおりです。

void* realloc(void* ptr, size_t size);

ptr パラメータは、malloc または calloc によって以前に割り当てられたメモリ ブロックへのポインタで、size パラメータは調整する必要があるサイズ (バイト単位) を示します。realloc 関数は、新しいサイズに従ってメモリ ブロックを再割り当てし、再割り当てされたメモリ ブロックの開始アドレスへのポインタを返します。メモリブロックを再割り当てできない場合、realloc関数は新しいメモリブロックを作成し、元のメモリブロックのデータを新しいメモリブロックにコピーすることができる。

free 関数: free 関数は、malloc、calloc、または realloc 関数によって以前に割り当てられたメモリ ブロックを解放するために使用されます。その関数プロトタイプは次のとおりです。

void free(void* ptr);

ptr パラメータは、以前に割り当てられたメモリ ブロックへのポインタです。free 関数を呼び出すと、メモリ ブロックは空きとしてマークされ、他のメモリ ニーズに再度割り当てることができます。

1.2 需要の調整

ベア チップ プログラムはメモリ リソースによって制限されており、一般に静的割り当て方法を使用して設計されています。一部の周辺ドライバを移植する場合は、基本的な動的メモリ管理方法のみを提供する必要があり、事前に割り当てられた新しい動的メモリはほとんど必要ありません。したがってrealloc、 およびcalloc関数を省略できるため、タスクの負荷は半分に軽減されます。

2 ホイールを見つけます - オペレーティング システムから学びます

オペレーティング システムはハードウェアを抽象化したものです。ベア チップの要件のほとんどは、オペレーティング システムのソース コードに記載されています。では、なぜ車輪を再発明して、オペレーティング システムの羊毛をつかみ取る必要があるのでしょうか。

2.1 FreeRTOS のメモリ管理スキーム

FreeRTOS は、いくつかのヒープ管理スキームを提供します。これらのスキームの複雑さと機能は異なり、さまざまな需要シナリオに適しています。詳細については、次の図を参照してください。
ここに画像の説明を挿入
要約すると、FreeRTOS はソース コード ディレクトリ Source/Portable/MemMang にメモリ管理モジュールの 5 つのオプション実装を提供します。

  • heap_1: ミニマリストバージョン、メモリ解放をサポートしていません (空き機能はありません)
  • heap_2: 解放をサポートしますが、解放されたメモリ ブロックをマージしません
  • heap_3: スレッドセーフな malloc および free 関数をサポートします。
  • heap_4: メモリの断片化を避けるために、解放されたメモリ ブロックをマージします。
  • heap_5: 4 に基づいて複数のメモリ ブロックにわたる割り当てをサポートします。

ここでは、必要に応じて選択しますが、基本的な機能が包括的で十分にシンプルであるため、この記事では heap_2 移植を選択します。

2.2 ソースコードをプルする

以下に示すように、ソース ツリーで Source/Portable/MemMang/heap2.c を見つけます。これを開くと、割り当て関数と解放関数が範囲内にあり、それぞれ名前が付けられ、プロジェクトに追加されていることがわかります。次に、このソース ファイルの依存関係を詳しく見て、ソース ツリーから依存関係を抽出します
ここに画像の説明を挿入
メモリ管理モジュールがオペレーティング システムから削除されます。pvPortMallocvPortFree

2.3 依存関係の削除

heap_2.c には、FreeRTOS.h と task.h という 2 つの FreeRTOS 関連のヘッダー ファイルが含まれています。後者はタスク スケジューラに関連するステートメントであり、明らかに必要ありません。直接削除してください。FreeRTOS は一部の設定項目をマクロ定義したものですが、メモリ管理に関係する部分を切り取っており、FreeRTOS.h ファイル全体を保持する必要はありません。

ここに画像の説明を挿入

次に、マネージド メモリ領域のサイズをメモリ アライメント要件を満たすようにするために使用されるマクロ定義があります。

/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

configTOTAL_HEAP_SIZE と portBYTE_ALIGNMENT の両方で、heap_2.c を手動で #define し
ここに画像の説明を挿入
、マクロ定義を使用する必要がありますportBYTE_ALIGNMENT_MASK
ここに画像の説明を挿入
元々は FreeRTOS.h にありましたが、それを portmacro.h に追加しました。
ここに画像の説明を挿入
残りはいくつかの基本的な型の置換であり、それらを portmacro に置きました。 h ファイル: projdefs.h も必要で、その中にのマクロが
ここに画像の説明を挿入
あります。truefalse
ここに画像の説明を挿入

2.4 利用可能なソースコード

Github リポジトリ: memManPort

3つのテスト

移植結果の有用性をテストするには、次のデモを使用できます。pb と pc の値が一致している限り、基本的には正しいです。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_33904382/article/details/132130018