这里说的架构,是指用户可以定义较大的数组,一般是二维数组,每块的size为数组的二组的列数(第二维),总块数为数组行数(第一维)。
上面指的算法是一种按照单向链接的链表的算法,初始每块的首存放下的一块首地址,并有一指针记录当前的空闲的地址(初始的时候指向第一块)。需要使用的时候从当前空闲块指针取,并将空闲块的指针指向下一块可用的块。呵呵,这就是所谓的"单向链表"。那使用完后又是怎样的呢?就是当前块首存储空闲块指针,而后,空闲块指针需要得到当前使用完块的地址(即空闲块指针=当前使用完块的地址)。注意下这个先后顺序。
来看看ucosII的源码吧。
以下是创建内存块的函数实现代码
点击(此处)折叠或打开
- OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
- {
- INT8U *pblk;
- void **plink;
- plink = (void **)addr;
- //....
- //代码有省略
- /* Create linked list of free memory blocks */
- plink = (void **)addr; //第1处
- pblk = (INT8U *)addr + blksize;//第2处
- for (i = 0; i < (nblks - 1); i++) {
- *plink = (void *)pblk; //第3处
- plink = (void **)pblk; //第4处
- pblk = pblk + blksize;
- }
- //....
- //代码有省略
- }
咋一看,是不是对(void **)然后又(void*)这些强制转换晕了?确实,我第一次也晕了,醉了。不过也很佩服这种用法的“老道”与娴熟。这也是看OS的源码的值得学习的地方——代码的优美,使用的精炼又准确,周全也顾及阅读感受。
对(void **)与(void *)糊涂的读者,建议百度,笔者推荐CSDN博文《理解*(void**)b》。需要指明的是
若定义了 void *p;
1,(void **)p,将p强制为指向指针(该指针指向void型)的指针,p指向的类型是固定的了,就是指针(该指针指向void型);
2,(void *)p,p指针指向的类型就不固定了
第1处和第2处,强制转换就是类型匹配。
第3处 *plink = (void *)pblk,将pblk强制后赋值给plink指向单元,i=0,就是赋给第一块的块首。也就是说,第一块块首存储着第二块的地址了。
第4处是plink = (void **)pblk什么意思呢?将pblk强制转换成指向指针的指针,所以pblk还是指针嘛,本质没有变化。这句话的意思就是将指针指向的单元地址赋给plink。
那么问题来了。。为什么要强制成(void **)呢?
答案就在上面说的(void **)p的含义,p指向的类型是固定的了,就是指针(该指针指向void型)。
那么再看看获得内存块函数void *OSMemGet (OS_MEM *pmem, INT8U *err)
主要就是以下两条语句
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pblk = pmem->OSMemFreeList ; //当前空闲块的地址取出
pmem->OSMemFreeList = *(void **)pblk; //pblk就指向空闲块了,空闲块的首地址的存储值(存放的是下一块可以使用的地址)取出赋给空闲块地址
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
两条语句的含义见注解。可见,这就是链表的指向算法,一链扣一链。
这个获得内存的函数有要求,每次调用只能获得一块。可以对其进行扩展,加入需要获取的内存块数这一参数,满足获得多块的需求。
释放内存函数OSMemPut (OS_MEM *pmem, void *pblk),也是同理,就不在赘述了。
下面上一张OSMemCreate的示意图,从邵贝贝的ucosII中截取的。
2014-11-28 23:55:06