<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                數據包申請函數pbuf\_alloc()在系統中的許多地方都會用到,例如在網卡接收數據時,需要申請一個數據包,然后將網卡中的數據填入數據包中;在發送數據的時候,協議棧會申請一個pbuf數據包,并將即將發送的數據裝入到pbuf中的數據區域,同時相關的協議首部信息也會被填入到pbuf中的layer區域內,所以pbuf數據包的申請函數幾乎無處不在,存在協議棧于各層之中,當然,在不同層的協議中,layer字段的大小是不一樣的,因為不一樣的協議其首部大小是不同的,這個知識點會在后文講解各協議的時候講解,此處只需了解一下即可。協議棧中各層首部的大小都會被預留出來,LwIP采用枚舉類型的變量將各個層的首部大小記錄下來,在申請的時候就把layer需要空間的大小根據協議進行分配,具體見代碼清單 6?5。 ``` 1 #define PBUF_TRANSPORT_HLEN 20 2 #define PBUF_IP_HLEN 20 3 4 typedef enum 5 { 6 PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + 7 PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN,(1) 8 9 PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + 10 PBUF_LINK_HLEN + PBUF_IP_HLEN, (2) 11 12 PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN, (3) 13 14 PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN, (4) 15 16 PBUF_RAW = 0 (5) 17 } pbuf_layer; ``` (1):傳輸層協議首部內存空間,如UDP、TCP報文協議首部。 (2):網絡層協議首部內存空間,如IP協議。 (3):鏈路層協議首部內存空間,如以太網。 (4)(5): 原始層,不預留空間, PBUF_LINK_ENCAPSULATION_HLEN宏定義默認為0。 數據包申請函數有兩個重要的參數:數據包pbuf的類型和數據包在哪一層被申請。數據包類型就是我們之前講的那四種,數據包在哪一層申請這個參數主要是為了預留各層協議的內存大小,也就是前面所說的layer值,當數據包申請時,所處的層次不同,就會導致預留空間的的layer值不同。 pbuf分配函數pbuf_alloc()的實現具體見: ``` 1 struct pbuf * 2 pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) 3 { 4 struct pbuf *p; 5 u16_t offset = (u16_t)layer; 6 7 switch (type) 8 { 9 case PBUF_REF: /* fall through */ 10 case PBUF_ROM: 11 p = pbuf_alloc_reference(NULL, length, type); (1) 12 break; 13 case PBUF_POOL: (2) 14 { 15 struct pbuf *q, *last; 16 u16_t rem_len; /* remaining length */ 17 p = NULL; 18 last = NULL; 19 rem_len = length; 20 do 21 { 22 u16_t qlen; 23 q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); (3) 24 if (q == NULL) (4) 25 { 26 PBUF_POOL_IS_EMPTY(); 27 /* free chain so far allocated */ 28 if (p) 29 { 30 pbuf_free(p); (5) 31 } 32 /* bail out unsuccessfully */ 33 return NULL; 34 } 35 qlen = LWIP_MIN(rem_len,(u16_t)(PBUF_POOL_BUFSIZE_ALIGNED - 36 LWIP_MEM_ALIGN_SIZE(offset))); (6) 37 pbuf_init_alloced_pbuf(q, LWIP_MEM_ALIGN((void *) 38 ((u8_t *)q + SIZEOF_STRUCT_PBUF + offset)), 39 rem_len, qlen, type, 0); (7) 40 41 if (p == NULL) 42 { 43 /* allocated head of pbuf chain (into p) */ 44 p = q; 45 } 46 else 47 { 48 /* make previous pbuf point to this pbuf */ 49 last->next = q; (8) 50 } 51 last = q; 52 rem_len = (u16_t)(rem_len - qlen); (9) 53 offset = 0; 54 } 55 while (rem_len > 0); (10) 56 break; 57 } 58 case PBUF_RAM: (11) 59 { 60 u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + 61 LWIP_MEM_ALIGN_SIZE(length)); 62 mem_size_t alloc_len = (mem_size_t) 63 (LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len); (12) 64 65 66 if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) || 67 (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) 68 { 69 return NULL; 70 } 71 72 /* If pbuf is to be allocated in RAM, allocate memory for it. */ 73 p = (struct pbuf *)mem_malloc(alloc_len); (13) 74 if (p == NULL) 75 { 76 return NULL; 77 } 78 pbuf_init_alloced_pbuf(p, LWIP_MEM_ALIGN((void *) 79 ((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)), 80 length, length, type, 0); (14) 81 82 break; 83 } 84 default: 85 return NULL; (15) 86 } 87 return p; 88 } ``` (1):根據具體的pbuf類型進行分配,對于PBUF_ROM與PBUF_REF類型的pbuf,只分配pbuf結構體空間大小。 (2):對于PBUF_POOL這種類型的pbuf,可能需要進行分配幾個內存塊才能描述一個數據包。 (3):調用memp_malloc(MEMP_PBUF_POOL)分配內存塊嗎,內存塊類型為MEMP_PBUF_POOL。 (4):分配失敗,可能內存塊已經用完。 (5):如果前面分配內存塊成功,但是這次分配失敗,無法描述一個完整的數據包,則將之前分配的內存塊都釋放掉。 (6):分配成功,得到實際數據區域長度。 (7):初始化pbuf結構體的成員變量。 (8):將這些pbuf連接成pbuf鏈表。 (9):計算存下所有數據需要的長度。 (10):繼續分配內存塊,直到將所有的數據裝下為止 (11):對于PBUF_RAM這種類型的pbuf,內核將從內存堆中申請pbuf。 (12):計算要申請的內存大小。 (13):調用mem_malloc()函數申請內存。 (14):初始化pbuf結構體的成員變量。 (15):類型超出預期,直接返回。 pbuf_alloc()函數的思路很清晰,根據傳入的pbuf類型及協議層次layer,去申請對應的pbuf,就能預留出對應的協議首部空間,對于PBUF_ROM與PBUF_REF類型的pbuf,內核不會申請數據區域,因此,pbuf結構體中payload指針就需要用戶自己去設置,我們通常在申請PBUF_ROM與PBUF_REF類型的pbuf成功后,緊接著就將payload指針指向某個數據區域。 舉個例子,假設TCP協議需要申請一個pbuf數據包,那么就會調用下面代碼進行申請: ``` p = pbuf_alloc(PBUF_TRANSPORT, 1472, PBUF_RAM); ``` 內核就會根據這句代碼進行分配一個PBUF_RAM類型的pbuf,其數據區域大小是1472字節,并且會根據協議層次進行預留協議首部空間,由于是傳輸層,所以內核需要預留54個字節空間,即以太網幀首部長度PBUF_LINK_HLEN(14字節)、IP數據報首部長度PBUF_IP_HLEN(20字節)、TCP首部長度PBUF_TRANSPORT_HLEN(20字節)。當數據報往下層遞交的時候,其他層直接填充對應的協議首部即可,無需對數據進行拷貝等操作,這也是LwIP能快速處理的優勢。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看