当前位置: 首页 > news >正文

Zynq7000系列FPGA中的DMA控制器的编程限制

有关DMAC编程时适用的限制信息,有四个考虑因素:

  • 固定非对齐突发
  • Endian swap size restrictions:在数据传输或处理过程中,不同字节序(Endian)之间的转换和对应的限制
  • 在DMA周期内更新通道控制寄存器
  • 当MFIFO满时,会导致DMAC的watchdog机制可能会触发并导致DMA通道被abort(中止)

1 固定且未对齐的突发传输

突发传输(Burst Transfer)是DMA传输中常用的一种模式,它允许DMA控制器在单个传输请求中连续地从一个地址读取多个数据项(或向一个地址写入多个数据项),而不需要CPU的干预。然而,如果这些数据项的地址不是按照特定的对齐方式(如按字节、字或双字对齐)连续排列的,那么这种传输就被称为“未对齐的突发传输”。

固定且未对齐的突发传输可能会导致几个问题:

  • 性能下降:未对齐的突发传输可能会降低数据传输的效率,因为DMA控制器需要花费额外的时间来处理地址的偏移和可能的内存访问冲突。
  • 复杂性增加:实现支持未对齐突发传输的DMA控制器在硬件设计上会更加复杂,因为需要处理各种可能的地址偏移情况。
  • 数据一致性问题:在某些系统中,未对齐的数据访问可能会导致数据一致性问题,特别是当多个处理器或设备共享同一块内存时。

解决方案

  • 使用对齐的突发传输:尽可能确保DMA传输的数据项是按照系统要求的对齐方式连续排列的。这可以通过在软件层面进行数据处理或内存分配时考虑对齐要求来实现。
  • 硬件支持:设计DMA控制器时,可以添加对未对齐突发传输的支持,但这通常会增加硬件的复杂性和成本。
  • 软件优化:在软件层面,可以优化数据结构和算法,以减少对未对齐突发传输的需求。例如,可以调整数据缓冲区的大小和位置,以确保它们与DMA控制器的对齐要求相匹配。

请注意,以上内容是基于一般DMA传输原理的解释,并未特指某个特定的DMA控制器或系统。在实际应用中,还需要根据具体的硬件和软件环境进行调整和优化。

2 Endian swap size restrictions

主要涉及在数据传输或处理过程中,由于不同系统或设备可能采用不同的字节序(Endianness),即大端(Big-Endian)或小端(Little-Endian),而可能导致的限制或问题。

  • 大端:最高有效字节(MSB)存储在最低的内存地址,而最低有效字节(LSB)存储在最高的内存地址。
  • 小端:最低有效字节(LSB)存储在最低的内存地址,而最高有效字节(MSB)存储在最高的内存地址。

当数据需要在不同字节序的系统之间传输或共享时,就需要进行Endian swap,以确保数据的正确解释。

虽然Endian swap本身是一个相对简单的操作(即反转字节的顺序),但在实际应用中,可能会受到以下限制:

  • 处理时间:Endian swap 需要额外的处理时间,尤其是在处理大量数据时,这可能会影响系统的整体性能。
  • CPU 负载:如果Endian swap 是在CPU上执行的,那么它可能会增加CPU的负载,从而影响其他任务的执行。
  • 临时存储:在进行Endian swap 时,可能需要额外的存储空间来临时存储反转后的字节。虽然这通常不是问题,但在内存受限的环境中可能需要特别注意。

数据类型与对齐

  • 数据类型:不同的数据类型(如整数、浮点数等)可能有不同的字节大小和对齐要求。在进行Endian swap 时,需要确保正确处理这些数据类型的字节序。
  • 对齐要求:某些硬件平台可能对数据类型有严格的内存对齐要求。如果在进行Endian swap 后破坏了这些对齐要求,可能会导致性能下降或硬件异常。

网络协议与标准

  • 网络字节序:在网络通信中,通常使用大端字节序(也称为网络字节序)。因此,当数据需要在网络上传输时,需要确保它符合网络字节序的要求。
  • 协议和标准:不同的协议和标准可能对字节序有不同的要求。在设计和实现系统时,需要仔细考虑这些要求,并确保系统的Endian swap 策略与之兼容。

