全部学习汇总: GreyZhang/c_units: A small piece of code which can be reuse anywhere, I call it a unit. This is a collection of unit in C language! Ok, yes, it would be my toolbox. (github.com)
在嵌入式,尤其是控制类的嵌入式中很少有malloc以及free的使用。但是,如果有这么个功能的话会让很多成熟的软件移植得到很大的方便。正好,在之前看FreeRTOS的时候也看到过这方面的一些论争描述。这个FreeRTOS中有一个可以在嵌入式中使用而且还解决了一些弊端的malloc和free的存储管理实现。这里尝试把这个功能处理成一个初步的模块,然后做几个基本的功能测试。
这个在使用的时候一些关键区保护等处理,这里为了简单方便先不考虑。如果后续进行实际使用的时候,这部分代码肯定还是需要做一部分改进。
大部分的处理其实是处理一下编译中的问题,我使用到的配置如下:
我专门增加了一个头文件用来管理这里的一些配置信息以及数据结构,同时提供一些接口的声明。
功能的使用需要一个初始化,对应的接口是一个静态函数。其实看一下代码,这个在第一次调用分配的时候会自动调用。我想做一部分测试,又单独写了一个测试文件,因此这里临时加了一个初始化,也尝试进行主动的调用。后面还会处理掉。
这里的大结构不改,干脆把两个定义改成了一样,全都是私有的模式。这样的处理,相对来说安全可靠性好一些。
关于一组函数的功能,之前我其实是尝试过用文学编程的模式进行过分析的。这里不再继续做过多的阐述,简单来说其实就是一个链表的管理。因此,存储的分配其实在使用的时候会有一些额外的消耗。这部分消耗主要是链表资源占用的。
而不同芯片,很多参数是不相同的,我常用的都是32bit的MCU,因此我尝试在尽力相同的环境中测试。正好,手中的树莓派3B可以发挥这样的作用。
这是我用到的编译器,这样直接编译运行后的结果基本接近于我常用的芯片行为。
这一个测试主要是看看初始化的资源消耗,其实应该就是一个链表的节点。
实际看看其实也是这样,这个链表为什么消耗8个字节呢?
从内容看,一个size_t,其实是整形了,外加一个指针。这个数值还是准确的。
接下来看看分配一个int的空间,存储的消耗。
这个信息的获取不是很对,其实通过基本的信息来计算,占用的空间应该是8192 – 8 – 8168,结果为16。为什么数据不对呢?主要还是处在内存池的初始化上,这个是在分配的时候识别并调用的。也就是说,如果连续做几次测试,后面的就会是对的。那么这16个字节如何来的呢?其中的8个字节跟前面一样,是一个链表节点的消耗,而另外的8个字节就是给整形分配的空间。那么为什么不是分配4个字节呢?那是因为在策略上设置了8个字节的对齐。
也就是上面的这个参数。
这个数值如果是改成4,那么效果是上面这样。所差出来的4个字节就没有了。这个从代码的注释中看其实是跟硬件的架构有关的,一时间我还没有弄清楚是什么硬件特性决定了这样的设计,暂时先保持原来的8个字节对齐。
针对此,再增加一组测试。
看这里第二组的输出就可以看得出来,这一次申请了8个字节,正好满足对齐的要求。因此在存储分配上跟前面消耗一样,都是16个字节。
最后增加free的测试。
最终存储全都释放了。
其实,更加合理的测试应该有存储大小动态的调整过程。这样,能够看到内存碎片的一个整理过程。针对这方面,我觉得我还是来考虑相信FreeRTOS代码测试的充分性。暂且只做这部分功能性的测试。