Xilinx Vivado simple DMA and Scatter-Gather DMA (SGDMA)

DMA基本原理在此不介绍,请百度。
https://xilinx.github.io/embeddedsw.github.io/axidma/doc/html/api/index.html

BD组成

Within the ring, the driver maintains four groups of BDs. Each group consists of 0 or more adjacent BDs:

Free: The BDs that can be allocated by the application with XAxiDma_BdRingAlloc().
Pre-process: The BDs that have been allocated with XAxiDma_BdRingAlloc(). These BDs are under application control. The application modifies these BDs through driver API to prepare them for DMA transactions.
Hardware: The BDs that have been enqueued to hardware with XAxiDma_BdRingToHw(). These BDs are under hardware control and may be in a state of awaiting hardware processing, in process, or processed by hardware. It is considered an error for the application to change BDs while they are in this group. Doing so can cause data corruption and lead to system instability.
Post-process: The BDs that have been processed by hardware and have been extracted from the Hardware group with XAxiDma_BdRingFromHw(). These BDs are under application control. The application can check the transfer status of these BDs. The application use XAxiDma_BdRingFree() to put them into the Free group.
BDs are expected to transition in the following way for continuous DMA transfers:

    XAxiDma_BdRingAlloc()                   XAxiDma_BdRingToHw()

Free ------------------------> Pre-process ----------------------> Hardware
|
/|\ |
| XAxiDma_BdRingFree() XAxiDma_BdRingFromHw() |
±-------------------------- Post-process <----------------------+

The following diagram shows the state transition for the DMA engine:

_____ XAxiDma_StartBdRingHw(), or XAxiDma_BdRingStart(), ______
| | or XAxiDma_Resume() | |
| H |----------------------------------------------------->| NH |
| |<-----------------------------------------------------| |
----- XAxiDma_Pause() or XAxiDma_Reset() ------

Software Initialization

To use the Simple mode DMA engine for transfers, the following setup is required:

DMA Initialization using XAxiDma_CfgInitialize() function. This step initializes a driver instance for the given DMA engine and resets the engine.
Enable interrupts if chosen to use interrupt mode. The application is responsible for setting up the interrupt system, which includes providing and connecting interrupt handlers and call back functions, before enabling the interrupts.
Set the buffer address and length field in respective channels to start the DMA transfer
To use the SG mode DMA engine for transfers, the following setup are required:

DMA Initialization using XAxiDma_CfgInitialize() function. This step initializes a driver instance for the given DMA engine and resets the engine.
BD Ring creation. A BD ring is needed per DMA channel and can be built by calling XAxiDma_BdRingCreate().
Enable interrupts if chose to use interrupt mode. The application is responsible for setting up the interrupt system, which includes providing and connecting interrupt handlers and call back functions, before enabling the interrupts.
Start a DMA transfer: Call XAxiDma_BdRingStart() to start a transfer for the first time or after a reset, and XAxiDma_BdRingToHw() if the channel is already started. Calling XAxiDma_BdRingToHw() when a DMA channel is not running will not put the BDs to the hardware, and the BDs will be processed later when the DMA channel is started through XAxiDma_BdRingStart().

Examples

We provide five examples to show how to use the driver API:
One for SG interrupt mode (xaxidma_example_sg_intr.c), multiple BD/packets transfer
One for SG polling mode (xaxidma_example_sg_poll.c), single BD transfer.
One for SG polling mode (xaxidma_poll_multi_pkts.c), multiple BD/packets transfer
One for simple polling mode (xaxidma_example_simple_poll.c)
One for simple Interrupt mode (xaxidma_example_simple_intr.c)

Scatter Gather Descriptor

This section defines the fields of the S2MM (Receive) and MM2S (Transmit) Scatter Gather
Descriptors for when the AXI DMA is configured for Scatter / Gather Mode. The descriptor
is made up of eight 32-bit base words and 0 or 5 User Application words. Multiple
descriptors per packet are supported through the Start of Frame and End of Frame flags.

Table 2-26: Descriptor Fields (Non-multichannel Mode)
在这里插入图片描述
We added XAxiDma_LookupConfig() so that user does not need to look for the hardware settings anymore. A helper function, XAxiDma_BdRingClone(), can speed up the BD ring setup if the BDs have same types of controls, for example, SOF and EOF. After using the XAxiDma_BdRingClone(), the application only needs to setup the buffer address and transfer length.

AXI DMA提供的demo,基于的Vivado设计中是将DMA的M_AXIS_MM2S和S_AXIS_S2MM通过AXIS DATA FIFO进行回环。
demo中完成如下过程:
初始化TxBuffer
将TxBuffer中数据通过DMA写入到FIFO
再将FIFO中数据通过DMA都回到RxBuffer
等待传输完成,比对TxBuffer和RxBuffer
上次过程循环多次
在这个demo中,其实两个没有顺序要求,因为有FIFO的存在,XAXIDMA_DEVICE_TO_DMA要等待XAXIDMA_DMA_TO_DEVICE向FIFO中写数据后才能真正开始传输。
在你实际应用中,就要根据你的应用要求进行操作了。

Configured in simple mode

简单中断方式

