Nios® Vプロセッサー・ソフトウェア開発者ハンドブック

ID 743810
日付 10/31/2022
Public

このドキュメントの新しいバージョンが利用できます。お客様は次のことを行ってください。 こちらをクリック 最新バージョンに移行する。

ドキュメント目次

6.9.2. DMAの受信チャネル

DMA 受信チャネルは、DMA 送信チャネルと同様に動作します。ソフトウェアは、DMA 受信チャネルのハンドルを取得できます。 alt_dma_rxchan_open() 関数。その後、 alt_dma_rxchan_prepare() 受信リクエストを送信する関数。alt_dma_rxchan_prepare()のプロトタイプは:
typedef void (alt_rxchan_done)(void* handle, void* data);
int alt_dma_rxchan_prepare (alt_dma_rxchan dma, 
void* data,
alt_u32 length,
alt_rxchan_done* done, 
void* handle);

この関数を呼び出すと、最大lengthバイトのデータがアドレスdataに配置されるように、受信リクエストがチャネルdmaにポストされます。この関数は、DMA トランザクションが完了する前に戻ります。戻り値は、リクエストが正常にキューに入れられたかどうかを示します。負の戻り値は、リクエストが失敗したことを示します。トランザクションが完了すると、ユーザー指定の関数done()が引数handleとともに呼び出され、通知と受信データへのポインタが提供されます。

特定のエラーにより、DMA 転送が完了しない場合があります。通常、これは壊滅的なハードウェア障害が原因です。たとえば、転送に関与するコンポーネントが読み取りまたは書き込み要求に応答しない場合などです。DMA 転送が完了しない場合 (つまり、length 未満のバイトが転送された場合)、関数は呼び出されません。

DMA 受信チャネルを操作するために、次の 2 つの追加関数が提供されています。 alt_dma_rxchan_depth()およびalt_dma_rxchan_ioctl().

注: Avalon-MM DMA デバイスを使用して(メモリー間転送ではなく)ハードウェアから受信している場合、リクエスト引数を alt_dma_rxchan_ioctl()に設定してALT_DMA_RX_ONLY_ON関数を呼び出します。

alt_dma_rxchan_depth()は、デバイスのキューに入れることができる受信リクエストの最大数を返します。 alt_dma_rxchan_ioctl()は、受信デバイスのデバイス固有の操作を実行します。

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include "sys/alt_dma.h"
#include "alt_types.h"
/* flag used to indicate the transaction is complete */
volatile int dma_complete = 0;
/* function that is called when the transaction completes */
void dma_done (void* handle, void* data)
   {
   dma_complete = 1;
   }
   int main (void)
      {
      alt_u8 buffer[1024];
      alt_dma_rxchan rx;
      /* Obtain a handle for the device */
      if ((rx = alt_dma_rxchan_open ("/dev/dma_0")) == NULL)
         {
            printf ("Error: failed to open device\n");
            exit (1);
         }
      else
         {
         /* Post the receive request */
         if (alt_dma_rxchan_prepare (rx, buffer, 1024, dma_done, NULL) < 0)
            {
               printf ("Error: failed to post receive request\n");
               exit (1);
            }
         /* Wait for the transaction to complete */
         while (!dma_complete);
            printf ("Transaction complete\n");
            alt_dma_rxchan_close (rx);
      }
      return 0;
}