硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3407|回复: 3
收起左侧

[以太网] RL-TCPnet V7.X支持的以太网原始数据通信,不使用协议栈

[复制链接]

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120448
QQ
发表于 2019-10-21 10:24:09 | 显示全部楼层 |阅读模式


之前多位网友咨询这方面的问题,新版TCPnet这方面做得还是很人性化的。

QQ截图20191021102324.jpg
回复

使用道具 举报

6

主题

85

回帖

103

积分

初级会员

积分
103
发表于 2019-10-21 13:31:42 | 显示全部楼层
这个比较爽,用于板子之间高速差分连接,这个好。
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120448
QQ
 楼主| 发表于 2025-11-27 12:11:08 | 显示全部楼层
Interface Number
Several functions have a parameter if_num, which indicates an instance of the Ethernet or Wifi interface. The interface number is a zero-based number to identify the interface within the Ethernet or WiFi class.

Note
Currently two Ethernet interfaces and two WiFi interfaces are supported, so if_num is set to 0 or 1.


1.png

2.png
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120448
QQ
 楼主| 发表于 2025-11-27 12:23:30 | 显示全部楼层

用户函数 netETH_ReceiveRaw 由以太网接口调用,用于向用户提供原始以太网帧。该数据包含以太网帧头和有效载荷数据。这允许用户实现网络库不支持的附加以太网协议。

当以太网类型不被支持时,网络库会调用此函数。对于支持的以太网类型:ARP(0x0806)、IPv4(0x0800)和 IPv6(0x86dd),则不会调用此函数。

参数 if_num 指定接收帧的以太网接口。

参数 buf 指向包含接收到的以太网帧数据的缓冲区。

参数 len 指定接收到的数据字节数。

[C] 纯文本查看 复制代码
/* ETH Definitions */
#define ETH_MTU             1500        // Ethernet maximum transmission unit
#define ETH_QSIZE           32          // Receive queue size (must be 2^n)

/* ETH Protocol type */
#define ETH_PROT_ARP        0x0806      // Protocol type ARP, RARP
#define ETH_PROT_IP4        0x0800      // Protocol type IPv4
#define ETH_PROT_IP6        0x86dd      // Protocol type IPv6
#define ETH_PROT_VLAN       0x8100      // Protocol type VLAN

/* ETH State flags */
#define ETH_FLAG_PHY_OK     0x01        // Phy initialized successfully
#define ETH_FLAG_POLLING    0x02        // MAC driver in polling mode


