Arm Cortex-M55搭載 STM32N657でプログラムを作成 (2) セキュアアプリ実行

**※ [更新 2025.4.4] IDE等のバージョンアップに伴い更新しました。**

STM32N657は2024年末にリリースされたArm Cortex-M55コア搭載のSTM32マイコンです。メーカ純正の開発ボード STM32N6570-DK (Discovery kit) を使用してみたところ、最初からTrustZoneが有効となっており、これまでのSTM32のプログラム開発と少し違いがったので記事としてまとめておきます。
執筆時点で実際に試した内容ですが、新しいマイコンなのでこれから変わる可能性もあるので注意してください。記事は随時更新する予定ですので変更点は履歴を確認してください。

前回はFSBL(First Stage Boot Loader)から簡単なアプリケーションをデバッグ実行するまでを記載しました。

[第1回目 1st ステージ・ブートローダ](https://qiita.com/y_toyoyama/items/11bf98131713592106ae)

今回はFSBLからセキュアアプリケーション(以降セキュアアプリ)を実行するプロジェクトを作成します。


# 使用した開発環境・ツール
第1回目と同じです。

# 基本事項
第1回目で説明済みの事項は省きます。

## セキュアアプリ実行の流れ
マイコンのリセットからセキュアアプリの実行までの流れは以下となります。

(1) Boot ROMが実行され、最低限の初期化を行います。
Boot ROMの詳細は以下の資料を参照してください。
[How to proceed with boot ROM on STM32N6 MCUs](https://www.stmcu.jp/design/document/users_manual/112030/)

(2) Boot ROMがFSBLを内蔵RAMにロードし実行します。
FSBLは以下の外部FLASHメモリデバイスからロードできます。
- sNOR x4 and x8 flash devices
- HyperFlash™ Flash device
- SD memory card device (SD specifications V6.0)
- eMMC type of embedded memory card devices 

(3) FSBLがクロックなど各種の初期化を行います。
FSBLの内容はユーザが記述できます。

(4) FSBLがセキュアアプリをメモリにロードし実行します。

## 今回作成するプログラム
今回作成するプログラムでは、FSBLからセキュアアプリを実行し、セキュアアプリでHALとBSPを使用してLEDを点滅させます。
プログラムはSTM32CubeN6 MCU PackageのTemplate_FSBL_LRUN(Load & Run) プロジェクトを参考に作成します。

FSBLおよびセキュアアプリは、ボード上の外部FLASHメモリの以下に格納されます。

- FSBLバイナリ(ヘッダを含む) 先頭アドレス 0x7000_0000
- セキュアアプリ・バイナリ (ヘッダを含む) 先頭アドレス 0x7010_0000

FSBLからセキュアアプリをロード、実行するには、STM32CubeN6のSTM32 ExtMem Managerを使用します。

ただし、デバッグ時はデバッガがプログラムをメモリへロードしますので、外部FLASHメモリは使用しません。今回はデバッグ実行までとし、外部FLASHメモリからの実行は次回説明します。

# 新規プロジェクトの作成
新規にプロジェクトを作成します。
以下の手順でプロジェクトを作成していきます。すべてSTM32CubeIDEでの作業となります。(1)から(3)までは第1回目と同じ操作です。

(1) [File]メニューから[New]->[STM32 Project]を選択します。

(2) [Board Selector]タグを選び、STM32N6570-DKを選択します。

(3) [Next]を押下して進み、[Project Name]に任意のプロジェクト名を入力します。一つのワークスペースに同一のプロジェクト名は使用できないので注意が必要です。
本稿ではプロジェクト名は`test_sap`とします。

(4) [Project Structure]の[Appli]にチェックを入れます。これでセキュアアプリのサブプロジェクトが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/e1331cfa-354b-6885-da74-1cb1b4a204c2.png)
図1 STM32 Project

(5) [Finish]を押下し、プロジェクトが生成されるのでしばらく待ちます。何か聞かれてきたら基本は「Yes」と答えます。

(6) プロジェクトが生成されるとハードウェアの設定画面(***.iocファイル)が表示されます。第1回目の新規プロジェクトの作成の手順(5)(6)を参考にクロック設定の修正などを行ってください。

(7) ここまでうまくいくと、Project Explorerに作成したプロジェクトが図2のように表示されているはずです。`test_sap_FSBL`がFSBLのサブプロジェクト、`test_sap_Appli`がセキュアアプリのサブプロジェクトです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/9a4a1cd3-40a7-9003-bbc5-823e666e391d.png)
図2 新規プロジェクト

実際のファイルシステム上のディレクトリ構成は以下のようになります。サブプロジェクト名がディレクトリ名と異なっている点に注意してください(test_sap_FSBL=FSBL, test_sap_Appli=Appli)。

