このコーナーの他のページとは少し毛色の違う話を書きます。MMRアクセスをアセンブリ言語で書くと少々面倒ですが、これを効率化する方法を紹介します。
BlackfinのMMR(Memory Mapped Register)にはコアMMRとシステムMMRの2種類があり、それぞれ2MBの領域を持っています。
アドレスはいずれも32bitですので、たとえば次のようにしてアクセスします。
p0.L = lo(IMASK); p0.H = hi(IMASK); r0 = [P0]; // IMASKの値を取得 p0.L = lo(IPEND); p0.H = hi(IPEND; r1 = [P0]; // IPENDの値を取得
単純ですが、もったいないといえばもったいないコードです。第一に毎度毎度32bitアドレスをロードするのが面倒です。第二にアドレス・レジスタのロード直後にアクセスを行うとストールします。したがって、サイクル数がもったいないです。信号処理では行わないアクセスですが、RTOSのカーネル内部で行うとなると、やはりもったいないなと思います。
ところがよくしたもので、BlackfinのコアMMRは現在のところすべて上位16bitが0xffe0となっています。また、ADSP-BF533のシステムMMRは同様に上位16bitが0xffc0となっています。これを利用すると以下のようにアクセスを簡略化できます。
p5.H = hi(IMASK); // コアMMRの上位アドレス p5.L = 0; p4.H = hi(SIC_IMASK); // システムMMRの上位アドレス p4.L = 0; ... r0 = [p5+lo(IMASK)]; // IMASKの値を取得 r1 = [p5+lo(IPEND)]; // IPENDの値を取得 r2 = [p4+lo(SIC_IAR0)]; // SIC_IAR0の値を取得
この方法は最初の方法よりメモリ消費量が少なく、かつ高速です。難点としては、プログラムの可読性が下がることが上げられます。