在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于DWC_ether_qos的以太網驅動開發(fā)-LWIP的ICMP模塊介紹與PING收發(fā)測

嵌入式USB開發(fā) ? 來源:嵌入式USB開發(fā) ? 作者:嵌入式USB開發(fā) ? 2023-09-18 17:51 ? 次閱讀

本文轉自公眾號歡迎關注
https://mp.weixin.qq.com/s/6MTNop3zBKdQ-gabbWo63Q

一. 前言

ICMP即Internet Control Message Protocol因特網控制消息協議。

ICMP是網絡層協議,IP不可分割的一部分。

ICMP用于報告數據報處理中的錯誤,比如以下情況下時發(fā)送ICMP消息:當數據報無法到達其目的地時,當網關沒有轉發(fā)數據報的緩沖能力時,以及當網關可以指示主機在較短的路由上發(fā)送數據時。

互聯網協議的設計并不是絕對可靠的。ICMP這些控制消息的目的是提供有關通信環(huán)境中問題的反饋,而不是使IP可靠。不能確保數據報的傳遞或控制消息的返回,一些數據報可能無法送達時也沒有任何丟失報告。如果需要可靠的通信,則使用IP的更高級別協議必須實現其自己的可靠性程序。

ICMP消息通常報告數據報處理中的錯誤,且不發(fā)送關于ICMP消息的ICMP消息,否則消息會無限遞歸。此外,ICMP消息只發(fā)送關于處理分段數據報的零分段時的錯誤。(片段零的片段offeset等于零)。

參考

RFC 792

https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml

二. ICMP消息格式

ICMP消息格式

從 ICMP 的報文格式來說,ICMP 是 IP 的上層協議,他是在IP報的基礎上再添加ICMP報格式。但是 ICMP 是分擔了 IP 的一部分功能。所以,他也被認為是與 IP 同層的協議。

圖片

我們這里只關注ICMP部分,ICMP由首部和數據兩部分組成,如下

區(qū)域類型Type代碼Code校驗和Checksum
字節(jié)大小112
區(qū)域首部數據,根據類型不一樣而不一樣,對于ping拆為了16位的ID和16位的序列號
字節(jié)大小4
區(qū)域ICMP數據部分
字節(jié)大小類型不同長度不同

Type和Code如下表

類型TYPE代碼CODE**用途描述 Description**查詢類Query差錯類Error
00Echo Reply——回顯應答(Ping應答)x
30Network Unreachable——網絡不可達x
31Host Unreachable——主機不可達x
32Protocol Unreachable——協議不可達x
33Port Unreachable——端口不可達x
34Fragmentation needed but no frag. bit set——需要進行分片但設置不分片比特x
35Source routing failed——源站選路失敗x
36Destination network unknown——目的網絡未知x
37Destination host unknown——目的主機未知x
38Source host isolated (obsolete)——源主機被隔離(作廢不用)x
39Destination network administratively prohibited——目的網絡被強制禁止x
310Destination host administratively prohibited——目的主機被強制禁止x
311Network unreachable for TOS——由于服務類型TOS,網絡不可達x
312Host unreachable for TOS——由于服務類型TOS,主機不可達x
313Communication administratively prohibited by filtering——由于過濾,通信被強制禁止x
314Host precedence violation——主機越權x
315Precedence cutoff in effect——優(yōu)先中止生效x
40Source quench——源端被關閉(基本流控制)
50Redirect for network——對網絡重定向
51Redirect for host——對主機重定向
52Redirect for TOS and network——對服務類型和網絡重定向
53Redirect for TOS and host——對服務類型和主機重定向
80Echo request——回顯請求(Ping請求)x
90Router advertisement——路由器通告
100Route solicitation——路由器請求
110TTL equals 0 during transit——傳輸期間生存時間為0x
111TTL equals 0 during reassembly——在數據報組裝期間生存時間為0x
120IP header bad (catchall error)——壞的IP首部(包括各種差錯)x
121Required options missing——缺少必需的選項x
130Timestamp request (obsolete)——時間戳請求(作廢不用)x
14Timestamp reply (obsolete)——時間戳應答(作廢不用)x
150Information request (obsolete)——信息請求(作廢不用)x
160Information reply (obsolete)——信息應答(作廢不用)x
170Address mask request——地址掩碼請求x
180Address mask reply——地址掩碼應答

