本编文章是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的结构框图DataMoverThe 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 TransfersThe 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 OffsetName Description
00hCDMACR CDMA Control
04hCDMASR CDMA Status
08hCURDESC_PNTR Current Descriptor Pointer
0ChCURDESC_ PNTR_MSB Current Descriptor Pointer. MSB 32 bits. Applicable only when the address space is greater than 32.
10hTAILDESC_PNTR Tail Descriptor Pointer
14hTAILDESC_PNTR_MSB Tail Descriptor Pointer. MSB 32 bits. Applicable only when the address space is greater than 32.
18hSA Source Address
1ChSA_MSB Source Address. MSB 32 bits. Applicable only when the address space is greater than 32.
20hDA Destination Address
24hDA_MSB Destination Address. MSB 32 bits. Applicable only when the address space is greater than 32.
28hBTT Bytes to Transfer 设计流程(在PS端的配置)Simple DMA modeIn 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(删减了一些) BitsField Name Default Value Access Type CDMA Mode Used Description
31 to 6Current 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 0Reserved 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;}
|