UARTの受信DMA処理の定石
SPIマスタ等の自分からクロックを出力する通信の場合は、何バイト受信するかを自分で把握できているのでDMAを仕掛けるのは簡単ですが、UARTの場合、非同期でいつ来るかわからないデータを待ち受けてるのが普通だと思います。
いつ受信するかわからない。何バイト受信するかわからない、という状況なので、指定回数受信したらDMA割込み、というシンプルな使い方ができず、実装をどうすればいいのか悩んでいます。
パッと思いついたのは、下記で示しているように、贅沢にもバッファを3本用意して、周期的にDMAバッファを切り替えるという方法です。
for (;;)
{
メインループ処理;
if (前回の処理から適当な期間が経過した)
{
int count; // DMAカウンタ
int prev;
UART割込み無効;
count = getDMACount();
prev = index;
index ^= 1; // DMAバッファインデックスの切替
// この区間で他の割込み処理が入るとオーバーランが発生しそうなので全割込み禁
// 止にしておいた方がよい?
setDMABuffer(duble_buffer[index]);
UART割込み有効;
if (count > 0)
{
// ダブルバッファとは別に用意したメインのバッファの末尾にコピーする。
memcpy(main_buffer + last, duble_buffer[prev], count);
last += count;
}
}
}
こういう処理ってほとんどやることは決まっていると思うので、定石みたいな実装があると思うのですが、何か実装の参考になる文献や入手可能なソースコードはないでしょうか。Linuxカーネルのソースもちょっと覗いてみましたが、該当しそうな部分が見つけれらませんでした。