1. 程式人生 > >【ZYNQ-7000開發之七】AXI CDMA特點以及在PS端使用的步驟_理論部分 未完待續

【ZYNQ-7000開發之七】AXI CDMA特點以及在PS端使用的步驟_理論部分 未完待續

本編文章是AXI Central Direct Memory Access v4.1的閱讀筆記

硬體規格部分

簡介:

AXI CDMA為嵌入式系統提供了高效能的片上互聯
The AXI CDMA provides high-bandwidth Direct Memory Access (DMA) between a memory-mapped source address and a memory-mapped destination address using the AXI4 protocol. An optional Scatter
Gather (SG) feature can be used to offload control and sequencing tasks from thesystem CPU.
初始化,狀態和控制暫存器都是通過AXI4-Lite slave介面控制

特點概要

  • Independent AXI4-Lite slave interface for register access
    • Fixed 32-bit data width
    • Optional asynchronous operation mode
  • Independent AXI4 Master interface for the primary CDMA datapath. Parameterizable width of 32, 64, 128, 256, 512, and 1,024 bits with fixed-address burst (key hole) support.
  • Independent AXI4 Master interface for optional Scatter/Gather function. Fixed 32-bit data width.
  • Optional Data Realignment Engine for the primary CDMA datapath. Available with 32
    and 64-bit datapath widths.
  • Provides Simple DMA only mode and an optional hybrid mode supporting both Simple
    DMA and Scatter Gather automation.
  • Support for up to 64-bit Address Space

模式:

Register Direct Mode

吞吐量一般,使用簡單,佔用的邏輯資源少一些。

Scatter/Gather Mode

高吞吐量,減少CPU的干預,釋放CPU。使用要複雜一些,也更加消耗邏輯資源。

AXI CDMA的結構框圖

AXI CDMA的結構框圖

DataMover

The DataMover is used for high-throughput transfer of data. The DataMover provides CDMA operations with 4 KB address boundary protection, automatic burst partitioning, and can queue multiple transfer requests. Furthermore, the DataMover provides byte-level data realignment (for 32-bit and 64-bit data widths) allowing the CDMA to read from and write to any byte offset combination.

Unaligned Transfers

The AXI DataMover core optionally supports the Data Realignment Engine (DRE). When the DRE is enabled, data is realigned to the byte (8 bits) level on the Memory Map datapath (32-bit,64-bit).
If the DRE is enabled, data reads can start from any Address byte offset. Similarly, when the DRE is enabled, the writes can happen at any byte offset address. For example, if Memory Map Data Width = 32, data is aligned if it is located at address offsets of 0x0, 0x4, 0x8, 0xC, etc. Data is unaligned if it is located at address offsets of 0x1, 0x2, 0x3 and so forth.
Note: Performing unaligned transfers when DRE is disabled will give unpredictable results
執行不對齊傳輸會出現不可預測的結果,那這種方式的優勢是什麼?

關於Register Space要注意的

The registers are 32-bits wide, and the register memory space must be aligned on 128-byte (80h) boundaries.

AXI CDMA Register Summary

這個暫存器偏移地址的表格可能會經常使用,具體的暫存器經參考官方文件

Address Space Offset Name Description
00h CDMACR CDMA Control
04h CDMASR CDMA Status
08h CURDESC_PNTR Current Descriptor Pointer
0Ch CURDESC_ PNTR_MSB Current Descriptor Pointer. MSB 32 bits. Applicable only when the address space is greater than 32.
10h TAILDESC_PNTR Tail Descriptor Pointer
14h TAILDESC_PNTR_MSB Tail Descriptor Pointer. MSB 32 bits. Applicable only when the address space is greater than 32.
18h SA Source Address
1Ch SA_MSB Source Address. MSB 32 bits. Applicable only when the address space is greater than 32.
20h DA Destination Address
24h DA_MSB Destination Address. MSB 32 bits. Applicable only when the address space is greater than 32.
28h BTT Bytes to Transfer

設計流程(在PS端的配置)

Simple DMA mode

In this mode, Scatter Gather is excluded and **the CDMA executes one programmed DMA command and then stops. **This requires the CDMA registers to be set up by an external AXI4 Master for each DMA operation required.

