侵权投诉

动态内存管理模块的设计原理与实现

电子设计 2020-06-30 08:05 次阅读
引言 当前,绝大多数嵌入式平台上的软件都采用C语言编写。除了代码简洁、运行高效之外,灵活操作内存的能力更是C语言的重要特色。然而,不恰当的内存操作通常也是错误的根源之一。如“内存泄漏” ――不能正确地释放已分配的动态内存,就是一种非常难于检测的存错误。持续的内存泄漏会使程序性能下降到最终完全不能运行,进而影响到所有其它有动态内存需求的程序,在某些相对简单的嵌入式平台上甚至会妨碍操作系统的运转。再如“写内存越界”,一种不合法的写内存操作,极可能破坏到本程序中正在使用的其它数据,严重的时候还可能对其它正在运行的程序甚至整个系统造成影响。为此,本文介绍一个增强的、可定制的动态内存管理模块(以下不妨简称Fense),在 C语言提供的内存分配函数基础上,增加了对动态内存的管理功能;能记录软件运行过程中出现的内存泄漏信息,同时也具一定的监测内存操作的能力;可以发现绝大多数对动态内存的写越界错误。 1、Fense的设计原理 Fense 通过设立一个双向链表(struct Head *stHead)来保存所有被分配的动态内存块的信息。链表中的每个节点对应一个动态内存块,节点中包括此内存大小、分配发生时所在的源文件名和行号以及被释放的时候,Fense又从st_Head中删除之,检查st_Head中的节点即可得到未被释放的本节点的数值校验和等。Fense将每一个分配的动态内存块插入到链表st_Head中;当此内存放内存块信息。链表节点结构定义如下: struct Head{ char file; /分配所在源文件名*/ unsigned long line; /*分配所在的行号*/ size_t size; /*分配的内存大小*/ int checksum; /*链表节点校验和*/ struct Head prev,next; /*双链表的前后节点指针*/ }; /*全局的双向链表*/ struct Head *st_Head=NULL; 为了检测写越界的错误,Fense在用户申请的内存前后各增加了一定大小的内存作为监测区域,并初始化成预定值。这样,当程序发生越界写操作时,预定值就会发生改变,Fense即可检测到错误。 通过Fense分配到的动态内存结构如图1所示。由此可知,Fense_Malloc(Fense的内存分配函数)返回给用户的指针ptr指向的是用户申请内存区域的起始位置。链表节点、前/后监测区域均为Fense内部使用,是用户不可见的。
动态内存管理模块的设计原理与实现
2、 用户定制选项 Fense有5组宏定义提供给用户对功能进行定制。各组选项控制意义如下: WARN_ON_ZERO_MALLOC 用户申请零分配空间时警告信息。 FILL_ON_MALLOC 分配时初始化内存块 FILL_ON_MALLOC_VAL 分配初始化时的预设值 FILL_ON_FREE 释放时填充内存块 FILL_ON_FREE_VAL 释放时填充内存块的预设值 以上4个选项的主要功能是初始化刚分配到的内存和刚被释放的内存为预设值,尽可能地避免出现因使用未初始经的内存而引发的错误。 FENSE_FRONT_SIZE 定义前监测区域大小 FENSE_FRONT_VAL 定义前监测区域的预设值 FENSE_END_SIZE 定义后监测区域大小 FENSE_END_VAL 定义后监测工域的预设值 在Fense 工作过程中,对内存越界写操作的检验是通过比较监测区域的当前值与本监测区域的预设值来确定的。显然不能排除这样一种可能:即发生在监测区域的越界写操作写入的数值与监测区域的预设值恰好相同,此时,Fense无法发现错误的发生。对于这种情况,用户可以通过更改监测区域预设值(FENSE_FRONT_VAL和FENSE_END_VAL)和监测区域大小(FENSE_FRONT_SIZE和FENSE_END_SIZE)为多组不同的值来反复测试,这样就可以大幅度地提高监测的准确性。 VALIDATE_FREE free是检查本内存块是否在链表中 CHECK_ALL_MEMORY_ON_FREE free时检查链表中的所有内存块 由于存在这样一种情况:对内存块A的写操作出现了越界错误,写到了另一内存块B的区域内。此时,仅仅检查内存块A的有效性就无法发现问题,如果同时检查所有的动态内存块,则有可能发现错误所在。以上选项即为此而设。 FENSE_LOCK 获取对链表st_Head的操作权 FENSE_UNLOCK 释放对链表st_Head的操作权 考虑到的在多线程环境中,可能有多个线程同时用Fense进行内存管理,而Fense使用的链表st_Head是全局变量,因此提供了以上2个宏来实现对 st_Head的互斥访问。宏的具体定义依赖于用户所在的软件环境,用户可自行实现。对于单线程系统,仅需将这2个宏定义为空即可。 为便于使用,Fense的头文件中还包括了以下定义,使得用户基本不用改动现有的源代码就可引入Fense。 #define malloc(size) Fense_Malloc(size,_FILE_,_LINE_) #define free(ptr) Fense_Free(ptr,_FILE_,_LINE_) #define realloc(ptr,new_size) Fense_Realloc(ptr,new_size,_FILE_,_LINE_) #define colloc(num,size) Fense_Calloc(num,size,_FILE_,_LINE_) 3、 运行时控制 Fense 监测内存的功能可以在运行动态地开关。此功能通过将全局变量st_Disbaled赋值为零或非零来实现。在调试过程中,可以在调试器中即时修改 st_Disabled的值来控制Fense的行为,省去了重编译源代码的需要。对于那些需要大量编译时间的大型工程或交叉平台开发的软件项目来说,这是非常有利的。 4、 Fense的具体实现 Fense 提供Fense_Malloc、Fense_Free、Fense_Realloc及Fense_Calloc等内存管理函数,功能和调用形式与C语言中的malloc、free、realloc和calloc保持一致。限于篇幅,这里仅对Fense_Malloc和Fense_Free的实现过程做一个简单描述,具体实现请见本刊网络补充版。http://www.dpj.com.cn /*内存分配函数*/ void *Fense_Malloc(size_t size,char *file,unsigned long line) { //检查Fense的运行时开关,如果Fense被关闭,则调用malloc //分配并返回 //检查是否零分配,如有则提示警告信息后返回0(用户定制选项) //分配内存,包括链表节点区域和前/后监测区域 //初始化链表节点,保存分配内存的信息,包括分配的大小、所在文件名和行号 //将此节点插入链表st_Head //为本节点区域计算校验和 //用预设值初始化前/后监测区域 //用预设值填充用户内存区域(用户定制选项) //返回用户内存区域的起始位置 } /*内存释放函数*/ void Fense_Free(void *uptr,char *file,unsigned long line) { //检查Fense的运行时开关,如果Fense初关闭,则调用free释译并返回 //检查所有Fense管理下的动态内存(用户定制选项) //判断当前内存块是否在链表st_Head中,如果不在则提示 //警靠信息,退出(用户定制选项) //检查当前内存块是否存在越界操作 //将当前内存块的相应的链表节点从st_Head中删除 //重新计算当前节点的前后相邻节点的校验和 //用预设值填充被释放的内存区(用户定制选项) //调用free释放当前的内存块 } (文中代码在Visual C++++6.0、Borland C++ 3.1及CrossCode C 7.4环境中编译通过) 5、结束语 作为对C程序运行时的内存错误进行监测的代码模块,Fense能发现几乎所有的内存泄漏和绝大多数的越界操作,并尽可能地记录了改正程序错误所需要的信息;有效地减少了程序设计人员的调试时间,在实际嵌入式产品开发中取得了很好的效果。 责任编辑:gt

