用途
DMA(Direct Memory Access)を利用して、CPUを使わずにメモリ間のデータ転送を行うためのライブラリ。
CPUの負荷を減らしつつ高速転送がしたいときに使う。LCDの更新、オーディオ転送、バッファ間コピーなどに有用。
主要なメソッド
dma_channel_claim(channel)
DMAチャンネルを確保(専有)する
※0〜11までの12チャンネルが利用可能
dma_channel_get_default_config(channel)
DMA設定の初期値(config)を取得
channel_config_set_transfer_data_size(&config, size)
転送データサイズ(8bit、16bit、32bit)を設定
channel_config_set_read_increment(&config, enabled)
読み取り側のアドレスを自動で進めるかどうか
channel_config_set_write_increment(&config, enabled)
書き込み側のアドレスを自動で進めるかどうか
channel_config_set_dreq(&config, dreq)
DMA要求(DREQ)を設定
※SPIやPWMなどの周辺機器と連携する場合に使用
dma_channel_configure(channel, &config, write_addr, read_addr, count, start)
DMA転送を設定し、必要であれば同時に開始
※一度にまとめて設定するメイン関数
dma_channel_start(channel)
DMA転送を開始
dma_channel_is_busy(channel)
DMAが転送中かどうかを確認
dma_channel_abort(channel)
DMA転送を停止する
dma_channel_set_irq0_enabled(channel, enabled)
DMA完了割り込み(IRQ0)を有効化
dma_channel_set_irq1_enabled(channel, enabled)
DMA完了割り込み(IRQ1)を有効化(IRQ0と別系統)
DMAの基本的な仕組み
DMAはCPUの代わりに「メモリからメモリへ」「メモリから周辺機器へ」などのデータ転送を自動で行う仕組み。
例:画面更新
CPUが1バイトずつSPIへ書き込むと遅いため、DMAに任せると高速かつCPUが空いて効率が良い。
例:音声再生
PCMデータをPWMやI2Sへ流すとき、DMAを使うと安定して転送できる。
補足
DMAは「勝手に動くコピー機」
CPUが何もしなくてもメモリ転送してくれるため、動画・音声・LCD更新など処理が重い場面で非常に便利。
increment設定が重要
読み取り側・書き込み側でアドレスを進めるかどうかは用途で異なる。
例:バッファ → SPI へ転送(LCD更新)
読み取り側:increment = true(バッファを進めて読む)
書き込み側:increment = false(SPIは同じアドレスに送るだけ)
例:固定値を大量コピー
読み取り側:increment = false(同じ値を繰り返し読む)
書き込み側:increment = true(メモリへ書き込んでいく)
DREQ設定は「周辺機器とスピードを合わせる仕組み」
SPIやPWMに合わせてDMAが自動的に転送してくれる。
※DREQを設定しない場合、DMAは「全力」で即座にコピーを終えてしまう。
転送サイズ(8/16/32bit)も重要
メモリレイアウトに合わせないと正常にコピーされない場合がある。
DMAは「転送完了割り込み」と組み合わせると最強
転送が終わったタイミングで次の処理を実行することができる。
例:フレーム描画が終わったら次のバッファを準備する…など。
