使用VVD2013

APP(1171)

1,下载并安装VVD2013.3。

2,下载并解压1171设计文件。

3,找到目录:C:\Users\admin\AppData\Roaming\Xilinx\Vivado

4,如果目录中有类似project_1这种文件夹,备份好后删除掉。

5,把解压好的1171中 - kintexSubsystemFiles子目录复制过来。

6,开始菜单,运行TCL命令行;运行vivado -sourcee:/kintexsubsystemfiles/kintexgenerationscript.tcl

7,等待VVD启动,并生成SubSystem设计;也可以使用默认配置,直接生成BIT文件。


APP中包含的演示内容:

1,从Script生成VVD SubSystem 框图

2,PCIe Endpoint 配置

3,DMA通过PCIe的传输

4,动态地址映射 

5,DMA(SG)操作。


Overview

主要用到AXI_CDMA, AXI_PCI Express,AXI Internonnect等IP。用BRAM临时存储DMA传输时用到的address translation vectors。


AXI_Interconnect Address Map

AXI PortInstanceBase AddressHigh AddressSize
AXI_DDR3_MENMIG0x0000 00000x7FFF FFFF2GB
AXI_PCIe_DMaxi_pcie_1 AXI:BAR10x8000 00000x807F FFFF8MB
AXI_PCIe_SGaxi_pcie_1 AXI:BAR00x8080 00000x80FF FFFF8MB
Translation_BRAMtranslation_bram0x8100 80000x8100 0FFF32KB
AXI_PCIe_CTLaxi_pcie_10x8100 80000x8100 BFFF16KB
AXI_CDMA_LITEaxi_cdma_10x8100 C0000x8100 FFFF16KB


PCIe to AXIBar Config Address

从host接收PCIe downstream 

PCIe BAR0一共64KB,对应上面表中后3项:BRAM,AXI_PCIe_CTL,AXI_CDMA_LITE。

PCIe BARInterfacePCIe BAR Offset From Base AddressAXI AddressSize
0Translation_BRAM0x0000 00000x8100 0FFF32KB
0AXI_PCIe_CTL0x0000 80000x8100 BFFF16KB
0AXI_CDMA_LITE0x0000 C0000x8100 FFFF16KB
要在PC端访问指定寄存器,需要遵循下面原则:

<BAR0 Base Address> + < Offset of specified Interface > + < Register Offset in Interface>


例:假设BAR0在PC端映射的地址为:0x0000 0000_DEF0 0000

BRAM 0x0D10对应:0x0000 0000_DEF0 0D10

AXI_PCIe_CTL 0x20C 对应:0x0000 0000_DEF0 820C

AXI_CMDA_LITE 0x0004对应:0x0000 0000_DEF0 C004


PCIe AXI Master端不需要读写AXI_PCIe_SG, AXI_PCIe_DM, AXI_DDR3_MEM,因为DMA会读写到AXI Slave。

根据实际应用,还可以添加最多2个PCie BAR。


AXI to PCIe Bar Config Address

产生PCIe upstream到host

AXI BAR有2个: 

AXI BAR0 - 8MB, [SG]DMA (AXI_PCIe_SG port),通过这port, DMA读取、处理PC端的descriptors。

AXI BAR1 - 8MB, Data Mover (AXI_PCIe_DM port),通过这个port,DMA读写PCIe数据。

CDMA IP的最大传输数据量为8M。 


AXI BAR可以做64bit动态地址翻译,默认对应关系为:

AXI BARAXI AddressHost PCIe Address
BAR00x8080 00000x0000 0000_A000 0000
BAR10x8000 00000x0000 0000_C000 0000

这个对应关系可以在AXI_PCIe_CTL (0x8100 8000)中的相应寄存器中更改:

OffsetBitsRegister NameDescriptionDefault Value
0x20831:0AXI BAR 2 PCIe BAR 0_UAXI BAR0 Upper Address for AXI_PCIe_SG.
Host Address [63:32]
0x0000 0000
0x20C31:0AXI BAR 2 PCIe BAR 0_LAXI BAR0 Lower Address for AXI_PCIe_SG.
Host Address [31:0]
0xA000 0000
0x21031:0AXI BAR 2 PCIe BAR 1_UAXI BAR1 Upper Address for AXi_PCIe_DM.
Host Address [63:32]
0x0000 0000
0x21431:0AXI BAR 2 PCIe BAR 1_LAXI BAR1 Lower Address for AXi_PCIe_DM.
Host Address [31:0]
0xC000 0000
收到AXI BAR地址宽度限制,因为AXI_PCIe_SG,AXI_PCIe_DM 配置成了8MB地址空间,所以上面Lower Address中Bits[22:0]应该都是0。

根据实际应用,可以再添加最多4个AXI BAR。


Scatter Gather DMA