收藏 人收藏
分享:

评论

相关推荐

Linux系统的操作原理

提起linux对于平常经常接触程序代码的朋友来说是在熟悉不过了。作为一个开源的免费操作系统对于编写代....
发表于 07-13 11:33 17次 阅读
Linux系统的操作原理

具备哪些知识才能成为真正的嵌入式工程师???

哪些知识的具备才能成为真正的嵌入式工程师????...
发表于 07-13 10:40 9次 阅读
具备哪些知识才能成为真正的嵌入式工程师???

如何用STM32连接电脑的的烧录线给ESP8266烧写固件

如题,我现在有一个STM32F103的开发板和ESP8266WIFI模块,但是没有ESP8266的USB烧录模块,请问怎么才能用STM...
发表于 07-12 19:25 57次 阅读
如何用STM32连接电脑的的烧录线给ESP8266烧写固件

DSP芯片与其它芯片的最大区别在于什么?

让你说出知道的芯片的名称,你可能会一时想不起,也不能一一罗列DSP芯片都有哪些。或许是对DSP芯片深....
发表于 07-12 11:34 147次 阅读
DSP芯片与其它芯片的最大区别在于什么?

Linux系统的概念及由来

Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任....
发表于 07-12 10:12 120次 阅读
Linux系统的概念及由来

