Cortex-M7の性能を引き出す ソフトウェア開発

Cortex-M7の性能を引き出す
ソフトウェア開発
April 2015
IAR Systems K.K.
FAE Team
本ドキュメントについて
⽬的
 Cortex-M7は従来のマイコンよりも性能が⼤幅に向上されている。特徴を理
解し、ARM⽤統合開発環境、ARM⽤IAR Embedded Workbench
(EWARM)を⽤いて、性能を引き出すテクニックを習得する。
内容
 Cortex-M市場とCortex-M7の登場
 Cortex-M7の性能を引き出す開発環境
 ここが新しい! Cortex-M7
 M7の性能・機能を引き出すためのEWARM活⽤テクニック
 MPUを理解し、使いこなす
 TCMを理解し、使いこなす
 キャッシュを理解し、使いこなす
 STM32F7のFLASH ARTアクセラレータ
 Appendix MPU/Cache関連レジスタ
※本ドキュメントは、2015年4⽉現在のIARシステムズWebサイトおよびEWARMバー
ジョン7.40.2を元に作成しています。
2
IAR SYSTEMS— A LEADING GLOBAL VENDOR
168 Employees with HQ in Uppsala, Sweden
Listed in Stockholm/Nasdaq
R&D investment 32% of revenue
32 years in the industry
24 hour technical support in
13 languages
Uppsala
Munich
Sao Paulo
Tokyo
Seoul
Shanghai
London
Paris
San Francisco
Dallas
Boston
Los Angeles
+Distributor representation in
43 countries
Stability and growth
Licenses
# (000’s)
2010 - 2013
Operating
Margin %
20
20
15
15
10
10
5
5
0
0
2010
2011
License #
2012
2013
Operating Margin
Cortex-M市場とCortex-M7の登場
2015年 超⾼性能マイコンCortex-M7登場
従来MPUでしか対応できなかった性能をマイコンで実現!
1GHz
MMU、外部メモリ
開発難易度⾼い・・
Cortex-A
600MHz
CortexM7
400MHz
DOLBY
SURROUND 7.1 ch
200MHz
100MHz
50MHz
CortexM0 /
M0+
CortexM3/M4
簡単・超⾼性能!
DOLBY
DIGITAL 2.1 ch
5
Cortex-M7のベンチマーク性能実績
1MHz当たりの処理能⼒はシングルコアマイコンとして世界最速(2015年4⽉現在)
マルチコアMPU
Cortex-M7
http://www.eembc.org/coremark/index.php 2015年1⽉31⽇
EEMBC.org Webサイトより抜粋
クロック⾼速化と合わせて、超⾼性能マイコンの誕⽣!
6
おさらい、Cortex-Mマイコンの普及
Cortex-Mマイコンは、この数年で世界中の幅広い分野で普及
オーディオ
ゲーム機
カメラ
医療
無線
家電
産業
⾞載
43.2億
31.2億
Cortex-M
MCU出荷個数
19.1億
•
•
•
10.3億
2011
2012
2013
ラインナップ充実
エコシステム充実
ソフト資産充実
2014
http://ir.arm.com/phoenix.zhtml?c=197211&p=irol-reportsannual 2015年4⽉1⽇
ARM Webサイトより抜粋
7
Cortex-M7の性能を引き出す開発環境
IARシステムズとは?
⾃社コンパイラを持つ、組込み開発環境の専⾨メーカ
本社がスウェーデン
グローバルに展開
メーカによる営業・技術サポート
従業員
170+ ローカルオフィス 12拠点
GUI・マニュアル⽇本語
 世界初の商⽤組込C⾔語コンパイラメーカー
 世界40ヵ国以上で販売。のべ10万ライセンスの販売実績