Status = SetupIntrSystem(&Intc, &AxiDma, TX_INTR_ID, RX_INTR_ID);
	if (Status != XST_SUCCESS) {

		xil_printf("Failed intr setup\r\n");
		return XST_FAILURE;
	}

	/* Disable all interrupts before setup */

	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DMA_TO_DEVICE);

	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
				XAXIDMA_DEVICE_TO_DMA);

	/* Enable all interrupts */
	XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
							XAXIDMA_DMA_TO_DEVICE);

	XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
							XAXIDMA_DEVICE_TO_DMA);

	/* Initialize flags before start transfer test  */
	TxDone = 0;
	RxDone = 0;
	Error = 0;

	Value = TEST_START_VALUE;

	for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
			TxBufferPtr[Index] = Value;

			Value = (Value + 1) & 0xFF;
	}

	/* Flush the buffers before the DMA transfer, in case the Data Cache
	 * is enabled
	 */
	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
	Xil_DCacheFlushRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);

	/* Send a packet */
	for(Index = 0; Index < Tries; Index ++) {

		Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);

		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) TxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		/*
		 * Wait TX done and RX done
		 */
		while (!TxDone && !RxDone && !Error) {
				/* NOP */
		}

SG轮询方式

Status = TxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
	return XST_FAILURE;
}

Status = RxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
	return XST_FAILURE;
}

/* Send a packet */
Status = SendPacket(&AxiDma);
if (Status != XST_SUCCESS) {
	return XST_FAILURE;
}

/* Check DMA transfer result */
Status = CheckDmaResult(&AxiDma);

if (Status != XST_SUCCESS) {
	xil_printf("AXI DMA SG Polling Example Failed\r\n");
	return XST_FAILURE;
}

xil_printf("Successfully ran AXI DMA SG Polling Example\r\n");

static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
XAxiDma_Bd *BdPtr;
int ProcessedBdCount;
int FreeBdCount;
int Status;

TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr);

/* Wait until the one BD TX transaction is done */
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(TxRingPtr,
					       XAXIDMA_ALL_BDS,
					       &BdPtr)) == 0) {
}

创建DMA项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
电路图
在这里插入图片描述
验证成功
在这里插入图片描述

<think>好的,用户遇到了Git合并时本地更改会被覆盖的问题,需要解决方案。根据之前的引用资料,解决方法主要有commit、stash和revert三种。首先,我得确认用户的具体情况,比如他们的本地更改是否已经完成,是否需要保留,或者是否可以丢弃。用户可能不太清楚这三种方法的适用场景,需要详细解释每个选项的步骤和优缺点。比如,commit适用于需要保留更改的情况,stash适合临时保存以便后续恢复,而revert则是直接撤销更改,适用于不需要保留的情况。需要结构清晰,分点说明,每个方法都给出操作步骤和适用场景,帮助用户理解哪种情况最适合他们。还要注意使用中文,避免技术术语过于复杂,让用户容易理解。同时,生成相关问题,可能涉及如何恢复stash的内容,或者如何避免频繁冲突等,扩展用户的知识点。另外,要确保LaTeX格式正确,但在这个问题中可能用不上数学公式,所以主要关注代码块和引用标识。检查引用是否正确,比如引用[^1]和[^2]的来源是否相关,用户提供的引用内容是否准确对应解决方案。 最后,确保回答真实可靠,操作步骤准确无误,避免误导用户。可能还需要提醒用户根据具体情况选择方法,比如如果有未完成的实验性代码,stash可能是更好的选择,而如果是确定要保留的修改,则应该commit。</think>要解决Git合并时本地更改被覆盖的问题,可根据不同场景选择以下三种方法: ### 一、提交本地更改(commit) **适用场景**:当本地更改已测试通过且需要保留到版本历史中。 **操作步骤**: 1. 将改动添加到暂存区: ```bash git add . # 添加所有文件 # 或指定文件 git add file1.txt file2.py ``` 2. 提交更改并添加描述: ```bash git commit -m "完成用户登录模块优化" ``` 3. 执行合并操作: ```bash git merge origin/main ``` **优点**:保留完整的开发记录,便于后续追溯[^1]。 ### 二、暂存更改(stash) **适用场景**:需要临时保存未完成的修改(如调试代码),优先处理合并操作。 **操作步骤**: 1. 保存当前工作状态: ```bash git stash # 可选添加备注 git stash save "用户登录模块调试代码" ``` 2. 查看暂存记录列表: ```bash git stash list ``` 3. 合并远程分支: ```bash git merge origin/main ``` 4. 恢复暂存内容: ```bash git stash pop # 恢复并删除最近一次暂存 # 或指定特定暂存 git stash apply stash@{1} ``` **优点**:保持工作目录整洁,特别适合处理紧急合并任务[^2]。 ### 三、撤销本地更改(revert) **适用场景**:本地修改可丢弃(如实验性代码或错误修改)。 **操作步骤**: 1. 撤销所有未提交的修改: ```bash git checkout -- . # 全部文件 # 或指定文件 git checkout -- file1.txt ``` 2. 执行合并操作: ```bash git merge origin/main ``` **风险提示**:此操作不可逆,需确认文件无需保留。 --- ### 对比决策表 | 方法 | 保留记录 | 可恢复性 | 适用阶段 | |---------|----------|----------|------------------| | commit | ✅ | ✅ | 功能开发完成时 | | stash | ❌ | ✅ | 开发中途临时切换 | | revert | ❌ | ❌ | 放弃无效修改 | ### 扩展应用场景 - 当存在多个暂存时,可用`git stash list`查看记录,通过`git stash apply stash@{n}`精准恢复 - 合并后出现冲突时,可使用`git mergetool`可视化工具解决冲突 - 长期分支开发推荐使用`git rebase`保持提交历史线性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值