Linux系统有哪些优点

Linux系统Linux系统优点有哪些?Linux是GNU / Linux的全名,是一组免费使用和免....
发表于 07-12 10:03 105次 阅读
Linux系统有哪些优点

瑞萨电子:嵌入式终端与人工qy88千赢国际娱乐融合改变工业格局

瑞萨电子在汽车、工业、基础设施和物联网等多个领域提供了专业可信的嵌入式设计与半导体解决方案,面对工业....
的头像 E4Life 发表于 07-10 18:47 1629次 阅读
瑞萨电子:嵌入式终端与人工qy88千赢国际娱乐融合改变工业格局

LabView开发嵌入式系统的的挑战及应用解决方案

随着嵌入式系统的快速发展和复杂性的不断增加,基于文本的编程方式所面临的挑战愈发严峻,这种编程模式在将....
发表于 07-10 18:00 76次 阅读
LabView开发嵌入式系统的的挑战及应用解决方案

基于LabVIEW平台和CompactRIO开发移动机器人腿部动态步态

腿部和车轮这两种方法在地面运动平台上被广泛采用。经过漫长的演变过程,大多数陆地动物的腿部都灵活有力,....
发表于 07-10 17:16 140次 阅读
基于LabVIEW平台和CompactRIO开发移动机器人腿部动态步态

关于嵌入式Linux项目开发内容

 对于嵌入式Linux开发所需要的知识,也正是处理数据流转时所需要的技术, 对于嵌入式Linux项目....
发表于 07-10 16:57 55次 阅读
关于嵌入式Linux项目开发内容

Linux嵌入式操作系统有哪些优势

嵌入式Linux操作系统是将Linux操作系统进行裁剪,使Linux操作系统能够在嵌入式计算机系统上....
发表于 07-10 16:34 149次 阅读
Linux嵌入式操作系统有哪些优势

Linux操作系统与Windows操作系统的五大区别

Linux操作系统和Windows操作系统身为三大操作系统巨头里面的两大巨头,他们有什么区别呢?首先....
发表于 07-10 16:28 144次 阅读
Linux操作系统与Windows操作系统的五大区别

基于linux的十大操作系统排名

基于linux内核开源的特性,并随着linux的不断发展,各种基于Linux的操作系统版本也在不断发....
发表于 07-10 16:23 80次 阅读
基于linux的十大操作系统排名

基于FPGA和Nios II处理器IP软核实现实现SD卡接口和文件系统的设计

在嵌入式系统或移动设备上使用SD卡,接口的构建和文件系统实现是必须解决的问题。本文探讨在Cyclon....
发表于 07-10 10:19 116次 阅读
基于FPGA和Nios II处理器IP软核实现实现SD卡接口和文件系统的设计

Android 11的第二个公开beta版本的发布

平台稳定性意味着开发人员可以开始进行最终的Android 11兼容性更新,而不必担心平台从现在到最终....
的头像 倩倩 发表于 07-10 10:10 157次 阅读
Android 11的第二个公开beta版本的发布

单端口SRAM与双端口SRAM电路结构

SRAM是随机存取存储器的一种。所谓的静态是指这种存储器只要保持通电,里面储存的数据就可以恒常保持。SRAM不需要刷新电...
发表于 07-09 14:38 1225次 阅读
单端口SRAM与双端口SRAM电路结构

搞嵌入式,软件和硬件哪个更重要?

据王利涛表示,很多嵌入式初学者认为,学嵌入式,就是学习ARM,就是学习开发板。买一块开发板,然后在上....
的头像 玩转单片机 发表于 07-09 09:10 286次 阅读
搞嵌入式,软件和硬件哪个更重要?

香橙派开发板Orange Pi 4在Linux系统下如何使用PWM

香橙派4电脑开发板使用Rockchip RK3399主控芯片,拥有双通道4GB LPDDR4内存 ,板载16GB EMMC flash存储,支持运...
发表于 07-08 20:51 1336次 阅读
香橙派开发板Orange Pi 4在Linux系统下如何使用PWM

