Max10 NiosIIからOnchip_Flashへのアクセス方法

いちり
いちり

やっと正しく読み書きできた。 初心者なので1週間かかった。
シンプル読み書きでなく、Grained(緻密な)読み書きでミスせず書き込めるようになった。

アクセス手順

  1. Platform DesignでNiosIIとOnchip_Flashを組み込む
  2. Quartus Primeでコンパイルする
  3. Nois II Software Build Toolでプロジェクトを作る
  4. Nois II Software Build Toolでオンチップフラッシュメモリにアクセスするプログラムを記述

ここでは一番苦労した4だけを説明しています。

コードの説明

下のコードは、Intelの『Nios II Software Developer’s Handbook』の6-7章を参考にしてます。 まずコードです。

#include &lt;stdio.h&gt;<string.h>;
#include "sys/alt_flash.h"
#include "stdtypes.h"
#include "system.h"
#define BUF_SIZE 2048
int main (void)
{
flash_region* regions;
alt_flash_fd* fd;
int number_of_regions;
int ret_code;
char write_data[BUF_SIZE];

memset(write_data, 0xA, BUF_SIZE);      //全て0xAを書き込む(デモ用で通常は不要)
fd = alt_flash_open_dev(EXT_FLASH_NAME);   //フラッシュをオープン
if (fd)
{
ret_code = alt_get_flash_info(fd, &amp;regions, &amp;number_of_regions); //情報取得
    if (number_of_regions &amp;&amp; (regions-&gt;offset == 0))
    {
    ret_code = alt_read_flash(fd, </string.h>
                   <string.h>regions-&gt;offset, </string.h>
                   <string.h>write_data, </string.h>
                   <string.h>BUF_SIZE); //消す前に読み出し</string.h>
    //本来は、ここでもret_codeをチェック。<string.h>
        ret_code = alt_erase_flash_block(fd,   //書込む前にブロックを消去
                                    regions-&gt;offset,
                                    regions-&gt;block_size);
        if (ret_code == 0) {
            ret_code = alt_write_flash_block (fd,
                                    regions-&gt;offset,
                                    regions-&gt;offset,
                                    write_data,
                                    BUF_SIZE );
        }
    }
}
    return 0;
}
</string.h>
  1. Flash Memory ブロック情報取得 alt_get_flash_info( )
  2. 消去する前にデータをブロックごと読出して退避 alt_read_flash ( )
  3. ブロックのデータ消去 alt_erase_flash_block ( )
  4. ブロックで書込み  alt_write_flash_block( )

Flash Memoryの特性で、書き換える時は1から0にしか書換えず、値が0x0000のデータを書換える事はできません。 書込む為には、まずデータ消去(Erase)コマンドでデータを0xFFFFにした後、新しいデータを書込む事によってデータを正しく書換える事ができます。 しかし、このデータ消去はFlash Memoryの1ブロック単位で消去されます。 なので、ブロック単位で、読出し(退避)ー>消去(Erase)ー>書込みをします。 その為にはブロックサイズ、ブロックがどこから始まるかを、alt_get_flash_infoでブロックサイズ(region->block_size)、ブロック開始位置(region->offset)等の情報を取得するのです。

上記プログラムで、EXT_FLASH_NAMEはsystem.h内に記載されているFlash Memoryの名前を貼り付けてください。 Platform Designerで接続したFlash Memoryの名前になっています。

3つのアクセス方法

アクセス方法は3つあります。
(1)IORD、IOWRを使って直接アクセスする方法
(2)Intel APIを使ってアクセスする方法 (6-7章)
   (2)-1. シンプル書込み
   (2)-2. Grained(きめ細かい)書込み (これが一番良い)

詳細

結論は(2)-2を使う事です。
(1)のIORDやIOWRを使用して直接アクセスする際は、Flashの状態をbit単位で見ながら、読み出しや書き込みをしなければならず、プログラムが非常に複雑になります。

(2)-1. のIntel APIのシンプル書き込みでブロックを指定しない書き込みも出来ますが、書き込みがブロック単位でないため、ブロックの途中までしか書き込まない場合があります。 Flashは1から0にしか書き込めない為、書き込む前にブロック単位で消去(Erase:0xFF)しなければならず、ブロックを消去後にブロックの途中迄しか書き込まない場合は、その後の部分は消去されてしまいます。

なので、(2)-2.の方法の記述が少し複雑ですが、一番確実で間違いがなく、結果簡単な方法です。

コメント