変更要約: 初版
2.4DMAとメモリマップドI/O
CPUを介さずメモリとデバイス間でデータ転送を行いCPU負荷を分散するDMA(ダイレクトメモリアクセス)、周辺デバイスのレジスタをメモリ空間の一部として扱うメモリマップドI/O、そして複数のマスタがバスを共有するときに生じるバス調停とリアルタイム性との競合を学びます。
組込みシステムでは、センサからのデータ取得や通信インタフェースの送受信のたびにCPUが1バイトずつ介在すると、演算に使える時間が圧迫されます。DMAはこの問題を解決する仕組みですが、「CPUの負荷を減らす」というメリットの裏には、バス調停という新たな競合の種があります。この節では、DMAとメモリマップドI/Oの基本的な仕組みに加えて、DMAがリアルタイム性とどう競合し得るかという設計上の注意点を学びます。
2.4.1DMAによるCPU負荷分散
- DMA(ダイレクトメモリアクセス)=DMAコントローラが、CPUの介在なしにメモリとメモリ間、あるいはメモリと周辺デバイス間でデータを直接転送する仕組み。CPUは転送元・転送先・転送量をDMAコントローラに設定して起動するだけでよく、転送完了までの間、CPUは他の演算処理を並行して実行できる(=CPU負荷の分散)。
- 転送完了はCPUへの割込みで通知されるのが一般的。大量のデータ(センサのバースト取得・シリアル通信のバッファ転送等)を扱う用途ほどDMAの恩恵が大きいが、小容量・低頻度の転送ではDMA設定のオーバヘッドの方が上回り、単純なCPUによるポーリング/直接転送の方が効率的な場合もある。
2.4.2メモリマップドI/O
- メモリマップドI/O=周辺デバイスの制御・状態レジスタを、通常のメモリと同一のアドレス空間内の特定アドレスに割り当てる方式。CPUは専用のI/O命令を使わず、通常のメモリ読み書き命令だけでデバイスを操作できるため、命令セットが単純化でき、コンパイラの最適化やC言語からの直接操作もしやすい。
- メモリマップドI/Oのレジスタは、通常のメモリと違い読み書きのたびに副作用(デバイス状態の変化)が起きるため、コンパイラが最適化のために読み書きを省略・並べ替えしないよう、該当領域をvolatileとして宣言する必要がある。これを怠るとレジスタへの書き込みが最適化で消される等の重大な不具合になる。
「DMA=CPUを介さずメモリ⇔デバイス間転送・CPU負荷分散・完了は割込み通知」「メモリマップドI/O=デバイスレジスタを通常メモリと同一アドレス空間に配置し通常命令で操作・volatile宣言が必須」が最頻出です。DMAは万能ではなく小容量・低頻度転送では設定オーバヘッドが上回ることがある点も押さえましょう。
あるシステムアーキテクトが、複数のセンサからの高速なデータ取得と、ハードリアルタイムの制御ループ(一定周期でPWM出力を更新するタスク)を同じMCU上で両立させる設計を検討しています。センサデータの取得をDMAでバッファへ転送させることで、CPUがバイト単位の転送に張り付く必要がなくなり、制御ループの演算に集中できるようになるはずでした。ところが実際に動作させると、まれに制御ループの実行時間が跳ね上がり、周期を逸脱するという不具合が発生しました。原因を調べると、DMAコントローラとCPUは同じメモリバスを共有しており、バス調停の仕組みにより、DMAが大量データを転送している最中はCPUのメモリアクセス(命令フェッチやデータアクセス)がバス使用権を得られず待たされることが判明しました。つまり、「DMAでCPUの処理時間を解放したはず」が、実際にはCPUとDMAがメモリバスという共有資源を奪い合い、DMA転送中のCPUアクセスがバス調停によって遅延するという新たな競合を生んでいたのです。この対策として、DMAコントローラのバス使用権をラウンドロビン等の単純な調停に任せず、制御ループが動く周期の直前だけDMA転送を一時停止させる、あるいはDMA転送を小さいバースト単位に分割してCPUアクセスの合間に挟み込むといったスケジューリングの工夫が必要になります。この事例が示す教訓は、「CPUの負荷を下げる」ことと「バス競合を含めた全体のリアルタイム性を保証する」ことは別の問題であり、DMA導入時は必ずバス調停によるCPUアクセスの遅延も設計に織り込まなければならないという点です。
| 項目 | CPUによる直接転送 | DMA転送 |
|---|---|---|
| CPUの介在 | 転送のたび必要 | 起動時の設定のみ |
| CPU負荷 | 高い(占有される) | 低い(並行処理可能) |
| リアルタイム性への影響 | CPU占有時間が予測しやすい | バス調停による遅延を考慮要 |
ひっかけ: 「DMAを導入すればCPUの負荷が下がるので、リアルタイム性は必ず向上する」は誤りです——DMAコントローラとCPUは同じメモリバスを共有するため、大量データ転送中はバス調停によりCPUのメモリアクセスが遅延し、かえって制御ループの応答がばらつくことがあります。また「メモリマップドI/Oのレジスタは通常のメモリと同様に扱ってよく、volatile宣言は不要」も誤り=副作用のあるレジスタをvolatileなしで扱うと、コンパイラの最適化により読み書きが省略・並べ替えられ重大な不具合を招きます。
2.4.3この節のまとめ
- DMAはCPUを介さずメモリ⇔デバイス間転送を行いCPU負荷を分散、完了は割込みで通知
- メモリマップドI/Oはデバイスレジスタを通常メモリと同一アドレス空間に配置し通常命令で操作、volatile宣言が必須
- DMAとCPUはメモリバスを共有するためバス調停による遅延が生じ、リアルタイム性との競合を設計時に考慮する
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. センサデータの高速取得にDMAを導入し、CPUが制御ループの演算に専念できるようにした。ところが導入後、制御ループの実行時間がまれに大きく跳ね上がり周期を逸脱するようになった。この現象の原因として最も適切なものはどれか。
Q2. 周辺デバイスの制御レジスタを通常のメモリと同一のアドレス空間に配置し、通常のメモリ読み書き命令だけで操作できるようにする方式を採用した。この方式でC言語のコードを書く際に必ず注意すべき点として最も適切なものはどれか。
Q3. 小容量(数バイト)のセンサ値を数秒に1回だけ取得する用途で、DMAの導入を検討している。この用途にDMAを適用する判断として最も適切なものはどれか。