使用wirshark協助解析

圖片

圖片

三. LWIP中ICMP相關代碼分析

這里只看IPV4相關的,IPV6下也有對應的實現。

ipv4/icmp.c

icmp.h

3.1調試打印

可以配置宏ICMP_DEBUG,使能調試打印,一遍跟蹤對應的程序處理過程。

lwipopts.h中配置

#define ICMP_DEBUG LWIP_DBG_ON

3.2數據結構

實現了以下Type

#define ICMP_ER   0    /* echo reply */


#define ICMP_DUR  3    /* destination unreachable */


#define ICMP_SQ   4    /* source quench */


#define ICMP_RD   5    /* redirect */


#define ICMP_ECHO 8    /* echo */


#define ICMP_TE  11    /* time exceeded */


#define ICMP_PP  12    /* parameter problem */


#define ICMP_TS  13    /* timestamp */


#define ICMP_TSR 14    /* timestamp reply */


#define ICMP_IRQ 15    /* information request */


#define ICMP_IR  16    /* information reply */


#define ICMP_AM  17    /* address mask request */


#define ICMP_AMR 18    /* address mask reply */

定義了頭的數據結構

struct icmp_hdr {


PACK_STRUCT_FLD_8(u8_t type);


PACK_STRUCT_FLD_8(u8_t code);


PACK_STRUCT_FIELD(u16_t chksum);


PACK_STRUCT_FIELD(u32_t data);


} PACK_STRUCT_STRUCT;

如果四echo則,ICMP首部后面4字節(jié)數據拆分成id和序列號

struct icmp_echo_hdr {


PACK_STRUCT_FLD_8(u8_t type);


PACK_STRUCT_FLD_8(u8_t code);


PACK_STRUCT_FIELD(u16_t chksum);


PACK_STRUCT_FIELD(u16_t id);


PACK_STRUCT_FIELD(u16_t seqno);


} PACK_STRUCT_STRUCT;

3.3輸入數據流

關鍵代碼是icmp_input

ethernet_input->Type=0x0800 ip4_input-> Protocol=0x01 icmp_input

通過switch處理各種類型

switch (type) {


  case ICMP_ER:

比如對于收到別人的ping請求就是進入

case ICMP_ECHO:

如果是多播地址不響應

然后檢查ICMP頭部至少要8字節(jié)。

然后檢查checksum

最后調用ip4_output_if發(fā)送響應包。

3.4輸出數據流

icmp_dest_unreach

icmp_time_exceeded

都是調用

icmp_send_response

3.5發(fā)送PING

收到響應進入icmp_input的

case ICMP_ER:


    /* This is OK, echo reply might have been parsed by a raw PCB


       (as obviously, an echo request has been sent, too). */


    MIB2_STATS_INC(mib2.icmpinechoreps);


    break

發(fā)送ping可以裸機可以使用raw PCB,帶OS可以使用socket實現

詳見ping.c/h

#include "lwip/opt.h"


#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */


#include "ping.h"


#include "lwip/mem.h"
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "lwip/inet_chksum.h"
#include "lwip/prot/ip4.h"


#if PING_USE_SOCKETS
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include < string.h >
#endif /* PING_USE_SOCKETS */




/**
 * PING_DEBUG: Enable debugging for PING.
 */
#ifndef PING_DEBUG
#define PING_DEBUG     LWIP_DBG_ON
#endif


/** ping receive timeout - in milliseconds */
#ifndef PING_RCV_TIMEO
#define PING_RCV_TIMEO 1000
#endif


/** ping delay - in milliseconds */
#ifndef PING_DELAY
#define PING_DELAY     1000
#endif


/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
#define PING_ID        0xAFAF
#endif


/** ping additional data size to include in the packet */
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif


/** ping result action - no default action */
#ifndef PING_RESULT
#define PING_RESULT(ping_ok)
#endif


/* ping variables */
static const ip_addr_t* ping_target;
static u16_t ping_seq_num;
#ifdef LWIP_DEBUG
static u32_t ping_time;
#endif /* LWIP_DEBUG */
#if !PING_USE_SOCKETS
static struct raw_pcb *ping_pcb;
#endif /* PING_USE_SOCKETS */


/** Prepare a echo ICMP request */
static void
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
  size_t i;
  size_t data_len = len - sizeof(struct icmp_echo_hdr);


  ICMPH_TYPE_SET(iecho, ICMP_ECHO);
  ICMPH_CODE_SET(iecho, 0);
  iecho- >chksum = 0;
  iecho- >id     = PING_ID;
  iecho- >seqno  = lwip_htons(++ping_seq_num);


  /* fill the additional data buffer with some data */
  for(i = 0; i < data_len; i++) {
    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
  }


  iecho- >chksum = inet_chksum(iecho, len);
}


