[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK高级篇连载-02PL与PS数据LOOP传输(DMA)

文档创建者:FPGA课程
浏览次数:243
最后更新:2024-09-29
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 2-SDK高级应用方案
本帖最后由 FPGA课程 于 2024-9-29 13:16 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1概述
数据在PS和PL之间的交互是FPGA+ARM构架SOC的重要内容,从本文开始,下面的内容大部分都和DMA数据交互有关系。
本课讲解了一个最基本的DMA环路搭建,通过PS端控制DMA对DDR数据的读写和校验,完成环路测试。本课程是DMA设计的基础,读者务必认真阅读和学习。
本文实验目的:
1:PS端ARM将数据发送给DDR。
2:PS控制DMA,使DMA通过数据通道读取DDR中的数据;DMA将读取到的数据传给FIFO。
3:FIFO将数据传输给DMA;PS控制DMA,使DMA通过数据通道将数据写入DDR中。
4:传输校验,对比接收数据与发送数据是否一致。
本课程会详细介绍创建工程的每个步骤,后面的课程将不再详细介绍创建工程的步骤。
2系统框图
本系统中首先ZYNQ中的ARM把测试数据写入到PS DDR中,之后启动AXI-DMA通过AXI4总线把PS DDR中的测试数据发送给AXI-DMA IP。AXI-DMA的发送端把数据环路到接收端后通过AXI4总线把数据写入到ZYNQ的PS DDR中,并且产生中断通知ARM读取DDR中的数据。
de530a6cb76e4a4aab7b4d8f6221bfc5.jpg
3搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“3-1-01米联客2024版ZynqSocSDK入门篇”中第一个工程 “01Vitis Soc开发入门”这个实验。
3.1Zynq IP PS部分设置
本文中的PS设置内容是新增加的配置部分,关于DDR、MIO、CPU时钟等设置请参考“3-1-01米联客2024版ZynqSocSDK入门篇”中第一个工程 “01Vitis Soc开发入门”这个实验。
1:PS复位设置
986477fcb0744f07adcce414ed51b577.jpg
2:设置 PS GT Master 接口和 HP Slave 接口
3875fc40038b4c91a447de4d43966914.jpg
3:设置PL到PS的中断
Interurptsà勾选 Fabric Interrupt,勾选IRQ_F2P[15:0]。
19201add340c458ca7dafc35d4b489b8.jpg
4:设置PL的时钟
勾选FCLK_CLK0,设置为100,即PS的PLL提供本系统的时钟100MHZ。
e1c39bfbed934c67ace1b531bdd06289.jpg
5:ZYNQ IP设置完成后
下图中IRQ_F2P[0:0]会根据xconcat IP自动扩展
a3ff3993f03a441f9bb28f198d24aba3.jpg
3.2添加IP
单击添加IP按钮“ 641c4ff6c9be4b5a9a8cee0703db755e.jpg ​编辑”,输入如下模块IP名字的关键词,并双击添加。
9b933b55ff8a429083f961262be503d1.jpg

6e03861937fe4eb28e61dc86f8340598.jpg

675c70b2e52d4e01b86bd57b2e2f45de.jpg
3.3IP设置1:AXI-DMA IP设置
关于更多关于AXI-DMA的描述请阅读“附录2”
Enable Scatter Gather Engine 是否使能SG DMA模式,不勾选代表采用Direct DMA方式
Enable Micro DMA 是否使能微DMA ,不勾选代表不使能
Wideh of buffer length register :设置14。(寄存器设置最大为26,即2的26次方64MB大小,这里设置14bit 就够用了,长度越大,需要的资源也就越多)对于S2MM或者MM2S通道,这个值必须大于或者等于一次Stream的数据量。
Address Width:设置32 对于ZYNQ系统设置32bit
Enable Read Channel:使能AXI-DMA 读通道
Enable Write Channel:使能AXI-DMA写通道
Number of Channels:默认1不可修改
Memory Map Data Width:设置AXI4总线的数据位宽,越大效率越高
Stream Data Width:设置AXIStream数据接口的数据位宽
Max Burst Size:设置AXI4总线最大支持的Burst数据量,这个值越大效率越高,但是会过多占用AXI4总线带宽。
635e7e81639c4a698687d1f55707e699.jpg
2:AXI-DATA-FIFO IP设置
Data FIFO设置TDATA Width为4。
fbeca4d7fc0f43a4bd39112d2614706e.jpg
3:设置xlconcatIp
xlconcat IP实现了单个分散的信号,整合成总线信号。这里,将2个独立的中断信号,合并在一起连接到MPSOC IP的中断信号接口上。
94ec5722412e455991b319fa19eebf88.jpg
3.4PL图形编程
点击Run Connection Automation 快速自动连线。
48369be2fc124bb8ae313a1eaefaead4.jpg
只要软件提示你需要自动连线,一般都需要进行自动连线,除非自己知道如何连线,有特殊需求。
cb3aa17b99084a6a9bca1ffe9e3dff04.jpg
这部完成后,部分连线已经完成,如果还有提示需要自动连线的继续让软件自动连线
548d48aaa95143c49f80959455e44ca2.jpg
af1363de7ff34068bb7f9573fd057bc4.jpg
直到出下如下。可以看到,还有未连线的模块,这部分就需要手动完成了。
b2506e645c7349b2bbe3ad5b9ff9060f.jpg
完成后如下:
78a50742c09c46f8838ccea77cb67c53.jpg
3.5添加ila在线逻辑分析仪
对于图形化的设计,添加ila核比较简便,选中需要被添加的信号右击debug
c9f56423b4e44515be240c10de234280.jpg
之后软件会再次提醒需要自动连线
b10e14440cf84382a89415912fd6e935.jpg
自动添加ila核
2b2eea8e87ca45e4b75eaf33fa5050ce.jpg
由于我们还要观察2个中断信号,双击ILA核,增加对于非总线接口的信号支持,
5f2063780aec41f6a5fbf927637610d2.jpg
设置Monitor Type为MIX
8269602a831d4724a90f6fa0d409affd.jpg
之后手动添加中断信号到ila
e25a586f739743eeacc8ffed4920d1fc.jpg
3.6完成图形编程设计
d91b7d164bc743778ac63639eec60673.jpg
至此,就完成了工程架构的搭建。后面的操作过程是Validate Design->Generate Out products->Create wrappers-> Generate Bitstream ,产生完成后导出硬件,加载Vitis IDE。
3.7地址空间分配
bed8c06320ff44838d1004dabf8bda98.jpg
3.8编译并导出平台文件
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:生成Bit文件。
4:导出到硬件: FileàExport HardwareàInclude bitstream
5:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
90898e4804fb4ae6bda48bbfb32ff59e.jpg
4搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程。
4.1创建SDK Platform工程
启动Vitis-Sdk
91fb47f3cec44f23868b39dd81731afb.jpg
设置好路径
6369db2fce3845ffaae6ecb3dcb04204.jpg
米联客资料中的路径规范如下图:
soc_prj里面是基于SOC的硬件工程源码
soc_hw里面是xsa格式文件,soc_prj编译会导出system_wrapper.xsa到这个文件
soc_sdk里面是裸机的sdk工程,sdk工程创建依赖soc_hw中的system_wrapper.xsa
a8aa545c9a324ceaace00ead04dc77e9.jpg
单击Create Platform Project 创建基于开发平台的工程
460eb09bb15a4242bd286a188ecd77aa.jpg
42dce28995894577b9c30bd69b61d86f.jpg
添加之前导出的system_wrapper.xsa文件
ea344d8503824c6e9a3242e9e43613df.jpg
11c363abfd5f4d0cb3543fb1464a17fd.jpg
创建完成后
11bdcbbafb77407aacb7696f3e9ff9d3.jpg
最后,右击soc_base完成编译
095b4b459db348219f6b1317e68f2f81.jpg
4.2创建axi_dma_loop APP工程
首选创建一个空的工程
13cd4f2726da40a69884e20269f096e8.jpg
342041cc721f485e872a0f6d601d6aa1.jpg

ec5b020621d348188bcf2ed1f92dd17d.jpg
aa1b29f6e0e8473dbcac38ffbedaa528.jpg
8c09ee64b30746e6ad8446f1f61af2b9.jpg
a6c2fc9877d44b7a84990ad4df546e80.jpg
复制soc_prj/uisrc/07_sdk_src路径下已经编写好的源码到src路径下
571289ebb9b14794ac38d28755f82fe6.jpg
5程序分析
5.1总流程图
如下图所示,本文的程序工作流程如下,包括初始化中断、写测试数据到PS DDR、先启动DMA接收中断、再启动DMA发送中断、等待发送中断和接收中断都完成、读取PS DDR中接收到的数据、完成数据对比校验。
af3d59e2ed3d41bcb18a7d506b75ab8c.jpg
5.2main.c源码的分析
1:init_intr_sys函数
功能:对中断资源的初始化,使能中断资源。
说明:这个函数里面调用的函数是米联客封装好的初始化函数,使用起来比较方便。一般只要给出中断对象,中断号,就可以对中断进行初始化。
init_intr_sys函数
  1. int init_intr_sys(void)
  2. {
  3.         DMA_Intr_Init(&AxiDma,0);//初始化DMA中断
  4.         Init_Intr_System(&Intc); //初始化系统中断
  5.         Setup_Intr_Exception(&Intc); //设置系统中断
  6.         DMA_Setup_Intr_System(&Intc,&AxiDma,TX_INTR_ID,RX_INTR_ID);//设置DMA中断关联到系统中断
  7.         DMA_Intr_Enable(&Intc,&AxiDma); //使能DMA中断
  8.         return 0;
  9. }
复制代码

下面对init_intr_sys函数中调用的函数功能进行说明:
DMA_Intr_Init(&AxiDma,0)
第一参数是DMA的对象;第二参数是硬件ID。
Init_Intr_System(&Intc)
初始化系统中断系统
DMA_Setup_Intr_System(&Intc,&AxiDma,TX_INTR_ID,RX_INTR_ID)
初始化并设置DMA的中断系统。
第一参数是一个指向INTC实例指针;
第二个参数是一个指向DMAengine的实例指针;
第三个参数是AXI-DMA TX通道中断ID;
第四个参数是AXI-DMA RX通道中断ID;
DMA_Intr_Enable(&Intc,&AxiDma)
DMA中断使能
2:axi_dma_test()函数
该函数中的工程流程如下:
1:写测数据到DDR中,这里需要注意,必须用Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN)确保数据都从cache刷到DDR中,否则DMA发送数据的时候可能会错误。
  1.   Value = TEST_START_VALUE + (i & 0xFF);
  2.                 for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
  3.                                 TxBufferPtr[Index] = Value; //PS 发PL 缓存写入测试数据
  4.                                 Value = (Value + 1) & 0xFF;
  5.                 }
  6. Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN) ;//PS写数据到DDR用Xil_DCacheFlushRange函数确保数据都从cache刷如DDR