9
IARの開発環境Embedded Workbench
ビルド機能とデバッグ機能を兼ね備えた統合開発環境
プロジェクト設定
STM8
8051
8 bit
MSP430
16 bit
コーディング
ビルド
ARM11
Cortex-A
ARM9
Cortex-R
ARM7
Cortex-M
デバッグ
トレース
解析
Embedded Workbench for ARM
= EWARM
32 bit
10
Cortex-M7開発環境としてのEWARM
ハイパフォーマンスマイコンCortex-M7の性能を引き出すには
優れたコンパイラが不可⽋
Cortex-M7
IAR EWARM
http://www.eembc.org/coremark/index.php 2015年1⽉31⽇
EEMBC.org Webサイトより抜粋
業界標準のベンチマークCoremarkで最⾼速度として採⽤されているのは、
Cortex-M7も含め、IARシステムズのEWARM!
11
ここが新しい!
Cortex-M7
Cortex-M4とCortex-M7の仕様差分
Cortex-M4とCortex-M7の仕様差分
Cortex-M4
命令セット
Cortex-M7
Thumb2
Thumb2
Single cycle 16/32-bit MAC
Single cycle dual 16-bit MAC
8/16-bit SIMD arithmetic
Hardware Divide (2-12 Cycles)
Single cycle 16/32-bit MAC
Single cycle dual 16-bit MAC
8/16-bit SIMD arithmetic
Hardware Divide (2-12 Cycles)
単精度浮動⼩数点ユニット
単精度/倍精度浮動⼩数点ユニット
3段+投機的分岐
6段スーパースカラ + 分岐予測
性能効率
3.40 CoreMark/MHz
5.04 CoreMark/MHz
性能効率
1.25〜1.52 DMIPS/MHz
2.14 / 2.55 / 3.23 DMIPS/MHz
命令キャッシュ
-
0〜64kB、2ウェイ
データ キャッシュ
-
0〜64kB、4ウェイ
命令TCM
-
0〜16MB
データTCM
-
0〜16MB
メモリ保護
オプションの8領域MPU
オプションの8または16領域MPU
DSP拡張機能
浮動⼩数点ユニット
パイプライン
http://www.arm.com/ja/products/processors/cortex-m/cortex-m4-processor.php
http://www.arm.com/ja/products/processors/cortex-m/cortex-m7-processor.php 2015年4⽉1⽇ ARM Webサイトより抜粋
13
ソフトウェア開発から⾒た
Cortex-M4とCortex-M7の差分
M4
M7
3段パイプライン
6段パイプライン
シングル実⾏
デュアル実⾏
DSP
DSP(命令追加)
*FPU
*FPU / 倍精度FPU
*MPU
メモリ保護(信頼性)
メモリアクセス遅延解消
メモリアクセス遅延解消
同じコードでもM4と
⽐べて⾼速演算
(約1.5倍〜2倍)
基本性能向上
*MPU
TCM(密結合メモリ)
L1キャッシュ
その他(ECCなど)
M7⽤のソフト開発時に
気をつけるところは3点!
*はオプション
14
Cortex-M7 ベンチマーク結果
処理性能
4.9
5.0
5.0
ITCM/DTCM
ITCM/DTCM
約3.5倍
1.4
コード/データ
キャッシュ
Flash/SRAM
Flash/SRAM
ON
ON
*Coremarkスコア EWARM7.30.1にて実測
15
M7の性能・機能を引き出すための
EWARM活⽤テクニック
今回使うプロジェクト構成(バブルソート)
⽤意されたデータをバブルソートで並び替える
#include "include.h"
#include "core_cm7.h"
void __low_level_init()
{
SCB->VTOR = 0x08000000;
}
void main(void)
{
printf("start¥n¥n");
BubbleSort();
printf("¥nfinish¥n¥n");
}
バブルソート関数を呼ぶだけのmain関数
17
今回使うプロジェクト構成(バブルソート)
#include <stdio.h>
#include <intrinsics.h>
void BubbleSort();
#define NUM_DATA 256 /* Data Number for sort *
extern int original_data[ ];
#define
#define
#define
#define
#define
__CM7_REV
__MPU_PRESENT
__NVIC_PRIO_BITS
__Vendor_SysTickConfig
__FPU_PRESENT
0x0001
1
4
0
1
typedef enum IRQn
{
/****** Cortex-M7 Processor Exceptions Numbers **
NonMaskableInt_IRQn
= -14,
MemoryManagement_IRQn
= -12,
BusFault_IRQn
= -11,
UsageFault_IRQn
= -10,
SVCall_IRQn
= -5,
DebugMonitor_IRQn
= -4,
PendSV_IRQn
= -2,
SysTick_IRQn
= -1
} IRQn_Type;
共通のincludeファイル。⼀部CMSIS⽤の定義あり
18
今回使うプロジェクト構成(バブルソート)
#include "include.h"
void BubbleSort()
{
int work_data[NUM_DATA];
int i, j, temp;
__no_operation();
//copy data to stack
for(i = 0; i < NUM_DATA;i++) {
work_data[i] = original_data[i];
}
__no_operation();
//sort data
for (i = 0; i < (NUM_DATA - 1); i++) {
for (j = (NUM_DATA - 1); j > i; j--) {
if (work_data[j - 1] > work_data[j]) {
temp = work_data[j-1];
work_data[j-1] = work_data[j];
work_data[j]= temp;
}
}
}
__no_operation();
//print the result
for (i = 0; i < NUM_DATA ; i++) {
printf("%d¥n", work_data[i]);
}
__no_operation();
}
バブルソートの本体。データをローカル変数にコピーして並び替え。
19
今回使うプロジェクト構成(バブルソート)
#include "include.h"
int original_data[ ] =
{
179, 255, 105, 74, 42,
235, 177, 252, 155, 241,
249, 78, 52, 73, 226,
35, 214, 137, 93,
5,
248, 229, 212, 170, 14,
87, 224, 173, 147, 41,
158, 118, 30, 58, 96,
32, 51, 99, 84, 76,
112, 163, 69, 209, 111,
22, 40, 251, 98, 49,
193, 186, 131, 61, 104,
160, 101, 145, 134, 33,
12, 67, 232, 236, 107,
166, 250, 25, 56, 227,
223, 57, 45, 20, 218,
71, 95, 156, 89, 48,
};
117,
94,
206,
17,
133,
182,
108,
237,
29,
216,
185,
81,
187,
167,
159,
103,
3,
11,
65,
15,
115,
240,
183,
47,
146,
140,
85,
53,
231,
207,
62,
219,
13,
174,
188,
217,
10,
175,
60,
215,
63,
130,
197,
247,
64,
196,
136,
176,
129,
194,
171,
144,
23,
6,
253,
189,
211,
18,
1,
34,
153,
106,
43,
9,
31,
114,
70,
204,
26,
228,
178,
16,
54,
184,
233,
242,
180,
109,
157,
243,
198,
168,
125,
244,
164,
19,
7,
230,
201,
161,
39,
27,
142,
154,
221,
24,
59,
113,
75,
149,
126,
86,
72,
246,
238,
127,
245,
234,
66,
239,
203,
37,
128,
55,
77,
97,
172,
143,
190,
102,
122,
199,
181,
44,
79,
4,
68,
21,
119,
92,
165,
82,
192,
135,
123,
132,
150,
120,
116,
121,
100,
210,
200,
195,
148,
28,
191,
36,
225,
38,
46,
141,
88,
110,
169,
202,
90,
83,
124,
254,
2,
50,
208,
222,
151,
91,
80,
139,
213,
256,
220,
138,
152,
8,
162,
205
256点のint型(32bit)データ配列。
20
今回使うプロジェクト構成(バブルソート)
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ITCM_RAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCM_RAM_end__
= 0x00003FFF;
define symbol __ICFEDIT_region_FLASH_start__ = 0x08000000;
define symbol __ICFEDIT_region_FLASH_end__
= 0x080FFFFF;
define symbol __ICFEDIT_region_DTCM_start__ = 0x20000000;
define symbol __ICFEDIT_region_DTCM_end__
= 0x2000FFFF;
define symbol __ICFEDIT_region_SRAM1_start__ = 0x20010000;
define symbol __ICFEDIT_region_SRAM1_end__
= 0x2004BFFF;
define symbol __ICFEDIT_region_SRAM2_start__ = 0x2004C000;
define symbol __ICFEDIT_region_SRAM2_end__
= 0x2004FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__
= 0x800;
/**** End of ICF editor section. ###ICF###*/
define
define
define
define
define
define
memory
region
region
region
region
region
mem with size = 4G;
ITCM_RAM_region
=
mem:[from __ICFEDIT_region_ITCM_RAM_start__ to __ICFEDIT_region_ITCM_RAM_end__];
FLASH_region
=
mem:[from __ICFEDIT_region_FLASH_start__ to __ICFEDIT_region_FLASH_end__];
DTCM_region
=
mem:[from __ICFEDIT_region_DTCM_start__ to __ICFEDIT_region_DTCM_end__];
SRAM1_region
=
mem:[from __ICFEDIT_region_SRAM1_start__ to __ICFEDIT_region_SRAM1_end__];
SRAM2_region
=
mem:[from __ICFEDIT_region_SRAM2_start__ to __ICFEDIT_region_SRAM2_end__];
define block CSTACK
define block HEAP
with alignment = 8, size = __ICFEDIT_size_cstack__
with alignment = 8, size = __ICFEDIT_size_heap__
{ };
{ };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place
place
place
place
place
in
in
in
in
in
FLASH_region { readonly };
ITCM_RAM_region { };
DTCM_region { };
SRAM1_region { readwrite, block CSTACK, block HEAP};
SRAM2_region { };
メモリ配置を規定するIARオリジナルのリンカ設定ファイル(.icf)
21
今回使うプロジェクト構成(バブルソート)
オプション設定
(新規プロジェクトからの差分)
[Cortex-M7]
[CMSISを使⽤する]
[$PROJ_DIR$¥m7.txt]
[リンカマップファイルの表⽰]
22
まずは「⾒える化」
Cortex-M7ベンチマークテクニック
並び替えの実処理を計測。
ブレークポイント間のCPUレジスタの変化で測定可能
現在のサイクル数
前回のデバッガ表⽰からの
サイクル増加数
23
まずは「⾒える化」
Cortex-M7ベンチマークテクニック
CYCLECOUNTERが変わらない時は、機能を有効化することで対応可能
CYCLECOUNTERが更新される
Data Watchpoint and Trace unit
DWT_CTRL > CYCNTENAを1に
CPU速度が200MHzのとき、CCSTEPが826,801だったら
経過時間は4.134ms
24
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
M7では、TCM、キャッシュの使い分けが、性能に⼤きく影響
⾃由に配置するには、リンカの基本的な使い⽅を習得する必要がある
0x2004C000 – 0x2004FFFF : 16KB
SRAM2
0x20010000 – 0x2004BFFF : 240KB
SRAM1
0x20000000 – 0x2000FFFF : 64KB
0x08000000 – 0x080FFFFF : 1024KB
データ⽤
DTCM RAM
FLASH
コード⽤
0x00000000 – 0x00003FFF : 16KB
ITCM RAM
25
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
EWARMのリンカ名称はILINK。
ILINKでは4GBのメモリをRegionに分け、最⼩単位のセクションを配置する
Region(メモリ空間)
SRAM2
SRAM1
Block
Section
Section
DTCM RAM
Section
FLASH
ITCM RAM
Section
Section
26
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
リンカ設定ファイルの中⾝を⾒てみる
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ITCM_RAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCM_RAM_end__
= 0x00003FFF;
define symbol __ICFEDIT_region_FLASH_start__ = 0x08000000;
define symbol __ICFEDIT_region_FLASH_end__
= 0x080FFFFF;
define symbol __ICFEDIT_region_DTCM_start__ = 0x20000000;
define symbol __ICFEDIT_region_DTCM_end__
= 0x2000FFFF;
define symbol __ICFEDIT_region_SRAM1_start__ = 0x20010000;
define symbol __ICFEDIT_region_SRAM1_end__
= 0x2004BFFF;
define symbol __ICFEDIT_region_SRAM2_start__ = 0x2004C000;
define symbol __ICFEDIT_region_SRAM2_end__
= 0x2004FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__
= 0x800;
/**** End of ICF editor section. ###ICF###*/
アドレスシンボルの宣⾔
スタック、ヒープブロックサイズの宣⾔
define
define
define
define
define
define
memory
region
region
region
region
region
mem with size = 4G;
ITCM_RAM_region
=
mem:[from __ICFEDIT_region_ITCM_RAM_start__ to __ICFEDIT_region_ITCM_RAM_end__];
FLASH_region
=
mem:[from __ICFEDIT_region_FLASH_start__ to __ICFEDIT_region_FLASH_end__];
DTCM_region
=
mem:[from __ICFEDIT_region_DTCM_start__ to __ICFEDIT_region_DTCM_end__];
SRAM1_region
=
mem:[from __ICFEDIT_region_SRAM1_start__ to __ICFEDIT_region_SRAM1_end__];
SRAM2_region
=
mem:[from __ICFEDIT_region_SRAM2_start__ to __ICFEDIT_region_SRAM2_end__];
define block CSTACK
define block HEAP
with alignment = 8, size = __ICFEDIT_size_cstack__
with alignment = 8, size = __ICFEDIT_size_heap__
initialize by copy { readwrite };
do not initialize { section .noinit };
in
in
in
in
in
スタック、ヒープブロックの定義
{ };
{ };
初期化時のROM>RAM展開指⽰
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place
place
place
place
place
メモリ領域定義
FLASH_region { readonly };
ITCM_RAM_region { };
DTCM_region { };
SRAM1_region { readwrite, block CSTACK, block HEAP};
SRAM2_region { };
ベクタテーブル配置
どのメモリ領域にどの(属性の)セクションを
配置するか指⽰
27
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
ビルド後のメモリ配置状況はmapファイルで確認できる
[リンカマップファイルの表⽰]にチェックを
⼊れてビルド
Output以下にmapファイルが⽣成される
セクションごとの配置アドレスなどが確認可能
28
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
BubbleSort関数をROM⇒RAM展開して実⾏する
#include "include.h"
#pragma location="sram1_func"
void BubbleSort()
{
int work_data[NUM_DATA];
int i, j, temp;
1.配置先セク
ションを指定
__no_operation();
//copy data to stack
for(i = 0; i < NUM_DATA;i++) {
work_data[i] = original_data[i];
}
__no_operation();
//sort data
for (i = 0; i < (NUM_DATA - 1); i++) {
for (j = (NUM_DATA - 1); j > i; j--) {
if (work_data[j - 1] > work_data[j]) {
temp = work_data[j-1];
work_data[j-1] = work_data[j];
work_data[j]= temp;
}
}
}
__no_operation();
//print the result
for (i = 0; i < NUM_DATA ; i++) {
printf("%d¥n", work_data[i]);
}
__no_operation();
3.ROMからコピー展開するセ
クションであることを指定
initialize by copy { readwrite };
initialize by copy { section sram1_func };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly
section .intvec };
place
place
place
place
place
place
in
in
in
in
in
in
FLASH_region { readonly };
ITCM_RAM_region { };
DTCM_region { };
SRAM1_region { readwrite, block CSTACK, block HEAP};
SRAM1_region { section sram1_func};
SRAM2_region { };
m7.icf
2.セクションの配置
Regionを指定
}
sub.c
29
メモリ配置を柔軟に
リンカ使いこなしと確認テクニック
マップファイルとデバッグ実⾏時のアドレスで、RAM実⾏を確認
0x20000000台は、SRAM領域
30
「最適化」でこんなに変わる!
適用テクニック
C⾔語の最適化設定で、各種処理性能は⼤幅に変わる
プロジェクトを右クリック
SRAM上のStatic変数をSRAM
上のスタック(ローカル変
数)にコピー
Code
Static
Stack
スタック上の変数配列を並び
替え
Data Copy (Cycle)
BubbleSort (Cycle)
FLASH
SRAM
SRAM
4,789
1,202,575
FLASH (High-Speed)
SRAM
SRAM
1,046
546,215
最適化 ⾼(速度)
約4.5倍
約2.2倍
「最適化」でこんなに変わる!
適用テクニック
C⾔語の最適化はプロジェクト⼀括でも、ソースコード単位でも指定可能
[継承した設定をオーバライド]にチェックして
コンパイラオプションを上書き
Cファイルを右クリック
32
CMSISファイルを活用して、簡単設定
CMSISとは、ARM社 IARシステムズ社などが共同で作成した標準規格
CMSISファイル群にincludeパスを設定
[CMSISを使⽤する]にチェックを⼊れることでCMSISのIncludeディレクトリに
プリプロセッサのinclude Pathが規定される
33
CMSISファイルを活用して、可搬性を確保
Cortex-Mコアの各種レジスタの定義および、設定関数、マクロが規定
若⼲冗⻑の処理となるが、設定は⼀度のみと考えるとデバイス間の
メンテナンス性などを考慮し、積極的に活⽤すべき
34
Cortex-M7の標準初期化処理
アプリケーション実行までにやるべきこと
初期設定として、実⾏すべきこと
FPU初期化 *オプション
EWARMのランタイムライブラリが実⾏
MPU初期化
プログラムで処理
キャッシュ初期化
プログラムで処理
TCM初期化
データ初期化(ROM > RAMなど)
デフォルトで有効なデバイスが多い
EWARMのランタイムライブラリが実⾏
*カスタマイズも可能
36
MPUを理解し、使いこなす
MPU(メモリ保護ユニット)とは?
領域ごとにアクセス権限などを設定できる機能。キャッシュの設定にも必要
キャッシュ
コード実⾏
ペリフェラル
キャッシュ無効
実⾏不可
外部RAM
キャッシュ有効
実⾏不可
キャッシュ有効
実⾏不可
キャッシュ有効
実効可
内部RAM
コード
不正コード
悪意あるプログラム
DTCM
コードを実⾏させない
ITCM
38
MPUの設定プロセス
アプリケーション設計に合わせて、⼗分に検討を⾏う。
メモリ領域を⽤途・属性でどう区切るか決める
MPU
領域
番号0
MPU
領域
番号1
MPU
領域
番号2
最終
有効
設定
2
1
2
区切った領域の設定順番を決める
1
各領域の詳細設定を決める
0
0
レジスタ値をコーディングする
39
MPUの設定プロセス
MPU関連レジスタをシーケンスに沿って設定する
MPU無効化 (MPU>CTRL)
MPU領域開始アドレス+番号指定(MPU>RBAR)
該当領域の属性+サイズ指定(MPU>RASR)
MPU領域開始アドレス+番号指定(MPU>RBAR)
MPU領域ごとに設定
該当領域の属性+サイズ指定(MPU>RASR)
MPU有効化 (MPU>CTRL)
40
MPU関連レジスタ
重要なのは、下記3レジスタ(M4と共通)。詳細はAppendix参照
MPU有効化
9
8
7
6
5
4
3
2
HFNMIENA
ENABLE
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
PRIVDEFENA
MPU_CTRL: MPU Control Register
1
0
9
8
7
6
5
4
3
2
1
0
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
VALID
MPU_RBAR: MPU Region Base Address Register
開始アドレス
ADDR
REGION
Region番号
MPU_RASR: MPU Region Attribute and Size Register
8
7
6
5
4
3
AP
コード実⾏不可
権限制御
TEX
S
C
B
SRD
キャッシュポリシーなど
SIZE
サブ領域
サイズ
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihjddef.html
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihigffb.html
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihegaib.html 2015年4⽉1⽇ ARM Webサイトより抜粋
2
1
0
ENABLE
9
XN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
有効化
41
MPUの設定コード例
Flash, SRAM, Peripheral, M7 Peripheralの設定例
__DMB();
//Disable MPU
MPU->CTRL = 0x0UL << MPU_CTRL_ENABLE_Pos;
// MPU Setting
// Flash
//MPU->RBAR = 0x08000010;
MPU->RBAR = 0x08000000UL & MPU_RBAR_ADDR_Msk
MPU_RBAR_VALID_Msk
0x0UL & MPU_RBAR_REGION_Msk;
//MPU->RASR = 0x03020027;
MPU->RASR =
0x03UL << MPU_RASR_AP_Pos
MPU_RASR_C_Msk
0x13UL << MPU_RASR_SIZE_Pos
MPU_RASR_ENABLE_Msk;
// SRAM
//MPU->RBAR = 0x20000011;
MPU->RBAR = 0x20000000UL & MPU_RBAR_ADDR_Msk
MPU_RBAR_VALID_Msk
0x1UL & MPU_RBAR_REGION_Msk;
//MPU->RASR = 0x13070023;
MPU->RASR = MPU_RASR_XN_Msk
0x03 << MPU_RASR_AP_Pos
MPU_RASR_S_Msk
MPU_RASR_C_Msk
MPU_RASR_B_Msk
0x11 << MPU_RASR_SIZE_Pos
MPU_RASR_ENABLE_Msk;
;
// Peripheral
//MPU->RBAR = 0x40000012;
MPU->RBAR = 0x40000000UL & MPU_RBAR_ADDR_Msk
MPU_RBAR_VALID_Msk
0x2UL & MPU_RBAR_REGION_Msk;
|
|
|
|
|
|
|
|
|
|
|
|
|
//MPU->RASR = 0x13050039;
MPU->RASR =
MPU_RASR_XN_Msk
0x03 << MPU_RASR_AP_Pos
MPU_RASR_S_Msk
MPU_RASR_B_Msk
0x1C << MPU_RASR_SIZE_Pos
MPU_RASR_ENABLE_Msk;
// M7 Peripheral
//MPU->RBAR = 0xE0000013;
MPU->RBAR = 0xE0000000UL & MPU_RBAR_ADDR_Msk
MPU_RBAR_VALID_Msk
0x3UL & MPU_RBAR_REGION_Msk ;
//MPU->RASR = 0x13050039;
MPU->RASR =
MPU_RASR_XN_Msk
0x03 << MPU_RASR_AP_Pos
MPU_RASR_S_Msk
MPU_RASR_B_Msk
0x1C << MPU_RASR_SIZE_Pos
MPU_RASR_ENABLE_Msk;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Enable MPU
MPU->CTRL = MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
42
MPU違反が発⽣した場合
例外が発⽣し、例外ハンドラにジャンプする
デフォルトだとHardFaultハンドラにジャンプ
メモリマネジメントフォルトを有効にすると
MemManageハンドラにジャンプ
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
問題の発⽣したアドレスが判断できる
43
TCMを理解し、使いこなす
TCM(密結合メモリ)とは?
通常のメモリアクセスよりも⾼速にアクセスできるメモリ
⾼速CPUに対するメモリアクセスボトルネックの解消⼿段として採⽤
CPU早すぎ・・汗
WAIT
WAIT
実⾏
通常メモリ
遠い
実⾏
実⾏
実⾏
♪
TCM
近い
低レイテンシアクセスを確保できる。ただし、容量は⼩さいため
クリティカルな処理・データを配置して、アプリケーションの最適化を⾏う
45
メモリマップ上のTCM領域
コード実⾏⽤のITCMとデータアクセス⽤のDTCMがある。
通常のFlash、SRAM領域とくらべて⼩容量。
また、領域はRAM(揮発性)のため、起動時ロードする必要がある。
0x2004C000 – 0x2004FFFF : 16KB
SRAM2
0x20010000 – 0x2004BFFF : 240KB
SRAM1
0x20000000 – 0x2000FFFF : 64KB
0x08000000 – 0x080FFFFF : 1024KB
データ⽤
DTCM RAM
FLASH
コード⽤
0x00000000 – 0x00003FFF : 16KB
ITCM RAM
46
TCMをリンカ設定で活⽤する
Cソースコードで配置先セクションを、リンカ設定でセクションの配置場所を指定
sub.c
#include "include.h"
#pragma location= "itcm_func"
void BubbleSort()
BubbleSort関数の配置先
{
int work_data[NUM_DATA];
int i, j, temp;
__no_operation();
//copy data to stack
for(i = 0; i < NUM_DATA;i++) {
work_data[i] = original_data[i];
}
__no_operation();
data.c
m7.icf
initialize by copy { readwrite };
initialize by copy { section itcm_func };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__
{ readonly section .intvec };
place in FLASH_region
{ readonly };
place in ITCM_RAM_region
#include "include.h"
place in DTCM_region
#pragma location="dtcm_variable"
int original_data[ ] =
{
original_data配列の配置先
179, 255, 105, 74, 42, 117,
3
place in SRAM1_region
CSTACK, block HEAP};
place in SRAM2_region
{section itcm_func };
{section dtcm_variable };
{ readwrite, block
{ };
47
キャッシュを理解し、使いこなす
キャッシュとは?
動的・⾃動的に最近アクセスしたデータを蓄積し、アクセス⾼速化
WAIT
WAIT
実⾏
実⾏
実⾏
実⾏
通常メモリ
遠い
ラッキー♪
キャッシュに残ってた
キャッシュ
通常メモリ
近い
アプリケーション全体として、アクセススピードは改善される。
ただし、キャッシュヒットするかどうかは、そのときの条件による。
49
キャッシュの設定プロセス
データキャッシュ、命令キャッシュそれぞれにレジスタ設定をする
D-Cacheの無効化(PPB > DCISW)
Cacheラインごとに無効化必要
I-Cacheの無効化(PPB > ICIALLU)
⼀度の処理で無効化
D-Cacheの有効化(CCR)
CCRのビットを⽴てて有効化
I-Cacheの有効化(CCR)
CCRのビットを⽴てて有効化
50
キャッシュの有効化サンプルコード (データ)
CMSISの “core_cm7.h”に、キャッシュ設定関数が⽤意されている。
データキャッシュの有効化関数
__STATIC_INLINE void SCB_EnableDCache(void)
{
#if (__DCACHE_PRESENT == 1)
uint32_t ccsidr, sshift, wshift, sw;
uint32_t sets, ways;
ccsidr
sets
sshift
ways
wshift
=
=
=
=
=
SCB->CCSIDR;
CCSIDR_SETS(ccsidr);
CCSIDR_LSSHIFT(ccsidr) + 4;
CCSIDR_WAYS(ccsidr);
__CLZ(ways) & 0x1f;
__DSB();
do {
// invalidate D-Cache
int32_t tmpways = ways;
do {
sw = ((tmpways << wshift) | (sets << sshift));
SCB->DCISW = sw;
} while(tmpways--);
} while(sets--);
__DSB();
SCB->CCR |=
SCB_CCR_DC_Msk;
// enable D-Cache
__DSB();
__ISB();
#endif
}
51
キャッシュの有効化サンプルコード (命令)
CMSISの “core_cm7.h”に、キャッシュ設定関数が⽤意されている。
命令キャッシュの有効化関数
__STATIC_INLINE void SCB_EnableICache(void)
{
#if (__ICACHE_PRESENT == 1)
__DSB();
__ISB();
SCB->ICIALLU = 0;
// invalidate I-Cache
SCB->CCR |= SCB_CCR_IC_Msk;
// enable I-Cache
__DSB();
__ISB();
#endif
}
命令が確実に設定されるように、メモリバリア命令を適⽤している
52
STM32F7のFLASH ARTアクセラレータ
STM32F7のFLASH ARTアクセラレータ
Flash領域にTCM経由でアクセスができ、ARTを有効にすることで
⾼速アクセスができる
0x2004C000 – 0x2004FFFF : 16KB
SRAM2
0x20010000 – 0x2004BFFF : 240KB
AXIM
TCM
SRAM1
0x20000000 – 0x2000FFFF : 64KB
0x00200000 – 0x002FFFFF : 1024KB
or
0x08000000 – 0x080FFFFF : 1024KB
0x00000000 – 0x00003FFF : 16KB
データ⽤
DTCM RAM
キャッシュ
FLASH
コード⽤
ITCM RAM
54
STM32F7のFLASH ARTアクセラレータ
ARTはレジスタ設定で有効にする
FLASH_ACR:Flash access control register
0x4002-3C00
Type: RW
Reset Value: 0x0000-0000
9
ARTEN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/data_brief/DM00116941.pdf
8
7
6
5
4
3
2
1
0
LATENCY
2015年4⽉1⽇ ST社 Webサイトより抜粋
※TCM経由(0x0020xxxx)から起動するか、AXIM(0x0800xxxx)から起動するかは
BOOT_PINの状態と、OptionByteのBOOT_ADD0/1で決定される。
詳細はSTM32F7xxリファレンスマニュアルを参照
55
STM32F7のFLASH ARTアクセラレータ
ST社提供stm32f7xx_hal_flash.hにART有効/無効関数が含まれている
56
パフォーマンス評価結果
STM32F7の設定差分による性能評価
配置領域、設定により、性能は⼤きく異なる。
Code
Static
Stack
Icache DCache
FLASH
SRAM
SRAM
FLASH
SRAM
SRAM
FLASH
SRAM
SRAM
Yes
FLASH
SRAM
SRAM
Yes
ITCM_FLASH
SRAM
SRAM
ITCM_FLASH
SRAM
SRAM
ITCM_FLASH
SRAM
SRAM
Yes
ITCM_FLASH
SRAM
SRAM
Yes
ITCM_FLASH +ART
SRAM
SRAM
ITCM_FLASH +ART
SRAM
SRAM
ITCM_FLASH +ART
SRAM
SRAM
Yes
ITCM_FLASH +ART
SRAM
SRAM
Yes
ITCM
DTCM
SRAM
ITCM
DTCM
SRAM
ITCM
DTCM
SRAM
Yes
ITCM
DTCM
SRAM
Yes
ITCM
DTCM
DTCM
ITCM
DTCM
DTCM
ITCM
DTCM
DTCM
Yes
ITCM
DTCM
DTCM
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Data Copy (Cycle)
BubbleSort (Cycle)
4,789
1,202,575
7,371
1,341,410
4,779
934,650
1,817
460,829
7,473
1,039,525
4,362
901,197
4,791
1,010,178
5,950
935,851
3,117
934,561
1,803
455,859
3,117
934,576
1,805
460,804
1,579
930,088
1,579
455,937
1,579
929,901
1,579
455,861
1,579
455,979
1,579
455,940
1,579
455,905
1,579
455,858
58
まとめ
まとめ




Cortex-M7の⾼性能を引き出すためには、各種機能、特性を理解し、アプリ
ケーションにあった設計が必要。
⾼性能なコンパイラを持つ開発環境を使⽤する必要がある。
実際には、動作をさせながら評価をしながら、アプリケーションの最適化を
進めていく。
開発環境の提供する各種設定⽅法を理解し、またベンチマークやメモリマッ
プの確認⽅法を習得することで、開発するアプリケーションにあった最適化
を進めることができる。
60
Appendix MPU/Cache関連レジスタ
MPU: MPU Control Register
MPU機能全体の制御レジスタ
Bit
Name
8
7
6
5
4
3
2
1
0
ENABLE
9
HFNMIENA
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
PRIVDEFENA
MPU_CTRL: MPU Control Register
0xE000-ED94
Type: RW
Reset Value: 0x0x0000-0000
説明
2
PRIVDEFENA
0: Default Memory map が無効
1: 特権(Privilege)時に、Default memory mapをBackground Regionとしてアクセス可能
1
HFNMIENA
0: HardFault時やNMI例外時にMPUを無効にする
1: HardFault時やNMI例外時でもMPUを有効にする
0
ENABLE
0: MPUを無効にする
1: MPUを有効にする
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihjddef.html 2015年4⽉1⽇ ARM Webサイトより抜粋
62
MPU: MPU Region Base Address Register
MPU領域の開始アドレスとRegion番号の指定
MPU_RBAR: MPU Region Base Address Register
0xE000-ED9C
Type: RW
Reset Value: Unknown
9
8
7
6
ADDR
Bit
Name
5
4
VALID
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
3
2
1
0
REGION
説明
31:5
ADDR
Regionの開始アドレス(base address)
4
VALID
0: MPU_RNR.REGIONで指定したRegion番号の開始アドレスがADDRで指定される
1: 本レジスタのREGIONで指定したRegion番号の開始アドレスがADDRで指定される。
3:0
REGION
VALIDが1のとき、MPU_RNR.REGIONを上書き。
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihigffb.html 2015年4⽉1⽇ ARM Webサイトより抜粋
63
MPU: MPU Region Attribute and Size Register (1/3)
MPU領域の詳細設定⽤レジスタ
MPU_RASR: MPU Region Attribute and Size Register
0xE000EDA0
Type: RW
Reset Value: Unknown
8
7
6
5
4
3
AP
Bit
28
XN
Name
26:24
21:16
15-8
AP
TEX,S,C,B
SRD
5:1
SIZE
0
ENABLE
TEX
Execution Never
0: 命令コード実⾏可能
1: 命令コード実⾏不可
Access and Privilege
S
C
B
SRD
SIZE
2
1
0
ENABLE
9
XN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
説明
Sub-region Disable
1: Regionを8分割した該当Sub-Regionの設定無効
Bit15: もっとも⾼いアドレス領域
Bit8: もっとも低いアドレス領域
該当Regionのサイズ指定
2の(SIZE+1)乗
最⼩の値は4: 32 Byte
0: 該当Regionは無効
1: MPU有効時、該当Regionは有効
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihegaib.html 2015年4⽉1⽇ ARM Webサイトより抜粋
64
MPU: MPU Region Attribute and Size Register (2/3)
特権/⾮特権時のアクセス制御&領域サイズ指定
8
7
6
5
4
3
AP
AP
000
001
010
011
101
110
111
特権(Privileged)
No Access
Read / Write
Read / Write
Read / Write
Read-Only
Read-Only
Read-Only
TEX
S
⾮特権(Unprivileged)
No access
No access
Read-only
Read/Write
No access
Read-only
Read-only
C
B
SRD
SIZE
SIZE
00100(4)
01001(9)
10011(19)
11101(29)
11111(31)
2
1
0
ENABLE
9
XN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
Region size
32 B
1KB
1MB
1GB
4GB
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihegaib.html 2015年4⽉1⽇ ARM Webサイトより抜粋
65
MPU: MPU Region Attribute and Size Register (3/3)
ビット組み合わせで設定
9
8
7
6
5
4
3
XN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
AP
TEX
000
C
0
B
0
000
000
0
1
1
0
Memory Type
ストロングオーダ
(Strongly-ordered)
デバイス(Device)
ノーマル(Normal)
000
1
1
ノーマル(Normal)
001
001
0
1
0
1
ノーマル(Normal)
ノーマル(Normal)
010
1BB
0
A
0
A
デバイス(Device)
ノーマル(Normal)
TEX
S
C
B
SRD
説明
共有デバイス
ライトスルー(Write-Through)
書込割り当て(Write Allocate)なし
ライトバック(Write-Back)
書込割り当て(Write Allocate)なし
キャッシュなし
ライトバック(Write-Back)
書込・読込割り当て(Write Allocate)あ
り
⾮共有デバイス
キャッシュメモリ
AA:内部ポリシー(Inner Policy)
BB:外部ポリシー(Outer Policy)
SIZE
共有可
2
1
0
ENABLE
キャッシュ、共有、アクセス制御
共有
共有可
S bit
S bit
S bit
S bit
共有不可
S bit
00 : キャッシュなし
01: ライトバック、割り当てあり
10: ライトスルー、割り当てなし
11: ライトバック、割り当てなし
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihegaib.html 2015年4⽉1⽇ ARM Webサイトより抜粋
66
Cache: Data cache invalidate by Set/Way
データキャッシュのSet、Wayを指定して無効化
Way
Bit
31-32-A
31-A: B
B-1:L
L-1:4
3:1
Name
Way
SBZ
Set
SBZ
Level
SBZ
操作するWay数
常に0
操作するSet数
常に0
操作するCache level -1 .
Ex.
0 : L1 cache
L
Set
L-1
B
B-1
31
31-A
32-A
DCISW: Data cache invalidate by Set/Way
0xE000-EF60
Type: WO
Reset Value: Unknown
4
SBZ
3
2
1
0
Level
0
説明
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0489b/DDI0489B_cortex_m7_trm.pdf 2015年4⽉1⽇ ARM Webサイトより抜粋
67
Cache: Instruction cache invalidate All to PoU
Writeアクセスで命令キャッシュを無効化
ICIALLU: Instruction cache invalidate all to PoU (Point of unification)
0xE000-EF50
Type: WO
Reset Value: Unknown
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
9
8
7
6
5
4
3
2
1
0
Ignored
Bit
All
Name
IGNORED
説明
WriteアクセスでInstruction CacheをInvalidate化。
すべてのbitは無視.
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0489b/DDI0489B_cortex_m7_trm.pdf 2015年4⽉1⽇ ARM Webサイトより抜粋
68
Cache: Configuration and Control Register
ビットアサインで命令キャッシュとデータキャッシュを有効化
Bit
18
BP
17
IC
16
DC
Name
5
4
3
DC
2
1
USERSETMPEND
6
UNALIGN_TRP
7
DIV_0_TRP
8
0
NONBASETHRDENA
BP IC
9
BFHFNMIGN
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
STKALIGN
CCR: Configuration and Control Register
0xE000-ED14
Type: RW
Reset Value: 0x00040200
説明
分岐予測(Brance prediction)有効。
M7では常に1
0: Instruction Cache 無効
1: Instruction Cache有効
0: Data Cache 無効
1: Data Cache有効
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0489b/DDI0489B_cortex_m7_trm.pdf 2015年4⽉1⽇ ARM Webサイトより抜粋
69
本資料について
本資料取り扱い上の注意
本資料は2015年4⽉1⽇時点の情報を基に作成されており、将来変更の可能性
のあるものです。あわせてご紹介する設定や機能に関連して、動作保証をお約束す
るものではございませんので、ご了承ください
本資料で提供している情報は、ご利⽤されている⽅のご判断・責任においてご使⽤
ください。提供した情報に関連して、ご利⽤される⽅が不利益等を被る事態が⽣じ
たとしても、弊社及び執筆者は⼀切の責任を負いかねますので、ご了承ください。
本資料の内容に関する弊社または各社へのお問合せはご遠慮ください。
本資料及びデータの再配布・無断転⽤・転載等はご遠慮ください。
71
商標について
• IAR Systems, IAR Embedded Workbench, C-SPY, C-RUN, C-STAT,
visualSTATE, Focus on Your Code, IAR KickStart Kit, I-jet, I-scope, IAR, お
よび IAR Systems のロゴタイプはIAR Systems ABが所有する商標または登録
商標です。
• ARMおよびCortexは、ARM Limited(またはその⼦会社)のEUまたはその他の
国における登録商標です。CoreSightは、ARM Limited(またはその⼦会社)の
EUまたはその他の国における商標です。 All rights reserved.
• STM32は、STマイクロエレクトロニクスの登録商標です。
• その他、本資料中の製品名やサービス名は全てそれぞれの所有者に属する商標ま
たは登録商標です。
72