---------------------------------------------
-- 时间:2018-11-04
-- 创建人:Ruo_Xiao
-- 邮箱:xclsoftware@163.com
---------------------------------------------

一、前言

1、本博文是我自己的理解,在没有把握的地方我会特别注明。本人菜鸟一枚,真诚地期待大神地指教!

2、Tiniux 3.0下载地址。

3、建议使用Source Inlight看源码,效率更高!

4、为了避免篇幅过长,博文源码中使用的一些数据类型就不多解释了,本文只针对终点区域做详解。

5、根据Memory.h头文件可知,函数一共5个,如下:

uOSBase_t  OSMemInit(void);
void *OSMemMalloc(uOSMemSize_t size);
void *OSMemCalloc(uOSMemSize_t count, uOSMemSize_t size);void *OSMemTrim(void *pMem, uOSMemSize_t size);
void  OSMemFree(void *pMem);

二、OSMemInit

1、源码

/*****************************************************************************
Function    : OSMemInit
Description : Zero the heap and initialize start, end and lowest-free pointer.
Input       : None
Output      : None
Return      : None
*****************************************************************************/
uOSBase_t OSMemInit(void)
{tOSMem_t *ptOSMemTemp = OS_NULL;// align the heap gpOSMemBegin = (uOS8_t *)OSMEM_ALIGN_ADDR(OSRAM_HEAP_POINTER);/* Initialize the stack tiniux used. */memset(gpOSMemBegin, 0U, OSMEM_SIZE_ALIGNED);// initialize the start of the heap ptOSMemTemp = (tOSMem_t *)(void *)gpOSMemBegin;ptOSMemTemp->NextMem = OSMEM_SIZE_ALIGNED;ptOSMemTemp->PrevMem = 0;ptOSMemTemp->Used = 0;// initialize the end of the heap gpOSMemEnd = (tOSMem_t *)(void *)&gpOSMemBegin[OSMEM_SIZE_ALIGNED];gpOSMemEnd->Used = 1;gpOSMemEnd->NextMem = OSMEM_SIZE_ALIGNED;gpOSMemEnd->PrevMem = OSMEM_SIZE_ALIGNED;// initialize the lowest-free pointer to the start of the heap gpOSMemLFree = (tOSMem_t *)(void *)gpOSMemBegin;return 0U;
}

2、该函数的目的:

(1)将申请的堆初始化为0;

(2)设置指向堆开始位置的tOSMem_t结构体;

(3)设置指向堆结束位置和指向最低位置的已经释放内存的首地址的tOSMem_t结构体。

3、系统内存分布

gpOSMemEnd - gpOSMemBegin = OSMEM_SIZE_ALIGNED

4、tOSMem_t

typedef struct _tOSMem
{uOSMemSize_t NextMem;   uOSMemSize_t PrevMem;    uOS8_t Used;
}tOSMem_t;

(1)作用:用于记录堆中已分配的和未分配的内存块在系统内存中的位置(首地址)。

(2)NextMem:中,下一个tOSMem_t的首地址。

(3)PrevMem:中,上一个tOSMem_t的首地址。

(4)Used:指明其后面的内存块是否被分配,0则为分配,非0则已分配。

(5)注意:tOSMem_t中的元素指明的地址是中的地址,gpOSMemBegin、gpOSMemEnd 和 gpOSMemLFree首地址都是系统内存中的地址。

5、在系统内存中申请堆

gpOSMemBegin = (uOS8_t *)OSMEM_ALIGN_ADDR(OSRAM_HEAP_POINTER);

(1)OSMEM_ALIGN_ADDR,地址对齐操作。

(2)OSRAM_HEAP_POINTER,堆数组的首地址。

#define OSMEM_SIZE_ALIGNED        OSMEM_ALIGN_SIZE(512)
uOS8_t OSRamHeap[OSMEM_SIZE_ALIGNED + (2U*SIZEOF_OSMEM_ALIGNED) + OSMEM_ALIGNMENT];
#define OSRAM_HEAP_POINTER OSRamHeap

A、上述代码的作用是申请512个字节的堆,但是为了在堆中包含两个tOSMem_t(gpOSMemEnd 和 gpOSMemLFree)同时为了数据对齐,则加上了(2U*SIZEOF_OSMEM_ALIGNED) + OSMEM_ALIGNMENT。

B、特别声明:该数组类型为unsigned char,故1个字节即为1个元素,两个tOSMem_t首地址之间的差值就是二者在gpOSMemBegin数组中位置之间的差值。

6、对于刚刚分配好的堆,实际上就2个内存块,一个是ptOSMemTemp信息块和其对应的内存块,另一个是gpOSMemEnd信息块,如下图所示:

1、由于就两个内存块,故:ptOSMemTemp -> NextMem  = OSMEM_SIZE_ALIGNED。

由于ptOSMemTemp之前没有节点,故:ptOSMemTemp -> PrevMem  = 0,

