【代码质量】嵌入式编程节约内存技巧
1.写在前面
嵌入式开发,不同于PC、移动设备(手机、平板)以“GB”为单位的存储空间(ROM)和内存(RAM)。尤其是MCU、SOC,RAM是KB级别的容量,ROM则稍微较大;当然也有较大容量的MCU选择,成本也跟着上去。MCU类的产品出货量大,成本控制比较苛刻,所以在选择MCU时,老板当然希望占用资源越小越好,进而控成本。因此,我们在程序编码时,就需要考虑资源问题,甚至要使用上一些“手段”来控制,平衡资源和效率,尽可能降低固件占用资源同时保证效率。
2.一些技巧
程序界有句比较熟悉的话:“时间换空间、空间换时间”,字面意思就是资源空间和程序执行时间的权衡。比如,数据放在ROM中和RAM中时,两者的读取速度就不一样。本文目的是“节约内存”为出发点,所以对于一些处理技巧上,效率肯定会打折扣,这就是一个“权衡”问题,需根据具体实际应用场合来选择。
[1] ROM代替RAM
前面提到,MCU的ROM往往远大于RAM,而且ROM和RAM的成本6:1,常量数据可以存在在ROM中。常规操作就是加“const”修饰。
[2] 用位域
对于一些变量并未使用完整个数据类型范围,可以使用位域,未使用到的位留给其他使用。如1字节变量就可以实现8个bool型操作。位域常用在结构体中。
struct type
{uint8_t select : 1;uint8_t calc : 7;
};
[3] 传递指针(地址)
对于MCU裸机编程或者带RTOS(实时系统)编程,虽然没有明确的驱动、应用分层界限,但为了提高程序可移植性和可读性,也会做一些分层处理。底层驱动提供的接口应该是以指针(地址)方式作为形参,而且中间尽量避免一些内存拷贝。即,最终的内存空间应是由应用层申请的。
uint8_t driver_fun(void *buf);
uint8_t app_fun()
{uint8_t buf[10];driver_fun(buf);
}
[4] 逐个处理
对于处理,可以将某段内存数据首地址直接传递到调用函数,由函数内部实现内存偏移处理。换一个方式处理,也可以单个数据传入,牺牲效率以换取内存。最常见的情况有:
1)串口编码发送。比如用户端发送“abcdef”,实际需编码成“12abcdef34”发送。如果单个字符发送则可以节约中间编码时临时内存拷贝的开销,但效率明显降低。
2)串口接收。接收组串口字符数据并解析,单字节读读取缓存数据并解析,解析完则处理;比获取一定长度的数据再解析要节约一段内存。
[5] 共享内存
多个任何函数使用一段内存,可以进行“分时复用”。
[6] 内存池
对于嵌入式开发,特别是MCU类编程,一般不建议使用malloc/new等动态内存分配,因为多次申请释放过程会产生内存碎片,而MCU类内存并不大,容易导致内存申请不失败导致程序异常甚至崩溃。如果内存实在吃紧,可以使用“内存池”。
内存池,在操作系统中很常见,我们也可以自己实现一套简易的内存池算法。内存池基本原理就是以链表的结构实现一定数量、相同大小的内存块,使用时从该内存池中申请指定大小的内存块,使用完释放,效率提升并降低碎片化。内存池只是降低碎片化,非完全杜绝,一般情况下,MCU类编程少用动态内存,严格场合不用。
[7] 编译器优化
这个是编译器选项的设置,对于自身代码有足够的信心,可以尽可能使用编译器的高优化选项。,这项慎用,代码不严谨易导致一些异常问题。
【代码质量】嵌入式编程节约内存技巧相关推荐
- Rust嵌入式编程---动态内存分配器(Vec,String等)
本教程不是0基础的Rust嵌入式编程,需要有一定的Rust裸机编程的基础知识. 作为一个比较接近C的例子,适合入门,代码比较容易理解.本次例子使用的是target = "thumbv8m.m ...
- 嵌入式编程C语言提高代码效率的14种方法
嵌入式编程C语言提高代码效率的14种方法 1.在可能的情况下使用typedef替代define.当然有时候你无法避免define,但是typedef更好. typedef int* INT_PTR; ...
- 代码防御性编程的十条技巧
关注.星标公众号,不错过精彩内容 转自:C语言与CPP编程 1 什么是防御性编程? 顾名思义,防御性编程是一种细致.谨慎的编程方法.为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能的&qu ...
- 嵌入式系统编程之内存操作的注意事项
关注.星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 在嵌入式系统的编程中,内存操作是我们常用到的,但往往也是易错的地方,怎么避免呢,今天给大家分享一些相关的避坑指南. 数据指针 在嵌 ...
- 良好的编码习惯 —— 5 个提高代码质量的技巧
原文地址:Good Coding Practices – Five Tips to Enhance Code Quality 原文作者:Jay 译文出自:掘金翻译计划 本文永久链接:github.co ...
- java防御性编程_代码防御性编程的十条技巧
1 什么是防御性编程? 顾名思义,防御性编程是一种细致.谨慎的编程方法.为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能的"保护"自己.我们通过明确地在代码中对设想进行 ...
- 让你最快速地改善代码质量的 20 条编程规范
根据学习部分极客时间 <设计模式之美>专栏 (王争 前Google工程师)和<阿里 java 规范>整理总结. 分别介绍编码规范的三个部分:命名与注释(Naming and C ...
- 【笔记】编程的原则:改善代码质量的101个方法
代码必然被修改 Code will be changed 代码不是写完就结束了,它在日后必然会被修改.没有写完就扔的一次性代码. 在编写代码的时候,我们应将"代码会被修改"这一点作 ...
- 追求代码质量: 用 AOP 进行防御性编程
原文出处: IBM中国 开发人员测试的主要缺点是:绝大部分测试都是在理想的场景中进行的.在这些情况下并不会出现缺陷 -- 能导致出现问题的往往是那些边界情况. 什么是边界情况呢?比方说,把 null ...
最新文章
- c盘扩展卷是灰色的_银行电脑win7-C盘满了怎么办
- mysql自动挂载存储_Linux开机自动挂载存储
- PHP 年龄计算函数
- Linux进程间通信五 Posix 信号量简介与示例
- JS里的时间有关的标签
- mysql 命令 pdf_MySQL命令文档 PDF 下载
- Node.js初接触(一)
- nodejs中path的用法
- 边沿触发是什么意思_集基耦合双稳电路,集成化单稳电路,数字逻辑电路,门电路,触发器...
- python xlrd读取excel慢_python操作Excel读写--使用xlrd
- Unity之如何从fbx提取Animation clip文件
- K02-01通过简单exe介绍pro基本配置
- 思维导图 进阶(01)关键词提取,思维导图的灵魂
- python-scrapy模拟登陆网站--登陆青果教务管理系统(一)
- android最佳投屏,Android投屏神器(scrcpy使用教程)
- (一)绪论 | 如何判断某数据结构是逻辑结构还是存储结构,是线性结构还是非线性结构
- 通过IIS发布网站教程【十分钟完成一个网站发布】
- 奇虎360 php t5级别,奇虎360凭什么估值3800亿?核心价值只是他而已!
- HDU4585 Shaolin(treap)
- scikit-learn 学习笔记(一)