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
© Copyright 2024 ExpyDoc