#if PING_USE_SOCKETS


/* Ping using the socket ip */
static err_t
ping_send(int s, const ip_addr_t *addr)
{
  int err;
  struct icmp_echo_hdr *iecho;
  struct sockaddr_storage to;
  size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
  LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);


#if LWIP_IPV6
  if(IP_IS_V6(addr) && !ip6_addr_isipv4mappedipv6(ip_2_ip6(addr))) {
    /* todo: support ICMP6 echo */
    return ERR_VAL;
  }
#endif /* LWIP_IPV6 */


  iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
  if (!iecho) {
    return ERR_MEM;
  }


  ping_prepare_echo(iecho, (u16_t)ping_size);


#if LWIP_IPV4
  if(IP_IS_V4(addr)) {
    struct sockaddr_in *to4 = (struct sockaddr_in*)&to;
    to4- >sin_len    = sizeof(*to4);
    to4- >sin_family = AF_INET;
    inet_addr_from_ip4addr(&to4- >sin_addr, ip_2_ip4(addr));
  }
#endif /* LWIP_IPV4 */


#if LWIP_IPV6
  if(IP_IS_V6(addr)) {
    struct sockaddr_in6 *to6 = (struct sockaddr_in6*)&to;
    to6- >sin6_len    = sizeof(*to6);
    to6- >sin6_family = AF_INET6;
    inet6_addr_from_ip6addr(&to6- >sin6_addr, ip_2_ip6(addr));
  }
#endif /* LWIP_IPV6 */


  err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));


  mem_free(iecho);


  return (err ? ERR_OK : ERR_VAL);
}


static void
ping_recv(int s)
{
  char buf[64];
  int len;
  struct sockaddr_storage from;
  int fromlen = sizeof(from);


  while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
    if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) {
      ip_addr_t fromaddr;
      memset(&fromaddr, 0, sizeof(fromaddr));


#if LWIP_IPV4
      if(from.ss_family == AF_INET) {
        struct sockaddr_in *from4 = (struct sockaddr_in*)&from;
        inet_addr_to_ip4addr(ip_2_ip4(&fromaddr), &from4- >sin_addr);
        IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V4);
      }
#endif /* LWIP_IPV4 */


#if LWIP_IPV6
      if(from.ss_family == AF_INET6) {
        struct sockaddr_in6 *from6 = (struct sockaddr_in6*)&from;
        inet6_addr_to_ip6addr(ip_2_ip6(&fromaddr), &from6- >sin6_addr);
        IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V6);
      }
#endif /* LWIP_IPV6 */


      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
      ip_addr_debug_print_val(PING_DEBUG, fromaddr);
      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" msn", (sys_now() - ping_time)));


      /* todo: support ICMP6 echo */
#if LWIP_IPV4
      if (IP_IS_V4_VAL(fromaddr)) {
        struct ip_hdr *iphdr;
        struct icmp_echo_hdr *iecho;


        iphdr = (struct ip_hdr *)buf;
        iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
        if ((iecho- >id == PING_ID) && (iecho- >seqno == lwip_htons(ping_seq_num))) {
          /* do some ping result processing */
          PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER));
          return;
        } else {
          LWIP_DEBUGF( PING_DEBUG, ("ping: dropn"));
        }
      }
