C++并口开发大全例子包含17个通道分析器

发布一下 0 0

#程序员##IT教育##软件开发##IT#

锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。



背景

最近开发串口通信软件,在codeproject找了些例子,本文虽然是介绍并中开发的,但是里面作者介绍了一些通信的注意事项和高速大数据的实时分析软件框架,所以翻译下,自己学,也让大家有所提高。codeproject代码看不懂,找锐英源。


特征

  • 具有多达17 条输入线的数字示波器/逻辑分析仪
  • 使用并行(打印机)端口进行输入。
  • 虽然逻辑分析仪通常非常昂贵,但这款是零成本的
  • 用速度优化的C++编写,以获得最大可能的采样率
  • 该程序是一个独立的单个 EXE 文件,既不需要任何额外的 DLL,也不需要任何框架。它开箱即用
  • 所有 Windows 平台上运行(从 Win 95 到 Win 10)
  • 32 位Windows 和64 位Windows上运行
  • 首次运行时,安装驱动程序以访问所有 NT 平台上的硬件 IO 端口
  • 通过 PC 扬声器播放声音以证明驱动程序工作正常
  • 在 GUI 的 LED 中显示输入线寿命的实际状态
  • 捕获高达500.000 个样本/秒(取决于您的硬件和操作系统)
  • 捕获到内存(而不是磁盘)以获得最大速度
  • 捕获始终以硬件允许的最大频率运行
  • 节省内存的捕获技术仅存储输入行的变化,而不是存储每个采样的所有行
  • 捕获过程独立于数据分析,因此您可以尝试各种设置以最佳方式显示捕获的数据
  • 分析仪生成带有光栅网格的彩色示波器图
  • 输出写入一个HTML文件和一个或多个GIF文件
  • 因此,分析结果可以很容易地与其他人共享,这些人不必安装任何程序来查看专有的二进制格式
  • 您可以在每个分析器输出中写入一个单独的标题,以便稍后在大量文件中区分它们
  • 分析数据时,可以选择删除旧的分析器输出或保留旧文件
  • 时间轴以微秒精度显示绝对或相对时间(性能计数器)
  • 非活动输入线的自动检测仅显示有活动的通道
  • 空闲时间的自动检测减少了长时间的不活动
  • 输入频率的自动检测选择适当的光栅单元,如真实示波器(10 µs、20 µs、25 µs、50 µs、100 µs 等)
  • 自动检测操作系统的上下文切换
  • 解码的串行数据(起始位、奇偶校验、确认、停止位)和它们所代表的字节可以打印到图表中和/或打印到 HTML 中,然后可以将其复制到剪贴板。
  • 解码后的串行数据(起始位、奇偶校验、确认、停止位)和它们所代表的字节写入图表
  • 非常干净的源代码,具有适当的错误处理和大量注释

版本

  • 版本 1.0:初始版本
  • 1.1 版:改进了异步信号的串行分析仪
  • 1.2 版:支持9 位异步协议
  • 1.3 版:新选项:仅将解码后的字节显示为 Html(非常快)或显示在图形下方。
  • 1.4 版:选择开始和停止大型捕获数据中的部分分析的时间间隔
  • 1.5 版:带有进度显示的状态栏
  • 版本 1.7:错误修正

为什么仍然使用好的旧并行端口?

显然,并行端口比串行端口(RS232)快得多。此外,它提供了更多的输入线。
那么USB呢?
市场上有几种
专业的逻辑分析仪,如 PCI 卡或 USB 设备。但它们非常昂贵(> 350 美元)。如果您必须测量非常高的频率或需要超过 17 个输入通道,则必须购买其中一个。但是对于高达 500 kSamples/s 的频率,并行端口就足够了。最大的好处是它是免费的。您只需要一条打印机电缆和 ElmüSoft LogicAnalyzer。
如果您的 PC 没有并行端口,您可以
订购 PCI 适配器大约 10 美元。这是拥有数字示波器的最便宜的解决方案。

为什么不使用 USB 适配器?

例如,您可能会想到从 Dimax订购SUB-20设备。这是一款具有 32条通用输入/输出线( GPIO ) 和更多功能的 USB 适配器。