复制代码
2:在启动DMA发送前,先设置并且DMA接收,这样数据还没接收到前可以让DMA接收先做好接收准备
  1. Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);<img width="15" _height="15" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" border="0" alt="">
复制代码
3:启动本次DMA发送,把上面写入到DDR发射缓冲区的数据发送到FPGA的AXI-DMA控制器
  1. Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
复制代码
4:等待发送中断和接收中断都产生
  1. while (!TxDone || !RxDone)
复制代码
5:对比接收到的数据和发送的数据是否一致
  1. Status = DMA_CheckData(MAX_PKT_LEN, (TEST_START_VALUE + (i & 0xFF)));
复制代码
这一步需要注意,当从DMA接收中断接收数据后,读取DDR中的数据前也要采用Xil_DCacheInvalidateRange函数确保读取的数据都是从DDR读到的。
  1. int DMA_CheckData(int Length, u8 StartValue)
  2. {
  3.         u8 *RxPacket;
  4.         int Index = 0;
  5.         u8 Value;
  6.         RxPacket = (u8 *) RX_BUFFER_BASE;
  7.         Value = StartValue;
  8.         /* Invalidate the DestBuffer before receiving the data, in case the
  9.          * Data Cache is enabled
  10.          */
  11.         Xil_DCacheInvalidateRange((u32)RxPacket, Length); //PL写数据到DDR用Xil_DCacheInvalidateRange函数确保数据都从cache刷如DDR
  12.         for(Index = 0; Index < Length; Index++) {
  13.                 if (RxPacket[Index] != Value) {
  14.                         xil_printf("Data error %d: %x/%x\r\n",
  15.                             Index, RxPacket[Index], Value);
  16.                         return XST_FAILURE;
  17.                 }
  18.                 Value = (Value + 1) & 0xFF;
  19.         }
  20.         return XST_SUCCESS;
  21. }
