【原创】LWIP技术--->答网友问080422

本文探讨了LwIP网络栈中ethernetif_input任务的优先级调整及调试问题,并详细解析了etharp_arp_input函数的工作原理及其修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题一:
我在调试中发现我的程序永远在创建ethernetif_input的任务里出不来了。我的ethernetif_input任务是在low_level_init函数中创建的,于是我把ethernetif_input优先级降到了所有任务中的最低。
(请问应该可以让ethernetif_input是最低的优先级任务吧,我现在任务就只有tcpip任务——优先级为7,LWIP_ENTRY——优先级为10,MAIN_TASK——优先级为3,ethernetif_input——优先级为16。操作系统运行后创建任务MAIN_TASK,在MAIN_TASK中创建LWIP_ENTRY,在LWIP_ENTRY中调用的LwIP最基本的初始化工作函数中有tcpip_init(NULL, NULL);在tcpip_init中创建了tcpip任务——tcpip_thread,然后在设置LwIP,包括添加配置网络接口、建立接收任务等工作的函数中的函数ethernetif_input函数中创建任务ethernetif_input——优先级为16。请教这样的优先级安排没问题吧)。
答:对于你提出来优先级别的问题,我曾经也一直困扰我,不知道哪个任务优先级别高好一点,但是经过一段时间的测试,我把我的优先级别列出来,仅供你参考使用:不是唯一和一定的。
       函数                        优先级
tcpip_thread                       6
ethernetif_input                  7
LwIPEntry                           20      (这个任务建立了以上两个任务)
也就是说:我整个程序最高的优先级就是6  其他都别 6 和 7 低 应用程序更低
 
问题二:
我降低了ethernetif_input优先级后用PING命令还是无法PING通,在串口输出上没有看到ethernetif_input函数中加的调试输出的东西,我就想我的ethernetif_input函数可能有问题,于是想改为大哥您的那个ethernetif_input函数。在您的函数中发现一个问题。
void ethernetif_input(struct netif *netif)
{
  struct ethernetif *ethernetif;
  struct eth_hdr *ethhdr;
  struct pbuf *p;
 
  while(1)
  {
   ethernetif = netif->state;
   do{
    p = low_level_input(netif);
    if (p == NULL)
     OSTimeDlyHMSM(0,0,0,100);
   }while(p == NULL);
 #if LINK_STATS
   lwip_stats.link.recv++;
 #endif
   ethhdr = p->payload;
    
   switch (htons(ethhdr->type)) {
    case ETHTYPE_IP:
 #if 1
      etharp_ip_input(netif, p); //更新ARP表
 #endif
   //跳过以太网头部字段
      pbuf_header(p, -sizeof(struct eth_hdr));
      //传递到网络层
      netif->input(p, netif);
      break;
      
     case ETHTYPE_ARP:
        //将netif传递到ARP模块
        p = etharp_arp_input(netif, ethernetif->ethaddr, p);
        if(p != NULL) {
         low_level_output(netif, p);
         pbuf_free(p);
        p = NULL;
       }       
        break;
     default:
        pbuf_free(p);
       p = NULL;
        break;
   }       
  }
}
在上面函数中用到了p = etharp_arp_input(netif, ethernetif->ethaddr, p);但是在etharp.c中找到etharp_arp_input函数原型,它为void
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p),是无返回值类型,大哥应该是对函数etharp_arp_input()进行了修改的,能将修改后的函数给我看看吗,返回的是什么呢?
答:原函数如下->
struct pbuf *
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
  struct etharp_hdr *hdr;
  /* these are aligned properly, whereas the ARP header fields might not be */
  struct ip_addr sipaddr, dipaddr;
  u8_t i;
  u8_t for_us;
  LWIP_ASSERT("netif != NULL", netif != NULL);
 
  /* drop short ARP packets */
  if (p->tot_len < sizeof(struct etharp_hdr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F") ", p->tot_len, (s16_t)sizeof(struct etharp_hdr)));
    pbuf_free(p);
    return;
  }
  hdr = p->payload;
 
  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
   * structure packing (not using structure copy which breaks strict-aliasing rules). */
  memcpy((void *)&sipaddr, (void *)&hdr->sipaddr, sizeof(sipaddr));
  memcpy((void *)&dipaddr,(void *) &hdr->dipaddr, sizeof(dipaddr));
  /* this interface is not configured? */
  if (netif->ip_addr.addr == 0) {
    for_us = 0;
  } else {
    /* ARP packet directed to us? */
    for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
  }
  /* ARP message directed to us? */
  if (for_us) {
    /* add IP address in ARP cache; assume requester wants to talk to us.
     * can result in directly sending the queued packets for this host. */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);
  /* ARP message not directed to us? */
  } else {
    /* update the source IP address in the cache, if present */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
  }
  /* now act on the message itself */
  switch (htons(hdr->opcode)) {
  /* ARP request? */
  case ARP_REQUEST:
    /* ARP request. If it asked for our address, we send out a
     * reply. In any case, we time-stamp any existing ARP entry,
     * and possiby send out an IP packet that was queued on it. */
    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request "));
    /* ARP request for our address? */
    if (for_us) {
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address "));
      /* re-use pbuf to send ARP reply */
      hdr->opcode = htons(ARP_REPLY);
      hdr->dipaddr = hdr->sipaddr;
      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
      i = netif->hwaddr_len;
      while(i > 0) {
        i--;
        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
        hdr->shwaddr.addr[i] = ethaddr->addr[i];
        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
      }
      hdr->hwtype = htons(HWTYPE_ETHERNET);
      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
      hdr->proto = htons(ETHTYPE_IP);
      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
      hdr->ethhdr.type = htons(ETHTYPE_ARP);
      /* return ARP reply */
      netif->linkoutput(netif, p);
    /* we are not configured? */
    } else if (netif->ip_addr.addr == 0) {
      /* { for_us == 0 and netif->ip_addr.addr == 0 } */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored. "));
    /* request was not directed to us */
    } else {
      /* { for_us == 0 and netif->ip_addr.addr != 0 } */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us. "));
    }
    break;
  case ARP_REPLY:
    /* ARP reply. We already updated the ARP cache earlier. */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply "));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
    /* DHCP wants to know about ARP replies from any host with an
     * IP address also offered to us by the DHCP server. We do not
     * want to take a duplicate IP address on a single network.
     * @todo How should we handle redundant (fail-over) interfaces?
     * */
    dhcp_arp_reply(netif, &sipaddr);
#endif
    break;
  default:
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F" ", htons(hdr->opcode)));
    break;
  }
  /* free ARP packet */
  pbuf_free(p);
  p =NULL;
  return NULL;
}
 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值