但是如果您需要数字示波器,SUB-20不能代替并行端口。原因是USB 速度极慢

  • USB 的设计初衷就是要便宜。速度不是主要的设计目标。USB 电缆仅包含一根双绞线,不允许双向数据传输。当 PC 发送完一个数据包后,必须将传输方向反转以接收来自 USB 设备的响应包。USB 不能同时在两个方向上传输数据,例如 RS232,它有一根用于 RxD 的电缆,另一根用于 TxD。
  • 当 USB 设备有数据等待传输时,原始设计不允许通知 PC。相反,PC 必须以特定的时间表轮询所有连接的 USB 设备,这显然会导致最差的性能和处理器功率的浪费,即使所有设备都处于空闲状态。
  • USB 总线不是为传输少量数据而设计的。USB 是基于数据包的协议,因此传输 10 兆字节的速度相对较快。当 USB 从您的网络摄像头传输视频时,图像是否带有 1 毫秒的延迟并不重要。但是如果你读取 SUB-20 的 GPIO 端口,你只能读取 32 Bit = 4 Byte。(没有可用的 FIFO)USB 数据包大小较大,数据包的其余部分必须用虚拟零填充。
  • 由于 USB 协议的高度复杂性,USB驱动程序并不简单,因此您在驱动程序上浪费了额外的时间。


并口

USB 20

连接电脑

内置

USB

价格

自由的

$80 - $120

单次读取操作的速度

1.3 微秒

1 毫秒

最大采样率

500.000 个样本/秒

1.000 个样本/秒

如果使用两条双绞线和至少两条允许硬件握手的状态线,就像在 RS232 和 Centronix 等旧协议中常见的那样,设计更快的 USB 总线会很容易。但这会大大增加电缆和 USB 芯片的成本。在低价比高质量更重要的今天,USB 总线的设计者决定节省这些微小的额外成本,并用较慢的软件替换较快的硬件。

如果您需要用于低频率的模拟或数字输入,或者必须与慢速 I 2 C 总线、SPI 总线、RS232、RS485、ModBus 或 SMBus 通信,而时序并不那么重要,那么 SUB-20 的微控制器可以做到这一点为你。但是您无法使用 SUB-20 或类似的 USB 设备构建有用的数字示波器或与高速串行总线通信。如果您需要,您唯一的选择是PCI 适配器

并口

我没有用很多费话解释并口的逻辑,而是创建了一个图表。
俗话说:一张图说一千多个字:

注意:在某些计算机 (HP) 上,LPT 端口的针脚 21 未接地。
您必须将其接地,否则 LPT 端口将被禁用,甚至不会出现在控制面板中。

请注意,此图已简化:缺少 D 触发器,它存储处理器写入 IO 端口的数据。

根据硬件...

  • 输出可以实现为图腾柱输出,将固定的低或高电平或作为由上拉电阻和下拉晶体管组成的集电极开路输出。
  • 拉电阻可能不存在,或者可能具有不同于 2.2kΩ 的值。
  • 输出的高电平可能是+3V而不是+5V

每当您启动 ElmüSoft LogicAnalyzer 或更改Port ComboBox时,所选端口将立即被初始化,这意味着通过写入高电平释放所有开路集电极晶体管,并且通过设置位 5将数据端口输出驱动器切换到 3-State 模式控制端口高。因此,端口必须工作在扩展控制寄存器(ECR 端口)中设置的“字节模式”。

并行端口通常位于地址 0x378。您可以在控制面板 -> 硬件 -> LPT 端口中查看分配了哪个端口号。

  • 状态端口是只读端口。它总是能正常工作,没有并发症。
  • 控制端口通常实现为 Open Collector。但在某些硬件上,控制端口可能是带图腾柱输出的只写端口。
  • 数据端口通常实现为 3 态图腾柱输出。输出驱动器大部分可以关闭。

要找出您的硬件的输出类型,首先启动 LogicAnalyser,选择端口组合框,然后测量电压!
如果输出为 HIGH,则将其与 330Ω 电阻接地:

  • 如果电压从 +5V 下降到 +0,5V 或从 +3V 下降到 +0,4V,那么您有一个集电极开路输出(正常)
  • 但是,如果电压仅从 +5V 下降到 +4,5V 或从 +3V 下降到 +2,7V,那么您有一个图腾柱输出(不能用作输入)