复制代码

5.3dma_intr.c源码分析
1:DMA中断函数的设置和中断的使能
DMA_Setup_Intr_System函数
该函数用于设置接收和发送中断函数的回调函数。
首先通过XScuGic_SetPriorityTriggerType函数设置了PL中断的优先级为0Xa0,采用上升沿出发方式。
其次通过XScuGic_Connect完成中断函数的绑定
最后通过XScuGic_Enable函数完成DMA的PL中断绑定到INTC系统中断中,这样系统中断就能根据中断号回调之前绑定的函数。
  1. int DMA_Setup_Intr_System(XScuGic * IntcInstancePtr,XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId)
  2. {
  3.         int Status;
  4.         XScuGic_SetPriorityTriggerType(IntcInstancePtr, TxIntrId, 0xA0, 0x3); //设置中断上升沿触发
  5.         XScuGic_SetPriorityTriggerType(IntcInstancePtr, RxIntrId, 0xA0, 0x3); //设置中断上升沿触发
  6.         /*
  7.          * Connect the device driver handler that will be called when an
  8.          * interrupt for the device occurs, the handler defined above performs
  9.          * the specific interrupt processing for the device.
  10.          */
  11.         Status = XScuGic_Connect(IntcInstancePtr, TxIntrId, //把中断函数连接到系统中断
  12.                                 (Xil_InterruptHandler)DMA_TxIntrHandler,
  13.                                 AxiDmaPtr);
  14.         if (Status != XST_SUCCESS) {
  15.                 return Status;
  16.         }
  17.         Status = XScuGic_Connect(IntcInstancePtr, RxIntrId, //把中断函数连接到系统中断
  18.                                 (Xil_InterruptHandler)DMA_RxIntrHandler,
  19.                                 AxiDmaPtr);
  20.         if (Status != XST_SUCCESS) {
  21.                 return Status;
  22.         }
  23.         XScuGic_Enable(IntcInstancePtr, TxIntrId); //使能DMA发送中断
  24.         XScuGic_Enable(IntcInstancePtr, RxIntrId); //使能DMA接收中断
  25.         return XST_SUCCESS;
  26. }
