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] 编译器优化
  这个是编译器选项的设置,对于自身代码有足够的信心,可以尽可能使用编译器的高优化选项。,这项慎用,代码不严谨易导致一些异常问题。

【代码质量】嵌入式编程节约内存技巧相关推荐

  1. Rust嵌入式编程---动态内存分配器(Vec,String等)

    本教程不是0基础的Rust嵌入式编程,需要有一定的Rust裸机编程的基础知识. 作为一个比较接近C的例子,适合入门,代码比较容易理解.本次例子使用的是target = "thumbv8m.m ...

  2. 嵌入式编程C语言提高代码效率的14种方法

    嵌入式编程C语言提高代码效率的14种方法 1.在可能的情况下使用typedef替代define.当然有时候你无法避免define,但是typedef更好. typedef int* INT_PTR; ...

  3. 代码防御性编程的十条技巧

    关注.星标公众号,不错过精彩内容 转自:C语言与CPP编程 1 什么是防御性编程? 顾名思义,防御性编程是一种细致.谨慎的编程方法.为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能的&qu ...

  4. 嵌入式系统编程之内存操作的注意事项

    关注.星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 在嵌入式系统的编程中,内存操作是我们常用到的,但往往也是易错的地方,怎么避免呢,今天给大家分享一些相关的避坑指南. 数据指针 在嵌 ...

  5. 良好的编码习惯 —— 5 个提高代码质量的技巧

    原文地址:Good Coding Practices – Five Tips to Enhance Code Quality 原文作者:Jay 译文出自:掘金翻译计划 本文永久链接:github.co ...

  6. java防御性编程_代码防御性编程的十条技巧

    1 什么是防御性编程? 顾名思义,防御性编程是一种细致.谨慎的编程方法.为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能的"保护"自己.我们通过明确地在代码中对设想进行 ...

  7. 让你最快速地改善代码质量的 20 条编程规范

    根据学习部分极客时间 <设计模式之美>专栏 (王争 前Google工程师)和<阿里 java 规范>整理总结. 分别介绍编码规范的三个部分:命名与注释(Naming and C ...

  8. 【笔记】编程的原则:改善代码质量的101个方法

    代码必然被修改 Code will be changed 代码不是写完就结束了,它在日后必然会被修改.没有写完就扔的一次性代码. 在编写代码的时候,我们应将"代码会被修改"这一点作 ...

  9. 追求代码质量: 用 AOP 进行防御性编程

    原文出处: IBM中国 开发人员测试的主要缺点是:绝大部分测试都是在理想的场景中进行的.在这些情况下并不会出现缺陷 -- 能导致出现问题的往往是那些边界情况. 什么是边界情况呢?比方说,把 null  ...

最新文章

  1. c盘扩展卷是灰色的_银行电脑win7-C盘满了怎么办
  2. mysql自动挂载存储_Linux开机自动挂载存储
  3. PHP 年龄计算函数
  4. Linux进程间通信五 Posix 信号量简介与示例
  5. JS里的时间有关的标签
  6. mysql 命令 pdf_MySQL命令文档 PDF 下载
  7. Node.js初接触(一)
  8. nodejs中path的用法
  9. 边沿触发是什么意思_集基耦合双稳电路,集成化单稳电路,数字逻辑电路,门电路,触发器...
  10. python xlrd读取excel慢_python操作Excel读写--使用xlrd
  11. Unity之如何从fbx提取Animation clip文件
  12. K02-01通过简单exe介绍pro基本配置
  13. 思维导图 进阶(01)关键词提取,思维导图的灵魂
  14. python-scrapy模拟登陆网站--登陆青果教务管理系统(一)
  15. android最佳投屏,Android投屏神器(scrcpy使用教程)
  16. (一)绪论 | 如何判断某数据结构是逻辑结构还是存储结构,是线性结构还是非线性结构
  17. 通过IIS发布网站教程【十分钟完成一个网站发布】
  18. 奇虎360 php t5级别,奇虎360凭什么估值3800亿?核心价值只是他而已!
  19. HDU4585 Shaolin(treap)
  20. scikit-learn 学习笔记(一)

热门文章

  1. 商业智能BI与业务管理决策思维之三:业务质量分析
  2. SQLSERVER走起微信公众帐号已经开通搜狗微信搜索
  3. 基于cosmol软件的光纤热力学分析
  4. JavaScript 排序,不只是冒泡
  5. matlab 求取矩阵中值,matlab中取矩阵中指定列的值组成新矩阵
  6. 热伤风和感冒有什么区别
  7. ISO9000中服装加工行业应执行哪些检验标准?
  8. 免费公共DNS的IP地址
  9. Unity 的 Scroll View组件
  10. calc() 工作原理