具體步驟:
1. Verify CDMASR.IDLE = 1.(檢測狀態暫存器看看是不是在執行,執行的時候是不能配置的)
2. Program the CDMACR.IOC_IrqEn bit to the desired state for interrupt generation on transfer completion. Also set the error interrupt enable (CDMACR.ERR_IrqEn), if so desired.(配置中斷,中斷應該可以不使能吧???待確定!)
3. Write the desired transfer source address to the Source Address (SA) register. The transfer data at the source address must be valid and ready for transfer.(設定源地址,讀資料的地址,偏移地址是18h) If the address space selected is more than 32, write the SA_MSB register also.
4.* Write the desired transfer destination address to the Destination Address (DA) register.*(設定目的地址,寫資料的地址,偏移地址是20h)If the address space selected is more than 32, then write the DA_MSB register also.
5. Write the number of bytes to transfer to the CDMA Bytes to Transfer (BTT) register. Up to 8,388,607 bytes can be specified for a single transfer (unless DataMover Lite is being used). Writing to the BTT register also starts the transfer.(設定需要傳輸的長度,設定完成就開始傳輸)
6. Either poll the CDMASR.IDLE bit for assertion (CDMASR.IDLE = 1) or wait for the CDMA to generate an output interrupt (assumes CDMACR.IOC_IrqEn = 1).(等待傳輸完畢,如果沒設定中斷則當CDMASR.IDLE = 1的時候表示傳輸完成,如果設定了中斷,傳出完成(maybe)會進入中斷)
7. If interrupt based, determine the interrupt source (transfer completed or an error has occurred).
8. Clear the CDMASR.IOC_Irq bit by writing a 1 to the DMASR.IOC_Irq bit position.(清除中斷請求位,個人理解如果可以不使能中斷應該不需要這一步)
9. Ready for another transfer. Go back to step 1.(返回到STEP1開始下一次的傳輸)

Scatter Gather Mode(minimum steps)

Scatter Gather is a mechanism that allows for automated data transfer scheduling through a pre-programmed instruction list of transfer escriptors (Scatter Gather Transfer Descriptor Definition). This
list of instructions is organized into what is referred to as a transfer descriptor chain. Each descriptor has an address pointer to the next sequential descriptor to be processed(類似於C語言的連結串列). The last descriptor in the chain generally points back to the first descriptor in the chain but it is not required.
1. Write a valid pointer to the channel CURDESC_PNTR register (Offset 0x08). If the address space selected is more than 32, then write the CURDESC_PNTR_MSB to specify the upper bits of current descriptor pointer.(設定當前資料塊的指標)
PS:CURDESC_PNTR Register Details(刪減了一些)

Bits Field Name Default Value Access Type CDMA Mode Used Description
31 to 6 Current Descriptor Pointer 0 R/W (RO) SG Current Descriptor Pointer. Indicates the pointer of the current descriptor being worked on. This register must contain a pointer to a valid descriptor prior to writing to the TAILDESC_PTR register. When the CDMA SG Engine is running (CDMASR.IDLE = 0), the CURDESC_PNTR register is updated by the SG Engine to reflect the starting address of the current descriptor being executed. Descriptor addresses written to this field must be aligned to 64-byte boundaries (sixteen 32-bit words). Examples are 0x00, 0x40, 0x80. Any other alignment has undefined results. This register is cleared when CDMACR.SGMode = 0.
5 to 0 Reserved 0 RO N/A Writing to these bits has no effect and they are always read as zeros.

2. Write control information to the channel CDMACR register (Offset 0x00) to set interrupt enables and key hole feature if desired.(同簡單模式)
3. Write a valid pointer to the channel TAILDESC_PNTR register (Offset 0x10). This starts the channel fetching and processing descriptors(這是尾資料塊的指標).If the address space selected is more than 32, then write the AILDESC_PNTR_MSB to specify the upper bits of current descriptor pointer.
4. CDMA scatter gather operations continue until the descriptor at TAILDESC_PNTR is processed, and then the engine idles as indicated by CDMASR.Idle = 1.

Cyclic CDMA Mode(迴圈模式)

AXI CDMA can be run in cyclic mode by making certain changes to the BD chain setup.** In cyclic mode, CDMA fetches and processes the same BDs without any interruption. (資料傳輸會自動的在資料塊之間輪詢,沒有中斷產生,效率較高)The CDMA continues to fetch and process until it is stopped or reset. **To enable cyclic operation, the BD chain should be set up as show in Figure 3-1.
這裡寫圖片描述
……
(還有一些暫存器,這裡先略去)

中斷概要

