了解上位机代码的对malloc和free这两个函数都不陌生,使用内存分配和释放的目的是为了有效的利用内存。但在单片机中,彷佛是回到了石器时代,上位机中各种库函数不一定能用,即便能用也不够灵活,或者占用资源较多,出了问题也不好定位。作为一个玩转单片机的人,总不喜欢那些看不见的代码,所以特意学习了一下。
我是直接看TI 的一个协议栈中OSAL内存分配函数,思路是这样,定义一个用于内存分配的数组,这个数组就就相但于堆,需要时就从里面取一块出来,用完后有给放回去,这样就成了资源共享,提高内存利用率。每次取走一块内存,就在堆里做一个标记,标记本次被分配的内存是多大,然后把可分配内存的指针偏移相应的大小。
每一个内存块用一个两个字节的头来标记内存状态,其中低15位表示本块内存的大小,最高位表示本块内存是否已被使用。使分配函数时,得先对堆进行初始化,就是标记可用内存块大小为堆的总量-2字节大小,状态为0,即未被使用。并把内存块的索引地址指向堆第一个字节。分配内存时从索引地址往后偏移量字节后,划出指定长度的内存空间,并设置内存块的大小为指定大小,空闲标志置为1,然后再把内存所有地址知道被分配的内存块的后面,如此重复。
释放内存时,先将空闲标记置为0,然后判断被释放内存的头的地址是否小于内存当前索引地址,若小于,要将内存索引地址指到当前被释放的内存地址。比如被释放的内存块是1,当前内存索引地址是内存块3的头信息,那要将当前内存的索引地址改为内存块1的头信息地址。下次内存分配时从内存索引地址逐个查找大小满足需求的内存块,若不满足,检查下一块是否为空,若为空则判断两块内 将两块内存总和是否满足需求,若满足,就将两块内存合到一起分配,若不够再继续往下查,若相连的未被使用的内存不够,则需要找到下一个空闲的内存块 再继续找满足需求的内存块,若找到就返回分配的内存地址,若找不到就返回0,0表示分配失败。
在实际中,为了减小内存碎片问题,还要将堆分为大块区和小块去,小内存在从小块区分配,大的内存要到大块区分配。下面是代码,有详细的注释:
阅读(1082) | 评论(0) | 转发(0) |