1. はじめに
Platform Designer には、Flash ROM にアクセスする Flash Controller が多くあり、そのほとんどが Nios® II HAL API に対応しています。
Nios® II HAL API に用意されている関数を使用すれば、Flash ROM に対して、Erase・Write・Read の実行や Protect の設定などを簡単に行うことができます。
また、異なる Flash Controller を使用する場合でも、共通の Nios® II HAL API で実装しておけば、ソフトウェアの変更を最小限に抑えることができます。
この記事で、Flash Controller Driver の仕様とサンプルデザイン と Nios® II HAL API を活用したサンプルソフトウェアを紹介します。
2. Flash Controller の種類
各種 Flash Controller の違いについては、下記コンテンツで紹介しています。
参考:Embedded Peripherals IP - 各種 Flash Controller の比較
【表1】 では、Flash Controller の名称とユーザーガイドのリンク、Nios® II HAL API の対応について記載しています。略称はこの記事内における、説明の簡略化のために使用しています。
また、今回のサンプルソフトウェアは、1 番の Legacy SFC と 6 番の GSFI には対応していません。
GSFI に関しましては、*1 のメーカー公式のサンプルデザインをご確認下さい。
【表1】 Flash Controller の種類 と Nios® II HALとの関係性
No | 名称 (ユーザーガイド・リンク) | 略称 | サンプル対応 | Nios® II HAL |
1 | EPCS/EPCQA Serial Flash Controller Core | Legacy SFC | 未対応 | 有 |
2 | Intel FPGA Serial Flash Controller Core | SFC I | 対応 | 有 |
3 | Intel FPGA Serial Flash Controller II Core | SFC II | 対応 | 有 |
4 | Intel FPGA Generic QUAD SPI Controller Core | GQSPI I | 対応 | 有 |
5 | Intel FPGA Generic QUAD SPI Controller II Core | GQSPI II | 対応 | 有 |
6 | Generic Serial Flash Interface Intel FPGA IP Core | GSFI | 未対応 | ver21.1_Pro にて有 *1 |
*1: GSFI の サンプルデザインと Nios® II サンプル・ソフトウェアが下記のページで提供されています。ver21.1_Pro にて Nios II HAL が提供されましたが、このコンテンツのサンプルソフトウェアには対応していません。
参考: Embedded Peripherals IP - Generic Serial Flash Interface サンプル
参考: Generic Serial Flash Interface Intel FPGA IP Core Reference Design
参考: Generic Serial Flash Interface Intel® FPGA IP User Guide > 1.9. Nios II HAL Driver
3. Flash ROM の種類
Flash Controller が主に対応している Flash ROM を【表2】に示します。
各種 Flash Controller が 対応している Flash ROM の種類は、公式ユーザーガイドまたは、下記コンテンツに記載の 図2 ~ 図5 をご確認下さい。
参考:Embedded Peripherals IP - 各種 Flash Controller の比較
また、FPGA の コンフィグレーション に関しましては下記コンテンツをご参照ください。
参考:アクティブ・シリアル・コンフィグレーション デザイン & デバッグ・ガイドライン
【表2】 Flash Controller が主に対応している Flash ROM の種類
No | 名称 | メーカー | 特徴 |
① | EPCS シリーズ | Intel | Serial SPI Flash ROM であるため、データ線 2本でシリアル通信を行います。 現在ほとんどの FPGA デバイスで使用することはありません。 |
② | EPCQ シリーズ | Intel | QUAD SPI Flash ROM であるため、データ幅は Standard と QUAD をサポートしています。EPCQA がリリースされるまでは主要な Flash ROM でした。 |
③ | EPCQA シリーズ | Intel | EPCQ シリーズの後継版となる Flash ROM です。基本的は仕様は同じですが、Read Flag Status コマンドが無くなっていますので、ソフトウェアを作成する際には注意が必要です。 |
④ | MT25Q シリーズ *2 | Micron | ユーザーガイドをご参照ください。 |
⑤ | N25Q シリーズ *2 | Micron | ユーザーガイドをご参照ください。 |
*2: メーカーが発行している容量の合ったユーザーガイドを入手してご参照ください。
4. Nios® II HAL API と Flash Controller デバイスドライバーの紹介
Nios® II HAL API とは、ハードウェア・アブストラクション・レイヤー(HAL)アプリケーション・プログラム・インターフェイス(API)の略になります。
Nios® II HAL API に関しては、下記のコンテンツで解説しています。
参考:Nios® II SBT によるソフトウェア開発 セクション1
Nios® II HAL API は Nios® II Processor Core に標準で用意されている抽象化アプリケーション・プログラムであり、Nios® II の機能を実現するソフトウェアがあらかじめ用意されています。
Platform Designer に用意されている 各種 IP には、デバイスドライバーと呼ばれるソフトウェアが用意されており、Nios® II HAP API 経由でデバイスドライバーが実行される関数もございます。
また、Nios® II HAL API を使用しないで、デバイスドライバーを直接使用しても問題ありません。
今回のサンプルは、使用している Flash Controller のデバイスドライバーが Nios® II HAP API によって呼ばれる仕様を活用して、Flash Controller に依存しない、サンプル・ソフトウェアをご用意しました。
Nios® II HAL API のイメージを【図1】に示します。
【図1】 Nios® II HAL API とデバイスドライバーのイメージ
【表3】と【表4】には SFC II と GQSPI II における、Flash Controller デバイスドライバーの仕様を記載しています。
【表5】では、Flash Controller 関連で使用できる Nios® II HAL API についてまとめています。使用する Flash Controller の種類によって呼び出される関数が異なります。
関数の引数や詳しい処理内容は、該当ソフトウェアをご確認下さい。
【表3】 SFC II の 主な Flash Controller デバイスドライバー
SFC II Driver altera_epcq_controller2.c | 仕様 |
alt_epcq_controller2_lock() | Flash ROM に Protect の設定を行います。Write Enable を発行する処理が入っていないため、この関数を実行する前に、Write Enable を有効にする処理を実行する必要があります。 |
alt_epcq_controller2_erase_block() | Erase したい Sector のベースアドレスを指定すると、その Sector が Erase されます。Erase 実行中は Busy 状態になるので、Status Register の Write in Progress (WIP) Bit を監視して、Busy が解除されるまで次の処理に進まないようにしておく必要があります。 |
alt_epcq_controller2_write_block() | block_offset と data_offset と length を指定すれば、好きな場所に書き込むことができますが、セクターをまたいだ書き込みには対応していません。Erase と同様 WIP Bit を監視して、Busy が解除されるまで次の処理に進まないようにしておく必要があります。 |
alt_epcq_controller2_write() | offset と length を設定し、どこでも好きな場所に書き込むことができます。セクターをまたいだ書き込みも、関数内で調整します。しかしながら、Sector Erase が関数内で実行されるため、データを分割して書き込みたい場合は、セクター毎に書き込まないと書いたデータが消されてしまいます。関数内部で、alt_epcq_controller2_write_block() を実行しており、WIP Bit を監視して、Busy が解除されるまで次の処理に進まないようにしておく必要があります。 |
alt_epcq_controller2_read() | 引数に渡したバッファーに読み出したデータを格納します。 |
【表4】 GQSPI II の 主な Flash Controller デバイスドライバー
GQSPI II Driver altera_generic_quad_spi_controller2.c | 仕様 |
alt_qspi_controller2_lock() | Flash ROM に Protect の設定を行います。Write Enable を発行する処理が入っていないため、この関数を実行する前に、Write Enable を有効にする処理を実行する必要があります。 |
alt_qspi_controller2_erase_block() | Erase したい Sector のベースアドレスを指定すると、その Sector が Erase されます。Write in Progress (WIP) チェックは実施します。 |
alt_qspi_controller2_write_block() | block_offset と data_offset と length を指定すれば、好きな場所に書き込むことができますが、セクターをまたいだ書き込みには対応していません。WIP チェックは実施します。 |
alt_qspi_controller2_write() | offset と length を設定し、どこでも好きな場所に書き込みする事ができます。セクターをまたいだ書き込みも、関数内で調整します。しかしながら、Sector Erase が関数内で実行されるため、データを分割して書き込みたい場合は、セクター毎に書き込まないと書いたデータが消されてしまいます。関数内部で、alt_epcq_controller2_write_block() を実行するので、WIP チェックは実施します。 |
alt_qspi_controller2_read() | 引数に渡したバッファーに読み出したデータを格納します。 |
【表5】 Flash Controller で使用できる Nios® II HAL API
Nios® II HAL API alt_flash.h |
呼び出される関数 |
alt_lock_flash() | alt_epcq_controller2_lock() alt_qspi_controller2_lock() など |
alt_erase_flash_block() | alt_epcq_controller2_erase_block() alt_qspi_controller2_erase_block() など |
alt_write_flash_block() | alt_epcq_controller2_write_block() alt_qspi_controller2_write_block() など |
alt_write_flash() | alt_epcq_controller2_write() alt_qspi_controller2_write() など |
alt_read_flash() | alt_epcq_controller2_read() alt_epcq_controller2_read() など |
5. サンプルデザイン&サンプル・ソフトウェアの概要
この記事で紹介するサンプルデザイン情報を下記に記載します。
・使用 Kit : Cycloen V GX スタータ開発キット
(Qsys ファイルとソフトウェアを他の Kit に移植して再現可能)
・Tool バージョン : Quartus® Prime ver19.1_Standard
・主な使用 IP : Nios® II, On-Chip RAM, JTAG UART, PIO (LED), Flash Controller
・Nios® II/f(Gen2): 命令/データキャッシュ : 4 KB
・ On-Chip RAM : 128KB(ワークメモリー)
・ソフトウェア容量の目安 : program size (code + initialized data) :
enable_small_c_library : [有効] : 24 KBytes、[無効] : 76 KBytes
注記:
ソフトウェア容量に対して RAM の容量が少ない場合、スタックオーバーフローが発生する可能性がありますので、RAM 容量は余裕をもって設定してください。
Platform Designer の接続図を【図 2】に示します。
【図 2】 Platform Designer 接続図
5-1. サンプル・ソフトウェア解説
このサンプル・ソフトウェアは、Nios® II HAL API を使用し、Flash Controller に依存しないよう作成していますので、【表1】に記載の 2~5 番の Flash Controller でそのまま使用することが可能です。
Protect Sector がかかっていたり、Write Enable を発行していなかったり、WIP チェックを行っていなかったといったような、ソフトウェアの処理が原因による書き込みエラーは発生しにくくなっていますので、Flash ROM にアクセスできるか、全領域に対して Memory Test を行うことができます。
デフォルトの設定では、Flash ROM に対して下記の処理を実施します。
- Protect Sector の解除
- 1 Sector 分 Erase を実行し、0xFF になったか、Sub Sector 分確認
- Flash ROM の 0x00000_0000 から、Sub Sector 毎に書き込みを行い、1 Sector 分データの書き換え
- Sub Sector 毎に Verify を実施
- Verify エラーが発生した場合、読み取ったデータを表示してエラーのデータを確認
注記:
書き換えてはいけない領域のある Flash ROM に対して、そのまま実行しないでください。
下記 #define 文で定義されている定数を変更することで、ご自身の Platform Designer の構成に合わせて使用可能なソフトウェアになっています。
/***********************************************************************************
* re-definitions
* ※このセクションは"system.h"で定義された定数を、
* 本ソースファイル内で使用するために再定義したものです。
* ご使用の際は右側の定数を"system.h"を参照の上、変更してお使いください。
***********************************************************************************/
#define SFC_AVL_MEM_NAME (ASFC_II_AVL_MEM_NAME)
#define SFC_AVL_CSR_BASE (ASFC_II_AVL_CSR_BASE)
#define SFC_AVL_CSR_SECTOR_SIZE (ASFC_II_AVL_CSR_SECTOR_SIZE)
#define SFC_AVL_CSR_SUBSECTOR_SIZE (ASFC_II_AVL_CSR_SUBSECTOR_SIZE)
#define SFC_AVL_CSR_NUMBER_OF_SECTORS (ASFC_II_AVL_CSR_NUMBER_OF_SECTORS)
#define SFC_AVL_MEM_SPAN (ASFC_II_AVL_MEM_SPAN)
//#define PIO_LED_BASE (LED_BASE)
/***********************************************************************************
下記 #define 文で定義されている定数を変更する事で、書き込みを行う Sector の領域や Protect Sector の設定を変更できます。
READ_ERASE_ONLY を変えることで、Erase だけ行ったり、Read だけ行ったりすることができ、
PROTECT_CHANGE_ONLY を 1 にするとことで、Read Status のチェックと Protect Change のみ実行するように動作させることができます。検証の内容によって変更し、お使いください。
*注意点:
SFC I と GQSPI I は、Read Flag Status の レジスターが無い為、EPCQ_or_EPCQA は 0 にして実行してください。また、EPCQA にも、Read Flag Status の レジスターはありません。
/***********************************************************************************
* definitions (define, enum, typedef, etc..)
* ※ デフォルト状態の本ソースコードは、Flash ROM の 0x0000_00000 から、1 セクター分データの書き換えを行います。
* 書き換えてはいけない領域が無い Flash ROM でお試しください。
* Define で定義されている Start_Sector_Address、NUMBER_OF_SECTORS の値を変更する事で、書き換えを行う Sector を調整することができます。
* 設定した値がセクターのベースアドレスでない場合やセクターの数が Flash ROM を超える場合は、Nois II が終了します。
***********************************************************************************/
#define SEC_BASE_ADD (0x00000000) // Erase と Write と Read を行うセクターのベースアドレス
#define NUM_OF_SEC (1) //(SFC_AVL_CSR_NUMBER_OF_SECTORS)// Erase と Write と Read を行うセクター数
#define SECTOR_LOOK (0x0) // Sector Lock の設定値。0x0 を設定しておくと、LOCK 解除を行います。
#define BUFF_SIZE (SFC_AVL_CSR_SUBSECTOR_SIZE) // データサイズ
#define WRITE_DATA (0x00) // Write Data
#define PRINT_LENGTH (16) // Print_Sector_Data() で表示する列数 1~256
#define EPCQ_OR_EPCQA (1) // Read Flag Status 設定 EPCQ = 1 , EPCQA = 0
#define PRINT_LAST_DATA (0) // 1 にすると、セクターの最後のデータを表示しながら処理が進みます。
#define PRINT_VERIFY_DATA (1) // 1 にすると、Verify Error となったデータを表示します。
#define PROTECT_CHANGE_ONLY (0) // 1 にすると、Read Status のチェックと Protect Change のみ実行します。Erase Write Read は実行しません。
#define READ_ERASE_ONLY (0) // 設定値によって、Erase Write Read 関数の実行有無が変わります。
// 0 :Erase Write Read 実行, 1 :Erase Read 実行で、Verify 用に WRITE_DATA は 0xFF 固定, 2 :Read 実行。
#define BULK_ERASE_ON (0) // 1 にすると、Sector Erase が無効になり、Bulk Erase を実行してから、Write します。
// EPCQ512-L と EPQC1024-L は Bulk Erase をサポートしていません。
5-2. サンプル・ソフトウェア検証手順
Nios® II SBT にサンプル・ソフトウェアのプロジェクトを作成して、検証を行う手順を紹介します。
ユーザー作成の Qsys で検証する時も同様の手順です。
【最低限必要なシステム要件】
- Nios® II Processor Core ( Fast または Economy )
- Serial Flash Controller I/II または Generic QUAD SPI Controller I/II
- 実行 RAM ( On Chip RAM (約 27k Bytes以上)または 外部 RAM )
- stdout 機能の実装 (JTAG UART または UART Core など、Printf 文で結果を表示するため)
【手順】
- Platform Designer の Generate HDL で sopcinfo ファイルを生成
- Nios® II SBT にて Nios® II Application and BSP from Template を実行
( テンプレートは hello_world_small または hello_world ) - ソフトウェアを SFC_Access_sample.c に置き換えて、Define 文を修正
- BSP Editor を On Chip RAM または 外部 RAM 実行に設定し、Generate BSP 実行 (参考)
- Build を実行し、Run AS を実行
5-3. サンプル・ソフトウェア動作
Nios® II SBT の Run As で実行すると、Work RAM (このデザインでは、On Chip RAM) で Nios® II が実行されます。Nios® II Console にて、Flash ROM の Status Register 情報、設定した セクター・ベースアドレスの値と書き込みを行うセクター数の情報が表示されます。その後、Protect Sector の設定を更新し、書き込みを開始します。
1 Sector 分実行した際の Log を下記に記載します。
Hello from Nios II!
!!!!! Please use a Flash ROM that can be rewritten. !!!!!
The Start Sector Address you set = 0x0
The Number of Sector you set = 1
There are no setting errors.
Silicon ID = 0x1019ba20
Open flash device
Read Status = 0x0
Read Flag Status = 0x81
Protect Change OK
Read Status = 0x0
Read Flag Status = 0x81
*******************************************
Number of Writes= 0 [n]
Write Offset = 0x0 (Sector Number = 0)
Erase Sector = 0x0
//**** After Erase ****//
Read Status = 0x3
Read Flag Status = 0x1
//**** After WIP Check ****//
Read Status = 0x0
Read Flag Status = 0x81
Erase Check
Write Offset 0x00000000 : Read Offset 0x00000000 : Verify was successful
Erase OK, Data is 0xFF
Write Start
Write Offset 0x00000000 : Read Offset 0x00000000 : Verify was successful
Write Offset 0x00001000 : Read Offset 0x00001000 : Verify was successful
Write Offset 0x00002000 : Read Offset 0x00002000 : Verify was successful
Write Offset 0x00003000 : Read Offset 0x00003000 : Verify was successful
Write Offset 0x00004000 : Read Offset 0x00004000 : Verify was successful
Write Offset 0x00005000 : Read Offset 0x00005000 : Verify was successful
Write Offset 0x00006000 : Read Offset 0x00006000 : Verify was successful
Write Offset 0x00007000 : Read Offset 0x00007000 : Verify was successful
Write Offset 0x00008000 : Read Offset 0x00008000 : Verify was successful
Write Offset 0x00009000 : Read Offset 0x00009000 : Verify was successful
Write Offset 0x0000a000 : Read Offset 0x0000a000 : Verify was successful
Write Offset 0x0000b000 : Read Offset 0x0000b000 : Verify was successful
Write Offset 0x0000c000 : Read Offset 0x0000c000 : Verify was successful
Write Offset 0x0000d000 : Read Offset 0x0000d000 : Verify was successful
Write Offset 0x0000e000 : Read Offset 0x0000e000 : Verify was successful
Write Offset 0x0000f000 : Read Offset 0x0000f000 : Verify was successful
*******************************************
Finish Erase Write Read
*******************************************
Finish Nios II
サンプルデザインのダウンロードはこちらから