ガレスタさんのDIY日記

電子回路、Web、組み込み、自作エフェクターを語るblog

IMX RT1050 FlexRAMについて その1

ここ最近本格的にこのチップでの開発を始めて数ヶ月経った。
こいつはRAMオンリーということもあり初期設定のままではコードが入らなくなって来た。(初期設定ではコード、データ、ヒープスタックがITCMにリンクされるようになってるため)
どうやら色々調べてみるとFlexRAMという機能がありRAM(全体で512KB)のアロケーションが可能であり512KBを32KB単位で割り振りできるみたいだ。
その機能使ってITCMの範囲を広げたいなと感じため今回はそういった昨日の概要や設定方法などをまとめてみた。
これ知見が何かの役立てば嬉しい。


FlexRAM

NXP曰くFlexRAMは高度な構成が可能なフレキシブルRAMモジュールである。
簡単にいえばRAM array + PINMUX群 + 各種RAMコントローラになる。

f:id:gsmcustomeffects:20180120234432p:plain
figure1:FlexRAM概要

使えるメモリは

  • ITCM(Instruction-Tightly Coupled Memory)
  • DTCM(Data- Tightly Coupled Memory)
  • On-Chip-RAM

の3つである。

ITCMは64bitバス、DTCMはdual 32bitバス(メモリインターリーブ)、OCRAMは64bitバスでアクセス可能

インターリーブはここを参照したい。
https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%96

TCMインターフェイスはCortexM7コアと同じ速度で動作し同期している。一方OCRAMは64-bit AXI bus経由でのアクセスなので1/4程度のパフォーマンスとなってしまう。
それに関してはCacheを利用することで幾らか改善可能である。

i.MX RT1050の場合は512KBメモリアレイがあるのでその領域を以上3つの領域でアローケーション(自由分割)できる。
なおある程度の制約がある(後述

モリーコンフィグ

この機能を使用するためにはまずコンフィグレーションを行う必要がある。
コンフィグレーションには二通りの設定方法がある。

  1. FlexRAM FUSEを利用(デフォルトはこっち)
  2. IOMUXC_GPR_GPR17 registerを利用

以上二つの設定方法を決めるのが
IOMUXC_GPR_PGR16 registerの FLEXRAM_BANK_CFG_SEL bitである。
f:id:gsmcustomeffects:20180121001716p:plain

CFG_SEL description
0 FUSE利用
1 IOMUXレジスタ17を利用

APIとしては

static inline void FLEXRAM_SetAllocateRamSrc(flexram_bank_allocate_src_t src)
{
    IOMUXC_GPR->GPR16 &= ~IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL_MASK;
    IOMUXC_GPR->GPR16 |= IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL(src);
}

flexram_bank_allocate_src_tはこう

typedef enum _flexram_bank_allocate_src
{
    kFLEXRAM_BankAllocateThroughHardwareFuse = 0U, /*!< allocate ram through hardware fuse value */
    kFLEXRAM_BankAllocateThroughBankCfg = 1U,      /*!< allocate ram through FLEXRAM_BANK_CFG */
} flexram_bank_allocate_src_t;


次に実際のコンフィグを説明して行くことにしよう

FUSEを利用した静的コンフィグ

FlexRAMは4bit設定するこのビットはboot前に設定されている必要がある。
FlexRAM関連のFUSEは0x6D0 addressにマッピングされており [16-19]-bitがそれに当たる。

f:id:gsmcustomeffects:20180121002327p:plain

このようにFuseビットを利用した設定では16通りのRAM構成が選べるわけである。(4bit = 2^4 = 16)
初期状態はOCRAM(256KB),ITCM(128KB),DTCM(128KB)となっている。

IOMUXレジスタを利用した動的コンフィグ

FlexRAMバンクはIOMUXレジスタを書き換えることで動的なコンフィグも可能である。この時IOMUXC_GPR_PGR16 registerの FLEXRAM_BANK_CFG_SEL bitが1である必要がある。
いかにレジスタのdescriptionを示そう。

f:id:gsmcustomeffects:20180121002912p:plain

見ればわかるとおりに2bitで個別に役割を決められる。

モリタイプ定義の大きさ

iMXRT1050は合計512KBのRAM arrayを持っており、16個のブロックがあるので32KB単位でコンフィグして行くことになる。
一方OCRAMはBOOTROMになる関係で0KBでコンフィグできない。
ITCM or DTCMは0KBコンフィグ可能

各種メモリコントローラ

FlexRAMはAXIバスとTCMバス二つをもつモジュールである。
それぞれのメモリコントローラとRAM arrayはマルチプレクサを通して接続されている。

TCM Memory Controller(TCM Interface)

TCM InterfaceはCortexM7コアに同期し同じ周波数にて動作する。
ICTMは命令フェッチ、DTCMはデータを置くのに適している。

Read/Write accessには2つの方法がある。

  1. Fast access mode(1 cycle)
  2. Wait access mode(2 cycle)

wait accessは電力消費低減のための機能

設定APIはFLEXRAM_SetTCMWriteAccessModeってのがある。

static inline void FLEXRAM_SetTCMWriteAccessMode(FLEXRAM_Type *base, flexram_tcm_access_mode_t mode)
{
    base->TCM_CTRL &= ~FLEXRAM_TCM_CTRL_TCM_WWAIT_EN_MASK;
    base->TCM_CTRL |= mode;
}

設定にはTCM CRTL Register (TCM_CTRL)をセットする必要がある。

f:id:gsmcustomeffects:20180121033854p:plain
各種ビットと値による機能は以下の通り
f:id:gsmcustomeffects:20180121033926p:plain

On Chip RAM(AXI Interface)

OCRAMメモリは、64ビットシステムAXIバスに接続されたスレーブポートモジュールとして機能する。

読み込みと書き込みは、2つの独立した読み取り/書き込み制御モジュールによって処理される。(2つの処理が同時に来た場合のためのバスアービタをモジュールに含む)

アービタはラウンドロビン方式で動作する。

ラウンドロビン方式はここを参照したい。
第1回 RTOS概論 | トロンフォーラム

READ/WRITEで同様のバンクか異なるバンクのアクセスがあった場合READの方が高優先度になるみたい

FlexRAM power domains

FlexRAM arrayは3つに分割される。

  • PDRET domain.
  • PDRAM0 domain.
  • PDRAM1 domain.

上の図でいうとこの部分

f:id:gsmcustomeffects:20180121181102p:plain

それぞれのパワーモードでの各種RAMの状態は以下の通りです。

System IDLE LowPower IDLE SUSPEND SNVS
ARM Coreの状態 WFI WFI PowerDOWN OFF
FlexRAM(PDRET) ON ON ON OFF
FlexRAM(PDRAM0) ON ON ON/OFF OFF
FlexRAM(PDRAM1) ON ON PowerDOWN OFF

※SNVS:Secure Non-Volatile Storageのこと

All SOC digital logic, analog modules are shut off only except SNVS
domain
32KHz RTC is alive

とあるのでRTC以外全オフみたいな感じですかね。

この辺に関しては結構細かい設定があるのでリファレンスマニュアルのパワー項目の部分を参照すると良いでしょう。
そのほかAN12094というアプリケーションノートに色々書いてあります。

FlexRAM interrupt

FlexRAMはアロケーション範囲外のアクセスがあった場合に割り込みリクエストを出すことができます。

イベントはITCM,DCTM,OCRAMそれぞれに対して生成できる。
設定はInterrupt Enable Register (INT_SIG_EN)にて設定できる。

f:id:gsmcustomeffects:20180121205137p:plain

Interrupt Status Register (INT_STATUS)でstatus情報を得ることができる。