解决方案

  • 硬件支持:一些现代处理器提供了内置的Endian swap 指令或功能,可以高效地执行这一操作。
  • 软件优化:在软件层面,可以通过优化算法和数据结构来减少Endian swap 的需求,或者通过并行处理来加速Endian swap 的执行。
  • 中间件和库:使用现成的中间件或库来处理Endian swap 可以简化开发工作,并减少出错的可能性。

Endian swap size restrictions 主要涉及性能、存储空间、数据类型与对齐、以及网络协议与标准等方面的限制。在设计和实现系统时,需要仔细考虑这些因素,并采取相应的措施来确保数据的正确传输和处理。

3 在DMA周期内更新通道控制寄存器

在DMA周期中更新通道控制寄存器(如CCRn,即Channel Control Register n,源地址寄存器SARn,和目标地址寄存器DARn)需要谨慎操作,因为这些寄存器的某些字段在DMA传输过程中如果被修改,可能会导致数据传输出错或数据丢失。以下是关于在DMA周期中更新这些寄存器时需要注意的关键点,特别是针对影响目标地址和源地址的更新。

在DMAC执行DMALD和DMAST指令序列之前,CCRn寄存器、SARn寄存器和DARn寄存器中的值软件程序控制DMAC在将数据从源地址传输到目标地址时执行的数据字节通道操作。这些寄存器可以在DMA周期内更新,但如果某些寄存器字段发生了变化,DMAC可能会丢弃数据。

3.1 影响目标地址更新的寄存器字段

如果使用DMAMOV指令来更新DARn(Destination Address Register n)或CCRn(Channel Control Register n)寄存器,并且这些更新影响了目标地址的某些关键字段,那么可能会导致目标数据流的不连续性。以下是几种可能导致数据流不连续性的更新情况,以及当不连续性发生时,DMA控制器(DMAC)的行为:

  • dst_inc位:如果dst_inc位被更改(这通常控制目标地址在每次传输后是否递增),那么DMA传输的目标地址序列将被打乱,导致不连续性。
  • dst_burst_size字段(当dst_inc = 0时):当dst_inc设置为0时,表示目标地址是固定的,此时dst_burst_size字段定义了在一次突发传输中传输的数据量。如果在这个模式下更改dst_burst_size,那么DMA控制器可能无法按照预期的方式完成突发传输,导致数据不连续。
  • DARn寄存器中影响目标字节通道对齐的位:例如,在总线宽度为64位的情况下,如果更改了DARn寄存器的低3位(假设这些位控制地址的字节偏移),那么目标地址的字节对齐方式将发生变化,这可能导致DMA控制器无法正确地将数据写入目标内存位置,从而产生数据不连续性。
DMA控制器的响应

当目标数据流出现不连续性时,DMA控制器(DMAC)将执行以下操作:

  • 停止执行DMA通道线程:DMAC会暂停当前DMA通道的执行,以便处理不连续性。
  • 完成通道的所有挂起读写操作:DMAC会确保所有已经启动但尚未完成的读写操作都得以完成,这类似于执行DMARMB(DMA Read Memory Barrier)和DMAWMB(DMA Write Memory Barrier)指令的效果。
  • 丢弃通道中剩余的MFIFO数据:由于数据不连续性,MFIFO(Memory FIFO)中可能包含无法正确写入目标地址的数据。因此,DMAC会丢弃这些剩余的数据,以避免数据损坏。
  • 恢复DMA通道线程的执行:在处理完不连续性并清理了所有相关资源后,DMAC将恢复DMA通道的执行。然而,由于数据不连续性的影响,后续的数据传输可能需要重新配置DARn和/或CCRn寄存器,以确保数据能够正确地写入目标地址。

因此,在DMA传输期间更新影响目标地址的寄存器时,需要特别小心以避免数据不连续性的发生。如果必须更新这些寄存器,建议在DMA传输的适当阶段(如传输完成或暂停时)进行,并确保更新后的配置能够正确地支持后续的数据传输。

3.2 影响源地址更新的寄存器字段