[SG]DMA是一种自动化的DMA,它使用transfer descriptors,其中包含预先定义好的一系列指令;由PCIe host通过驱动和软件把一系列指令写入内存驻留数据结构。这些指令被组织成descriptor chain,其中每一个descriptor都描述一个单独的数据传输并包含一个指向下一个descripitor的指针。整个chain中的最后一个descriptor一般指向第一个descriptor。


Scatter Gather Transfer Decriptor Difition

descriptor 由8个32bit组成,共32Byte;必须64Byte对齐。相对于系统内存中Transfer Descriptor的起始地址,Descriptor的offset只能是0x00,0x40,0x80,0xC0。


Address OffsetRegister NameBitField NameDescription
0x00Next Descriptor Ptr31:6Next Descriptor Ptr指向下一个Descriptor首字节的指针。
必须是64Byte对齐的:0x00、0x40、0x80、0xC0
该指针是从AXI_PCIe_SG 开始,经AXI PCIe映射到host地址空间的的Offset
  5:0Reserved000000
确保指针是64Byte对齐的。
0x04Reserved   
0x08Source Address31:0SADMA传输,读取数据的起始地址。
0x0CReserved   
0x10Destination Address31:0DADMA传输,写入数据的起始地址。
由于DMA被配置成64bit数据位宽,DA地址的最后3位需要与SA的最后3位相同
0x14Reserved   
0x18Transfer Cotrol31:23Reserced 
  22:0Bytes To Transfer
(BTT)
需要做DMA传输的字节数:1-0x007F FFFF
设置为0会引起DMA内部错误。
0x0CTransfer Status31Transfer Complete0:Descriptor没有执行完,Host不能更改寄存器。
1:Descriptor已经执行完,Host可以更改寄存器。
  30DMA Decode Error0:No Errors
1:AXI Decode Error - Data Mover发现没有被映射到Slave Device。
  29DMA Slave Error0:No Errors
1:CDMA Data Mover在read/write时发现Slave Device有错误。
  28DMA Internal Error0:No Errors
1:CDMA Data Mover内部错误或者BTT被设为0。
  27:0Reserved 

Host驱动应该确保Transfer Status设置为0000;并且在该次Descriptor完成之前,不更改Transfer Status中的值;当AXI CDMA引擎完成操作以后,会主动更新Transfer Status中的值,供Host驱动查询。

Host驱动需要Relocate上面设置,并清空Transfer Status,为进行下一次DMA做准备。


在本例SubSystem中,使用了2类Descriptor:

Address Translation Description Descriptor 和 Target Data Transfer Descriptor

Descriptor 使用的 Address 必须是AXI Interconnector 映射的地址,而不是Host中的地址空间!


Address Translation Description Descriptor 通过写AXI_PCIe_CTL 来Update AXI to PCIe Translation Vector。其中包括:

1. Source Address:对应于BRAM中 (0x8100 0000 - 0x8100 7FFF)

2. Destination Address:对应AXI_PCIe_CTL (AXI: BAR1)寄存器(0x8100 8210 和 0x8100 8214)

3. Control Value:一个8Byte的数据传输 (0x0000 0008)

工作时,DMA引擎把8ByteTranslation Vector从Translation BRAM 复制到 Translation Registors (可通过AXI_PCIe_CTL访问)。

在Descriptor被执行前,必须update  Translation Vector 和 Block RAM;错误的设置可能导致获取非法内存地址。


Target Data Transfer Descriptor用于PCIe和目标设备(本例中DDR3)之间的数据传输。

1. SA和DA地址可以是:AXI_PCIe_DM(0x8000 0000)或者DDR3(0x0000 0000)

2. DMA Controller寄存器可以是: 1 - 0x007F FFFF

工作时,Descriptor在PCIe和DDR3之间进行数据传输。

在Descriptor被执行前,必须update PCIe Translation Vector。可以直接Update,也可以通过Address Translation Descriptor。


Scatter Gather DMA Operation

以下过程使用了一个descriptor chain,来实现(SG)DMA操作流程。

1. 设置DMA模式为SG;Enable中断。

   写AXI_CDMA_LITE寄存器(AXI 0x8100 C000 或者 PCIe:BAR0 offset 0x0000 C000)

2. 在Host内存中创建Descriptor Chain。

   需要包括:Address Translation Descriptor 和 Target Data Transfer Descriptor

3. Update AXI_PCIe_SG port 的 PCIe Translation Vector。

   写AXI:BARO translation 寄存器,

     位于AXI 0x8100 8208 -  0x8100 820C (AXI_PCIe_CTL port ) 或者PCIe:BAR0 offset 0x0000 8208 - 0x0000 820C。

   写入这些寄存器的值,应该与之前在Host内存中建立Descriptor Chain 的 8MB Memory Base Address 一致。