如果输出为低电平,则用一个 10kΩ 电阻将其连接到 +5V。

  • 如果电压从 0V 上升到 +5V,则您的输出处于三态模式,没有上拉电阻 (OK)
  • 如果电压保持 0V,则不会禁用输出(不能用作输入)

更改线路电压时,LogicAnalyzer GUI中相应的LED会发生变化(绿色或红色)。根据硬件,输入缓冲器的阈值通常为 0.8V,用于区分 LOW 和 HIGH。

注意

注意不要用跳线直接将任何线路短路到地或+5V,以免损坏!始终使用电阻器进行测试!

注意

建议先试用状态行。在将任何外部信号连接到数据控制线之前,请分析输出类型。如果不能用 330Ω 电阻接地或 10kΩ 电阻改变电压到 +5V,那么这条线不能用作输入。

注意

在您的 BIOS 中,您应该将并行端口设置为在“ ECP 和 EPP 模式”下运行。ElmüSoft LogicAnalyzer 既不使用 ECP 也不使用 EPP 模式(硬件握手),但通过此 BIOS 设置,扩展控制寄存器(ECR) 变为可用,允许手动配置操作模式。

在“文档”文件夹中,您可以找到 3 个关于在SPPEPPECP模式下对并行端口进行编程的详细 PDF 。

缓冲输入信号

在许多情况下,您可以将输入信号直接连接到并行端口。如果信号来自工作于 +5V 的芯片,例如 MAX485,就会出现这种情况。如果您得到奇怪的结果,请将模拟示波器连接到输入线,以查看它们是否干净或是否受到打印机电缆容量的影响。

如果您的输入信号较弱、打印机电缆较长(> 1 米)或工作频率较高,则可能需要缓冲输入信号。这可以通过74HC541轻松完成。

注意

74HC54174HCT54​1不能用74LS54174S541 代替
HC 芯片具有极高的输入阻抗(高速 CMOS 技术),而 LS 芯片(双极晶体管技术)对缓冲敏感输入信号无用。

注意

您必须将 74HC541 的所有未使用输入接地以避免剧烈振荡。

驱动

Windows 95、98、ME的旧时代,您可以使用命令_inp(Port)和_outp(Port, Value).

在所有NT 平台(NT、2000、XP、Vista、Win7)上,这是被禁止的。尝试读取/写入 IO 端口的程序将退出并出现异常。仅允许驱动程序访问硬件。缺点是通过驱动程序访问硬件比直接使用_inp()and要慢_outp()。为了避免这个缺点,LogicAnalyzer 使用未记录的 API 调用Ke386IoSetAccessProcess(),例如修改进程的I/O 权限位图。设置权限映射可以在 NT 平台上的 EXE 中直接_inp()使用命令。_outp()IOPM 的修改是通过 OpenSource PortTalk内核驱动程序完成的。

64 位 Windows上,很遗憾无法使用 PortTalk 驱动程序,因为不存在 64 位版本的驱动程序。所以在 64 位 Windows LogicAnalyzer 上使用 OpenSource WinRing0内核驱动程序。虽然它不能修改 IOPM,但它可以通过 IOCTL 驱动程序调用使用DeviceIoControl(). 这速度较慢,但​​这是使其在 64 位 Windows 上运行的唯一方法。此外,Microsoft 要求在 64 位 Windows 上,必须对所有驱动程序进行签名。最新版本的 WinRing0 符合此要求。

视窗 95,98,ME

32位Windows NT,2000,XP,2003,Vista,7,2008

64位Windows XP,2003,Vista,7,2008

无驱动(快)

PortTalk(快速)

WinRing0(较慢)

有关驱动程序的详细信息,请参见文件夹“文档”!

首次运行 LogicAnalyzer 时,必须以Administrator身份启动。否则无法安装 PortTalk 或 WinRing0 驱动程序。安装后,每个普通用户都可以使用。微小的驱动程序文件作为嵌入式资源编译到 EXE 中并复制到 Windows 驱动程序文件夹中。在 64 位 Windows 上,LogicAnalyzer 关闭系统文件重定向,Wow64DisableWow64FsRedirection()否则文件将被复制到不会加载驱动程序的Wow64文件夹中。