在DMA)传输过程中,如果使用DMAMOV指令来更新SARn或CCRn寄存器,并且这些更新影响了源地址的某些关键字段,那么可能会导致源数据流的不连续性。以下是几种可能导致数据流不连续性的更新情况,以及当不连续性发生时,DMA控制器(DMAC)的行为:

  • src_inc位:如果src_inc位被更改(这通常控制源地址在每次传输后是否递增),那么DMA传输的源地址序列将被打乱,导致不连续性。
  • src_burst_size字段src_burst_size字段定义了在一次突发传输中从源地址读取的数据量。如果更改这个字段,那么DMA控制器可能无法按照原始计划完成突发传输,导致源数据流的不连续性。
  • SARn寄存器中影响源字节通道对齐的位:例如,在总线宽度为32位的情况下,如果更改了SARn寄存器的低2位(假设这些位控制地址的字节偏移),那么源地址的字节对齐方式将发生变化。这可能导致DMA控制器无法正确地从源内存位置读取数据,从而产生数据不连续性。
DMA控制器的响应

当源数据流出现不连续性时,DMA控制器(DMAC)将执行以下操作:

  • 停止执行DMA通道线程:DMAC会暂停当前DMA通道的执行,以便处理不连续性。
  • 完成通道的所有挂起读操作:DMAC会确保所有已经启动但尚未完成的读操作都得以完成,这类似于执行DMARMB(DMA Read Memory Barrier)指令的效果。这是为了确保所有在地址更新之前开始的数据读取都能够正常完成。
  • 恢复DMA通道线程的执行:在处理完不连续性并完成了所有挂起的读操作后,DMAC将恢复DMA通道的执行。与目标地址不连续性不同,在源地址不连续性的情况下,MFIFO(Memory FIFO)中的数据不会被丢弃,因为这些数据是在地址更新之前已经成功读取的。

因此,在DMA传输期间更新影响源地址的寄存器时,需要谨慎操作以避免数据不连续性的发生。如果必须更新这些寄存器,建议在DMA传输的适当阶段(如当前突发传输完成后)进行,并确保更新后的配置能够支持后续的数据传输。同时,需要注意检查DMA控制器的文档或手册,以了解具体硬件在处理地址更新时的行为细节。

4 在DMA通道间的资源共享

在DMA系统中,DMA通道程序共享MFIFO数据存储资源。这意味着多个并发运行的DMA通道程序必须确保它们的资源需求不超过MFIFO配置的容量。如果超出了这个限制,DMAC可能会锁定并触发看门狗中断或异常。为了确保MFIFO资源被正确使用,DMAC实现了一个称为“加载锁”(load-lock)的机制。

4.1 加载锁

加载锁要么被一个通道所拥有,要么处于空闲状态。拥有加载锁的通道可以成功执行DMALD(DMA Load)指令。如果一个通道没有拥有加载锁,那么它在执行DMALD指令时会暂停,直到它获得加载锁的所有权。

  • 获取所有权:当一个通道执行DMALD或DMALDP(DMA Load with Post-increment)指令,并且没有其他通道当前拥有加载锁时,该通道将获取加载锁的所有权。
  • 释放所有权:通道可以通过以下任一控制器操作释放加载锁的所有权:
    • 执行DMAST、DMASTP或DMASTZ(DMA Store)指令。
    • 执行DMARMB(DMA Read Memory Barrier)或DMAWMB(DMA Write Memory Barrier)指令,即到达一个屏障。
    • 执行DMAWFP(DMA Wait For Program)或DMAWFE(DMA Wait For Event)指令,即等待。
    • 正常终止,即执行DMAEND指令。
    • 由于任何原因(包括DMAKILL)而中止。

DMA通道程序的MFIFO资源使用以MFIFO条目为单位进行测量,并随着程序的进行而增加或减少。DMA通道程序的MFIFO资源需求通过静态需求和动态需求来描述,这两者都受到加载锁机制的影响。

4.2 静态需求

Arm定义了静态需求为通道在执行以下任一操作之前当前正在使用的最大MFIFO条目数:

  • 执行WFP(Wait For Program)或WFE(Wait For Event)指令。
  • 获取加载锁的所有权。