基于ARM嵌入式人机交互的设计方案

人机交互过程中获得人的动作是一个关键,为了实现手部姿态的实时跟踪控制,分析了手形及手部的运动形式和特....
发表于 07-08 18:09 43次 阅读
基于ARM嵌入式人机交互的设计方案

操作系统的置换算法FIFO-OPT-LRU实现代码

在一个请求分页系统中,设页面大小占100个单元,假如系统分配给一个作业的物理块数为3,试求出用FIF....
发表于 07-08 17:24 19次 阅读
操作系统的置换算法FIFO-OPT-LRU实现代码

华为将有大动作,鸿蒙OS 2.0系统将与EMUI 11同时诞生

7月6日消息,随着Android 11的官宣,EMUI 11近日也有了消息。在近日举办的花粉8周年庆....
的头像 科技观察者 发表于 07-08 16:21 920次 阅读
华为将有大动作,鸿蒙OS 2.0系统将与EMUI 11同时诞生

概述Java的性能和执行效率

Java在九十年代中期出现以后,在赢得赞叹的同时,也引来了一些批评。赢得的赞叹主要是Java的跨平台....
发表于 07-08 16:04 121次 阅读
概述Java的性能和执行效率

嵌入式设计降低硬件功耗的方法

  (1)低功耗外围器件的选用   完成同样的功能,电路的实现形式有多种。例如,尽可能地将嵌入式系统的内部存储器RAM转换...
发表于 07-08 15:52 1068次 阅读
嵌入式设计降低硬件功耗的方法

如何提高操作系统的实时性

  1、缩短中断响应时间。几乎所有的实时事件都是通过中断上报的,当中断来临时,我们必须停止当前的一切任务,响应中断,我们把...
发表于 07-08 15:41 74次 阅读
如何提高操作系统的实时性

嵌入式uClinux的内核结构和开发环境

  1 引言   嵌入式操作系统是嵌入式系统的灵魂,而且在同一个硬件平台上可以嵌入不同的嵌入式操作系统。比如ARM7TDMI...
发表于 07-08 15:36 82次 阅读
嵌入式uClinux的内核结构和开发环境

概述ARM处理器的工作状态和工作模式

为了能够体现ARM的特点和性能,ARM处理器有两种工作状态和7种工作模式。
发表于 07-08 15:29 59次 阅读
概述ARM处理器的工作状态和工作模式

MAXHUB推出qy88千赢国际娱乐交互式平板,国产操作系统帮助用户快速上手

“国产化”是近年从国家层面到社会各行各业都十分重视的话题,比如会议信息安全、芯片技术、操作系统等多个....
的头像 牵手一起梦 发表于 07-08 15:12 327次 阅读
MAXHUB推出qy88千赢国际娱乐交互式平板,国产操作系统帮助用户快速上手

如何使用ARM9实现串行通讯的设计方案

嵌入式是以应用为中心,以计算机技术为基础,软硬件可剪裁,适应应用系统对功能、可靠性、成本、体积、功耗....
发表于 07-08 14:31 25次 阅读
如何使用ARM9实现串行通讯的设计方案

不通过装系统将旧硬盘的操作系统复制到新硬盘内的方法

现在很多人都喜欢给电脑升级固态硬盘,这是非常明智的一个决定,固态硬盘凭借自身的高速读写能力已经成为市....
的头像 如意 发表于 07-08 09:42 198次 阅读
不通过装系统将旧硬盘的操作系统复制到新硬盘内的方法

32位操作系统为什么不能安装aduino程序?

请问下win7 64位的操作系统aduino程序可以有,怎么32位操作系统不能安装aduino程序? ...
发表于 07-08 09:29 55次 阅读
32位操作系统为什么不能安装aduino程序?

内存溢出的解决办法 ?

求解决方案?????
发表于 07-08 08:34 49次 阅读
内存溢出的解决办法 ?

嵌入式Linux系统篇:RealARM2410技术手册

  RealARM2410是基于三星公司S3C2410X 高性能ARM 处理器的嵌入开发平台,旨在为....
发表于 07-07 16:35 39次 阅读
嵌入式Linux系统篇:RealARM2410技术手册

