C6678学习-IPC
文章目录
- 1、简介
- 2、模块
- MultiProc
- 静态设置(cfg设置)
- 动态设置
- IPC
- Notify
- MessageQ
- ShareRegion
1、简介
IPC: Inter-Processor Communication 处理器间通信,指提供多处理器环境中的处理器之间的通信、相同处理器不同线程间的通信。包括数据传递、数据流和链表。
IPC可用于以下通信:
- 在同一处理器上的其他线程
- 在其他处理器上运行的SYS/BIOS线程
- GPP处理器上运行的SysLink的线程(例如Linux)
IPC传输分为两种:
- QMSS(队列管理器):发送任务和内核之间的数据
- SRIO IPC:发送任务、内核和芯片之间的数据
2、模块
MultiProc
许多IPC模块需要在多处理器环境中识别处理器。MultiProc在一个模块中集中管理处理器id。因为这配置几乎是普遍要求,大多数IPC应用程序需要提供这个模块的配置。MultiProc可以在cfg文件中静态配置,也可以在程序中动态配置,一般都是用静态配置。 var MultiProc = xdc.useModule(‘ti.sdo.utils.MultiProc’); 调用模块,相当于是获取一个接口,然后用接口进行配置
静态设置(cfg设置)
/*********在cfg文件中配置************************/
MultiProc.numProcessors = 8; //设置系统的核数为8,这里的值就是nameList数组的总长度MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3", "CORE4", "CORE5", "CORE6", "CORE7"]); //设置各个核的名字,其ID是根据其名字在setConfig第二个参数数组中的位置+BaseID来确定的,BaseID默认是0,若位置为0,则ID就是0,其在nameList数组的位置就是0(nameList数组和setConfig中的数组不是同一个)
/**************在一个系统中有两个DSP,总共16个,这个16个核之间要进行通信,可以进行如下设置,使得各个核的ID不一样************************/
/*For first C6678 device:*/var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');MultiProc.baseIdOfCluster = 0; //设置baseidMultiProc.numProcessors = 16;//nameList总共有16个元素MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3","CORE4", "CORE5", "CORE6", "CORE7"]);
/***DSP0中的核name占据了nameList的0~7位*****/
/*For second C6678 device:*/var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');MultiProc.baseIdOfCluster = 8;//设置baseidMultiProc.numProcessors = 16;MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3","CORE4", "CORE5", "CORE6", "CORE7"]);
/***DSP1中的核name占据了nameList的8~15位*****/
动态设置
MultiProc_getNumProcessors();//获取MultiProc.numProcessors的值
MultiProc_self()//获取当前核的id
MultiProc_getName(id)//根据id获取核的name
MultiProc_getId("name")//根据name获取ID
IPC
IPC的启动很简单,只需要在函数中调用Ipc_start()就行。该函数只能被调用一次,除非返回值是Ipc_E_NOTREADY。它表示ShareRegion 0 无效或者还没有建立,所以Ipc_start可能需要再次调用,一旦它成功启动,后面调用的返回值是Ipc_S_ALREADYSETUP。
IPC的配置是在cfg文件中完成的:
var Ipc = xdc.useModule('ti.sdo.ipc.Ipc');
Ipc.procSync = Ipc.ProcSync_ALL;
Ipc.ProcSync_ALL :调用ipc_start还将在内部调用ipc_attach同步所有核,应用程序不应该再调用Ipc_attach。如果在一个设备上的所有的IPC核都是同时启动的话,可以选择这个同步方式。
Ipc.ProcSync_PAIR ipc_start不会调用ipc_attach,所有此时需要在代码中由应用程序调用ipc_attach;
Ipc.ProcSync_NONE Ipc_start将与ProcSync_PAIR工作完全一样,但是ipc_attach不会同步远程的核;
核的同步要按照ID号从小到大的顺序进行,比如当前核必须先同步核0,才能同步核1。两核之间的相互同步必须先满足ID号小的先同步ID号大的,比如核2需要等到核1调用了Ipc_attach(2)之后才能调用Ipc_attach(1) 。
Notify
/*注册事件,和回调函数进行绑定* @param[in] procId 远端的核号* @param[in] lineId Line id (大部分系统为0)* @param[in] eventId 事件ID 最大31* @param[in] fnNotifyCbck 回调函数* @param[in] cbckArg 回调函数的参数 */
Int Notify_registerEvent(UInt16 procId, UInt16 lineId, UInt32 eventId,Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg);
/*发送事件* @param[in] procId 目的的核号* @param[in] lineId Line id* @param[in] eventId 事件ID* @param[in] payload 和事件一起发送的数据.是一个int型的数据* @param[in] waitClear 如果为TRUE,则当前发送的事件会等待上一个相同ID的事件被目标核处理掉,如果为FALSE,则被挂起的事件中与最近发送的事件的ID相同的事件会被覆盖掉。如果notify设备是通过FIFO传递事件的,那么当FIFO满的时候,如果为TRUE则会一直等待到FIFO有空间,如果为FALSE则会返回Notify_E_FAIL*/
Int Notify_sendEvent(UInt16 procId, UInt16 lineId,UInt32 eventId, UInt32 payload,Bool waitClear);
/****回调函数的形式******************************************************/
Void myFxn2(UInt16 procId, UInt16 lineId, UInt32 eventNo, UArg arg, UInt32 payload)
MessageQ
MessageQ同Notify模块一样,也是用于多核之间的通信的,不过不同的是,Notify模块更加侧重于通知,其只能传递一个参数,而MessageQ却可以传递变长度的消息,更侧重于传递消息,另外不同线程间的消息是独立的,例如对于每个MessageQ来说,存在一个读者却可能有多个写者。
MessageQ模块的主要特点:
1. 实现了处理期间变长消息的传递,所需要传递的消息一般超过32bit;
2. 其消息的传递都是通过操作消息队列来实现的;
3. 每个消息队列可以有多个写者,但只能有一个读者,而每个任务(task)可以对多个消息队列进行读写;
4. 一个宿主在准备接收消息时,必须先创建消息队列,而在发送消息前,需要打开预定的接收消息队列;
HeapBufMP:固定大小的内存管理器,其分配的所有缓冲区都是一样的,当然也可以通过不同HeapBufMP实例来管理不同的大小的缓冲区。
HeapMultiBufMP:每个HeapMultiBufMP支持8个不同大小的缓冲区。当一个分配需求被发送,HeapMultiBufMP的实例从不同大小的待分配缓冲区中,选择一个能满足要求的最小缓冲区。如果待分配缓冲区为空,那么这个分配就失败了。
HeapMemMP:这是个能分配变长大小的内存管理器。另外HeapMemMP管理共享内存区(Shared memory)的一个缓冲区。
在cfg文件中开启MessageQ
/****需要HeapBufMP模块来给消息分配空间***************************************/
var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var HeapBufMP = xdc.useModule('ti.sdo.ipc.heaps.HeapBufMP');
创建MessageQ对象
/***MessageQ不是共享内存,只能有一个读者,所以要每个核都去创建自己的MessageQ***/
MessageQ_Handle MessageQ_create(String name, const MessageQ_Params *params);
消息创建好之后,需要给消息分配堆空间。消息其实就是一个结构体。但是其结构体的第一个元素必须是 MessageQ_MsgHeader类型的。
创建一个堆对象
/*因为测试例程只需要发送一个消息就可以了,所以HeapBufMP就只分配一个消息块*/
HeapBufMP_Params_init(&heapBufParams);
heapBufParams.regionId = 0;
heapBufParams.name = HEAP_NAME;
heapBufParams.numBlocks = 1; //分配的块数
heapBufParams.blockSize = sizeof(Msg);//块的大小,Msg是创建的消息结构体
heapHandle = HeapBufMP_create(&heapBufParams);
创建好对象后,需要给堆对象注册一个id,后面给消息分配内存的时候,就直接调用ID
/* @param[in] heap 要注册id的堆对象*/
/* @param[in] heapId 得到的堆ID*/
Int MessageQ_registerHeap(Ptr heap, UInt16 heapId);
根据堆ID给堆分配空间
//返回一个msg,这个msg就是用来传递消息的。
MessageQ_Msg MessageQ_alloc(UInt16 heapId, UInt32 size);
分配完空间得到msg后就可以发送了
/*通过接收核创建消息时注册的名称来打开消息队列,并返回消息队列的ID
根据消息队列ID,将消息发送给消息队列*/
Int MessageQ_open(String name, MessageQ_QueueId *queueId); //打开队列
Int MessageQ_put(MessageQ_QueueId queueId, MessageQ_Msg msg);//发送消息queueId就是打开消息的时候得到的,msg就是堆内存分配的时候返回的。
消息接收
Int MessageQ_get(MessageQ_Handle handle, MessageQ_Msg *msg, UInt timeout);
ShareRegion
SharedRegion模块是一个共享区域,特别是对于多处理器环境下,SharedRegion模块就是用于让一个内存区域能被不同处理器共享并操作。这个模块会给每个处理器上创建一个共享内存区域查找表,这个查找表保证各个处理器能查看到系统内的所有共享区域。查找表中共享内存区域在所有查找表中的区域ID是一致的,在运行时,查找表可以通过共享区域ID及共享区域名称来快速查找共享区域
通过cfg配置共享区域
var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
SharedRegion.numEntries = 4; //共享区域的最大个数
SharedRegion.translate = true; //是否需要进行地址转换/* Shared Memory base address and length */
var SHAREDMEM = 0x88000000;
var SHAREDMEMSIZE = 0x00300000;
SharedRegion.setEntryMeta(0,//共享区域的ID号{ base: SHAREDMEM, //共享区域的基地址len: SHAREDMEMSIZE, //共享区域大小ownerProcId: 0, //共享区域所有者的核IDisValid: true, //对于当前核,该区域是否有效name: "SR0", //区域的名称});1)base:区域的基地址,不同处理器其基地址可以是不同的。
2)len:区域的长度,同一个共享区域在所有处理器的查找表中的长度应该是相同的。
3)ownerProcID:管理该区域的处理器ID,如果存在区域所有者,这个区域所有者(owner)就是创造HeapMemMp实例的,而其他核打开这个实例。
4)isValid:表明该区域在当前核上是否可用,判断当前核能否使用此共享区域的。
5)cacheLineSize:这个值在所有核的查找表中都应该是相同的
6)createHeap:表明是否需要给当前区域创建一个堆。
7)name:区域的名称。
共享内存的使用
heaphandle = (IHeap_Handle)SharedRegion_getHeap(regionId); // 通过区域ID获得共享区域的堆句柄
buf = Memory_alloc(heap, size, align, NULL); // 通过堆句柄分配区域内存
地址转换
共享内存的地址在各个核上会被映射到不同的地址空间,因此我们需要进行地址转换。
/*先将本地分配的共享内存得到一个本地地址转换,通过SharedRegion_getSRPtr()将本地地址转换成共享内存地址,然后通过MessageQ将共享内存地址发送到其他核。其他核通过SharedRegion_getPtr()来得到共享内存对应的本地地址,然后就可以通过本地地址来访问共享内存的内容了*/
SharedRegion_getSRPtr() //根据给定的本地指针及区域ID来获得当前共享区域指针
SharedRegion_getPtr() //根据共享区域指针来获得本地指针
能否使用此共享区域的。
5)cacheLineSize:这个值在所有核的查找表中都应该是相同的
6)createHeap:表明是否需要给当前区域创建一个堆。
7)name:区域的名称。
共享内存的使用```c
heaphandle = (IHeap_Handle)SharedRegion_getHeap(regionId); // 通过区域ID获得共享区域的堆句柄
buf = Memory_alloc(heap, size, align, NULL); // 通过堆句柄分配区域内存
地址转换
共享内存的地址在各个核上会被映射到不同的地址空间,因此我们需要进行地址转换。
/*先将本地分配的共享内存得到一个本地地址转换,通过SharedRegion_getSRPtr()将本地地址转换成共享内存地址,然后通过MessageQ将共享内存地址发送到其他核。其他核通过SharedRegion_getPtr()来得到共享内存对应的本地地址,然后就可以通过本地地址来访问共享内存的内容了*/
SharedRegion_getSRPtr() //根据给定的本地指针及区域ID来获得当前共享区域指针
SharedRegion_getPtr() //根据共享区域指针来获得本地指针
相关文章:
C6678学习-IPC
文章目录 1、简介2、模块MultiProc静态设置(cfg设置)动态设置 IPCNotifyMessageQShareRegion 1、简介 IPC: Inter-Processor Communication 处理器间通信,指提供多处理器环境中的处理器之间的通信、相同处理器不同线程间的通信。包括数据传递…...
利用 Delte-Sigma ADC简化电路设计
很多时候在电路中选择合适的 ADC可以很大程度上简化前端的电路。这里我们一起来看一个电阻电桥的例子: 这里用到了一只仪表放大器和一只运算放大器,他们实际上主要完成了三个功能: 1. 抑制了 2.5V的共模信号; 2. 将-1…...
如何在 Windows 11 启用 Hyper-V
准备在本机玩一下k8s,需要先启用 Hyper-V,谁知道这一打开,没有 Hyper-V选项: 1、查看功能截图: 2、以下文件保存记事本,然后重命名为*.bat pushd "%~dp0" dir /b %SystemRoot%\servicing\Packa…...
哈希表企业应用-DNA的字符串检测
DNA的字符串检测-引言 若干年后, ikun DNA 检测部成立,专门对 这些ikun的解析检测 突然发现已经完全控制不了 因为学生已经会了 而且是太会了 所以DNA采用 以下视频测试: ikun必进曲 ikun必经曲 ikun必阶曲 如何感受到了吧!,如果你现在唱跳并且还Rap 还有打篮球 还有铁山靠 那…...
Kafka运维与监控
Kafka运维与监控 Kafka运维与监控一、简介二、运维1.安装和部署安装部署 2.优化参数配置配置文件高级配置分区和副本设置分区数量设置副本数量设置 网络参数调优传输机制设置连接数和缓冲区大小设置 消息压缩和传输设置消息压缩设置消息传输设置 磁盘设置和文件系统分区磁盘容量…...
【Redis—哨兵机制】
文章目录 概念哨兵机制如何工作的监控(如何判断主节点真的故障了)哪个哨兵进行主从故障转移?故障转移流程哨兵集群 概念 当进行主从复制时,如果主节点挂掉了,那么没有主节点来服务客户端的写操作请求了,也…...
MySQL学习笔记第七天
第07章单行函数 2. 数值函数 2.4 指数函数、对数函数 函数用法POW(x,y),POWER(X,Y)返回x的y次方EXP(X)返回e的x次方,其中e是一个常数,2.718281828459045LN(X),LOG(X)返回以e为底的X的对数,当x<0时,返…...
中级软件设计师备考---程序设计语言和法律法规知识
目录 需要掌握的程序语言特点法律法规知识---保护期限法律法规知识---知识产权人确定法律法规知识---侵权判定标准化基础知识 需要掌握的程序语言特点 Fortran语言:科学计算、执行效率高Pascal语言:为教学而开发的、表达能力强,演化出了Delp…...
Leetcode434. 字符串中的单词数
Every day a leetcode 题目来源:434. 字符串中的单词数 解法1:istringstream 我们知道,C默认通过空格(或回车)来分割字符串输入,即区分不同的字符串输入。 istringstream类用于执行C风格的串流的输入操…...
C++ cmake工程引入qt6和Quick 教程
目录标题 前言QML简介锻炼C水平 cmake修改方法方式一(qt6_add_resources)方式二 (qt_add_qml_module ) 其他相关知识为什么会有_other_files?qt_standard_project_setup() 函数qt_add_qml_module() 和 qt6_add_resources()的方式差异const QU…...
JavaEE - 网络编程
一、网络编程基础 为什么需要网络编程? 用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。 与本地打开视频文件类似,只是视频文件这个资源的来源是网络。 相比本…...
【Android车载系列】第11章 系统服务-SystemServer自定义服务
1 编写自定义系统服务 1.1 AIDL接口定义 系统源码目录/frameworks/base/core/java/android/app/下新建AIDL接口IYvanManager.aidl package android.app;/** * 目录:/frameworks/base/core/java/android/app/IYvanManager.aidl */ interface IYvanManager{String …...
Lerna
Lerna Lerna是一个优化基于gitnpm的多pagkage项目的管理工具 解决的痛点 痛点一:重复操作 多Package本地link多Package依赖安装多Package单元测试多Package代码提交多Package代码发布 痛点二:版本一致性 发布时版本一 致性发布后相互依赖版本升级 package越多,管…...
迁移学习 pytorch
迁移学习(Transfer Learning)是通过使用一个预训练模型来快速训练一个新的网络模型,通常应用于数据集较小或计算资源较少的情况下。在 PyTorch 中,由于 torchvision 库中已经内置了一些经典的预训练模型,因此我们可以通过简单的调用函数来实现迁移学习。 下面是一个基于 …...
【python】keras包:深度学习( RNN循环神经网络 Recurrent Neural Networks)
RNN循环神经网络 应用: 物体移动位置预测、股价预测、序列文本生成、语言翻译、从语句中自动识别人名、 问题总结 这类问题,都需要通过历史数据,对未来数据进行预判 序列模型 两大特点 输入(输出)元素具有顺序关系…...
vue框架快速入门
vue 1、第一个Vue程序1.1、什么是Vue程序1.2、为什么要使用MVVM1.3、Vue1.4、第一个vue程序 2、基础语法2.1、v-bind2.2、v-if, v-else2.3、v-for2.4、v-on 3、Vue表单双绑、组件3.1、什么是双向数据绑定3.2、在表单中使用双向数据绑定3.3、什么是组件 4、Axios异步…...
Java连接顺丰开放平台
今天使用Java去访问顺丰的开放平台时,JSON转换一直不成功,最终发现是 可以看到这里是 "apiResultData": "{\"success\": .........它是以 " 开头的!!!如果是对象的话,那么…...
前端三剑客 - HTML
前言 前面都是一些基础的铺垫,现在就正式进入到web开发环节了。 我们的目标就是通过学习 JavaEE初阶,搭建出一个网站出来。 一个网站分成两个部分: 前端(客户端) 后端(服务器) 通常这里的客户端…...
【计算机视觉 | 自然语言处理】BLIP:统一视觉—语言理解和生成任务(论文讲解)
文章目录 一、前言二、试玩效果三、研究背景四、模型结构五、Pre-training objectives六、CapFilt架构七、Experiment八、结论 一、前言 今天我们要介绍的论文是 BLIP,论文全名为 Bootstrapping Language-Image Pre-training for Unified Vision-Language Understa…...
c++基础-运算符
目录 1关系运算符 2运算符优先级 3关系表达式的书写 代码实例: 下面是面试中可能遇到的问题: 1关系运算符 C中有6个关系运算符,用于比较两个值的大小关系,它们分别是: 运算符描述等于!不等于<小于>大于<…...
美术馆c++
题目: 杜老师非常喜欢玩一种叫做“美术馆”的数字游戏,蜗蜗看了之后决定也来试一试,他改编了这个游戏,规则如下: 有一个 n� 行 m� 列的方格,每一个格子中有一个数,数字…...
浅谈MySQL索引以及执行计划
MySQL索引及执行计划 🐪索引的作用🐫索引的分类(算法)🦙BTREE索引算法演变🦒Btree索引功能上的分类4.1 辅助索引4.2 聚集索引4.3 辅助索引和聚集索引的区别 🐘辅助索引分类🦏索引树高…...
在c++项目中使用rapidjson(有具体的步骤,十分详细) windows10系统
具体的步骤: 先下载rapidjson的依赖包 方式1:直接使用git去下载 地址:git clone https://github.com/miloyip/rapidjson.git 方式2:下载我上传的依赖包 将依赖包引入到项目中 1 将解压后的文件放在你c项目中 2 将rapidjson文…...
编译方式汇总:Makefile\configure\autogen.sh\configure.ac、Makefile.am文件
一、前言 文章目的:针对各种开源项目,由于部分项目文档写的不够详细,(或者是我太菜了),没有进行详细的介绍怎么编译该项目,导致花费过多时间在查找如何编译该项目上。因此该篇文章针对目前遇到的…...
explicit关键字
explicit关键字只能用来修饰构造函数。使用explicit可以禁止编译器自动调用拷贝初始化,还可以禁止编译器对拷贝函数的参数进行隐式转换。 那么什么是隐式转换呢? 类 命名 参数; //有参构造类 命名 命名对象; //拷贝构造&#x…...
[优雅的面试] 你了解python的对象吗
前情提要:小编面试,结果面试官着急去吃饭~又约了这次来面,不晓得又会问什么问题呢? 面试官大佬:小伙子来的挺准时的(赞赏的表情~),今天咱们接着聊哈,小伙子,你有对象了没?…...
【hello Linux】线程概念
目录 1. 线程概念的铺设 2. Linux线程概念 2.1 什么是线程 2.2 线程的优点 2.3 线程的缺点 2.4 线程异常 2.5 线程用途 3. Linux进程VS线程 4. Linux线程控制 4.1 POSIX线程库 4.2 创建线程 4.3 进程ID和线程ID 4.4 线程终止 4.5 线程等待 4.6 分离线程 Linux🌷 1…...
JavaWeb07(MVC应用01[家居商城]连接数据库)
目录 一.什么是MVC设计模式? 1.2 MVC设计模式有什么优点? 二.MVC运用(家居商城) 2.1 实现登录 2.2 绑定轮播【随机三个商品】 2.2.1 效果预览 index.jsp 2.3 绑定最新上架&热门家居 2.3.1 效果预览 2.3.2 代码实现 数据…...
如何使用电商API接口API接口如何应用
使用API接口 API(应用程序接口)是现代软件开发中必不可少的一部分,它通常允许软件与其他软件或服务进行交互。使用API可以大大提高软件的灵活性和可扩展性,并允许您轻松添加新的功能和服务,因此,API接口的…...
【移动端网页布局】流式布局案例 ⑥ ( 多排按钮导航栏 | 设置浮动及宽度 | 设置图片样式 | 设置文本 )
文章目录 一、多排按钮导航栏样式及核心要点1、实现效果2、总体布局设计3、设置浮动及宽度4、设置图片样式5、设置文本 二、完整代码实例1、HTML 标签结构2、CSS 样式3、展示效果 一、多排按钮导航栏样式及核心要点 1、实现效果 要实现下面的导航栏效果 ; 2、总体布局设计 该导…...
网站建设为什么这么贵/优化系统的软件
在Linux下怎么确定哪个网卡对应哪个接口? 有个需求,公司一台CentOS 6.5需要连接外网和内网环境,所以额外安装一块千兆网卡,主板集成的一个,以及千兆网卡的两个,一共三个网卡接口。系统安装完成之后&#…...
学校网站建设的验收单/营销方案包括哪些内容
2019独角兽企业重金招聘Python工程师标准>>> 一般,页面上会分为很多部分,而不同的部分更新的频率是不一样的。如果对整个页面采用统一的缓存策略则不太合适, 而且很多系统的页面左上角都有一个该死的“Welcome XXX”。这种特定于…...
中山移动网站建设报价/世界杯大数据
最近在看李沐的实用机器学习课程,讲到regression问题的loss的时候有弹幕问:“为什么要平方?”如果是几年前学生问我这个问题,我会回答:“因为做回归的时候的我们的残差有正有负,取个平方求和以后可以很简单…...
郑州做的比较好网站公司/seo攻略
c语言上机填空题.DOC1. 在考生目录下,有Modify.c程序,该程序中 N 是根据程序功能需要填充部分,请完成程序填充(注意不得加行、减行、加句、减句,否则后果自负)。 该程序功能输入m、n(要求输入数均大于0),输出它们的最大…...
山东网站app制作/北京朝阳区优化
clickHouse的简单介绍,详细介绍请查看官网或者百度1)clickhouse非hadoop体系2)使用sql语句,对于熟悉关系数据的人员入门相对简单3)clickhouse最好用来读,不要用来变更,写用批量的方式4)各种日志数据我们可以用flume同步到clickhou…...
网站建设 全包 制作/太原网络推广价格
就当下的商显市场而言:不管是LED拼接屏、lcd液晶拼接屏还是DLP屏都是用户比较亲睐的大尺寸显示设备。但在这些显示设备中、很多的用户对LED拼接屏与lcd液晶拼接屏不是特别的清楚。往往认为两者是同一类显示设备。这两者间真的没有什么明显的区别吗?为此、…...