DMA引擎的編程指南通常涉及一系列步驟和API調用,以確保數據在內存之間的高效傳輸,而無需CPU的直接干預。
DMA引擎的編程指南包括以下部分:
一、編寫微代碼為AXI事務編寫CCRx程序
通道微碼用于設置dmac.CCRx寄存器以定義AXI事務的屬性。這是通過使用DMAMOV CCR指令完成的。
在啟動DMA傳輸之前,用戶應該通過寫入dmac.CCR{7:0}寄存器對微碼進行編程。以下是微碼中寫入的AXI屬性:
- 基于突發的類型(遞增或固定地址)對src_inc和dst_inc比特字段進行編程。這會影響ARBURST[0]和AWBURST[0]AXI信號。
- 對src_burst_size和dst_burst_size比特字段(AXI上每個數據節拍的字節數)進行編程。這會影響ARSIZE[2:0]和AWSIZE[2:0]AXI信號。
- 對src_burst_len和dst_burst_len比特字段(每個AXI突發事務的數據節拍數)進行編程。這會影響ARLEN[3:0]和AWLEN[3.0]AXI信號。
- 對src_cache_ctrl和dst_cache_ctrl位字段進行編程(緩存策略)。這會影響ARCACHE[2:0]和AWCACHE[2:0]AXI信號。
- 對src_prot_ctrl和dst_prot_ctrl位字段(管理器線程的安全狀態)進行編程。如果管理器線程是安全的,則ARPROT[1]應設置為0,如果不安全,則應設置為1。ARPROT[0]和ARPROT[2]值應設置為=0。例如:
? ? ? ? ? --如果DMA管理器是安全的,則設置src_prot_ctrl=0'b0000;
? ? ? ? ? --如果DMA管理器是不安全的,則設置scr_prot_ctrl=0'b010。
? ? ? 6. 程序endian_swap_size=0(不交換)
二、內存到內存的傳輸
顯示DMAC操作以執行對齊、未對齊和固定數據傳輸的微碼示例。對齊傳輸請參見表1,未對齊傳輸請參閱表2,固定傳輸請參閱圖3。
注意:如果DMA傳輸使用緩存,程序員應確保使用適當的緩存操作來保持緩存一致性。在對DMA通道進行編程之前,應清除與存儲器地址范圍相對應的高速緩存條目并使其無效。
描述 | 代碼 | MFIFO使用 |
簡單對齊程序 | DMAMOV CCR, SB4 SS64 DB4 DS64 DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4000 DMALP 16 DMALD DMAST DMALPEND DMAEND | 每個DMALD需要四個條目,而每個DMAST刪除四個條目。 |
具有多個負載的對齊不對稱程序 | DMAMOV CCR, SB1 SS64 DB4 DS64 DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4000 DMALP 16 DMALD DMALD DMALD DMALD DMAST DMALPEND | 每個DMALD需要一個條目,而每個DMAST刪除四個條目。 |
具有多個存儲的對齊不對稱程序 | DMAMOV CCR, SB4 SS64 DB1 DS64 DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4000 DMALP 16 DMALD DMAST DMAST DMAST DMAST DMALPEND DMAEND | 每個DMALD需要四個條目,而每個DMAST刪除一個條目。 |
描述 | 代碼 | MFIFO使用 |
已對齊的源地址與未對齊的目標地址 | DMAMOV CCR, SB4 SS64 DB4 DS64 DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4004 DMALP 16 DMALD DMAST DMALPEND DMAMOV CCR, SB4 SS64 DB1 DS32 DMAST DMAEND | 第一條DMALD指令加載四個雙字,但由于目標地址未對齊,DMAC將它們移位四個字節,因此它只刪除第一個循環中的三個條目,留下一個靜態MFIFO條目。每個DMAST只需要四個數據條目,因此額外的條目在程序的持續時間內一直使用,直到最后一個DMAST清空為止。 |
未對齊的源地址與對齊的目標地址 | DMAMOV CCR, SB4 SS64 DB4 DS64 DMAMOV SAR, 0x1004 DMAMOV DAR, 0x4000 DMALD DMALP 15 DMALD DMAST DMALPEND DMAMOV CCR, SB1 SS32 DB4 DS64 DMALD DMAST DMAEND | 第一DMALD指令沒有加載足夠的數據以使DMAC能夠執行DMAST,因此在循環開始之前,程序包括額外的DMALD。在第一個DMALD之后,隨后的DMALD與源突發大小對齊。這優化了性能,但需要更多的MFIFO條目。 |
未對齊的源地址到對齊的目標地址,初始負載過多 | DMAMOV CCR, SB5 SS64 DB4 DS64 DMAMOV SAR, 0x1004 DMAMOV DAR, 0x4000 DMALD DMAST DMAMOV CCR, SB4 SS64 DB4 DS64 DMALP 14 DMALD DMAST DMALPEND DMAMOV CCR, SB3 SS64 DB4 DS64 DMALD DMAMOV CCR, SB1 SS32 DB4 DS64 DMALD DMAST DMAEND | 第一DMALD指令加載五拍數據以使DMAC能夠執行第一DMAST。 |
對齊的突發大小,未對齊的MFIFO | DMAMOV CCR, SB4 SS32 DB4 DS32 DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4004 DMALP 16 DMALD DMAST DMALPEND DMAEND | 如果DMAC配置具有32位AXI數據總線寬度,則該程序需要四個MFIFO條目。然而,在這個例子中,DMAC具有64位AXI數據總線寬度,并且由于目的地地址不是64位對齊的,所以它需要三個而不是預期的兩個MFIFO條目。 此示例具有零個MFIFO條目的靜態要求和三個MFIF奧條目的動態要求。 |
描述 | 代碼 | MFIFO使用 |
地址對齊的固定目的地 | DMAMOV CCR, SB2 SS64 DB4 DS32 DAF DMAMOV SAR, 0x1000 DMAMOV DAR, 0x4000 DMALP 16 DMALD DMAST DMALPEND DMAEND | 程序中的每個DMALD將兩個64位數據傳輸加載到MFIFO中。因為目的地地址是32位固定地址,所以DMAC將每個64位數據項拆分為MFIFO中的兩個條目。 |
三、PL外設DMA傳輸長度管理
示例:由外圍設備管理的長度
以下示例顯示了一個DMAC程序,當外圍設備發送突發請求(DMA{3:0}_DRTYPE[1:0]=01)時,該程序將64個字從存儲器傳輸到外圍設備0。當外圍設備發送單個請求(DMA{3:0}_DRTYPE[1:0]=00)時,DMAC程序將一個字從存儲器傳輸到外圍設備0。
為了傳輸64個字,程序指示DMAC執行16個AXI總線事務。每個事務由4比特突發(SB=4,DB=4)組成,其每個節拍移動一個數據字(SS=32,DS=32)。
在本例中,程序顯示了以下說明的使用:
- DMAWFP指令——DMAC等待來自外圍設備的突發或單個請求。
- DMASTPB和DMASTPS指令——DMAC在傳輸完成時通知外圍設備。
# Set up for burst transfers (4-beat burst, so SB4 and DB4),
# (word data width, so SS32 and DS32)
DMAMOV CCR SB4 SS32 DB4 DS32
DMAMOV SAR ...
DMAMOV DAR ...
# Initialize peripheral '0'
DMAFLUSHP P0
# Perform peripheral transfers
# Outer loop - DMAC responds to peripheral requests until peripheral
# sets drlast_0 = 1
DMALPFE
# Wait for request, DMAC sets request_type0 flag depending on the
# request type it receives
DMAWFP 0, periph
# Set up loop for burst request: first 15 of 16 sets of transactions
# Note: B suffix - conditionally executed only if request_type0
# flag = Burst
DMALP 15
DMALDB
DMASTB
# Only loopback if servicing a burst, otherwise treat as a NOP
DMALPENDB
# Perform final transaction (16 of 16). Send the peripheral
# acknowledgement of burst request completion
DMALDB
DMASTPB P0
# Perform transaction if the peripheral signals a single request
# Note: S suffix - conditionally executed only if request_type0
# flag = Single
DMALDS
DMASTPS P0
# Exit loop if DMAC receives the last request, that is, drlast_0 = 1
DMALPEND
DMAEND
示例:DMAC管理的長度
這個例子顯示了一個DMAC程序,當外圍設備發出16個連續的突發請求和3個連續的單個請求信號時,該程序可以傳輸1027個字。
# Set up for AXI burst transfer
# (4-beat burst, so SB4 and DB4), (word data width, so SS32 and DS32)
DMAMOV CCR SB4 SS32 DB4 DS32
DMAMOV SAR ...
DMAMOV DAR ...
# Initialize peripheral '0'
DMAFLUSHP P0
# Perform peripheral transfers
# Burst request loop to transfer 1024 words
DMALP 16
# Wait for the peripheral to signal a burst request.
# DMAC transfers 64 words for each burst request
DMAWFP 0, burst
# Set up loop for burst request: first 15 of 16 sets of transactions
DMALP 15
DMALD
DMAST
DMALPEND
# Perform final transaction (16 of 16).
# Send the peripheral acknowledgment of burst request completion
DMALD
DMASTPB 0
# Finish burst loop
DMALPEND
# Set up for AXI single transfer (word data width, so SS32 and DS32)
DMAMOV CCR SB1 SS32 DB1 DS32
# Single request loop to transfer 3 words
DMALP 3
# Wait for the peripheral to signal a single request. DMAC to transfer
# one word
DMAWFP 0, single
# Perform transaction for single request and send completion
# acknowledgement to the peripheral
DMALDS
DMASTPS P0
# Finish single loop
DMALPEND
# Flush the peripheral, in case the single transfers were in response
# to a burst request
DMAFLUSHP 0
DMAEND
四、使用事件重新啟動頻道
當INTEN寄存器被編程為生成事件時,DMASEV和DMAWFE指令可用于重新啟動一個或多個DMA通道。
以下部分描述了DMAC在以下情況下的行為:
- DMAC在DMASEV之前執行DMAWFE
- DMAC在DMAWFE之前執行DMASEV
DMAC在DMASEV之前執行DMAWFE
要重新啟動單個DMA通道:
- 第一個DMA通道執行DMAWFE,然后在等待事件發生時暫停。
- 另一個DMA通道使用相同的事件編號執行DMASEV。這將生成一個事件,并且第一個DMA通道將重新啟動。DMAC在執行DMASEV一個DMA{3:0}_ACLK周期后清除該事件。
可以對多個通道進行編程,以等待同一事件。例如,如果四個DMA通道都執行了事件12的DMAWFE,那么當另一個DMA通道執行事件12的DMASEV時,四個DMA信道都同時重新啟動。DMAC在執行DMASEV一個時鐘周期后清除事件。
DMAC在DMAWFE之前執行DMASEV
如果DMAC在另一個通道執行DMAWFE之前執行DMASEV,則該事件將一直掛起,直到DMAC執行DMAWFE。當DMAC執行DMAWFE時,它會在一個DMA{3:0}_ACLK周期內停止執行,清除事件,然后繼續執行通道線程。
例如,如果DMAC執行DMASEV 6,而其他線程都沒有執行DMAWFE 6,則該事件保持掛起狀態。如果DMAC對通道4執行DMAWFE 6指令,然后對通道3執行DMAWFE6指令,則:
- DMAC在一個DMA{3:0}_ACLK周期內停止信道4線程的執行。
- DMAC清除事件6。
- DMAC恢復信道4線程的執行。
- DMAC暫停通道3線程的執行,并且線程在等待事件6的下一次發生時暫停。
五、中斷處理器
控制器通過中斷控制器(GIC)向CPU提供七個活動的高敏感中斷(IRQ ID#75:72和49:46)。當INTEN寄存器被編程為生成中斷時,在DMAC執行DMASEV之后,控制器將相應的中斷設置為活動高狀態。
外部微處理器可以通過寫入中斷清除寄存器(ICR)來清除中斷。
執行DMAWFE不會清除中斷。
如果DMASEV指令用于在DMAC完成DMALD或DMAST指令時通知微處理器,Arm建議在DMASEV之前插入內存屏障指令。否則,DMAC可能會在AXI事務完成之前發出中斷信號。
以下示例對此進行了演示:
DMALD
DMAST
# Issue a write memory barrier
# Wait for the AXI write transfer to complete before the DMAC can
# send an interrupt
DMAWMB
# The DMAC sends the interrupt
DMASEV
六、 指令集引用
表4和表5總結了DMAC指令和命令。
表4?DMA引擎指令摘要
表5 匯編程序提供的DMA引擎附加命令
?