复制代码

DMA_Intr_Enable函数:
由于AXI-DMA控制器是FPGA端实现的,因此为了让其产生中断还要使能其中断能能寄存器,通过调用DMA_Intr_Enable使能DMA控制器的发送和接收中断。
  1. int DMA_Intr_Enable(XScuGic * IntcInstancePtr,XAxiDma *DMAPtr)
  2. {
  3.         /* Disable all interrupts before setup */
  4.         XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
  5.         XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
  6.         /* Enable all interrupts */
  7.         XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
  8.         XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
  9.         return XST_SUCCESS;
  10. }
复制代码

2:DMA发送中断函数DMA_TxIntrHandler
当启动XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE)函数后,数据从DDR通过AXI总线搬运到AXI-DMA控制器后,AXI-DMA控制器会产生一个发送中断通知CPU,发送中断函数就会被回调。DMA_TxIntrHandler函数中的内容分析如下:
XAxiDma *AxiDmaInst = (XAxiDma *)Callback;这句代码是为了获取当前中断的对象。void *Callback是一个无符号的指针,传递进来的阐述可以强制转换成其他任何的对象,这里就是强制转换成 XAxiDma 对象了。
IrqStatus =XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DMA_TO_DEVICE)这个函数获取当前中断号。
XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DMA_TO_DEVICE);这个函数是响应当前中断,通知CPU 当前中断已经被接收,并且清除中断标志位。如果中断全部正确,TxDone将被置为1表示发送中断完成。如果有错误,则复位DMA,并且设置超时参数。
函数源码如下:

3:DMA接收中断函数DMA_RxIntrHandler
当启动XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE)函数后,数据从DDR通过AXI总线搬运到AXI-DMA控制器,数据通过AXI-DMA 的TX通道环路到AXI-DMA的RX通道.这样数据会被再次写入到DDR.当RX通道数据被AXI-DMA控制器发送完毕,DMA控制器就会产生一个PL的RX中断。XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA)函数已经被设置,所以当AXI-DMA控制器发送了RX中断后,中断系统会回调DMA_RxIntrHandler函数。DMA_TxIntrHandler函数中的内容分析如下:
XAxiDma *AxiDmaInst = (XAxiDma *)Callback;这句代码是为了获取当前中断的对象。void *Callback是一个无符号的指针,传递进来的阐述可以强制转换成其他任何的对象,这里就是强制转换成 XAxiDma 对象了。
IrqStatus =XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA)这个函数获取当前中断号。
XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);这个函数是响应当前中断,通知CPU 当前中断已经被接收,并且清除中断标志位。如果中断全部正确,TxDone将被置为1表示发送中断完成。如果有错误,则复位DMA,并且设置超时参数。
函数源码如下:
  1. static void DMA_RxIntrHandler(void *Callback)
  2. {
  3.         u32 IrqStatus;
  4.         int TimeOut;
  5.         XAxiDma *AxiDmaInst = (XAxiDma *)Callback;
  6.         /* Read pending interrupts */
  7.         IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA);
  8.         /* Acknowledge pending interrupts */
  9.         XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);
  10.         /*
  11.          * If no interrupt is asserted, we do not do anything
  12.          */
  13.         if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
  14.                 return;
  15.         }
  16.         /*
  17.          * If error interrupt is asserted, raise error flag, reset the
  18.          * hardware to recover from the error, and return with no further
  19.          * processing.
  20.          */
  21.         if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
  22.                 Error = 1;
  23.                 /* Reset could fail and hang
  24.                  * NEED a way to handle this or do not call it??
  25.                  */
  26.                 XAxiDma_Reset(AxiDmaInst);
  27.                 TimeOut = RESET_TIMEOUT_COUNTER;
  28.                 while (TimeOut) {
  29.                         if(XAxiDma_ResetIsDone(AxiDmaInst)) {
  30.                                 break;
  31.                         }
  32.                         TimeOut -= 1;
  33.                 }
  34.                 return;
  35.         }
  36.         /*
  37.          * If completion interrupt is asserted, then set RxDone flag
  38.          */
  39.         if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
  40.                 RxDone = 1;
  41.         }
  42. }