为了检查一切正常,LogicAnalyzer 将通过 PC 扬声器播放 Blip 声音。要通过 PC 扬声器播放声音,必须访问多个 IO 端口。(它的工作原理超出了本文的范围。研究源代码!)因此,当您启动 LogicAnalyzer 的发布版本并从您的 PC 扬声器中听到 Blip 时,您就知道该驱动程序可以正常工作并且您已准备好使用程序。

如果您没有听到 Blip 声音,您可能正在使用 LogicAnalyzer 的 Debug 版本,它保持静音,或者您使用的是Notebook。笔记本电脑从来没有 PC 扬声器。笔记本的内置扬声器连接到声卡。一些笔记本电脑模拟 PC 扬声器,但前提是声卡的驱动程序支持此功能。

最大速度

最大速度显然取决于您的硬件。因为 LogicAnalyzer 是用 C++ 编写的,以尽可能快地运行。

32 位 Windows上,您可以使用更高的采样率进行捕获,因为 PortTalk 驱动程序允许直接访问 IO 端口。
64 位 Windows上,访问通过 WinRing0 驱动程序调用。每次进行 IOCTL 调用以访问端口时,处理器必须从环 3 切换到环 0,然后再切换回来。

奇怪的是,即使直接访问端口,_inp()命令执行也很慢。C++_inp()命令直接编译成以下汇编代码:

没有明显的理由说明这应该很慢。但这绝对是:
单个_inp()命令与以下运行 500 次的循环所用的时间相同:

C++

_inp( 0x378 );


C++

DWORD D=0;for (DWORD L=0; L<500; L++){     D = (D + 3) * 2;}

执行时间:1,3µs

执行时间:1,3µs

结果是最大捕获速度还取决于您启用了多少端口。对于每个端口(状态、控制、数据),_inp()必须执行一个:

运行普通的捕获循环

捕获 1 个端口

捕获 2 个端口

捕获 3 个端口

2,4 兆循环/秒

520 公斤样本/秒

300 公斤样品/秒

200 公斤样品/秒

这些值对应于我使用 PortTalk 驱动程序的机器 (2 GHz)。您可以使用“测量速度”按钮来检查硬件的速度。使用 WinRing0 驱动程序,它的速度大约是相同硬件上的一半。

在我的计算机上,我分析了一个运行速度为192 kBaud且没有问题的 RS485 总线。


  • CDriver 管理两个驱动程序:PortTalk 和 WinRing0,并在程序第一次运行时安装它们
  • CPort 访问打印机和 PC 扬声器的 IO 端口并将数据捕获到内存
  • CGraphics 是一个超快速的类,用于在内存中将图表创建为位图图像并将彩色线条和文本写入其中。最后,它将Bitmap压缩成GIF并保存到磁盘
  • CAnalyzer 分析已在 CPort 中捕获的数据并使用 CGraphics 绘制示波器图并生成 HTML 文件
  • CSerial 源自 CAAnalyzer(因此它可以访问所有变量)并分析 PS/2、异步等串行总线。

源代码

您会发现一个非常干净的源代码,具有适当的错误处理和大量由经验丰富的程序员编写的注释。您可以重用代码,例如CGraphics绘制您自己的任何类型图表的类或CDriver可CPort在其他应用程序中用于访问 IO 端口的类。
LogicAnalyzer 非常复杂。在这里你得到几周的开发结果!免费编码!

捕获数据

重要的

在连接任何输入信号之前,请通读并行端口”一章!
在将任何输入信号连接到
数据端口控制端口之前,您必须始终启动 LogicAnalyzer 并从要扫描的端口的组合框中选择正确的端口!线路可以切换输出!LogicAnalyzer 将它们切换为输入。状态端口没有问题,因为它不能用作输出。连接实时输入信号时不要关闭 PC!

GUI 始终在 LED 中显示输入线的真实状态。您不必关心线路是否是硬件反转的。如果 LED 为绿色,则电平为 +3V 或 +5V。如果 LED 为红色,则为 0V。如果它是灰色的,则端口被禁用。

捕获时,LED 显示屏会关闭,以便为捕获线程提供完整的处理器电源。该线程始终以您的硬件允许的最大速度运行。捕获的数据存储在内存中,这比将其写入磁盘要快。

内存使用得到优化:捕获循环不会将每个样本都写入内存。只有当任何输入线的电平发生变化或出现故障时(见下文),才会将一个 11 字节的捕获数据包写入内存。因此,您需要多少内存首先取决于输入行的活动。

