欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
LWIP內存池memp.c文件學(xué)習

http://blog.csdn.net/Angel_94/article/details/50817918

2016

  

使用LWIP源碼版本為1.4.1

使用內存池分配內存的優(yōu)點(diǎn)在于速度快、效率高、不會(huì )產(chǎn)生很多內存碎片,但是缺點(diǎn)在于只能分配各種固定大小的內存空間,LWIP必須實(shí)現知道用戶(hù)要使用哪些類(lèi)型的POOL,每種類(lèi)型的POOL數量,然后根據這個(gè)需求建立內存池。

一、內存池管理關(guān)鍵函數

內存池初始化函數memp_init,在內核初始化時(shí),該函數必須被調用,用來(lái)完成內存池的建立;
內存池分配函數memp_malloc,通常被內核調用,以實(shí)現核中固定數據結構的申請;
內存池釋放函數memp_free;


二、臨界區與臨界資源

個(gè)人一直是跟老師自學(xué)嵌入式,許多問(wèn)題也是第一次遇到,比如這個(gè)臨界區。下面一些代碼多次遇到了臨界問(wèn)題。

雖然多個(gè)進(jìn)程可以共享系統中的各種資源,但其中許多資源一次只能為一個(gè)進(jìn)程所使用,我們把一次僅允許一個(gè)進(jìn)程使用的資源稱(chēng)為臨界資源。許多物理設備都屬于臨界資源,比如打印機,輸入機等。此外,還有許多變量、數據等都可以被若干進(jìn)程共享,也屬于臨界資源。

對臨界資源的訪(fǎng)問(wèn),必須互斥的進(jìn)行,在每個(gè)進(jìn)程中,訪(fǎng)問(wèn)臨界資源的那段代碼稱(chēng)為臨界區。為了保證臨界資源的正確使用,可以把臨界資源的訪(fǎng)問(wèn)過(guò)程分為四個(gè)部分:
+ 進(jìn)入臨界區:為了進(jìn)入臨界區使用臨界資源,在進(jìn)入區要檢查可否進(jìn)入臨界區,如果可以進(jìn)入,則應設置正在訪(fǎng)問(wèn)臨界區的標志,以組織其他進(jìn)程同時(shí)進(jìn)入臨界區
+ 臨界區:進(jìn)程中訪(fǎng)問(wèn)臨界資源的那段代碼,又稱(chēng)為臨界段。
+ 退出區:將正在訪(fǎng)問(wèn)臨界區的標志清除
+ 剩余區:代碼中的其余部分


三、 memp結構體

struct memp {        struct memp *next;  //下一個(gè)鏈表#if MEMP_OVERLOW_CHECK    /*發(fā)生溢出時(shí)調用函數的文件名,mem_malloc調用者的文件*/    const char *file;    /*發(fā)生溢出時(shí)調用函數的行號,mem_malloc調用者的行數*/    int line;#endif  /* MEMP_OVERFLOW_CHECK */}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

四、一些重要數組

1、memp_tab:

全局指針數組,指向每類(lèi)POOL的第一個(gè)POOL,memp.c文件中

static struct memp *memp_tab[MEMP_MAX];
  • 1
  • 1

2、memp_sizes:

全局數組,用來(lái)記錄每個(gè)POOL的大小,memp.c文件中

const u16_t memp_sizes[MEMP_MAX]={    #define LWIP_MEMPOOL(name, num, size, desc) LWIP_MEM_ALIGN_SIZE(size),    #include "lwip/memp_std.h"};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

memp_sizes的真實(shí)面目如下:

const u16_t memp_sizes[MEMP_MAX] ={    LWIP_MEM_ALIGN_SIZE(sizeof(struct raw_pcb)),    LWIP_MEM_ALIGN_SIZE(sizeof(struct udp_pcb)),    LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_pcb)),    LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)),    LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_seg)),    …….};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

memp_sizes中保存了每種類(lèi)型POOL的大小,這里的大小都是進(jìn)行了內存對
齊的。

3、memp_num[]:

全局數組,用來(lái)記錄每類(lèi)POOL中POOL的個(gè)數,memp.c文件中