复制代码

4:数据对比
数据对比函数用于对比发送的数据是否和接收的数据一致,以此验证我们的DMA环路实验是否正确。这里需要注意必须使用Xil_DCacheInvalidateRange确保读取的数据都是从DDR中读到
  1. int DMA_CheckData(int Length, u8 StartValue)
  2. {
  3.         u8 *RxPacket;
  4.         int Index = 0;
  5.         u8 Value;
  6.         RxPacket = (u8 *) RX_BUFFER_BASE;
  7.         Value = StartValue;
  8.         /* Invalidate the DestBuffer before receiving the data, in case the
  9.          * Data Cache is enabled
  10.          */
  11.         Xil_DCacheInvalidateRange((u32)RxPacket, Length);
  12.         for(Index = 0; Index < Length; Index++) {
  13.                 if (RxPacket[Index] != Value) {
  14.                         xil_printf("Data error %d: %x/%x\r\n",
  15.                             Index, RxPacket[Index], Value);
  16.                         return XST_FAILURE;
  17.                 }
  18.                 Value = (Value + 1) & 0xFF;
  19.         }
  20.         return XST_SUCCESS;
  21. }
复制代码

6方案演示
6.1硬件准备
本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即 ON ON (注意新版本的 MLK-H3-CZ08-7100FC(米联客 7X 系列),支持 JTAG 模式,对于老版本的核心板,JTAG 调试 的时候一定要拔掉 TF 卡,并且设置模式开关为 OFF OFF)
4aae3f1cd2be4b00b72d1390ebc2e1f8.jpg
6.2实验结果
7f88d47890144cb5b995ba28503432fc.jpg
Debug程序,单程序停止main函数处,打开VIVADO,扫描芯片,这个时候会自动之前添加的在线逻辑分析仪IP核。如下红框的按键先不要单击
2b6203896fa7455d9c842b6093b41728.jpg
具体步骤如下:
在VIVADO工程中点击Open Target 然后点击Auto Connect
f4f6536edd924015a4977197c00ee11d.jpg
连接成功后入下图
957a99f562dd482da5472a4c40e15dc0.jpg
设置触发条件、观察信号。设置波形偏移500。
Settings -->Trigger position in window:500
Trigger Setup --> 添加触发信号axi_dma0_mm2s_introut,设置Value为R。如图所示。
6c8873f4cd63444c8f8d488505a19380.jpg
启动波形捕捉
400937b07d5f47829cf429ce0862d4bc.jpg
SDK中点击继续运行
84aabcdcfb234dde8408d99b96ee1218.jpg
当中断触发的时,VIVAIDO中Hardware Manager出现捕捉波形,如下图所示
a1593acd150f429a97e39ff5fac4c6ad.jpg
观察数据,打开Memory:Window->Show View->Memory
299b6c776fb741309c10077ea332d5ed.jpg
点击添加接收内存部分地址用于观察内存中的数据 地址为 0x08300000
af056e360996425caa5ad2e6f61d59ef.jpg

4d616c0467c645d497fa7a19cce129ec.jpg
为了观察一次收发数据:设置断点,重新让收发程序跑一次。
8f1d5cfa2cb743828f9a32261c7969b5.jpg
86f932d73b304b4597029b6a95badc4c.jpg
收发一次,从内存中读取的数据如图:
1874096d5f604c4897d38c07d622c84a.jpg

7c100aad84d24f17b48a8b4234de7282.jpg
可以看到第一个数据是0X0C ,后面是依次加1,一次接收的数据量是2047。发送数据也是OX0C后面依次加1,发送量是2047。接收数据一致,测试结束。

b7a8876747e549c9b035d016910b91c8.jpg
34a7baacdd464b74b4176139a087c013.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则