メモリ使用量
概要
このセクションでは、TouchGFXアプリケーションのメモリ使用量について説明します。 一般的なTouchGFXアプリケーションは4タイプのメモリを使用しますが、これは使用するハードウェアによって異なります。
| メモリ・タイプ | 使用法 | 
|---|---|
| 内部RAM | 内部RAMは、すべてのウィジェットの座標や色などの設定データに使用されます。 ここには現在のスクリーンのいくつかのオブジェクトが割り当てられます。 UIタスクの実行時スタックを含む、オペレーティング・システムのメモリも内部RAMにあります。 ファイルシステムやディスプレイ・ドライバなど、他のソフトウェア・コンポーネントのデータもすべて内部RAMに配置されます。 | 
| 内部Flash | 内部Flashは、アプリケーション、TouchGFXライブラリ、使用されるその他のライブラリのプログラム・コード用に使用されます。 | 
| 外部RAM | 外部RAMは、通常はフレームバッファ用に使用され、ビットマップ・キャッシュに使用されることもあります。 | 
| 外部Flash | 外部Flashは、画像、フォント、テキストの保存に使用されます。 | 
静的なメモリ割り当て
TouchGFXでは静的なメモリ割り当てのみを使用できます。 つまり、すべてのメモリは事前に割り当て済みであるということです。 TouchGFXによって実行時に割り当てられるメモリはありません。 このため、開始時にアプリケーションがメモリのサイズに適合していれば、メモリ不足に陥ることはありません。
スクリーンとウィジェット
TouchGFXのユーザ・インタフェースは、多数のC++クラスを開発することで作成されます。 クラスは、スクリーンの設計時にTouchGFX Designerによって作成されます。 TouchGFX Designerでスクリーンを設計するたびに、ユーザには多数のクラス(MVPアーキテクチャ)が自動的にもたらされます。 ディスプレイ上にスクリーンを表示すると、TouchGFXによってクラスのオブジェクトが内部RAMに自動的に割り当てられます。
スクリーンから別のスクリーンに変更すると、前のスクリーンに割り当てられていたオブジェクトは使用されなくなり、新しいスクリーンのオブジェクトのみが使用されます。 したがって、新しいオブジェクトは、前のオブジェクトが割り当てられていた内部RAMの場所に割り当てられます(前のオブジェクトが上書きされます)。 内部RAMは一度に1つのスクリーンのオブジェクトのみを保持します。
定義されたクラスに基づいて、C++コンパイラは最も大きいスクリーンのクラスのサイズを計算し、それらのクラス用にメモリを予約します。
つまり、内部RAMのメモリ使用量は、アプリケーション内のスクリーンの数によって決まるのではなく、最も大きいスクリーンのサイズによって決まります。
これらのオブジェクト用に確保されるメモリは、FrontendHeapと呼ばれます。
TouchGFX
アプリケーション・コード
アプリケーション・コードは通常は内部Flash内に配置されます。 アプリケーション・コードは、ユーザ記述のコード、TouchGFX Designerによって生成されるコード、TouchGFXライブラリやユーザが使用する他のライブラリからのコードで構成されます。
ユーザが多くのコードを記述し、アプリケーションに多くのスクリーンを追加すれば、当然ながらアプリケーション・コードの量も増大します。 ライブラリから取得されるコードの量は、機能を最初に使用する時点で増大します。 たとえば、最初にあるButtonをスクリーンに追加すると、TouchGFXライブラリのButtonコードがアプリケーションに含められ、コード量が増大します。 2回目にButtonを同じ(または別の)スクリーンに追加するときには、TouchGFXライブラリから追加のコードは取得されないので、アプリケーションのコード量は、ユーザが記述したコード分かTouchGFX Designerによって生成された分しか増大しません。
アセット
画像、テキスト、フォントなどのアセットは、c++ファイルに変換され、アプリケーションにリンクされます。 アセットのデータは、通常は外部Flashに配置されますが、内部Flashにも配置されることがあります。 これはリンカ・スクリプトで指定します。
画像を追加すると、画像のサイズに比例してアプリケーションのサイズが増大します。
テキストを追加すると、テキストの1文字につき2バイトずつアプリケーションが増大します。 同じ文字列を2回使用する場合、含められるのは1回だけです。
アプリケーションで使用される文字のみが、フォント・ファイルから取得されます。 つまり、アプリケーションで大文字のAからZのみを使用する場合、小文字のaからzのフォントはアプリケーションに含められません。 これらの小文字を使用するテキストを後で追加した場合、アプリケーションのフォント・データのサイズが増大します。
Flash内の文字のサイズは、選択されたフォント・サイズによって異なります。 フォント・サイズを増やすと、アプリケーションのサイズも増えます。
メモリ使用量のチェック
特定のアプリケーションのメモリ使用量は、リンカによって生成されるマップ・ファイルを調べるとわかります。
ここでは、IAR Embedded Workbenchによって生成されたマップ・ファイルを調べてみます。 他のコンパイラでも同じようなマップ・ファイルが生成されます。
最初に、TouchGFX Designerで、STM32F746Discovery評価キット用の空のプロジェクトを作成します。
このプロジェクトをIARで開いた後、IARによって.MAPファイルが生成されたことをプロパティで確認します。
IARでのコンパイル後、リンカ・マップ・ファイルSTM32F746G_DISCO.mapが、EWARM/STM32F746G_DISCO/Listフォルダ内にあることを確認できます。
IARのリンカ・マップ・ファイルには、わかりやすいサマリが含まれています。 MODULE SUMMARYを見てみましょう。
*******************************************************************************
*** MODULE SUMMARY
***
    Module                                   ro code  ro data  rw data
    ------                                   -------  -------  -------