静态需求是DMA通道程序在不需要等待外部事件或程序完成时,可能同时占用的MFIFO条目的最大数量。这有助于设计者确保在并发运行多个DMA通道程序时,系统有足够的MFIFO资源来避免资源冲突和溢出。

在解释Arm定义的动态需求时,有一些细节需要澄清和修正。首先,动态需求并不是简单地定义为静态需求与通道程序执行过程中任何时间使用的最大MFIFO条目数之间的差值。实际上,动态需求更多地与程序执行过程中MFIFO资源使用的动态变化相关,但它通常不是通过直接减去静态需求来计算的。

不过,为了讨论和理解的目的,我们可以这样理解:动态需求反映了在程序执行过程中,除了静态需求之外,额外需要的MFIFO资源量。这通常取决于程序的具体逻辑和数据访问模式。

然而,Arm并没有直接给出一个关于如何计算动态需求的明确公式,因为这是一个相对复杂且依赖于具体实现的概念。但我们可以从总体上理解如何评估和管理MFIFO资源的需求。

4.3 计算总MFIFO需求

要计算一组通道程序的总MFIFO需求,确实需要将所有通道程序的最大可能MFIFO使用量(这可以视为一个结合了静态和动态需求的综合指标)相加。这通常意味着你需要考虑每个程序在任何时候可能达到的最大MFIFO使用量,而不是仅仅基于静态需求。

为了避免DMAC锁定,你需要确保所有并发运行的通道程序的总MFIFO需求不超过DMAC的最大MFIFO深度。这个最大深度是DMAC能够支持的MFIFO条目的最大数量,以字(word)为单位,每个字通常是64位(尽管这取决于具体的硬件实现)。

4.4 注意事项

  • 设计考量:在设计DMA通道程序时,应该仔细规划MFIFO资源的使用,以确保不会超出系统的能力。
  • 实时监控:在某些情况下,可能需要实时监控MFIFO资源的使用情况,以确保在并发执行时不会发生冲突或溢出。
  • 优化:通过优化程序逻辑和数据访问模式,可以减少对MFIFO资源的需求,从而提高系统的整体性能和稳定性。

虽然Arm没有直接定义如何计算动态需求,但了解MFIFO资源的总需求(包括静态和动态方面)对于确保DMAC的稳定运行至关重要。通过合理规划和优化,可以避免DMAC锁定和其他与资源使用相关的问题。

相关文章:

Zynq7000系列FPGA中的DMA控制器的编程限制

有关DMAC编程时适用的限制信息,有四个考虑因素: 固定非对齐突发Endian swap size restrictions:在数据传输或处理过程中,不同字节序(Endian)之间的转换和对应的限制在DMA周期内更新通道控制寄存器当MFIFO满…...

超简易高效的 AI绘图工具—与sd-webui一致界面,6G显存最高提升75%出图速率!(附安装包)

大家好,我是灵魂画师向阳 今天给大家分享一个基于Stable Diffusion WebUI 构建的AI绘图工具—sd-webui-forge,该工具的目标在于简化插件开发,优化资源管理,加速推理。 Forge承诺永远不会对Stable Diffusion WebUI用户界面添加不…...

ArduPilot开源代码之OpticalFlow_backend

ArduPilot开源代码之OpticalFlow_backend 1. 源由2. Library设计3. 重要例程3.1 OpticalFlow_backend::_update_frontend3.2 OpticalFlow_backend::_applyYaw 4. 总结5. 参考资料 1. 源由 光流计是一种低成本定位传感器,所有的光流计设备传感驱动代码抽象公共部分统…...

设计模式探索:适配器模式

1. 适配器模式介绍 1.1 适配器模式介绍 适配器模式(adapter pattern)的原始定义是:将一个类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作。 适配器模式的主要作用是把原本不兼容的接口&#xff0c…...

OpenCV 寻找棋盘格角点及绘制

目录 一、概念 二、代码 2.1实现步骤 2.2完整代码 三、实现效果 一、概念 寻找棋盘格角点(Checkerboard Corners)是计算机视觉中相机标定(Camera Calibration)过程的重要步骤。 OpenCV 提供了函数 cv2.findChessboardCorners…...

