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

メモリ使用量

概要

このセクションでは、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ライブラリです。

We can see that the TouchGFX library (the "touchgfx_core.a: [7]" section) adds 12,728 bytes of code to the application (and 4,286 bytes of constant data).

内部RAM

内部RAMの合計使用量を見つけるには、Module Summaryテーブルの一番下のGrand Total行を確認します。 3つ目の列が内部RAMです。 This means that the project uses 42,731 bytes of internal RAM. TouchGFXライブラリの合計を見ると、TouchGFXライブラリ[7]によって使用されているのは256バイトであることがわかります。 32,792 bytes are used by heap_4.o. これはFREERTOS用のダイナミック・メモリ・ヒープです。 32 KBがデフォルト値ですが、このヒープ・サイズはSTM32CubeMXで設定可能です。 通常のTouchGFXプログラムでは、主にユーザ・インタフェース・タスク用のスタックを割り当てるために、このヒープから数Kbを使用します。

FrontendHeapを検索すると、スクリーン・オブジェクトのサイズを見つけることができます。

FrontendHeap::getInstance()::instance
0x2000'95d0 0x240 Data Gb TouchGFXConfiguration.o [1]

ユーザ・インタフェースに必要なオブジェクトが、0x240バイト= 576バイトを占めています。

内部Flash

We see from the Grand Total row that this application uses 38,676 bytes code + 88,973 bytes data. このうち内部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

This means that 0x1c8 bytes = 456 bytes are used by "A0", and 0xb05d bytes = 45,149 bytes by "P1". The total usage of the internal flash is thus 45,605 bytes.

外部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

We see that the total usage of the external flash is 0x14076 bytes = 82,038 bytes. The majority of that is used by the two images for the Button (two times 0x9f60 bytes = 40,800 bytes). 残りのデータは3つのフォント用です。 この例には'?'という文字しか含まれていないので、さほど多くのスペースを使用していません。この例ではテキストを使用していないからです。

サマリ

外部RAMに配置されるのはフレームバッファのみです。 これらはアプリケーション内で変数として定義されていないので、リンカ・スクリプトで見つけることはできません。 解像度は、480x272ピクセル、24ビットです。 We have two framebuffers to the total usage is 480 * 272 * 3 * 2 = 786,360 bytes.

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

デモ1

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

STM32F746デモ1

サマリ

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