command line/config:
    ------------------------------------------------------------------
    Total:
C:\TouchGFXProjectsDocumentation\STM32F746MemoryUsage\EWARM\STM32F746G_DISCO\Obj: [1]
    ApplicationFontProvider.o                              20
    BitmapDatabase.o                              12       40
    Blue_Buttons_Round_Edge_small.o                    40'800
    Blue_Buttons_Round_Edge_small_pressed.o            40'800
    Font_verdana_10_4bpp_0.o                               24
    Font_verdana_20_4bpp_0.o                               72
    Font_verdana_40_4bpp_0.o                              280
    FrontendApplication.o                         46       60
    FrontendApplicationBase.o                    706      816
    GeneratedFont.o                               84       84
    Kerning_verdana_10_4bpp.o                               4
    Kerning_verdana_20_4bpp.o                               4
    Kerning_verdana_40_4bpp.o                               4
    Model.o                                       10
    OSWrappers.o                                 156        1        9
    STM32DMA.o                                   898      176
    STM32TouchController.o                       162       24        4
...
    heap_4.o                                     444            32'792
...
touchgfx_core.a: [7]
    AbstractButton.o                             136
    AbstractPartition.o                            8
    Application.o                              2'218      290       28
    Bitmap.o                                   1'064      604       36
    Box.o                                        108      104
    Button.o                                     276      308
    ConstFont.o                                   62
    Container.o                                  510      396
    DMA.o                                        558      252
    DisplayTransformation.o                      192
    Drawable.o                                   418
    FontManager.o                                 12                 4
    Gestures.o                                   364       60
    HAL.o                                      1'758      544       18
    LCD24bpp.o                                 2'732    1'604       80
    Screen.o                                   1'924      124
    TouchCalibration.o                           252                76
    TypedText.o                                                     14
    ------------------------------------------------------------------
    Total:                                    12'728    4'286      256
    Gaps                                                    4        3
    Linker created                                         36    2'560
----------------------------------------------------------------------
    Grand Total:                              38'676   88'973   42'731
このテーブルには3列の数値があります。 ro codeとro dataは読取り専用で、Flash内に配置されています。 rw dataは非定数の読み書き変数で、RAMに配置されています。
テーブル内の行は、7ブロックに分割されています。 最初のブロックはプロジェクト内のすべての.cppファイルです。 次の6ブロックは、プロジェクトで使用されるライブラリです(.aファイル)。 最後の1つがTouchGFXライブラリです。
上記からは、TouchGFXライブラリ("touchgfx_core.a: [7]"セクション)によって12,728バイトのコード(および4,286バイトの定数データ)がアプリケーションに追加されていることがわかります。
内部RAM
内部RAMの合計使用量を見つけるには、Module Summaryテーブルの一番下のGrand Total行を確認します。 3つ目の列が内部RAMです。 つまり、このプロジェクトでは42,731バイトの内部RAMが使用されています。 TouchGFXライブラリの合計を見ると、TouchGFXライブラリ[7]によって使用されているのは256バイトであることがわかります。 32,792バイトが heap_4.oによって使用されています。 これはFREERTOS用のダイナミック・メモリ・ヒープです。 32 KBがデフォルト値ですが、このヒープ・サイズはSTM32CubeMXで設定可能です。 通常のTouchGFXプログラムでは、主にユーザ・インタフェース・タスク用のスタックを割り当てるために、このヒープから数Kbを使用します。
FrontendHeapを検索すると、スクリーン・オブジェクトのサイズを見つけることができます。
FrontendHeap::getInstance()::instance
                        0x2000'95d0   0x240  Data  Gb  TouchGFXConfiguration.o [1]
ユーザ・インタフェースに必要なオブジェクトが、0x240バイト= 576バイトを占めています。
内部Flash
Grand Total列から、このアプリケーションが38,676バイトのコードと88,973バイトのデータを使用していることがわかります。 このうち内部Flashは一部のみです。 少なくともButtonの2つの画像は外部Flashにあります。
内部Flashに収められるコードとデータの量を確認するため、最初にPLACEMENT SUMMARYをチェックしてみます(いくつかの詳細部分は削除してあります)。
*******************************************************************************
*** PLACEMENT SUMMARY
***
"A0":  place at address 0x800'0000 { ro section .intvec };
"P1":  place in [from 0x800'0000 to 0x80f'ffff] { ro };
"P2":  place in [from 0x2000'0000 to 0x2004'ffff] { rw };
"P3":  place in [from 0x9000'0000 to 0x90ff'ffff] {
          section ExtFlashSection, section FontFlashSection,
          section TextFlashSection };