```
├─Appli
│  ├─.settings
│  ├─Core
│  │  ├─Inc
│  │  ├─Src
│  │  └─Startup
│  └─Drivers
│      └─STM32N6xx_HAL_Driver
├─Drivers
│  ├─CMSIS
│  │  ├─Device
│  │  │  └─ST
│  │  │      └─STM32N6xx
│  │  │          ├─Include
│  │  │          └─Source
│  │  │              └─Templates
│  │  └─Include
│  └─STM32N6xx_HAL_Driver
│      ├─Inc
│      │  └─Legacy
│      └─Src
├─FSBL
│  ├─.settings
│  ├─Core
│  │  ├─Inc
│  │  ├─Src
│  │  └─Startup
│  └─Drivers
│      └─STM32N6xx_HAL_Driver
└─Secure_nsclib
```

(8) 確認のため、各サブプロジェクトをビルドしてみましょう(ビルドはサブプロジェクトの単位で行います)。
それぞれのサブプロジェクトを右クリックし、[Build Project]を選択して実行プログラムをビルドします。図2でtest_sap_FSBLとtest_sap_Appliと表示されているのがサブプロジェクトです。

# FSBLサブプロジェクトの作成
続いてFSBLサブプロジェクトを作っていきます。

## ExtMem Managerのインストール
FSBLからセキュアアプリのロード、実行を行うため、ExtMem Managerのインストールします。
ExtMem Managerは以下の手順でインストールできます。

(1) ハードウェアの設定画面(***.iocファイル)で、[Pinout & Configuration]タブを選び、[Middleware snd Software Packs]の中の[EXTMEM_MANAGER]を選択します。

(2) [EXTMEM_MANAGER]のFSBLをチェックします。

(3) [EXTMEM_MANAGER]の[Mode]を以下のように設定します。

- [Runtime Contexts]の[First Stage Boot Loader]をチェック
- [Active External Memory Manager]をチェック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/7ffd54fd-c656-7c37-91a2-dda9b9683722.png)
図3 [EXTMEM_MANAGER]のMode設定

(4)  [EXTMEM_MANAGER]の[Configuration]を図4のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/fbe83910-4c38-45ab-9899-d1b73015c3ae.png)
図4 [EXTMEM_MANAGER]のConfiguration設定

(4) ***.iocファイルをセーブすると、コードを自動生成するか聞かれるので[Yes]とします。プロジェクトに図5のようにExtMem Managerがインストールされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/fff195bf-75d4-c619-f1dc-d770b12fc772.png)
図5 ExtMem Manager

**※ [更新 2025.4.4] STM32CubeIDE 1.18.0 から以下の操作は不要となりました。ヘッダ・サイズはコンフィグレータがコードを自動生成します（デフォルト値で通常は大丈夫です）**
~~(5) FSBLサブプロジェクトの以下にExtMem Mabagerのコンフィグレーションファイルが生成されます。~~
~~`(project)\FSBL\Core\Inc\stm32_extmem_conf.h`~~

~~このファイルにリスト1のように設定を追記します。~~

```C
/* リスト1 stm32_extmem_conf.hに追記 */

/* USER CODE BEGIN PV */
#define EXTMEM_HEADER_OFFSET 0x400  << この行を追記
/* USER CODE END PV */
```

## FSBLのMain関数の変更
以下のファイルのFSBLのMain関数を変更します。
`(project)\FSBL\Core\Src\main.c`

(1) HALの初期化の修正
本来、自動生成したプロジェクトはそのまま実行できるはずなのですが、FSBLのmain関数に変更が必要です。main関数の中の MX_SDMMC2_SD_Init() とMX_USB2_OTG_HS_HCD_Init()の呼び出しをリスト2のようにコメントアウトするか削除します(第1回目の新規プロジェクトの作成の手順(9)を参照)。
もしくはハードウェアの設定でSDMMC2とUSB2の無効にします（第1回目の新規プロジェクトの作成の[追加 25/02/27] を参照）。こちらの方がコード自動生成時の上書きが防げます。

```C
/* リスト2  main.cのmain関数の一部修正 */

  MX_SAI1_Init();
  // MX_SDMMC2_SD_Init();  << これ
  MX_UCPD1_Init();
  MX_USART1_UART_Init();
  MX_USB1_OTG_HS_USB_Init();
  // MX_USB2_OTG_HS_HCD_Init();  << これ
  MX_XSPI1_Init();
```

(2) セキュアアプリをロード、実行するコードを追加します。
ExtMem Managerの`BOOT_Application`関数により、セキュアアプリをFLASHメモリからロードし、実行を行うことができます。
ただし、今回はデバッガによるデバック実行を行いますのでFLASHメモリからのロードは不要です(プログラムはデバッガからロードするので、FLASHメモリからのロードすると上書きされてしまいます)。
そこでリスト3のようにJumpToApplication関数を追加しました。ただし、JumpToApplication関数はExtMem Managerのローカル関数ですので、外部から使用するのがあまりよろしくないかと思います（とりあえずデバッグ用ということで）

```C
/* リスト3 セキュアアプリの実行プログラムの追記 */

  /* USER CODE BEGIN 2 */
  JumpToApplication();      // セキュアアプリの実行
  /* USER CODE END 2 */
```

以上でFSBLサブプロジェクトは完成です。

# セキュアアプリ・サブプロジェクトの作成
セキュアアプリをボード上のLEDを点滅するように作成します。LEDの点滅にはメーカ提供のHALとBSPの機能を使用します。