const u16_t memp_num[MEMP_MAX]={    #define LWIP_MEMPOOL(name, num, size, desc) (num),    #include "lwip/memp_std.h"};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

memp_num的真實(shí)面目如下:

const u16_t memp_num[MEMP_MAX] ={    MEMP_NUM_RAW_PCB,    MEMP_NUM_UDP_PCB,    MEMP_NUM_TCP_PCB,    MEMP_NUM_TCP_PCB_LISTEN,    MEMP_NUM_TCP_SEG    ……};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上面的MEMP_NUM_RAW_PCB、MEMP_NUM_UDP_PCB等等都是又用戶(hù)
定義的,用來(lái)記錄對應的POOL的數量,用戶(hù)可以在lwipopts.h文件中定義,
LWIP在opt.h中已經(jīng)配置了默認值。

4、memp_desc[]:

全局型指針數組,指向每類(lèi)POOL的描述符,memp.c文件中:

static sonst char *memp_desc[MEMP_MAX]={    #define LWIP_MEMPOOL(name, num, size, desc) (desc),    #include "lwip/memp_std.h"};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

memp_desc的真實(shí)面目如下:

static const char *memp_desc[MEMP_MAX] ={    ("RAW_PCB"),    ("UDP_PCB"),    ("TCP_PCB"),    ("TCP_PCB_LISTEN"),    ("TCP_PCB_LISTEN"),    …….};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

memp_desc中的每個(gè)元素指向了一個(gè)字符串,這些字符串在統計信息輸出中
可能用到。

5、memp_memory[]

這是一個(gè)數組,這才是真正的內存池,memp.c文件中

static u8_t memp_memory[MEM_ALIGNMENT - 1    #define LWIP_MEMPOOL(name,num,size,desc) + ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))    #include "lwip/memp_std.h"];
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

memp_memory的真實(shí)面目如下:

static u8_t memp_memory[MEM_ALIGNMENT – 1+((MEMP_NUM_RAW_PCB) * (MEMP_SIZE +MEMP_ALIGN_SIZE(sizeof(struct raw_pcb)) ))+((MEMP_NUM_UDP_PCB) * (MEMP_SIZE +MEMP_ALIGN_SIZE(sizeof(struct udp_pcb)) ))+((MEMP_NUM_TCP_PCB) * (MEMP_SIZE +MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb)) ))……..];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

其中MEMP_SIZE表示需要在每個(gè)POOL頭部預留的空間,LWIP中在某些特殊
場(chǎng)合使用該空間中的值來(lái)對POOL進(jìn)行特殊處理,這里不使用該項功能,所以
MEMP_SIZE為0,。如果使用到MEMP_SIZE的話(huà)也需要對這個(gè)大小進(jìn)行內存對
齊!


五、內存池初始化函數memp_init()

內存池的初始化,主要是為每種內存池建立鏈表memp_tab,其鏈表是逆序的,此外,如果有統計功能使能的話(huà),也記錄了各種內存池的數目
通過(guò)struct memp作為節點(diǎn),以單鏈表的形式串聯(lián)起來(lái)

voidmemp_init(void){  struct memp *memp;  u16_t i, j;  for (i = 0; i < MEMP_MAX; ++i) {    MEMP_STATS_AVAIL(used, i, 0);    MEMP_STATS_AVAIL(max, i, 0);    MEMP_STATS_AVAIL(err, i, 0);    MEMP_STATS_AVAIL(avail, i, memp_num[i]);  }#if !MEMP_SEPARATE_POOLS  memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);  //將內存池起始空間進(jìn)行對齊#endif /* !MEMP_SEPARATE_POOLS */  /* for every pool: */  for (i = 0; i < MEMP_MAX; ++i) {  //依次對每種類(lèi)型的POOL進(jìn)行操作    memp_tab[i] = NULL;  //初始指針為空#if MEMP_SEPARATE_POOLS    memp = (struct memp*)memp_bases[i];#endif /* MEMP_SEPARATE_POOLS */    /* create a linked list of memp elements */    for (j = 0; j < memp_num[i]; ++j) {  //將該類(lèi)所有POOL組成鏈表的形式      memp->next = memp_tab[i];      memp_tab[i] = memp;      memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]#if MEMP_OVERFLOW_CHECK        + MEMP_SANITY_REGION_AFTER_ALIGNED#endif      );  //將每個(gè)POOL的起始處轉換為memp類(lèi)型,以實(shí)現鏈表連接    }  }#if MEMP_OVERFLOW_CHECK  memp_overflow_init();  /* check everything a first time to see if it worked */  memp_overflow_check_all();#endif /* MEMP_OVERFLOW_CHECK */}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

系統初始化時(shí),函數,memp_init是必須被調用的,否則內存池空間將無(wú)效。

下圖是初始化內存池空間示意圖


六、內存池分配函數memp_malloc()

分配過(guò)程是如果memp_tab[]數組中相應鏈表的指針為空,說(shuō)明該類(lèi)型的POOL已經(jīng)沒(méi)有了,分配失??;否則選擇鏈表中的第一個(gè)POOL,并在POOL最開(kāi)始處預留出MEMP_SIZE(這里為0)的空間,最后將有效地址返回給函數調用者。

void *#if !MEMP_OVERFLOW_CHECKmemp_malloc(memp_t type)#else/* memp_t type 輸入參數為需要分配的POOL的類(lèi)型*/memp_malloc_fn(memp_t type, const char* file, const int line)#endif{  struct memp *memp;  SYS_ARCH_DECL_PROTECT(old_level);  //聲明一個(gè)臨界區保護變量  LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);  SYS_ARCH_PROTECT(old_level);  //進(jìn)入臨界區#if MEMP_OVERFLOW_CHECK >= 2  memp_overflow_check_all();#endif /* MEMP_OVERFLOW_CHECK >= 2 */  memp = memp_tab[type];  //獲得對應頭指針指向的POOL  if (memp != NULL) {  //不為空,則說(shuō)明還有空閑的POOL    memp_tab[type] = memp->next;  //頭指針指向下一個(gè)節點(diǎn)#if MEMP_OVERFLOW_CHECK    memp->next = NULL;    memp->file = file;    memp->line = line;#endif /* MEMP_OVERFLOW_CHECK */    MEMP_STATS_INC_USED(used, type);  //增加內存池分配相關(guān)統計量    LWIP_ASSERT("memp_malloc: memp properly aligned",                ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);    memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);//留出預留空間,這里MEMP_SIZE為0,不預留任何空間  } else {    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));    MEMP_STATS_INC(err, type);  //增加內存池分配出錯統計量  }  SYS_ARCH_UNPROTECT(old_level);  //退出臨界區  return memp;  //返回可用空間起始地址}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

七、內存池釋放函數memp_free()

voidmemp_free(memp_t type, void *mem)//兩個(gè)參數,釋放的POOL的類(lèi)型及起始地址{  struct memp *memp;  //聲明臨界區保護變量  SYS_ARCH_DECL_PROTECT(old_level);  if (mem == NULL) {  //釋放地址如果為空,直接返回    return;  }  LWIP_ASSERT("memp_free: mem properly aligned",                ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);  memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);//得到POOL的起始地址  SYS_ARCH_PROTECT(old_level); //進(jìn)入臨界區#if MEMP_OVERFLOW_CHECK#if MEMP_OVERFLOW_CHECK >= 2  memp_overflow_check_all();#else  memp_overflow_check_element_overflow(memp, type);  memp_overflow_check_element_underflow(memp, type);#endif /* MEMP_OVERFLOW_CHECK >= 2 */#endif /* MEMP_OVERFLOW_CHECK */  MEMP_STATS_DEC(used, type);  //減少內存池分配相關(guān)的統計量  memp->next = memp_tab[type];  //將POOL插入到memp_tab[頭部]  memp_tab[type] = memp;#if MEMP_SANITY_CHECK  LWIP_ASSERT("memp sanity", memp_sanity());#endif /* MEMP_SANITY_CHECK */  SYS_ARCH_UNPROTECT(old_level);  //退出臨界區}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
lwip之內存管理
lwip
說(shuō)說(shuō)樓宇安防視頻監控系統的設計與優(yōu)化
嵌入式以太網(wǎng):Lwip內存管理之內存堆
LwIP在stm32上的無(wú)操作系統移植
如何使用STM32CubeMX配置ETH(RMII)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久