内部Flashは、アドレス0x08000000から始まる部分です。 "A0"と"P1"という2つの領域に対応します。
マップ・ファイルを少し詳しく見てみると、これらの領域に何が配置されているのかわかります。
  Section                Kind         Address      Size  Object
  -------                ----         -------      ----  ------
"A0":                                             0x1c8
  .intvec                ro code   0x800'0000     0x1c8  startup_stm32f746xx.o [1]
                                 - 0x800'01c8     0x1c8
"P1":                                             0xb05d
  .text                   ro code   0x800'01c8     0x9b8  main.o [1]
  .text                   ro code   0x800'0b80      0x14  memset.o [5]
...
  .text                   ro code   0x800'b17a       0x2  AbstractButton.o [7]
  .rodata                 const     0x800'b17c       0x1  unwind_debug.o [6]
  .rodata                 const     0x800'b17d       0x0  zero_init3.o [5]
  .rodata                 const     0x800'b17d       0x0  lz77_init_single.o [5]
  Initializer bytes       const     0x800'b17d      0xa8  <for P2-1>
                                  - 0x800'b225    0xb05d
ここには、0x1c8バイト= 456バイトが"A0"によって使用され、0xb05dバイト= 45,149バイトが"P1"によって使用されていることが示されています。 したがって、内部Flashの合計使用量は45,605バイトになります。
外部Flash
外部Flashは、"P3"領域(アドレス0x90000000から開始)です。 この領域のコンテンツは以下のとおりです。
"P3":                                          0x1'4076
  ExtFlashSection        const    0x9000'0000    0x9f60  Blue_Buttons_Round_Edge_small.o [1]
  ExtFlashSection        const    0x9000'9f60    0x9f60  Blue_Buttons_Round_Edge_small_pressed.o [1]
  FontFlashSection       const    0x9001'3ec0     0x118  Font_verdana_40_4bpp_0.o [1]
  FontFlashSection       const    0x9001'3fd8      0x48  Font_verdana_20_4bpp_0.o [1]
  FontFlashSection       const    0x9001'4020      0x18  Font_verdana_10_4bpp_0.o [1]
  FontFlashSection       const    0x9001'4038      0x10  Table_verdana_10_4bpp.o [1]
  FontFlashSection       const    0x9001'4048      0x10  Table_verdana_20_4bpp.o [1]
  FontFlashSection       const    0x9001'4058      0x10  Table_verdana_40_4bpp.o [1]
  FontFlashSection       const    0x9001'4068       0x4  Kerning_verdana_10_4bpp.o [1]
  FontFlashSection       const    0x9001'406c       0x4  Kerning_verdana_20_4bpp.o [1]
  FontFlashSection       const    0x9001'4070       0x4  Kerning_verdana_40_4bpp.o [1]
  TextFlashSection       const    0x9001'4074       0x2  Texts.o [1]
                                - 0x9001'4076  0x1'4076
外部Flashの合計使用量は、0x14076バイト= 82,038バイトであることがわかります。 この大部分は、Buttonの2つの画像によって使用されています(0x9f60バイトの2倍= 40,800バイト)。 残りのデータは3つのフォント用です。 この例には'?'という文字しか含まれていないので、さほど多くのスペースを使用していません。この例ではテキストを使用していないからです。
サマリ
外部RAMに配置されるのはフレームバッファのみです。 これらはアプリケーション内で変数として定義されていないので、リンカ・スクリプトで見つけることはできません。 解像度は、480x272ピクセル、24ビットです。 ここでは2つのフレームバッファがあるので、合計使用量は480 x 272 x 3 x 2 = 786,360バイトです。
| メモリ・タイプ | 使用法 | 
|---|---|
| 内部RAM | 42,731バイト | 
| TouchGFXスクリーンのオブジェクト | 576バイト | 
| 内部Flash | 45,605バイト | 
| TouchGFXフレームワーク | 12,728バイトのコード | 
| 外部RAM | 786,360バイト | 
| 外部Flash | 82,028バイト | 
デモ1
別の例として、ここではTouchGFX Designerに含まれている、TouchGFXデモ1の数値を示します。 ここには5つのスクリーンと、100を超える画像が格納されています。
サマリ
| メモリ・タイプ | 使用法 | 
|---|---|
| 内部RAM | 51,387バイト | 
| TouchGFXスクリーンのオブジェクト | 10,772バイト | 
| 内部Flash | 187,768バイト | 
| TouchGFXフレームワークのコード | 85,174バイトのコード | 
| 外部RAM | 786,360バイト | 
| 外部Flash | 5,281,812バイト | 