分析仪

分析器会创建一个 HTML 文件和一个或多个 GIF 文件。GIF 文件包含 1 到 17 条彩色示波器线。分析仪检测到不显示的非活动行。您可以选择让分析仪自动检测光栅单元和空闲间隔。如果要放大或缩小,可以在 GUI 中手动修改光栅单元空闲间隔的设置,然后再次单击“分析”。

重要的

GUI 和示波器图表使用对用户更友好的位编号。如果状态端口的输出从第 3 位开始,那会很奇怪。请不要将 GUI 和图表中显示的位与 IO 端口上的真实位混淆!
“状态 0”表示对应于引脚 10(如 GUI 中显示的)的第一条状态行,尽管它实际上读取状态 IO 端口的位 6!

串行协议

该类CSerial 将输入数据解释为串行总线上的活动。有几种可以分析的串行总线:

  • I 2 C 总线、SMBus、ModBus
  • PS/2 总线
  • SPI总线
  • 异步(RS232、RS422、RS485)
  • 红外线遥控器
  • 智能卡

一些协议已经实现,其他的必须由您添加。如果您添加新协议,请给我发送电子邮件。如果是干净编写的代码,我会将其添加到类中并在 CodeProject 上发布。

重要的

将输入信号连接到数据、控制或状态端口以及连接到它们的哪个位都没有关系。但是第一条有效线被解释为时钟线,第二条有效线是 PS/2 和 I 2 C 协议的数据线。
示例:您可以将 PS/2 时钟连接到状态端口线 2 (Pin12),将 PS/2 数据连接到状态端口线 3 (Pin 13),并将其他输入连接到地或 +5V。显然,您可以连接超过 2 个输入信号,但它们必须跟在时钟和数据线的后面。如果连接正确,您会立即在 HTML 输出中看到。

异步注意事项

虽然 PS/2、I 2 C、SPI 等协议都有自己的时钟信号,但只有正确输入BaudrateParityStop Bits才能正确检测到异步协议。如果波特率偏离了几个百分点,这无关紧要,因为串行分析仪会根据每个起始位重新与数据流同步。

PS/2 注释

如果您测量 PS/2 键盘,您将永远不会看到线路上传输的 ASCII 代码。传输的字节是扫描代码。当您按下一个键时,其扫描码会发送到计算机。当您随后释放该键时,将再次发送相同的扫描码,并带有一个0xF0字节,表示该键已被释放。Windows API 将扫描代码转换为虚拟键代码,然后转换为ASCIIUnicode。请参阅 MSDN 文档以获取MapVirtualKey().

当计算机向键盘发送命令时(例如,当它在按下 CapsLock 键后打开/关闭键盘 LED 时),PS/2 协议会切换到完全不同的模式。有关详细信息,请参阅文档文件夹中“Manual PS2 Bus.chm ”中的“主机到设备通信”一章!

如果您同时使用 PS/2 键盘和 PS/2 鼠标,您会注意到在您单击或移动鼠标时 PC 会拉低键盘的时钟线。这是正常现象,表示 PC 正忙。当时钟线为低电平时,键盘无法发送数据。

关闭图形

当您分析一个非常繁忙的 RS485 或 I 2 C 总线时,您将在几秒钟内获得一兆字节的 Capture 数据。那么很容易发生 LogicAnalyzer 必须生成 5000 张图像。尽管 GIF 压缩经过了速度优化并用快速 C++ 编写,但这需要一段时间。此外,当您打开包含 5000 张图像的页面时,您的浏览器将占用大量内存。

在这种情况下,您可以通过从 Combobox 中选择“ Print ONLY decoded Bytes as HTML ”来关闭图形。你会看到这样的东西:

分析的数据是纯 HTML,可以复制到剪贴板并在其他地方使用。

没有图形的生成速度非常快,但显然您会丢失有关时间和故障确切位置的信息。如果您想查看有关捕获数据特定部分的更多详细信息,只需将时间码从浏览器复制到 LogicAnalyzer 字段“分析开始”和“分析结束”,选择创建图像并再次分析数据。然后,您可以快速获得感兴趣的部分及其所有详细信息。

上下文切换