## BSPのインストール
セキュアアプリからBSPの機能を使用するために、BSPをインストールします。なお、今回はセキュアアプリのみがBSPを使用しますが、FSBLサブプロジェクトもBSPを使用する場合は同様の手順が必要です。

(1) ソースコードのコピー&リンク
STM32N6CubeからプロジェクトにBSPのソースコード一式をコピーし、セキュアアプリのサブプロジェクトに`stm32n6570_discovery.c`のリンクファイルを作成します。手順は第1回目の「BSPのインストール」と同じです。

(2) インクルードパスの追加
セキュアアプリのサブプロジェクトのBSPへのインクルードパスを追加します。
インクルードパスの追加方法は第1回目の「インクルードパスの追加」と同じです。

(3) インクルードファイルの追加
BSPの定義ファイルを以下のセキュアアプリのサブプロジェクトのmain.hファイルにインクルードします。
`(project)\Appli\Core\Inc\main.h`

第1回目の「インクルードファイルの追加」と同じです。

(4) コンフィギュレーションファイルの作成
BSPのコンフィグレーションファイルを以下に作成します。
`(project)\Appli\Core\Inc\stm32n6570_discovery_conf.h`

BSPのコンフィグレーションファイルは、以下のSTM32CubeN6のTemplate_FSBL_LRUNプロジェクトのコンフィグレーションファイルをそのまま使用しました。

`en.stm32cuben6-v1-1-0\STM32Cube_FW_N6_V1.1.0\Projects\STM32N6570-DK\Templates\Template_FSBL_LRUN\Appli\Inc\stm32n6570_discovery_conf.h`

第1回目の「コンフィギュレーションファイルの作成」も参考にしてください。

## セキュアアプリのMain関数の変更
自動生成したセキュアアプリには何もしないプログラムが書かれています。ここにボードのLEDを点滅されるプログラムを追加します。
以下のファイルのセキュアアプリのMain関数を変更します。
`(project)\Appli\Core\Src\main.c`

セキュアアプリのmain関数にHALとBSPのAPI呼び出してLEDを点滅させるプログラムをリスト4のように記述します。
説明は第1回目の「main関数の変更」をご覧ください。

```C
/* リスト4 LED点滅プログラムの追記 */

  /* USER CODE BEGIN 2 */
  BSP_LED_Init(LED_GREEN);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    BSP_LED_Toggle(LED_GREEN);
    HAL_Delay(500);
  }
  /* USER CODE END 3 */
```

# ビルドとデバッグ実行
## サブプロジェクトのビルド
FSBLとセキュアアプリのサブプロジェクトをそれぞれビルドします。サブプロジェクトを右クリックし、メニューから[Build project]を選択すると、プログラムがビルドされます。
FSBLのメモリへのアサインは以下のファイルに記述されています。
`(project)\FSBL\STM32N657X0HXQ_AXISRAM2_fsbl.ld`
内容は第1回目の「サブプロジェクトのビルド」と同じです。

セキュアアプリのメモリへのアサインは以下のファイルに記述されています。
`(project)\Appli\STM32N657X0HXQ_LRUN.ld`

上記ファイル中に以下の記述があります。
```
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x34000400,   LENGTH = 2047K
}
```

## デバッグ実行
以下の手順でFSBLをデバッグ実行します。セキュアアプリはFSBLに関連付けし、FSBLから実行されます。

### FSBLのデバッグ構成の作成
FSBLのサブプロジェクトをビルドした後に、[Debug]メニューから[Debug Configurations]を選択します。開いたダイアログで[STM32 C/C++ Application]をダブルクリックすると、FSBLのデバッグ構成が作成されます。
作成されるデバッグ構成は直前にビルドしたプロジェクトのものです。手順に気をつけてください。
また、事前にセキュアアプリのビルドも行っておく必要があります。
図6のようにデバッグ構成が作成されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/21e07365-1180-9944-78aa-53a3661b0ded.png)
図6 FSBLのデバッグ構成

### セキュアアプリの関連付け
FSBLのデバッグ構成の[Startup]タブで、[Add]を押下し、[Project]に`test_sap_Appli`を選択します。
図7のように[Load Image and Symbols]にセキュアアプリの実行ファイル(ELFファイル）が追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/dfffe3ee-663d-c3ea-f1bb-4bf339361f40.png)
図7 セキュアアプリの関連付け

### デバッグ実行
PCとボードをUSBケーブルで接続します。USBコネクタはSTLINKと書かれている方です。ボード上のSW1(BOOT1) が1-3側にしてDevelopment bootのモードとします。
デバッグ構成のダイアログから[Debug]を押下すると、実行プログラムがボードに転送され、デバッグ画面に変わった後、実行を開始します。
初期の設定ではFSBLのmian関数でブレーク(一時停止)します。[Run]メニューから[Resume]を選択するとプログラムは実行を再開しFSBLからセキュアアプリが実行されます。セキュアアプリが実行されるとボード上のLEDが点滅します。

# 次回は
今回はFSBLからセキュアアプリをデバッグ実行させました。
次回はこのプログラムをFLASHメモリに書き込んで、デバッガ無しに実行する手順を説明します。