RT-Thread Memory Pool
使用此管理方式: #define RT_USING_MEMPOOL
- mempool 的管理方法(靜態管理):
- 從 RAM 中要一塊記憶體
- 將此記憶體切成固定大小的區塊
- 以間接定址的方式接起來,形成 free list
結構
我們從文本的圖來解釋結構:

start_address
為每個 mempool 的起始位置,此圖為例則為mempool 1 的起始位置
size
為 mempool 的大小,此圖為例則為mempool 1 的大小(灰色區塊)
block_size
為由 mempool 產出的空閒鏈表中,每一塊的大小,以mempool 1 為例,則為 32k
block_list
為空閒鏈表,此圖為例則為mempool 1 旁邊的鏈結
block_total_count
為空閒鏈表創建時的總塊數,以mempool 1 為例,則為 128
block_free_count
為為空閒鏈表現在可用的總塊數
suspend_thread
則為等待隊伍,此圖為例為最右邊的鏈結
suspend_thread_count
則為等待隊伍的總排隊數,以此圖為例為 3
建立 memory pool
- 建立 memory pool 的方法一樣也可分為靜態的與動態的
- 這裡的動態是指從原先記憶體 heap 的區塊拿取記憶體
動態
rt_mp_create
功能 |
回傳值 |
建立 mempool(使用 heap) |
mempool |
*name |
block_count |
block_size |
名字 |
要切割的總塊數 |
一塊 free block 的大小 |
- 首先一樣先從 heap 取一塊記憶體作為 mempool 使用
- 接著對齊
block_size
後填入結構中,一併計算 mempool 的大小
- 並從 heap 中取出一塊待會做成 free list
- 最後製作 free list:
- 一個 free block 分成兩部分:前 8-bit (rt_uint8_t *)與一個 block_size
- 前 8-bit 存放下一個 free block 的位置
靜態
rt_mp_init
*mp |
*name |
*start |
size |
block_size |
結構位址 |
名字 |
所要使用的記憶體位址 |
mempool 大小 |
一塊 free block 的大小 |
- 可直接用
rt_object_init
初始化物件
- 同時用
RT_ALIGN_DOWN
對齊 size
- 填入
block_size
RT_ALIGN_DOWN
v.s. RT_ALIGN
- 當傳入 (13,4) 時:
RT_ALIGN_DOWN
回傳 12,也就是在不超過 13 中,4 的倍數中最大的
RT_ALIGN
回傳 16,也就是在大於等於 13 中,4 的倍數中最小的
刪除 memory pool
動態
rt_mp_delete
功能 |
回傳值 |
刪除 mempool(使用 heap) |
RT_EOK |
- 當要把 mempool 刪除前,先將正在等待分配記憶體的 thread 一個一個叫醒
- 叫醒前,先將錯誤碼改成
ERROR
- 接著透過
rt_thread_resume
叫醒 thread
從等待鏈上移出的動作,在 rt_thread_resume
中會實現。
( code in RT-Thread Thread)
- 最後更新
suspend_thread_count
- 叫醒完,free 掉建立 mempool 時所要的記憶體
- 再透過
rt_object_delete
刪除
靜態
rt_mp_detach
分配記憶體
rt_mp_alloc
功能 |
回傳值 |
分配記憶體 |
一塊 free block |
- 如果目前無法取得記憶體,且等待時間為 0,回傳 NULL,並設置錯誤碼為 TIMEOUT
- 如果可以要記憶體,更新
block_free_count
- 並將 free list 往後一顆
block_list
是使用間接定址,前 8-bit 是下一顆的位置
- 最後回傳取得的 free block
- 注意這裡回傳的是
block_ptr + 8
,也就是真正可以使用的位址
- 如果要尋找這個 block 所屬的 mempool 則需要 -8。
Free
- 更新
block_free_count
- 接著定址到 free list,重新指定 block list
- 也就是將此 block 插到第一顆