#endif /* LWIP_IPV4 */
    }
    fromlen = sizeof(from);
  }


  if (len == 0) {
    LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeoutn", (sys_now()-ping_time)));
  }


  /* do some ping result processing */
  PING_RESULT(0);
}


static void
ping_thread(void *arg)
{
  int s;
  int ret;


#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
  int timeout = PING_RCV_TIMEO;
#else
  struct timeval timeout;
  timeout.tv_sec = PING_RCV_TIMEO/1000;
  timeout.tv_usec = (PING_RCV_TIMEO%1000)*1000;
#endif
  LWIP_UNUSED_ARG(arg);


#if LWIP_IPV6
  if(IP_IS_V4(ping_target) || ip6_addr_isipv4mappedipv6(ip_2_ip6(ping_target))) {
    s = lwip_socket(AF_INET6, SOCK_RAW, IP_PROTO_ICMP);
  } else {
    s = lwip_socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6);
  }
#else
  s = lwip_socket(AF_INET,  SOCK_RAW, IP_PROTO_ICMP);
#endif
  if (s < 0) {
    return;
  }


  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
  LWIP_ASSERT("setting receive timeout failed", ret == 0);
  LWIP_UNUSED_ARG(ret);


  while (1) {
    if (ping_send(s, ping_target) == ERR_OK) {
      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      ip_addr_debug_print(PING_DEBUG, ping_target);
      LWIP_DEBUGF( PING_DEBUG, ("n"));


#ifdef LWIP_DEBUG
      ping_time = sys_now();
#endif /* LWIP_DEBUG */
      ping_recv(s);
    } else {
      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      ip_addr_debug_print(PING_DEBUG, ping_target);
      LWIP_DEBUGF( PING_DEBUG, (" - errorn"));
    }
    sys_msleep(PING_DELAY);
  }
}


#else /* PING_USE_SOCKETS */


/* Ping using the raw ip */
static u8_t
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
{
  struct icmp_echo_hdr *iecho;
  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(pcb);
  LWIP_UNUSED_ARG(addr);
  LWIP_ASSERT("p != NULL", p != NULL);


  if ((p- >tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) &&
      pbuf_remove_header(p, PBUF_IP_HLEN) == 0) {
    iecho = (struct icmp_echo_hdr *)p- >payload;


    if ((iecho- >id == PING_ID) && (iecho- >seqno == lwip_htons(ping_seq_num))) {
      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
      ip_addr_debug_print(PING_DEBUG, addr);
      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" msn", (sys_now()-ping_time)));


      /* do some ping result processing */
      PING_RESULT(1);
      pbuf_free(p);
      return 1; /* eat the packet */
    }
    /* not eaten, restore original packet */
    pbuf_add_header(p, PBUF_IP_HLEN);
  }


  return 0; /* don't eat the packet */
}


static void
ping_send(struct raw_pcb *raw, const ip_addr_t *addr)
{
  struct pbuf *p;
  struct icmp_echo_hdr *iecho;
  size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;


  LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
  ip_addr_debug_print(PING_DEBUG, addr);
  LWIP_DEBUGF( PING_DEBUG, ("n"));
  LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);


  p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
  if (!p) {
    return;
  }
  if ((p- >len == p- >tot_len) && (p- >next == NULL)) {
    iecho = (struct icmp_echo_hdr *)p- >payload;


    ping_prepare_echo(iecho, (u16_t)ping_size);


    raw_sendto(raw, p, addr);
#ifdef LWIP_DEBUG
    ping_time = sys_now();
#endif /* LWIP_DEBUG */
  }
  pbuf_free(p);
}


static void
ping_timeout(void *arg)
{
  struct raw_pcb *pcb = (struct raw_pcb*)arg;


  LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL);


  ping_send(pcb, ping_target);


  sys_timeout(PING_DELAY, ping_timeout, pcb);
}


