コンテンツにスキップ

DMA

DMAとは

DMA(Direct Memory Access)は、CPUを介さずに周辺機器とメモリの間でデータを転送する機能である。

通常、UARTやADCなどの周辺機器からデータを取得する場合はCPUが処理を行う。

ADC
 ↓
CPU
 ↓
メモリ

しかし大量のデータを扱う場合、この方法ではCPUの負荷が大きくなる。

そこでDMAを利用すると、

ADC
 ↓
DMA
 ↓
メモリ

のようにCPUを介さずにデータ転送が可能になる。


なぜ必要なのか

例えばADCで1秒間に10000回測定する場合を考える。

DMAを使わない場合、

ADC変換完了
↓
CPU割り込み
↓
データ取得
↓
メモリへ保存

を10000回繰り返す必要がある。

そのためCPUはほとんどADC処理だけに使われてしまう。


DMAを使う場合、

ADC
 ↓
DMA
 ↓
メモリ

で自動的にデータが保存される。

CPUは必要な時だけデータを参照すればよい。


DMAの仕組み

DMAは専用の転送回路を持っている。

CPUとは独立して動作し、

  • ADC
  • UART
  • SPI
  • I2C
  • DAC

などの周辺機器とメモリを直接接続できる。


イメージ

           CPU
            ↑
            │
            │
ADC ←→ DMA ←→ RAM

CPUは転送開始を指示するだけでよい。


転送の流れ

DMA転送は一般的に以下の流れで行われる。

CPU
 ↓
DMA設定
 ↓
転送開始
 ↓
DMAが自動転送
 ↓
転送完了
 ↓
割り込み通知

DMAのメリット

CPU負荷を削減できる

DMA最大のメリットである。

大量のデータ転送をCPUが行う必要がなくなる。


高速処理が可能

CPUより効率よくデータ転送できる。

高速なADCやSPIではほぼ必須である。


リアルタイム性が向上する

CPUは別の処理に集中できる。

例えば

  • モータ制御
  • 通信処理
  • 状態監視

などを同時に実行しやすくなる。


DMAのデメリット

設定が少し複雑

通常の周辺機器設定に加えてDMA設定が必要になる。


デバッグが難しい

CPUが直接触らないため、問題発生時の原因特定が難しくなる場合がある。


ADCとDMA

DMAが最もよく利用される例である。


DMAなし

ADC
 ↓
CPU
 ↓
メモリ

DMAあり

ADC
 ↓
DMA
 ↓
メモリ

ADC値が自動的に配列へ格納される。

uint16_t adcBuffer[100];

UARTとDMA

UART受信でもよく利用される。

DMAなし

受信
 ↓
割り込み
 ↓
CPU処理

DMAあり

受信
 ↓
DMA
 ↓
受信バッファ

大量の通信でもCPU負荷を抑えられる。


SPIとDMA

SPIは高速通信を行うためDMAとの相性が良い。

SDカード
 ↓
SPI
 ↓
DMA
 ↓
RAM

液晶やSDカードでは頻繁に利用される。


Circular Mode

DMAには循環モードが存在する。


通常モード

転送完了
 ↓
停止

循環モード

転送完了
 ↓
先頭へ戻る
 ↓
再開

イメージ

[1][2][3][4]
 ↑        ↓
 └────────┘

常時データを取得する用途に向いている。


STM32での利用

CubeMXではDMAを簡単に有効化できる。

ADC1
 └ DMA Enabled

または

USART1
 └ DMA RX Enabled

ADC + DMAのコード例

uint16_t adcBuffer[100];

HAL_ADC_Start_DMA(
    &hadc1,
    (uint32_t*)adcBuffer,
    100
);

これだけで100個のADC値が自動的に格納される。


UART + DMAのコード例

uint8_t rxBuffer[64];

HAL_UART_Receive_DMA(
    &huart1,
    rxBuffer,
    64
);

64バイト分の受信データが自動保存される。


DMA完了割り込み

転送完了時に通知を受けることができる。

void HAL_ADC_ConvCpltCallback(
    ADC_HandleTypeDef *hadc
)
{
    // 転送完了時の処理
}

Asterでの利用例

Asterでは以下の用途でDMAの利用が考えられる。

ADC監視

電圧測定
 ↓
ADC
 ↓
DMA
 ↓
RAM

UART通信

AC
 ↓
UART
 ↓
DMA
 ↓
受信バッファ

センサデータ収集

センサ
 ↓
SPI
 ↓
DMA
 ↓
RAM

DMAを使うべき場面

以下のような場合はDMA利用を検討するとよい。

  • ADCを定期的に読む
  • UARTで大量通信する
  • SPIで高速通信する
  • CPU負荷を下げたい
  • リアルタイム性を高めたい

まとめ

DMAはCPUを介さずにデータ転送を行う機能である。

  • CPU負荷を大幅に削減できる
  • ADCとの相性が非常に良い
  • UARTやSPIでもよく利用される
  • 高速通信や大量データ処理で効果を発揮する
  • STM32開発では必須級の機能である

特にSTM32では「ADC + DMA」「UART + DMA」の組み合わせが非常によく利用されるため、DMAの仕組みを理解しておくことで効率的なシステム設計が可能になる。