STM32いじってみた(10) DMA編(その1)

このシリーズもご無沙汰ですが、DMA で遊んでみたという結果として載せたいと思います。

DMA とは

Direct Memory Access の略で、要はメモリ間のデータのやり取りを CPU を介さずして行うというものです。つまり CPU に負荷をかけることなくデータ転送が行えるというのが最大の特徴でありメリットなのです。基本はペリフェラルからどこかにデータを格納するのに使いますね。
でもデータ転送ってそんなにコストがかかるものなの?と思われる方もいると思いますので、技術的に反論したいとおもいます。

ケース1: ペリフェラルからのセンサ値をシリアルで表示

計測等でよく使うルーチンです。最初に DMA 無しの処理を考えてみましょう。

  1. ペリフェラル(ADC等)にトリガーを送る
  2. 値の取得完了まで待つ
  3. シリアル通信送信用の関数を呼ぶ
  4. 送信完了まで待つ

と、まあ非常に無駄が多い動きです。特に

  • 関数ジャンプ
  • 処理完了まで待つ無駄ループ

これが動作のボトルネックになりかねません。じゃあペリフェラルの割り込みでいいじゃないかと思いますが、確かに比較的長い周期でセンサ取得を行うならそれでいいと思います。というのも、従来の割り込みだと連続的にデータを読めないからです。
そこで DMA を使うと CPU はペリフェラル、DMAC(DMA Controller) の初期化をしたあとは、全くそのペリフェラルに関して無視を決め込むことができます。つまり逐一トリガーを送らなくてもず〜〜っとリアルタイムでスキャンを続けるという処理が可能なのです。

まとめて言うと、以下のようです↓

  • ペリフェラル割り込みだと逐一トリガ送信が必要リアルタイムなデータ取得には向かない
  • DMA だと一度設定してしまえば後は何もしなくてもペリフェラルが動作してくれる。リアルタイムにデータを取れる
    • 常にデータ更新があるので、ユーザは知らん顔をして読みたい時にデータを読めばいい

ケース2: ペリフェラルからデータを複数個取得して割り込み発生

こちらも上と似たケースですが、まとめてデータを処理したいときにメリットの多いケースです。DMA を使わないと…

  • データ数カウンタの計算が必要(最低でも3サイクル CPU クロックを食う)
  • 無駄な割り込み関数ジャンプが増える

というデメリットがありますが、一方で DMA を使うと

  • データをリアルタイムで複数個読んだ段階ですでにメモリ上の変数にデータが格納されている
  • 個数を DMAC に登録しておいて、規定の数だけ読み込まれたら割り込みが入るので、その時に所望の処理をしてしまえばいい
    • 無駄な割り込み関数ジャンプがない

ということなのです。すごいでしょう。

さて

…と書いた所で記事が長くなりましたので続きは次回!つまらない利用例も提示します。