4. 向 Translation BRAM 写入 Translation Vector。

   BRAM 地址:AXI 0x8100 0000 - 0x8100 7FFF 或者 PCIe:BAR0 offset 0x0000 0000 - 0x0000 7FFF。

   写入BRAM的值,应该与Host内存中(需要DMA引擎进行传输之数据)的8MB Memory 一致。

5. 向 DMA_CURDESC_PNTR 寄存器写入 pointer

   DMA_CURDESC_PNTR地址:AXI 0x8100 C0008 或者 PCIe:BAR0 offset 0x0000 0008。

6. 向 DMA_TAILDESC_PNTR 寄存器写入 pointer

   DMA_TAILDESC_PNTR 地址:AXI 0c8100 C010 或者 PCIe:BAR0 offset 0x0000 C010。

   写入Tail Desc Pointer以后,DMA 启动,开始处理Descriptors。

7. DMA SG 工作中,直至 DMA_TAILDESC_PNTR 或者 是之前已经完成的descriptor。


下面是操作实例:把64KB数据从PCIe写入DDR,再从DDR读回PCIe

1. 设置DMA模式为SG;Enable中断。

   32bit Write 0x0A000100 到 PCIe:BAR0 offset 00000 000C。


2. Description Chain

   PCIe Address Translation for AXI_PCIe_SG:0x0000 0001 0000 0000

   PCIe Address Translation for ACI_PCIe_DM:Set Dynamically by Descriptors 1 and 3

Descriptor1Descriptor2Descriptor3Descriptor4
Address:
0x0000 0001 0000 0000
Address::
0x0000 0001 0000 0040
Address:
 0x0000 0001 0000 0080
Address:
0x0000 0001 0000 00C0
NEXTDESC_PNTR:
0x0000 0001 0000 0040
NEXTDESC_PNTR:
0x0000 0001 0000 0080
NEXTDESC_PNTR:
0x0000 0001 0000 00C0
NEXTDESC_PNTR:
0x0000 0001 0000 0000
SA:0x8100 0000 (Translation BRAM)SA:0x8000 0000 (AXI_PCIe_DM)SA:0x8100 0008 (Translation BRAM)SA:0x8100 0000 (DDR)
DA:0x8100 8210 (AXI_PCIe_CTL)DA:0x0010 0000 (DDR)DA:0x8100 8210 (AXI_PCIe_CTL)DA:0x8011 0000 (AXI_PCIe_DM)
Control:
0x0000 0008 (64bit transfer)
Control:
0x0001 0008 (64bit transfer)
Control:
0x0000 0008 (64bit transfer)
Control:
0x0001 0008 (64bit transfer)
Status:
0x0000 0000 (Not Proceed)
Status:
0x0000 0000 (Not Proceed)
Status:
0x0000 0000 (Not Proceed)
Status:
0x0000 0000 (Not Proceed)
Translation DescriptorTarget Data Transfer DescriptorTranslation DescriptorTarget Data Transfer Descriptor

 3. Update AXI_PCIe_SG port 的 PCIe Translation Vector。

   64bit Write 0x0000 0001 0000 0000 到 AXI_PCIe_SG @ PCIe:Bar0 offset 0x0000 8208 。


4. 向 Translation BRAM 写入 Translation Vector。

   a. 64bit Write 0x0000 CCC0 C000 0000 到 PCIe:BAR0 offset 0x0000 0000;在descriptor1 和 descriptor2 之间update。

   b. 64bit Write 0x0000 DDD0 D000 0000 到 PCIe:BAR0 offset 0x0000 0008;在descriptor3 和 descriptor4 之间update。


5. 向 DMA_CURDESC_PNTR 寄存器写入 pointer

   32bit Write 0x8080 0000 到 DMA_CURDESC_PNTR @ PCIe:BAR0 offset 0x0000 0000 0000 C008。

   pointer = AXI_PCIe_SG Base Address + [Host] Descriptor Offset From 0x0000 0001 0000 0000 (step2 中的地址)。


6. 向 DMA_TAILDESC_PNTR 寄存器写入 pointer

   32bit Write 0x8080 00C0 到 DMA_TAILDESC_PNTR @ PCIe:BAR0 offset 0x0000 0000 0000 C010。

   pointer = AXI_PCIe_SG Base Address + [Host] Descriptor Offset From 0x0000 0001 0000 0000 (step2 中的地址)。

   这时,DMA启动


7. DMA 继续工作,直到 DMA_TAILDESC_PNTR @ 0x0000 0001 0000 00C0 执行完。


注:

在descriptor 1、2 操作过程中,不能更改descriptor 3、4

descriptor 1、2 完成操作,而descriptor 3、4 还在执行过程中,可以reallocate descriptor 1、2 从而实现 Continous DMA