static void
ping_raw_init(void)
{
  ping_pcb = raw_new(IP_PROTO_ICMP);
  LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);


  raw_recv(ping_pcb, ping_recv, NULL);
  raw_bind(ping_pcb, IP_ADDR_ANY);
  sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
}


void
ping_send_now(void)
{
  LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
  ping_send(ping_pcb, ping_target);
}


#endif /* PING_USE_SOCKETS */


void
ping_init(const ip_addr_t* ping_addr)
{
  ping_target = ping_addr;


#if PING_USE_SOCKETS
  sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
#else /* PING_USE_SOCKETS */
  ping_raw_init();
#endif /* PING_USE_SOCKETS */
}


#endif /* LWIP_RAW */
#ifndef LWIP_PING_H
#define LWIP_PING_H


#include "lwip/ip_addr.h"


/**
 * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used
 */
#ifndef PING_USE_SOCKETS
#define PING_USE_SOCKETS    LWIP_SOCKET
#endif


void ping_init(const ip_addr_t* ping_addr);


#if !PING_USE_SOCKETS
void ping_send_now(void);
#endif /* !PING_USE_SOCKETS */


#endif /* LWIP_PING_H */

如下是帶OS的測試

ip_addr_t ping_addr;


  IP4_ADDR(&ping_addr, 192, 168, 1, 9);


  ping_init(&ping_addr);

打印如下,(這里printf不支持某些格式所以IP地址打印顯示不對)

圖片

四. 總結

了解ICMP包的格式,了解LWIP發(fā)送ping和對堆ping請求響應的過程。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 以太網
    +關注

    關注

    40

    文章

    5423

    瀏覽量

    171683
  • ICMP
    +關注

    關注

    0

    文章

    52

    瀏覽量

    14928
  • Ping
    +關注

    關注

    0

    文章

    69

    瀏覽量

    15977
  • LwIP
    +關注

    關注

    2

    文章

    86

    瀏覽量

    27166