简易嵌入式计算器的设计方案

  随着电子科技技术的不断发展在当今社会计算器已深入人们生活中给人们的生活带来了方便推动了社会的发展....
发表于 07-07 16:25 55次 阅读
简易嵌入式计算器的设计方案

I.MX6ULL终结者开发板裸机仿真jlink调试

I.MX6ULL‘终结者’开发板预留了JTAG仿真接口,并给出了开发文档,可以实现在JLINK仿真器条件下的单步跟踪、断点...
发表于 07-07 10:56 270次 阅读
I.MX6ULL终结者开发板裸机仿真jlink调试

qy88千赢国际娱乐安防:网络视频存储服务器的重要性

网络视频存储服务器是一种用于视频和音频数据压缩、存储和处理的嵌入式设备。它广泛应用于远程监控和bbb....
的头像 如意 发表于 07-07 10:40 136次 阅读
qy88千赢国际娱乐安防:网络视频存储服务器的重要性

4G内存和6G内存的手机成本差异是多少?

现在手机4G内存和6G内存的成本差异大概有多少呢?实际上,现在大多数的手机厂商还是使用LPDDR4X....
的头像 如意 发表于 07-05 10:38 290次 阅读
4G内存和6G内存的手机成本差异是多少?

工控机由哪几部分组成

那我们的工控机的是怎样做的呢?我们的工控机是由哪几方面组成的,下面给大家讲解一下:
发表于 07-05 09:30 123次 阅读
工控机由哪几部分组成

Linux主要应用在那些领域

日前,国际超算大会发布了最新的全球TOP500超级计算机列表,其中最著名的是日本超级计算机“ Fug....
的头像 Wildesbeast 发表于 07-04 11:38 424次 阅读
Linux主要应用在那些领域

Apple宣布采用全新设计的macOS Big Sur

苹果还进行了其他一些调整。菜单栏现在变得更高且更透明,界面的字体颜色根据桌面背景的颜色而变化,下拉菜....
的头像 倩倩 发表于 07-03 17:03 359次 阅读
Apple宣布采用全新设计的macOS Big Sur

华为云全球首发容器安全服务,市场份额位居国内厂商第一

近日,国际权威咨询机构IDC发布了《PRC SDC Software Market Overview....
的头像 牵手一起梦 发表于 07-03 16:34 285次 阅读
华为云全球首发容器安全服务,市场份额位居国内厂商第一

iOS 14的隐私功能显示了复制到剪贴板的TikTok阅读文本

开发人员开始下载并使用iOS 14 beta版,他们发现流行的视频共享平台TikTok是读取用户复制....
的头像 倩倩 发表于 07-03 16:33 520次 阅读
iOS 14的隐私功能显示了复制到剪贴板的TikTok阅读文本

什么是嵌入式与物联网,物联网与嵌入式之间的关系

互联网着重信息的互联互通和共享,解决的是人与人的信息沟通问题;物联网则是通过人与人、人与物、物与物的....
发表于 07-03 14:23 98次 阅读
什么是嵌入式与物联网,物联网与嵌入式之间的关系

SECORA™ ID S:为各地电子身份证卡和电子政务带来高安全级别的灵活解决方案

搭配英飞凌的线圈模块封装技术,可以有效的提高证卡的耐久度,使其生产、签发、及使用的周期更具成本效益。
的头像 西西 发表于 07-02 16:14 202次 阅读
SECORA™ ID S:为各地电子身份证卡和电子政务带来高安全级别的灵活解决方案

嵌入式必看 Linux内存管理工作原理

机器的内存是有限资源,而进程数量是无法确定的,如果在某些时候已经启动的进程占据了所有内存空间,此时就....
发表于 07-02 15:10 227次 阅读
嵌入式必看 Linux内存管理工作原理

Linux下对于函数调用的工作原理

高地址的一部分空间会分配给内核,称为内核空间,剩下的内存空间给用户使用,称为用户空间。
发表于 07-02 14:46 73次 阅读
Linux下对于函数调用的工作原理

CUDA 6中的统一内存模型

NVIDIA在CUDA 6中引入了统一内存模型 ( Unified Memory ),这是CUDA历....
的头像 Linuxer 发表于 07-02 14:08 132次 阅读
CUDA 6中的统一内存模型

苹果iOS系统迎来更新,最新加入三大功能

