ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

嵌入式节省内存的手段(1)

2022-10-01 22:03:42  阅读:67  来源: 互联网

标签:


为了方便描述,这里进行总结,嵌入式,一般是c语言常用的节省内存的手段

1.编程技巧

1.1最基本也是最常用的就是字节对齐

这个需要平时的积累。例如,在变量的排列方面,我们都知道编译器会考虑对齐。明显,以下第一种定义需要的内存比第二种要大。

1)char a;int b; char c;

2)char a; char c; int b;

1.2 共用体union

共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。什么意思呢,就是在同一块内存存储可以定义多个数据类型,但是在使用的时候,只有一个变量有效。 这里就有一个问题,变量有大有小呀,对的,所以这个时候共用体的空间为内部变量最大占用空间的值。如此这般,共用体就可以通过共享存储空间,来避免当前没有被使用的变量所造成的存储空间的浪费。

1.3 代码

判断条件一定要少,合并为一个

if()
{
 if()
  {
  }
}

编译优化

编译时选择优化级别高的,这样生成代码大小有有大规模的减小。

内存分时复用

业务

1. 很多电子产品并不是像现在的安卓手机一样同时跑多个应用,顶多就听歌时浏览图片而已,非智能手机也是如此。但我们也会看到电子产品里面有有很多的应用,如设置、电子书、电话本、录音啊等等。因此,不同时运行的应用占用同一块内存空间理所当然。

2. 驱动空间。有很多的驱动并不同时使用,如听FM时是FM驱动,听歌又是使用解码器,所以很多驱动也是可以服用同一块空间的。

3. 中间件的复用。如UI、硬件驱动的再次封装使用等等,其由对应的应用直接调用,一般也存在复用的需求。

4. 数据段的复用。应用和驱动都有数据,同样有复用的场景需求。

理论上驱动和代码也可以服用空间的,但需要考虑的细节太多,而且这样做扩展性不好,所以应用一般是不会跟驱动复用空间的。一般较为粗糙地将软件系统分为以下几个部分:启动、驱动、操作系统、中间件、应用等层次。启动为一次性执行,不需太多考虑复用的空间。操作系统一般有常驻内存的需求,如中断管理、时间管理、调度管理、模块代码管理、虚拟文件系统等等,当然操作系统的一部分功能并不需要常驻内存,主要是一些调用频率较小的一些接口,如驱动装卸载、应用初始化等模块。不需常驻内存的一些接口实现也可以跟驱动复用空间。

编程

在编程时也可以是用union 进行处理,多个变成一个

内存分块的大小

上一点是分块管理的需求和大致的原则,但是如何分块,块大小的设计极为考虑系统架构师的功力。块设大了浪费,小了会导致代码切换频繁效率低下。既然都是RAM,有时数据可以跟代码段放到同一个块中,而没有必要另加一块数据块。当然这些细节需要综合评估并加以详细设计。在成本敏感的电子产品中,这些技巧需要努力挖掘发挥。

ROM代替RAM

这只是从成本的角度去节省内存资源,有些代码需要常驻内容,但其内容并不会随着版本的更新而发生变化,如上节所讲操作系统的调度管理等,可以考虑将这些代码固化到ROM中。理论上操作系统大部分需要常驻内存的代码都可以固化。RAM和ROM同样大小的成本比大概是6:1,因此使用ROM也能大幅降低成本。

系统移植裁剪

这是操作系统设计人员务必要考虑的。每个产品都有独有的功能,而底层操作系统具有普适性,在资源紧缺型系统中,砍掉不必要的模块是非常明智的。

重构可执行程序

我们所阐述的系统一般都是封闭系统,只要能高效地实现功能,我们可以任意改动系统中所有的代码。例如对于可执行的ELF文件,操作系统如果按标准的流程要解析完ELF文件再加载,但不仅需要很多的内存资料,而且也效率低下。ELF有关加载和执行最重要的就是.CODE、.DATA、.CONST、.BSS等段信息,我们完全可以离线抽取出来生成一个新的简单的定制文件格式,操作系统只需解析这个简单的文件就可以了。这样做不仅节省内存,也能节省外存储空间,更能实现高效加载的目的。

算法设计

好的算法一般会是轻巧的,效率高的。

编译优化

编译时选择优化级别高的,这样生成代码大小有有大规模的减小。

指令编译模式

如arm里面选thumb指令,mips选择mips16e,这是由体系结构所决定的,体系结构也是为了考虑节省代码空间资源而设计了16位的指令模式,而这些CPU的字长往往是32位。这种方式能减少30%左右的代码量。

栈空间规划

每个线程都会有自己的栈,而每个线程的栈都应该根据其线程的调用深度来具体设定,像UCOS就有一个栈使用率的任务,我们不妨借用这种思路来看看某个线程最终的栈深度。

设定独立的中断栈,可以避免每个任务栈都要给中断预留栈空间。

扁平的函数调用方法用栈一般要比纵向的函数调用小。嵌入式开发有时为了效率和资源,不应该把代码分块分得太细,函数一大摞,既增加代码量和栈,也降低运行效率。

定制链接脚本,合理规划内存空间

例如,我们规划空间时往往代码段和数据段分开,但实际的代码段可能又用不完,这时就可以把一部分变量定位到代码段之后。这样能够尽可能地利用完内存,而不留“碎片”。

标签:
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有