收藏 人收藏

    評論

    相關推薦

    基于DWC_ether_qos以太網驅動開發(fā)-MAC幀格式介紹

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-MAC幀格式介紹 (qq.com) 一.前言 ? 在
    的頭像 發(fā)表于 08-30 09:23 ?2379次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-MAC幀格式<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發(fā)-MDIO驅動編寫與測試

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-MDIO驅動編寫與測試 一.前言
    的頭像 發(fā)表于 08-30 09:37 ?3762次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-MDIO<b class='flag-5'>驅動</b>編寫與測試

    基于DWC_ether_qos以太網驅動開發(fā)-描述符鏈表介紹

    本文轉自公眾號歡迎關注 一.描述符概述 1.0 前言 對于DWC Ethernet QoS驅動的編寫來說,初始化完成之后,核心操作就是DMA的描述符鏈表配置(linked list
    的頭像 發(fā)表于 08-30 09:39 ?4533次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-描述符鏈表<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發(fā)-數據流驗證過程

    轉自公眾號歡迎關注 https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA 基于DWC_ether_qos以太網驅動開發(fā)-數據流驗證過程
    的頭像 發(fā)表于 08-31 08:41 ?2048次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-數據流驗證過程

    基于DWC_ether_qos以太網驅動開發(fā)-收發(fā)驅動編寫與調試

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-收發(fā)驅動編寫與調試 (
    的頭像 發(fā)表于 09-05 08:47 ?2339次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>收發(fā)</b><b class='flag-5'>驅動</b>編寫與調試

    基于DWC_ether_qos以太網驅動開發(fā)-無OS環(huán)境移植LWIP

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-無OS環(huán)境移植LWIP (qq.com) https://mp.we
    的頭像 發(fā)表于 09-06 08:40 ?1610次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-無OS環(huán)境移植<b class='flag-5'>LWIP</b>

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP的內存池介紹

    本文轉自公眾號,歡迎關注 https://mp.weixin.qq.com/s/mBoGSf_u9edFF01U_OZT9g 一.前言 lwIP為基礎結構提供了專用的內存池管理,比如netconn
    的頭像 發(fā)表于 09-07 08:45 ?1742次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的內存池<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP的堆管理介紹

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-LWIP的堆管理介紹 (
    的頭像 發(fā)表于 09-08 08:40 ?1317次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的堆管理<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP的堆(內存池)未對齊導致問題的案例分享

    本文轉自公眾號歡迎關注 https://mp.weixin.qq.com/s/ErIa2ss2YZLGYbSwoJEzog 一.?前言 內存未對齊訪問問題這個已經是老生常談的問題了, 由于LWIP
    的頭像 發(fā)表于 09-09 08:44 ?1738次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的堆(內存池)未對齊導致問題的案例分享

    基于DWC_ether_qos以太網驅動開發(fā)-RTOS環(huán)境移植LWIP與性能測試

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-RTOS環(huán)境移植LWIP與性能測試 (qq.com) https:
    的頭像 發(fā)表于 09-11 11:20 ?2122次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-RTOS環(huán)境移植<b class='flag-5'>LWIP</b>與性能測試

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP在PC上進行開發(fā)調試

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發(fā)-LWIP在PC上進行開發(fā)
    的頭像 發(fā)表于 09-11 08:40 ?2031次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>在PC上進行<b class='flag-5'>開發(fā)</b>調試

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP的定時器模塊詳解

    一. 前言 LWIP的定時器模塊,實現了通用的軟件定時器,用于內部的周期事件處理,比如arp,tcp的超時等,用戶也可以使用。這一篇來分析該模塊的實現。 二.代碼分析 2.1源碼 源碼
    的頭像 發(fā)表于 09-18 09:33 ?1676次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的定時器<b class='flag-5'>模塊</b>詳解

    基于DWC_ether_qos以太網驅動開發(fā)-LWIP的ARP模塊介紹

    TCP/IP通訊第一步需要先調通ARP,否則TCP/IP包都不知道MAC地址要發(fā)給誰。這一篇來基于LWIP的ARP實現進行相關的分析。
    的頭像 發(fā)表于 09-18 09:34 ?1910次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的ARP<b class='flag-5'>模塊</b><b class='flag-5'>介紹</b>

    設計軟件核心以太網服務質量數據手冊免費下載

    本文描述Synopsys設計軟件核心以太網服務質量DWC以太網QoS核心5.10A。DWC以太網
    發(fā)表于 10-23 08:00 ?16次下載
    設計軟件核心<b class='flag-5'>以太網</b>服務質量數據手冊免費下載

    基于DWC_ether_qos以太網驅動開發(fā)-包過濾

    以太網上數據非常多,如果所有數據都接收交給軟件去處理軟件負載會非常重,所以一般只需要接收發(fā)給自己的數據即可
    的頭像 發(fā)表于 09-02 09:19 ?1783次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>-包過濾
    主站蜘蛛池模板: 黑人xxxx精品| 色婷婷九月| 日韩啪啪网| xxxx69日本hd| 乌克兰毛片| 69久久夜色精品国产69小说| 伊人久久大香线蕉综合网站| 黄色永久免费| 美女被异性狂揉下部羞羞视频 | 女人张开腿等男人桶免费视频| 久久综合免费| www.妖精视频| 手机看片国产在线| 国产精品久久久久久久午夜片| 国产在线观看黄色| 手机在线精品视频| 你懂得视频在线| 手机在线1024| 第四色亚洲| 日本人的色道免费网站| 国产一级做a爰片久久毛片| 午夜神马嘿嘿| 综合7799亚洲伊人爱爱网| 热99精品| 日韩精品免费一区二区三区| 国产人成精品免费视频| 天天干夜夜添| 国产精品久久久久久久9999| 日本亚洲天堂网| 涩色影院| 热久热| 两性色午夜视频免费网| 国产男人午夜视频在线观看| 亚洲国产精品婷婷久久久久| 免费成人看片| 天天操天天干天天插| 亚洲一区不卡视频| 色网站欧美| 99伊人| 免费我看视频在线观看| 日本暴力喉深到呕吐hd|