<think>好的,用户现在问的是关于STM32F407IGT6的DMA连续请求是否需要开启的问题。我需要先回顾之前的问题,用户之前问的是ADC3使用DMA接收数据时数组大小的设定,现在可能是在同一项目中进行配置,遇到了DMA相关的问题。 首先,我需要确认用户所说的“DMA continuous request”具体指的是什么。在STM32中,DMA有不同的模式,比如普通模式和循环模式,可能用户在这里指的是循环模式(Circular Mode)或者是否使能DMA的连续请求功能。通常,DMA的连续请求可能涉及外设是否持续发出DMA请求,比如ADC在连续转换模式下是否需要DMA持续传输。 接下来,我应该考虑用户的使用场景。如果用户需要ADC连续采样并实时传输数据,那么可能需要开启循环模式,这样DMA在完成一次传输后会自动重新开始,不需要软件干预。反之,如果只是单次采样,可能不需要开启循环模式。 然后,我需要查阅STM32F4的参考手册,特别是关于DMA和ADC的部分。确认ADC在连续转换模式下的行为,以及DMA如何配合工作。例如,当ADC配置为连续转换模式时,每次转换完成后会触发DMA请求,DMA需要配置为循环模式以持续传输数据。 同时,要注意到用户可能混淆了术语,比如“continuous request”可能指的是DMA的循环模式,或者外设的连续触发。需要明确区分这些概念,避免误导用户。 此外,用户可能没有正确配置DMA的相关寄存器,导致数据传输不连续,或者在单次模式下需要频繁重启DMA,影响效率。因此,需要说明在什么情况下需要开启循环模式,以及如何配置。 最后,我应该给出具体的配置建议,比如在CubeMX中的设置步骤,或者直接代码示例,帮助用户正确启用DMA的循环模式,并解释其作用,确保用户理解不同模式下的行为差异。</think>在STM32F407IGT6中使用DMA的**连续请求(Continuous Request)**是否需要开启,取决于具体应用场景和工作模式。以下是关键分析: --- ### 一、DMA连续请求的核心作用 1. **功能定义**: - 当使能连续请求时(`DMA_CCRx: CIRC = 1`),DMA会在传输完成后**自动重置计数器**,无需软件干预即可循环传输。 - 若关闭(`CIRC = 0`),DMA完成一次传输后停止,需手动重启。 2. **典型应用场景**: - **实时数据流**(如ADC连续采样、音频传输) - **缓冲区循环覆盖**(避免数据丢失) --- ### 二、是否需要开启的判断依据 | **场景** | **是否需要开启** | **原因** | |--------------------------|------------------|--------------------------------------------------------------------------| | 单次传输(如读取一次传感器) | 不需要 | 单次传输后DMA自动停止,节省资源 | | 循环采样(如持续ADC采集) | **必须开启** | 确保DMA持续搬运数据,防止缓冲区溢出或数据不连续 | | 双缓冲(Ping-Pong Buffer) | 通常开启 | 配合双缓冲机制实现无缝数据传输 | --- ### 三、配置建议(以ADC+DMA为例) #### 1. **CubeMX配置** - 启用DMA循环模式: ```c hdma_adc.Init.Mode = DMA_CIRCULAR; // 关键配置! ``` - 设置数据宽度和优先级: ```c hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc.Init.Priority = DMA_PRIORITY_HIGH; ``` #### 2. **代码启动DMA** ```c HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buffer, BUFFER_SIZE); ``` --- ### 四、注意事项 1. **内存管理**: - 循环模式下,DMA会持续覆盖缓冲区旧数据,需通过**半传输中断(HT)**或**传输完成中断(TC)**及时处理数据。 2. **中断配置**: ```c // 在DMA初始化中启用传输完成中断 hdma_adc.Init.Mode = DMA_CIRCULAR; hdma_adc.XferCpltCallback = DMA_TransferCompleteHandler; // 自定义回调函数 ``` 3. **资源冲突**: - 避免在DMA传输过程中修改缓冲区地址或大小。 --- ### 五、典型案例分析 #### 场景:ADC多通道连续采样 - **需求**:4个ADC通道,每个通道采样100次 - **配置**: ```c #define CHANNEL_NUM 4 #define SAMPLE_TIMES 100 uint16_t adc_buf[CHANNEL_NUM * SAMPLE_TIMES]; // DMA配置为循环模式 HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buf, CHANNEL_NUM * SAMPLE_TIMES); ``` - **结果**:DMA持续填充缓冲区,当达到`SAMPLE_TIMES`次数后自动循环,无需软件重置。 --- ### 总结 - **必须开启**:需要持续、无间断数据传输的场景(如实时监测)。 - **不应开启**:单次或需要精确控制传输次数的场景。 - 关键配置项为`DMA_CIRCULAR`模式,需结合中断机制实现可靠的数据处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值