同时由于该内存块没有分配,故:ptOSMemTemp -> Used = 0。

2、由于gpOSMemEnd的作用是作为堆的尾端,故: gpOSMemEnd -> Used = 1。

同时为了不让其参加运算,孤立它,故:

gpOSMemEnd -> NextMem = OSMEM_SIZE_ALIGNED;
gpOSMemEnd -> PrevMem = OSMEM_SIZE_ALIGNED;

三、拓展

解决了delete []ptr,在delete不知道该ptr数组大小的时候就准确地释放了内存的问题。原因就是在每一个已分配的内存块的前面都添加了相应的信息块,用于存放该存储块首尾在系统内存中的位置,如Tiniux中的tOSMem_t。

(SAW:Game Over!)

Tiniux 3.0 / Memory.c / OSMemInit相关推荐

  1. Tiniux 3.0 / Memory.c / OSMemMalloc 和 OSMemCalloc

    --------------------------------------------- -- 时间:2018-11-13 -- 创建人:Ruo_Xiao -- 邮箱:xclsoftware@163 ...

  2. Tiniux 3.0 / Memory.c / OSMemFree

    --------------------------------------------- -- 时间:2018-11-14 -- 创建人:Ruo_Xiao -- 邮箱:xclsoftware@163 ...

  3. SK hynix announces 96GB DDR5 CXL 2.0 memory expansion solution【搬运外媒VedioCardz报道(手工翻译)】

    SK hynix announces 96GB DDR5 CXL 2.0 memory expansion solution (SK海力士发布最新CXL2.0标准的DDR5 96GB内存扩展方案) S ...

  4. android studio dump java heap_Android Studio 3.0 Memory Profiler使用

    Memory Profiler是Android Profiler中的一个组件,Android Profiler是Android Studio3.0用来替换之前Android Monitor的观察工具, ...

  5. Android 10.0系统启动之init进程-[Android取经之路]

    摘要:init进程是linux系统中用户空间的第一个进程,进程号为1.当bootloader启动后,启动kernel,kernel启动完后,在用户空间启动init进程,再通过init进程,来读取ini ...

  6. redis info memory

    参考:http://redis.readthedocs.org/en/latest/server/info.html INFO [section] 以一种易于解释(parse)且易于阅读的格式,返回关 ...

  7. redis-4.0.10集群安装(3台机器,6个node),以及在Spring项目中的集成,redis操作工具类

    1 Redis安装 redis高可用的三种常见的集群方式:redis sentinel .redis cluster(多主机+分布式).redis sharding.接下来主要介绍redis sent ...

  8. Persistent Memory编程简介

    Persistent Memory编程简介 编程 libpmem 持久化函数 libpmemobj 跟对象 root object 例程 事务支持 type safety 线程安全 管理工具 ipmc ...

  9. GCC9.2/Python3.8/Libvirt6.0/QEMU4.2 编译/配置/安装

    文章目录 安装CentOS系统 安装GCC 4.8 安装wget/bzip2 编译安装GCC 9.2 卸载GCC4.8版本 编译安装Python3 获取configure时的设定参数 安装Libvir ...

最新文章

  1. IIS监控--自动重启脚本工具
  2. 和smi_nvidia-smi 报错:无法与 nvidia driver 通信
  3. angular js一factory,service,provider创建服务
  4. AI基础:正则表达式
  5. Apache——启动错误:[Cannot load modules/mod_actions.so into server]解决方案
  6. python 报错traceback-python-traceback捕获并打印异常
  7. [ZJOI2012]灾难(建图)
  8. 【RobotStudio学习笔记】(七)工件坐标
  9. Linux/Ubuntu下解压命令
  10. 知网caj文件怎么转换成Word文档?
  11. 【原创】关于改变电脑默认安装地址后桌面快捷键显示“指定路径不存在”错误的解决方法之一
  12. 概率练习 (16.04.30)
  13. poco源码简单分析
  14. linkMap深度解析
  15. python实现泊松分布_常见的分布及如何使用python实现
  16. MY-I.MX6-DEMO Android4.4.2环境搭建
  17. Codeforces C. Ehab and Path-etic MEXs (树 / 构造 / MEX)
  18. java super父类方法_java super关键字,super调用父类构造方法详解
  19. 你不得不知的北京十大驾校
  20. linux只W25Q256驱动,使用m25p80,支持w25q系列nor flash

热门文章

  1. 我觉得要技术者上升到整体去考虑会好点
  2. 大学生html5设计大赛方案,2018年大学生三维设计大赛策划书范文
  3. java 注解 id_java注解
  4. 前端趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210924
  5. k8s部署ingress:使用heptio-contour部署ingress controller(通过sealos安装,非nginx-ingress类型)
  6. docker --link容器互联
  7. elasticsearch ik分词插件配置自定义分词词典
  8. python文件中环境声明_Python环境构建
  9. python进度条 pyqt_python如何通过pyqt5实现进度条
  10. volatile的学习总结