contiki源码阅读之mmem.c
上次我們說了list,這次我們就借著mmem.c的代碼來用一下這個鏈表。
代碼目錄是./core/lib/mmem.c
結(jié)構(gòu)體定義如下
struct mmem {struct mmem *next;unsigned int size;void *ptr; };請注意,第一個成員必須是指針,這樣才可以借用list的代碼。第二個成員是要申請的字節(jié)數(shù),第三個成員是指針,指向返回內(nèi)存的首地址。
插句話,對于單片機,如果想內(nèi)存管理(不考慮虛擬地址,只考慮物理地址),主要有兩種方法。一種是引出堆的指針,在此基礎(chǔ)上自己封裝,把這個堆管理起來(沒有嘗試過這種方法,也沒有讀到這方面的資料,留待以后研究。)還有一種方法,就是簡單的定義一片全局變量,把這些空間管理起來。今天討論的是第二種方法。
#ifdef MMEM_CONF_SIZE #define MMEM_SIZE MMEM_CONF_SIZE #else #define MMEM_SIZE 4096 #endifLIST(mmemlist); unsigned int avail_memory; static char memory[MMEM_SIZE];這里定義了全局?jǐn)?shù)組,4096個字節(jié)。
定義了全局變量avail_memory,用來記錄還剩余多少個字節(jié)沒有分配。
定義了一個鏈表(上次已經(jīng)介紹過相關(guān)代碼了)。
初始化函數(shù),初始化鏈表并且設(shè)置全局變量avail_memory=4096,4K個字節(jié)。
在上次的list.h文件中,可以看到作者這樣的注釋:
A linked list is made up of elements where the first element ?must be a pointer. This pointer is used by the linked list library?to form lists of the elements.
這呼應(yīng)了開頭的話,因為list里面就是一個指針,所以用戶的結(jié)構(gòu)體必須把指針作為第一個成員,這樣才能在不同指針(用戶的結(jié)構(gòu)體和 struct list)之間自由轉(zhuǎn)換而不會發(fā)生錯位。
如果不是,就要進(jìn)行字節(jié)的拷貝。把這個內(nèi)存之后的所有內(nèi)容(內(nèi)存的末尾減去后面的內(nèi)存塊的起始地址)向前面移動(移動的距離剛好是這個內(nèi)存塊的大小)。
但是這樣還沒有完,因為后面的內(nèi)存塊移動了,所以要修改每個內(nèi)存塊的指針,指針的值也要相應(yīng)減少m->size個字節(jié)。
這樣做的好處是什么,就是沒有內(nèi)存碎片。因為每次釋放,都會把后面的內(nèi)容移動到前面,填補釋放的空洞。
總結(jié)
以上是生活随笔為你收集整理的contiki源码阅读之mmem.c的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: contiki源码阅读之list
- 下一篇: 2020年中国在线少儿英语培训市场研究报