An interrupt output is provided by the AXI CDMA. This output drives High when an internal interrupt event is logged in the CDMA Status Register (CDMASR) and the associated interrupt enable bit is set in the CDMA Control Register (CDMACR).
IMPORTANT: This interrupt output is synchronized to the s_axi_lite_aclk clock input.
Internal interrupt events are different depending on whether the AXI CDMA is operating in Simple DMA mode or SG Mode. Simple DMA mode generates an IOC interrupt whenever a programmed transfer is completed.(簡單模式每次傳輸完成都會有產生中斷,效率較低) In addition, three error conditions reported by the DataMover (internal error, slave error, and decode error) can also generate an interrupt assertion. For Scatter Gather mode, the delay interrupt and the three SG engine error interrupt events are added to the interrupt event mix(SG模式可以只產生一次中斷,通過中斷級聯減少中斷頻率).

API 函式部分

傳輸模式(兩種)

  • simple DMA transfer
    • 僅僅需要 source buffer address, destination buffer address and transfer length,每次只能傳輸一個BD(buffer descriptor )
  • scatter gather (SG) DMA transfer
    • A SG DMA transfer 需要設定多個(>=1)BD, 多個BDs之間以連結串列的形式相連。同時也需要 source buffer address, destination buffer address, and transfer length.

原始碼例程分析

看原始碼可能更容易理解過程
官方的API函式初始化方法一般步驟(以AXI CDMA為例):
CfgPtr = XAxiCdma_LookupConfig(DeviceId);
Status = XAxiCdma_CfgInitialize(&AxiCdmaInstance, CfgPtr, CfgPtr->BaseAddress);

函式原型

這個函式查詢硬體裡有沒有我們要使用的裝置(AXI CDMA等等)
XAxiCdma_Config* XAxiCdma_LookupConfig ( u32 DeviceId )
Look up the hardware configuration for a device instance

Parameters:

  • DeviceId is the unique device ID of the device to lookup for

Returns:

  • The configuration structure for the device. If the device ID is not found,a NULL pointer is returned.

int XAxiCdma_CfgInitialize ( XAxiCdma * InstancePtr,XAxiCdma_Config * CfgPtr,u32 EffectiveAddr )
This function initializes the driver. It should be called before any other function calls to the driver.
It sets up the driver according to the hardware build. It resets the hardware at the end.

Parameters

  • InstancePtr is the driver instance that is working on
  • CfgPtr is the pointer to the hardware configuration structure
  • EffectiveAddr is the virtual address of the hardware instance. If address translation is not in use, please use the physical address

Returns:

  • XST_SUCCESS for success
  • XST_INVALID_PARAM if word length is less than 4
  • XST_FAILURE for reset failure

……

simple poll模式


/*******************************************************************/
/**
* The example to do the simple transfer through polling. The constant
* NUMBER_OF_TRANSFERS defines how many times a simple transfer is repeated.
*
* @param DeviceId is the Device Id of the XAxiCdma instance
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if error occurs
*
* @note If the hardware build has problems with interrupt,
* then this function hangs
*
*
********************************************************************/
int XAxiCdma_SimplePollExample(u16 DeviceId)
{
XAxiCdma_Config *CfgPtr;
int Status;
int SubmitTries = 10; /* try 10 times on submission */
int Tries = NUMBER_OF_TRANSFERS;
int Index;

/* Initialize the XAxiCdma device.
 */
CfgPtr = XAxiCdma_LookupConfig(DeviceId);
if (!CfgPtr) {
    return XST_FAILURE;
}

Status = XAxiCdma_CfgInitialize(&AxiCdmaInstance, CfgPtr,
    CfgPtr->BaseAddress);
if (Status != XST_SUCCESS) {
    return XST_FAILURE;
}

/* Disable interrupts, we use polling mode
 */
XAxiCdma_IntrDisable(&AxiCdmaInstance, XAXICDMA_XR_IRQ_ALL_MASK);

for (Index = 0; Index < Tries; Index++) {
    Status = DoSimplePollTransfer(&AxiCdmaInstance,
        BUFFER_BYTESIZE, SubmitTries);
    if (Status != XST_SUCCESS) {
            return XST_FAILURE;
    }
}

/* Test finishes successfully
 */
return XST_SUCCESS;

}
/*******************************************************************/
/*
* The entry point for this example. It invokes the example function,
* and reports the execution status.
*
* @param None.
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if example fails.
*
* @note None.
*
********************************************************************/
int main()
{
int Status;

xil_printf("\r\n--- Entering main() --- \r\n");

/* Run the poll example for simple transfer */
Status = XAxiCdma_SimplePollExample(DMA_CTRL_DEVICE_ID);

if (Status != XST_SUCCESS) {

    xil_printf("AxiCdma_SimplePollExample: Failed\r\n");
    return XST_FAILURE;
}

xil_printf("AxiCdma_SimplePollExample: Passed\r\n");

xil_printf("--- Exiting main() --- \r\n");

return XST_SUCCESS;

}