【深度学习】PyTorch深度学习笔记02-线性模型

1. 监督学习 2. 数据集的划分 3. 平均平方误差MSE 4. 线性模型Linear Model - y x * w 用穷举法确定线性模型的参数 import numpy as np import matplotlib.pyplot as pltx_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0]def forward(x):return x * wdef loss(x, y):y_pred…...

10.FreeRTOS_互斥量

互斥量概述 在博文“ FreeRTOS_信号量 ”中,使用了二进制信号量实现了互斥,保护了串口资源。博文链接如下: FreeRTOS_信号量-CSDN博客 但还是要引入互斥量的概念。互斥量与二进制信号量相比,能够多实现如下两个功能&#xff1a…...

EtherCAT总线冗余让制造更安全更可靠更智能

冗余定义 什么是总线冗余功能?我们都知道,EtherCAT现场总线具有灵活的拓扑结构,设备间支持线型、星型、树型的连接方式,其中线型结构简单、传输效率高,大多数的现场应用中也是使用这种连接方式,如下图所示…...

Android IdleHandler源码分析

文章目录 Android IdleHandler源码分析概述前提基本用法源码分析添加和删除任务执行任务 应用场景 Android IdleHandler源码分析 概述 IdleHandler是一个接口,它定义在MessageQueue类中,用于在主线程的消息队列空闲时执行一些轻量级的任务。IdleHandle…...

Mac安装stable diffusion 工具

文章目录 1.安装 Homebrew2.安装 stable diffusion webui 的依赖3.下载 stable diffusion webui 代码4.启动 stable diffusion webui 本体5.下载模型6.这里可能会遇到一个clip-vit-large-patch14报错 参考:https://brew.idayer.com/install/stable-diffusion-webui/…...

CVE-2024-6387Open SSH漏洞彻底解决举措(含踩坑内容)

一、漏洞名称 OpenSSH 远程代码执行漏洞(CVE-2024-6387) 二、漏洞概述 Open SSH是基于SSH协议的安全网络通信工具,广泛应用于远程服务器管理、加密文件传输、端口转发、远程控制等多个领域。近日被爆出存在一个远程代码执行漏洞,由于Open SSH服务器端…...

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式(爬取百度logo为例) import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…...

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容(含视频)

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容(含视频) 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。d…...

【学术会议征稿】第三届智能电网与能源系统国际学术会议

第三届智能电网与能源系统国际学术会议 2024 3rd International Conference on Smart Grid and Energy Systems 第三届智能电网与能源系统国际学术会议(SGES 2024)将于2024年10月25日-27日在郑州召开。 智能电网可以优化能源布局,让现有能源…...

01. 课程简介

1. 课程简介 本课程的核心内容可以分为三个部分,分别是需要理解记忆的计算机底层基础,后端通用组件以及需要不断编码练习的数据结构和算法。 计算机底层基础可以包含计算机网络、操作系统、编译原理、计算机组成原理,后两者在面试中出现的频…...

iOS热门面试题(三)

面试题1:在iOS开发中,什么是MVC设计模式?请详细解释其各个组成部分,并给出一个实际应用场景,包括具体的代码实现。 答案: MVC设计模式是一种在软件开发中广泛使用的架构模式,特别是在iOS开发中…...

ECS中postTransform.Value = float4x4.Scale(1, math.sin(elapsedTime), 1)

在Unity的ECS(Entity Component System)架构中,postTransform.Value float4x4.Scale(1, math.sin(elapsedTime), 1); 用于设置一个变换矩阵的缩放部分。下面是对这行代码的详细解释: postTransform: 这是一个表示变换的组件或结构…...

VLM技术介绍

1、背景 视觉语言模型(Visual Language Models)是可以同时从图像和文本中学习以处理许多任务的模型,从视觉问答到图像字幕。 视觉识别(如图像分类、物体保护和语义分割)是计算机视觉研究中一个长期存在的难题&#xff…...

x264 编码器 AArch64 汇编函数模块关系分析