苹果推送了 iOS 13 的又一个公测版本,其版本号为 13.6,具体代号为 c17G5059,一同....
发表于 07-02 10:17 351次 阅读
苹果iOS系统迎来更新,最新加入三大功能

雷克沙进军内存市场,内存市场大风暴

雷克沙的笔记本和台式机内存条采用了黑色的 PCB。参数方面,笔记本和台式机内存条都是 DDR4 26....
发表于 07-02 09:42 75次 阅读
雷克沙进军内存市场,内存市场大风暴

曙光中标分布式块存储产品集采 中国移动给大订单

近年来,分布式存储技术在电信行业得到广泛的推广,在云化转型、 IoT、5G 等新兴业务,虚拟化资源池....
发表于 07-02 09:07 69次 阅读
曙光中标分布式块存储产品集采  中国移动给大订单

嵌入式ICE-RT逻辑和嵌入式跟踪宏核(ETMS)系列

ARM的Jazelle技术使Java加速得到比基于软件的Jaarm处理器阶梯图va虚拟机(JVM)高....
的头像 ARM视频 发表于 07-02 08:36 874次 观看
嵌入式ICE-RT逻辑和嵌入式跟踪宏核(ETMS)系列

如何使用UCOS操作系统实现万年历的设计

本文档的主要内容详细介绍的是如何使用UCOS-II操作系统实现万年历的设计。
发表于 07-02 08:00 30次 阅读
如何使用UCOS操作系统实现万年历的设计

国产操作系统产业深度解析

中国的操作系统国产化浪潮源于20世纪末,历经二十余年,厚积薄发、屡败屡战。目前,依托开源生态以及政策....
的头像 玩转单片机 发表于 07-01 17:10 1186次 阅读
国产操作系统产业深度解析

8位的MCU的情形又如何,很多嵌入式工程师都有一些误解

不少人会认为既然现在市场的宠儿是32位的MCU,厂商们是不是都没有投入研发资源在8位产品上了。这么想....
的头像 玩转单片机 发表于 07-01 16:58 331次 阅读
8位的MCU的情形又如何,很多嵌入式工程师都有一些误解

梳理嵌入式Linux的一些知识

学单片机的朋友有些已经有一些Linux基础了,但也不乏有些朋友没用过Linux,甚至有些初学的读者朋....
的头像 玩转单片机 发表于 07-01 16:56 493次 阅读
梳理嵌入式Linux的一些知识

Gigantic巨页与CMA的完全结合

用户可以在开机的时候通过hugetlb_cma bootargs来设置CMA的大小,如果是NUMA架....
的头像 Linuxer 发表于 07-01 14:46 152次 阅读
Gigantic巨页与CMA的完全结合

基于PSoC3可编程嵌入式片上系统的qy88千赢国际娱乐手机电池充电器

  PSoC®3是一款真正的可编程嵌入式片上系统,在单个芯片上集成了可配置的模拟和数字外设功能,存储....
的头像 Cypress视频 发表于 07-01 12:23 309次 观看
基于PSoC3可编程嵌入式片上系统的qy88千赢国际娱乐手机电池充电器

采用MPLAB代码配置器配置ADC及FVR

MPLAB 集成开发环境(IDE)是综合的编辑器、项目管理器和设计平台,适用于使用Microchip....
的头像 Microchip视频 发表于 07-01 10:08 572次 观看
采用MPLAB代码配置器配置ADC及FVR

CompactRIO系统拥有坚固的硬件架构

CompactRIO是美国国家仪器(NI)公司生产的一款可重新配置的嵌入式测控系统。CompactR....
的头像 NI视频 发表于 07-01 08:20 825次 观看
CompactRIO系统拥有坚固的硬件架构

KUKA.ProConOS软件功能简史

ProConOS是一款高性能PLC运行时间引擎,专为基于嵌入式和PC的控制应用而设计。ProConO....
的头像 机器人及PLC自动化应用 发表于 06-30 15:54 182次 阅读
KUKA.ProConOS软件功能简史

华为强势出击!更新HMS系统,谷歌断供策略失败

只要华为跟美国的这一出“戏”还没落下帷幕,还是有不少人都会担忧华为的发展。华为是让我国人们很骄傲的存....
的头像 如意 发表于 06-30 08:44 601次 阅读
华为强势出击!更新HMS系统,谷歌断供策略失败