[C] 纯文本查看 复制代码
static void eth_iface_run (NET_ETH_CFG *h) {
  NET_FRAME *frame;

  if (sys->Flags & SYS_FLAG_SEC2) {
    /* Sync timings for ETH thread */
    ctrl->th.SecTick = true;
  }
  else if (ctrl->th.ChangeSt) {
    if (ctrl->th.LinkState == ARM_ETH_LINK_UP) {
      DEBUGF (ETH,"Link %d up\n",h->IfNum);
      DEBUG_INFO (ctrl->th.LinkInfo);
      EvrNetETH_LinkUpStatus (h->IfNum, ctrl->th.LinkInfo);
      net_eth_config_mcast (h->IfNum);
      netETH_Notify (h->IfNum, netETH_LinkUp, ctrl->th.LinkInfo);
      if (h->If->Ip4Cfg && !h->If->Ip4Cfg->DhcpCfg) {
        /* Send Gratuitous ARP here if DHCP is disabled */
        net_arp_notify (h->If);
      }
      h->If->State->LinkUp = true;
    }
    else {
      DEBUGF (ETH,"Link %d down\n",h->IfNum);
      EvrNetETH_LinkDownStatus (h->IfNum);
      netETH_Notify (h->IfNum, netETH_LinkDown, 0);
      h->If->State->LinkUp = false;
    }
    ctrl->th.ChangeSt = false;
  }
  /* Check if a frame has been received */
  if (ctrl->q_head == ctrl->q_tail) {
    return;
  }
  sys->Busy = true;
#ifdef ACHILLES_TEST
  if (h->IfNum == 0) eth_test.n_proc++;
#endif

  /* Global parameters for input frame processing */
  sys->RxIpAddr  = NULL;
  sys->RxOffload = h->If->State->Offload;

  DEBUGF (ETH,"*** Process_frame %d ***\n",h->IfNum);
  frame = ctrl->rx_q[ctrl->q_tail & (ETH_QSIZE-1)];
  __COMPILER_BARRIER();
  ctrl->q_tail++;

  EvrNetETH_ReceiveFrame (h->IfNum, frame->length);
  if (ctrl->VlanId != 0) {
    /* VLAN enabled on interface */
    if (!eth_vlan_accept (h, frame)) {
      /* VLAN ID is not ours, dump the frame */
      DEBUGF (ETH," Discarded, VLAN invalid\n");
      EvrNetETH_VlanInvalid (h->IfNum);
      net_mem_free (frame);
      return;
    }
  }
  DEBUG_INF2 (frame->data, frame->length);
  EvrNetETH_ShowFrameHeader (frame->data);

  switch (ntohs(ETH_FRAME(frame)->Prot)) {
    case ETH_PROT_ARP:
      if (!h->If->Ip4Cfg) {
        DEBUGF (ETH," Discarded, %s:IPv4 disabled\n",h->If->Name);
        EvrNetETH_Ip4Disabled (h->IfNum);
        break;
      }
      net_arp_process (h->If, frame);
      break;

    case ETH_PROT_IP4:
      if (!h->If->Ip4Cfg) {
        DEBUGF (ETH," Discarded, %s:IPv4 disabled\n",h->If->Name);
        EvrNetETH_Ip4Disabled (h->IfNum);
        break;
      }
      if (net_mac_comp (ETH_FRAME(frame)->DstAddr, h->MacAddr)) {
        /* Link-layer addressed, destination address our local MAC */
        sys->Flags |= SYS_FLAG_LINKADDR;
      }
      /* Check IPv4 header and update ARP cache */
      if (!net_ip4_chk_frame (h->If, frame)) {
        break;
      }
      /* In NIC teaming mode, which is used for load balancing, all */
      /* broadcasts and multicasts are sent from the Primary NIC.   */
      if (!eth_is_ucast4 (ETH_FRAME(frame)->DstAddr)) {
        /* Add the sender's IP of bc/mc packet to the ARP cache */
        net_arp_cache_add (h->If, IP4_FRAME(frame)->SrcAddr,
                                  ETH_FRAME(frame)->SrcAddr);
      }
      else {
        /* Early cache & resolve sender's IP of unicast packet */
        net_arp_cache_early (h->If, IP4_FRAME(frame)->SrcAddr,
                                    ETH_FRAME(frame)->SrcAddr);
      }
      /* Process fragmented frame reassembly */
      frame = net_ip4_reass_frame (frame);
      if (frame == NULL) {
        /* Reassembly has taken over this frame */
        return;
      }
      /* Now check IPv4 frame protocol type */
      switch (IP4_FRAME(frame)->Prot) {
        case IP4_PROT_ICMP:
          net_icmp_process (h->If, frame);
          break;

        case IP4_PROT_IGMP:
          net_igmp_process (h->If, frame);
          break;

        case IP4_PROT_UDP:
          net_udp_process (h->If, frame, IP_VER4);
          break;

        case IP4_PROT_TCP:
          net_tcp_process (h->If, frame, IP_VER4);
          break;
      }
      break;

    case ETH_PROT_IP6:
#ifdef Network_IPv6
      if (!h->If->Ip6Cfg) {
        DEBUGF (ETH," Discarded, %s:IPv6 disabled\n",h->If->Name);
        EvrNetETH_Ip6Disabled (h->IfNum);
        break;
      }
      /* Check IPv6 header and update Neighbor cache */
      if (!net_ip6_chk_frame (h->If, frame)) {
        break;
      }
      /* Frame is accepted */
      if (!(ETH_FRAME(frame)->DstAddr[0] & 0x01)) {
        /* Refresh unicast sender in neighbor cache */
        if ((IP6_FRAME(frame)->NextHdr == IP6_PROT_UDP) ||
            (IP6_FRAME(frame)->NextHdr == IP6_PROT_TCP)) {
          net_ndp_cache_refresh (h->If, IP6_FRAME(frame)->SrcAddr,
                                        ETH_FRAME(frame)->SrcAddr);
        }
      }
      /* Process fragmented frame reassembly */
      frame = net_ip6_reass_frame (frame);
      if (frame == NULL) {
        /* Reassembly has taken over this frame */
        return;
      }
      /* Now check IPv6 frame protocol type */
      switch (IP6_FRAME(frame)->NextHdr) {
        case IP6_PROT_ICMP:
          net_icmp6_process (h->If, frame);
          break;

        case IP6_PROT_UDP:
          net_udp_process (h->If, frame, IP_VER6);
          break;

        case IP6_PROT_TCP:
          net_tcp_process (h->If, frame, IP_VER6);
          break;
      }
#endif
      break;

    default:
      /* Not supported, unknown Ethernet protocol */
      DEBUGF (ETH," Discarded, Unknown protocol\n");
      EvrNetETH_ProtocolUnknown(h->IfNum, ntohs(ETH_FRAME(frame)->Prot));
      netETH_ReceiveRaw (h->IfNum, frame->data, frame->length);
      break;
  }
  /* Release memory allocated for frame */
  net_mem_free (frame);
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-1-10 17:26 , Processed in 0.046354 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表