DMA転送
CPUを回さずにデータを運ぶ仕組みが腑に落ちる。DMAコントローラが転送を肩代わりし、CPUは割り込みで完了だけ受け取る——高スループットと低CPU負荷が両立する理由を原理から理解できる。
- 1.DMAはCPUを介さずメモリ・ペリフェラル間を直接転送する専用ハードウェア。CPUは開始と完了割り込みだけを扱い、コピーループから解放される。
- 2.チャネルごとに送信元・宛先・長さを設定し、ペリフェラル要求やタイマなどのトリガで起動。単発/バースト/連続の各モードで粒度を選ぶ。
- 3.CPUとDMAは同じバスを共有するため競合が起きる。アービトレーションで調停され、CPUが完全に空くわけではなくバス帯域の奪い合いになる点が実務の勘どころ。
CPUに「運搬」をさせない
ADCが1サンプルごとに割り込みを上げ、CPUが値をレジスタからメモリへ1語ずつ書き写す——この素朴な方式は、サンプルレートが上がった瞬間に破綻します。1回の割り込みは文脈保存・ハンドラ実行・復帰で数十〜数百サイクルを消費し、毎サンプルでこれを払えば CPU は運搬だけで飽和するからです。
DMA(Direct Memory Access)は、この「ただの運搬」を CPU から切り離す専用ハードウェアです。DMA コントローラ(DMAC)が自らバスマスタとなり、送信元アドレスから宛先アドレスへデータを直接動かします。CPU の役割は転送の設定と、終わった後の後始末だけ。その間、CPU は演算やほかの割り込み処理に専念できます。
転送を成立させる3つの記述子
DMA の1回の転送は、最低限つぎの3要素で定義されます。DMAC 内部のレジスタ(またはメモリ上のディスクリプタ)にこれらを書き込むことが「設定」の実体です。
| パラメータ | 意味 | 典型的な扱い |
|---|---|---|
| 送信元アドレス | 読み出し元。ペリフェラルのデータレジスタ or メモリ | ペリフェラル側は固定、メモリ側は転送ごとに自動インクリメント |
| 宛先アドレス | 書き込み先。メモリ or ペリフェラル | 同上。方向により固定側/増加側が入れ替わる |
| 転送語数/サイズ | 残り転送カウントと1語のビット幅 | カウントは1語ごとに減算、0で転送完了 |
肝は アドレスインクリメントの向き です。メモリからペリフェラルへ送る(メモリ・ツー・ペリフェラル)なら、メモリ側アドレスは1語ごとに進め、ペリフェラル側の固定レジスタ(送信FIFO 等)には同じアドレスへ書き続けます。受信はこの逆です。この非対称な番地制御こそが、DMAC が CPU なしで転送を回せる中核ロジックです。
チャネルとトリガ:誰が「今だ」と言うか
DMAC は複数の チャネル を持ちます。チャネルとは独立した転送コンテキストのことで、UART受信・SPI送信・ADC取り込みなどを同時並行で担当させられます。各チャネルは自分専用のアドレスとカウントを保持します。
問題は「いつ1語を動かすか」です。答えは トリガ(リクエスト) で、大きく2系統あります。
メモリ間コピー(memcpy 代替)のように相手の準備を待つ必要がない転送は、設定直後にソフトウェアが起動を指示し、DMAC が全力で連続実行します。一方でペリフェラル絡みの転送は、ハードウェアトリガで駆動します。UART受信レジスタにデータが入った、送信FIFO に空きができた、ADC変換が完了した——といったペリフェラル側の DMA リクエスト信号が1語ぶんの転送を要求し、DMAC がそれに応じて1語動かす。これによりデータの生成・消費の速度に転送が自然に同期します。
タイマを使えば、一定周期で規則的にトリガをかけることもできます。たとえば「10kHz のタイマ更新ごとに1サンプルを DAC へ送る」構成にすれば、CPU を一切介さずに正確なレートの波形出力が成立します。
バースト転送:1回のトリガでまとめて運ぶ
トリガ1発で動かす量は選べます。ここがスループットを左右します。
[転送単位のモード]
単発(single) … 1トリガ → 1語だけ転送
ペリフェラルFIFOの1段対応に向く
バースト(burst) … 1トリガ → 連続数語(例4語/8語)をまとめて転送
バス権を握ったまま複数語を流すため
アドレス確定などの固定オーバーヘッドを償却でき効率的
ブロック/連続 … カウントが尽きるまで一気に転送(主にメモリ間)
バースト転送が効くのは、バスの1トランザクションには起動コスト(アービトレーション、アドレスフェーズ)が必ず伴うからです。1語ごとにそれを払うより、バス権を保持したまま複数語を連射したほうが、実効帯域が上がります。ただしバースト長を伸ばすほど、その間 CPU がバスを待たされる時間も伸びる——このトレードオフは後述します。
連続ストリーム(オーディオ、連続ADC)では、転送が終わるたびに CPU が再設定していては隙間が生じます。多くの DMAC はサーキュラ(循環)モードを備え、カウントが0になると自動で先頭アドレスへ巻き戻して転送を続けます。さらに ping-pong(ダブルバッファ)では、半分埋まった時点で「ハーフ完了」割り込みを上げます。CPU が前半バッファを処理している間に DMA が後半を埋める——という交互運用で、取りこぼしのない連続処理が組めます。
完了割り込みとエラー通知
転送カウントが0に達すると、DMAC は 転送完了(TC)割り込み を上げます。CPU はここで初めて介入し、受信バッファを上位へ渡す、次の転送を仕込む、といった後処理を行います。割り込みの回数が「サンプルごと」から「バッファごと」へ激減する点が、DMA が CPU 負荷を下げる直接の理由です。
多くの実装は ハーフ完了割り込み(前述の ping-pong 用)や、バスエラー・設定不整合を知らせる エラー割り込み も持ちます。DMA を使うコードのバグは往々にして「割り込みが来ない」形で現れるため、TC/ハーフ/エラーの各フラグを取り違えないことが実装上の要点です。割り込みの一般的な仕組みは /os/ 側の解説も参照してください。
CPU負荷とバス競合:ここが本質
DMA は「CPU を完全に解放する魔法」ではありません。DMAC と CPU は同じシステムバス(とメモリ)を共有 しており、両者が同時にアクセスしようとすれば競合します。これを裁くのが バスアービトレーション です。
DMAC がバス権を1語ぶんだけ借りては CPU に返す方式を サイクルスチール と呼びます。CPU の隙間を縫うため CPU 停止は最小ですが、転送は遅くなります。逆にバースト/ブロック転送でバス権を長く握ると転送は速い反面、その間 CPU はメモリアクセスを待たされ、実効性能が落ちます。「DMA を回したのに CPU の処理が妙に遅い」現象の正体は、多くがこのバス帯域の奪い合いです。優先度の高いバスマスタ設定やバースト長の調整で均衡を取ります。
競合の影響は接続トポロジにも依存します。CPU コアと DMAC が別々のバスマトリクス経路・別バンクのメモリへアクセスするなら競合はほぼ起きませんが、同一メモリを奪い合う構成では上限が見えてきます。SoC のバス構造(クロスバー、AXI/AHB のマスタ・スレーブ関係)を把握することが、DMA 設計では欠かせません。
もう1つ見落とされがちなのが キャッシュとの整合性 です。CPU が書いたデータがまだキャッシュに留まり主メモリへ届いていない状態で DMA がメモリを読むと、古い値を送ってしまいます。逆に DMA が書き込んだ受信データを、CPU が古いキャッシュ内容で読むこともあります。
キャッシュを持つ MCU/SoC で DMA を使うなら、コヒーレンシ対策は必須です。送信前にはバッファを クリーン(write-back) して主メモリへ書き戻し、受信後には該当領域を インバリデート して古いキャッシュ行を捨てる——この操作を怠ると、間欠的で再現困難なデータ化けを招きます。DMA バッファをノンキャッシャブル領域に置く、あるいはハードウェアコヒーレントなバス経路を使う、という設計上の回避策も定石です。
「DMA の利点は」には『CPU を介さず転送でき、割り込み回数と CPU 負荷を削減できる』。「CPU は完全に自由になるか」には『否。バスを共有するためアービトレーションで競合し、バス帯域を奪い合う』。バースト転送の意義(固定オーバーヘッドの償却)と、キャッシュコヒーレンシ対策(送信前クリーン・受信後インバリデート)まで押さえると得点源になります。
まとめ
DMA 転送は、CPU を「運搬役」から降ろし、設定と完了処理だけを任せることで高スループットと低 CPU 負荷を両立させる仕組みです。チャネルに送信元・宛先・カウントを与え、ペリフェラル要求やタイマでトリガし、バーストで効率を稼ぎ、完了割り込みで CPU を呼ぶ——この一連が骨格になります。ただし CPU とバスを共有する以上、競合とキャッシュ整合性という現実がついて回ります。DMA を「万能の高速化」ではなく「バス資源をやりくりする非同期転送エンジン」として捉えると、設計もデバッグも一本の筋で見通せます。
組込み・IoT Article
DMA転送を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
DMA
比較で見る軸
難易度: advanced / カテゴリ: 組込み・IoT / タグ数: 5
導入後に効く点
チャネルごとに送信元・宛先・長さを設定し、ペリフェラル要求やタイマなどのトリガで起動。単発/バースト/連続の各モードで粒度を選ぶ。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- 組込み・IoT
- タグ数
- 5
判断チェックリスト
- 自社の用途が「DMA / 組み込み」に近いか確認する。
- 強みである「DMAはCPUを介さずメモリ・ペリフェラル間を直接転送する専用ハードウェア。CPUは開始と完了割り込みだけを扱い、コピーループから解放される。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。