Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux DMA 引擎核心操作接口全集:s3c2410_dma API 規範

編輯:Linux 教學

Samsung S3C 系列 SoC 的 DMA 子系統定義了一套完整的操作函數集,涵蓋通道申請/釋放、配置/控制、傳輸排隊、狀態查詢、回調通知等全生命周期。這些接口形成 arch/arm/plat-samsung/include/plat/dma.h,為上層驅動(音頻、LCD、NAND 等)提供統一抽象。本文系統梳理核心枚舉、結構體與函數原型。

一、 核心枚舉類型

1. 傳輸結果 s3c2410_dma_buffresult

enum s3c2410_dma_buffresult {
    S3C2410_RES_OK,      // 成功完成
    S3C2410_RES_ERR,     // 總線/設備錯誤
    S3C2410_RES_ABORT    // 被主動終止
};

2. 數據源類型 s3c2410_dmasrc

enum s3c2410_dmasrc {
    S3C2410_DMASRC_HW,       // 源為硬件(外設→內存)
    S3C2410_DMASRC_MEM,      // 源為內存(內存→外設)
    S3C_DMA_MEM2MEM,         // 內存→內存(雙向)
    S3C_DMA_MEM2MEM_SET,     // 內存填充
    S3C_DMA_MEM2MEM_P,       // 硬件輔助內存拷貝
    S3C_DMA_PER2PER          // 外設→外設
};

3. 通道操作命令 s3c2410_chan_op

enum s3c2410_chan_op {
    S3C2410_DMAOP_START,     // 啟動通道
    S3C2410_DMAOP_STOP,      // 停止
    S3C2410_DMAOP_PAUSE,     // 暫停
    S3C2410_DMAOP_RESUME,    // 恢復
    S3C2410_DMAOP_FLUSH,     // 刷新隊列
    S3C2410_DMAOP_TIMEOUT,   // 內部超時信號
    S3C2410_DMAOP_STARTED,   // 已啟動通知
    S3C2410_DMAOP_ABORT      // 異常中止
};

二、 客戶端與回調結構

struct s3c2410_dma_client {
    char *name;   // 驅動名稱,用於調試
};

struct s3c2410_dma_chan;  // 前向聲明

// 緩衝完成回調:buf=傳輸緩衝區, size=字節數, result=結果碼
typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *, void *buf, int size, enum s3c2410_dma_buffresult result);

// 通道操作回調:處理 START/STOP 等命令
typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, enum s3c2410_chan_op);

三、 核心 API 函數表

函數原型功能描述
s3c2410_dma_set_opfnint s3c2410_dma_set_opfn(unsigned int chan, s3c2410_dma_opfn_t rtn);註冊通道操作回調
s3c2410_dma_set_buffdone_fnint s3c2410_dma_set_buffdone_fn(unsigned int chan, s3c2410_dma_cbfn_t rtn);註冊傳輸完成回調
s3c2410_dma_requestint s3c2410_dma_request(unsigned int chan, struct s3c2410_dma_client *client, void *dev);獨佔申請 DMA 通道
s3c2410_dma_ctrlint s3c2410_dma_ctrl(unsigned int chan, enum s3c2410_chan_op op);改變通道狀態
s3c2410_dma_setflagsint s3c2410_dma_setflags(unsigned int chan, unsigned int flags);設置通道標志位
s3c2410_dma_freeint s3c2410_dma_free(unsigned int chan, struct s3c2410_dma_client *client);釋放通道(含中止未完成傳輸)
s3c2410_dma_enqueueint s3c2410_dma_enqueue(unsigned int chan, void *id, dma_addr_t data, int size);將緩衝區入隊(需 DMA 一致性內存)
s3c2410_dma_configint s3c2410_dma_config(unsigned int chan, int xferunit);配置傳輸單元大小
s3c2410_dma_setswapint s3c2410_dma_setswap(unsigned int chan, unsigned int bytes_swap);配置字節交換(大小端轉換)
s3c2410_dma_devconfigint s3c2410_dma_devconfig(unsigned int chan, enum s3c2410_dmasrc source, unsigned long devaddr);配置外設地址與傳輸方向
s3c2410_dma_getpositionint s3c2410_dma_getposition(unsigned int chan, dma_addr_t *src, dma_addr_t *dest);獲取當前傳輸源/目標地址

四、 使用流程範例

// 1. 定義客戶端
static struct s3c2410_dma_client my_client = { .name = "my_audio" };

// 2. 申請通道(假設通道 1 用於 I2S TX)
int ret = s3c2410_dma_request(1, &my_client, dev);
if (ret < 0) return ret;

// 3. 註冊回調
s3c2410_dma_set_buffdone_fn(1, my_dma_callback);
s3c2410_dma_set_opfn(1, my_op_callback);

// 4. 配置外設
s3c2410_dma_devconfig(1, S3C2410_DMASRC_MEM, I2S_TX_FIFO_ADDR);

// 5. 配置傳輸參數
s3c2410_dma_config(1, 4);  // 32-bit 寬度

// 6. 準備緩衝區(必須 dma_alloc_coherent 或 cache 操作)
void *buf = dma_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);

// 7. 入隊並啟動
s3c2410_dma_enqueue(1, token, dma_addr, size);
s3c2410_dma_ctrl(1, S3C2410_DMAOP_START);

// 8. 釋放流程
s3c2410_dma_ctrl(1, S3C2410_DMAOP_STOP);
s3c2410_dma_free(1, &my_client);
dma_free_coherent(dev, size, buf, dma_addr);

五、 遷移至 dmaengine 子系統

現代內核(3.0+)推薦使用統一 dmaengine API:

  • dma_request_chan() / dma_release_chan()
  • dmaengine_prep_slave_single() / dmaengine_submit()
  • dma_async_issue_pending() / dmaengine_terminate_all()

S3C DMA 驅動實現 struct dma_device 並註冊到 dmaengine,舊版 s3c2410_dma_* API 通過兼容層映射,新驅動請直接使用 dmaengine 接口。

Copyright © Windows教程網 All Rights Reserved