我们在写应用程序的过程中通常都是采用一个malloc/free系列函数进行内存的管理,这样分配的内存空间是从应用程序的栈空间分配处理,一般而言我们在写程序的过程中要对内存空间进行适时的释放,才不至于导致栈空间的不足,当然这样也会导致内存垃圾的产生,因为不同大小的内存分配因为对齐等原因导致很多的内存不能再使用,进而使得系统的可用内存越来越小,因此在实时操作系统中通常都需要创建自己的内存管理操作。
uc/os-II中的内存管理主要是采用内存分区控制块实现的,具体的实现过程如下:
点击(此处)折叠或打开
- /*
- 关于内存控制块的结构体,
- 用来跟踪每一个内存分区
- 每一个分区可以分成很多个小的内存块
- 每一个内存块的大小都是相同的
- */
- #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
- typedef struct { /* MEMORY CONTROL BLOCK */
- /*内存的起始地址*/
- void *OSMemAddr; /* Pointer to beginning of memory partition */
- /*
- 链表指针,
- 能够快速的实现内存的控制
- */
- void *OSMemFreeList; /* Pointer to list of free memory blocks */
- /*每一个内存块的大小*/
- INT32U OSMemBlkSize; /* Size (in bytes) of each block of memory */
- /*存在的内存块数量*/
- INT32U OSMemNBlks; /* Total number of blocks in this partition */
- /*空闲的内存空间*/
- INT32U OSMemNFree; /* Number of memory blocks remaining in this partition */
- } OS_MEM;
基本的实现思想就是将内存分区分解成很多的大小相同的内存块,然后OSMemFreeList将所有的内存块链接起来,但是此处的链接与我们常用的链表存在一定的差别,这也是内存管理中常用的技巧之一,即在当前块的起始地址处存放下一个内存块的地址,这样就能比较快速的实现内存的管理。在uc/os-II的内存管理代码的OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)函数中存在一些代码难点。特别是强制类型转换的使用,在uc/os-II中我们看见了大量的强制类型转换问题,下面就做一下简要的分析:
点击(此处)折叠或打开
- OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err