メイン・コンテンツまでスキップ

メモリ使用量

概要

このセクションでは、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評価キット用の空のプロジェクトを作成します。

BoxとButtonを含むSTM32F746プロジェクト

このプロジェクトを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バイトです。

メモリ・タイプ使用法
内部RAM42,731バイト
TouchGFXスクリーンのオブジェクト576バイト
内部Flash45,605バイト
TouchGFXフレームワーク12,728バイトのコード
外部RAM786,360バイト
外部Flash82,028バイト

デモ1

別の例として、ここではTouchGFX Designerに含まれている、TouchGFXデモ1の数値を示します。 ここには5つのスクリーンと、100を超える画像が格納されています。

STM32F746デモ1

サマリ

メモリ・タイプ使用法
内部RAM51,387バイト
TouchGFXスクリーンのオブジェクト10,772バイト
内部Flash187,768バイト
TouchGFXフレームワークのコード85,174バイトのコード
外部RAM786,360バイト
外部Flash5,281,812バイト