x264 编码器 AArch64 汇编介绍 x264 是一个流行的开源视频编码器,它实现了 H.264/MPEG-4 AVC 标准。x264 项目致力于提供一个高性能、高质量的编码器,支持多种平台和架构。对于 AArch64(即 64 位 ARM 架构),x264 编码器利用该架构的特性来优化编码过程。在 x264 编码器中,…...

windows10开启防火墙,增加入站规则后不生效,还是不能访问后端程序

一、背景: 公司护网要求开启防火墙,开启防火墙后,前后端分离的项目调试受影响,于是增加入站规则开放固定的后台服务端口,增加的mysql端口3306和redis端口6379,别人都可以访问,但是程序的端口808…...

academic-homepage:快速搭建个人学术主页,页面内容包括个人简介、教育经历、发布过的学术列表等,同时页面布局兼容移动端。

今天给大家分享GitHub 上一个开源的 GitHub Pages 模板 academic-homepage。 可帮助你快速搭建个人学术主页,页面内容包括个人简介、教育经历、发布过的学术列表等最基本内容,同时页面布局兼容移动端。 相关链接 github.com/luost26/academic-homepage …...

.env.development、.env.production、.env.staging

环境变量文件(如 .env.development、.env.production、.env.staging)用于根据不同的环境(开发、生产、测试等)配置应用程序的行为。 作用 .env.development:用于开发环境的配置。开发人员在本地开发时会使用这个文件…...

国密证书(gmssl)在Kylin Server V10下安装

1.查看操作系统信息 [root@localhost ~]# cat /etc/.kyinfo [dist] name=Kylin milestone=Server-V10-GFB-Release-ZF9_01-2204-Build03 arch=arm64 beta=False time=2023-01-09 11:04:36 dist_id=Kylin-Server-V10-GFB-Release-ZF9_01-2204-Build03-arm64-2023-01-09 11:04:…...

【数据服务篇】法律快车问答数据:为法律智能化铺就道路

数据来源 法律快车汇集了广泛的法律问题和专业律师的回答,这些来自用户和律师的数据构成了丰富的问答资源。用户通过平台提交各类法律疑问,得到资深律师的详尽解答,形成了一系列真实、多样化的法律案例和讨论。 数据获取见文末。 数据内容…...

各向异性含水层中地下水三维流基本微分方程的推导(二)

各向异性含水层中地下水三维流基本微分方程的推导 参考文献: [1] 刘欣怡,付小莉.论连续性方程的推导及几种形式转换的方法[J].力学与实践,2023,45(02):469-474. 书接上回: 我们能得到三个方向的流入流出平衡方程: ∂ ρ u x ∂ x d x d y d…...

2024 微信小程序 学习笔记 第一天

微信公众平台 (qq.com) 小程序代码的构成 项目结构 JSON 配置文件 WXML 模板 WXSS 样式 JS 逻辑交互 小程序的宿主环境 宿主 通信模型 运行机制 组件 视图组件 view scrioll-view swiper swiper-item swiper属性 text button image image mode属性 小程序API 协…...

PCIe驱动开发(3)— 驱动设备文件的创建与操作

PCIe驱动开发(3)— 驱动设备文件的创建与操作 一、前言 在 Linux 中一切皆为文件,驱动加载成功以后会在“/dev”目录下生成一个相应的文件,应用程序通过对这个名为“/dev/xxx” (xxx 是具体的驱动文件名字)的文件进行相应的操作即…...

【Redis】简单了解Redis中常用的命令与数据结构

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 关注 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、Redis的特点和适用场景三、Redis的数据类型和使用3.1字符串(String&…...

IDEA启动Web项目总是提示端口占用

文章目录 IDEA启动Web项目总是提示端口占用一、前言1.场景2.环境 二、正文1.场景一:真端口占用2. 场景二:假端口占用 IDEA启动Web项目总是提示端口占用 一、前言 1.场景 IDEA启动Web项目总是提示端口占用: 确实是端口被占用,比如:没有正常…...

JRT打印鉴定记录单

良好的基础会使上层实现越做越简单,jrt在开始写业务之前就把运用场景需要的基础实验和设计完毕了。基于jrt的基础可以很轻松的实现强大的打印效果。jrt的打印和lodop比较像,是高度为满足建议系统打印定制的打印实现,设计器可能没lodop通用&am…...