如果您测量像 PS/2(具有 10 kHz 时钟)或 4800 波特异步通信这样的慢速信号,您根本不会遇到任何问题。但是,如果您必须测量更高的频率,很明显在测量(捕获)期间 CPU 应该尽可能空闲

单击“测量速度”按钮以了解您的计算机当前如何忙于后台活动。此测量将运行一个循环 10000 次,并测量每个循环运行的时间。您将看到一个宽度为 10000 像素的图表,其中 X 轴上的每个像素代表一个循环周期,Y 轴对应于每个循环运行的时间:

请注意,速度很大程度上取决于您启用了多少端口!在此示例中,捕获了一个端口。您会看到循环通常需要 1.9 µs (= 520 kHz)。在 6.3 毫秒时,您会看到一个小故障。在这里,Windows 中断了 LogicAnalyser 20 µs。在此期间,操作系统已切换到其他应用程序或驱动程序。这称为“上下文切换”(参见Wikipedia)。

有些程序会产生永久性的后台活动,例如聊天程序“Trillian”,它每毫秒都会产生轻微的故障:

此示例说明如果您必须测量 10 kHz 以上的频率,停止所有正在运行的程序和服务是多么重要。您停止的应用程序和服务越多,捕获循环可用的 CPU 功率就越多,故障就会越少。断开网络和 USB 设备!即使 Taskmanager 显示 CPU 100% 空闲,后台活动也始终存在。

保持用于测量的 PC 不受其他活动影响。您不应该想到测量在同一台计算机上启动的高速 RS232 通信。由于串行端口驱动程序占用了大部分 CPU,这将失败。

一个不可避免的毛刺源是主板每 15,625 ms (64 Hz) 触发的时钟中断。它用于增加滴答计数器和系统时间。

在上下文切换期间,LogicAnalyser 将无法捕获数据。因此,如果您的输入频率很高,您
可能会丢失输入数据……但前提是在此期间,其中一条输入线的电平至少改变了两次!上下文切换通常不会经常发生。如果您尽可能多地关闭后台活动,您将看到很少的故障。如果在上下文切换期间输入行没有改变它们的状态,那么你很幸运并且不会丢失任何输入数据。

你现在可能会问:“所以我永远不能确定我看到的数据没有残缺?”
是的。您将始终知道这一点,因为 LogicAnalyser 会
自动检测 Context Switches
如果发生了上下文切换,图表中的背景颜色会被涂成深红色。
如果这段时间很长,您可以假设您
可能丢失了数据。如果这段时间很短,你知道没关系。

在此示例中,上下文切换肯定无关紧要,因为它非常短。可能在红色间隔期间,驱动程序处理了 PS/2 击键。

单个上下文开关总是在其长度超过 5 个光栅单位时显示,否则将被忽略。

如果可能的数据丢失对您来说实际上是一个问题,取决于您打算使用 LogicAnalyser 做什么。例如,如果您想分析红外遥控器发出的信号,您只需重复测量,直到获得清晰的图表。对于可以重复的简短测量,上下文切换根本不重要。

使用 LogicAnalyzer 时,您会很快注意到上下文切换很少出现,以至于落入信号中间的概率非常低。

请不要忘记 LogicAnalyser 是一款免费软件,可与免费硬件一起使用!
如果您需要更可靠的高速工具,您将不得不为此付费!

使用 FIFO/DMA

并行端口有一个 16 位 FIFO 缓冲器,用于缓冲 8 条数据端口线。可以使用此 FIFO。但缺点是复杂的握手和 FIFO 需要工作的外部时钟。并行端口还支持 DMA。但是编程很复杂,还需要硬件握手。(请参阅 ZIP 文件中的文件夹“文档”。)

我发现这一切都太尴尬了,所以没有实现它。LogicAnalyser 的工作令我非常满意,并且可以满足我的所有需求。如果您需要更多,请实现它并将代码发送给我!

调试

虽然不打算将原始捕获的数据写入磁盘,但您可以在将新协议添加到串行分析器时使用两个编译器开关:编译SAVE_CAPTURE_TO_FILE并单击捕获创建 BIN 文件,然后编译LOAD_CAPTURE_FROM_FILE并单击捕获,然后分析它分析来自 BIN 文件的数据。因此,您可以修改代码直到它工作,而不必在每次构建后重新捕获。

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/181670.html