Aurix TC387 Ethernet代码解析之七_MAC的LwIP初始化4

1、原始代码

代码位置1: ...\Ethernet_TC387_Example\Cpu0_Main.c

cs 复制代码
void core0_main(void)
{
    ...

    /* Define a MAC Address */
    eth_addr_t ethAddr;
    ethAddr.addr[0] = 0xDE;
    ethAddr.addr[1] = 0xAD;
    ethAddr.addr[2] = 0xBE;
    ethAddr.addr[3] = 0xEF;
    ethAddr.addr[4] = 0xFE;
    ethAddr.addr[5] = 0xED;

    Ifx_Lwip_init(ethAddr);      /* Initialize LwIP with the MAC address   */
    ...
}

代码位置2: ...\Ethernet_TC387_Example\Libraries\Ethernet\lwip\port\src\Ifx_Lwip.c

cs 复制代码
/** \brief Runtime structure of the AURIX LWIP stack */
typedef struct
{
    netif_t    netif;
#if LWIP_DHCP
    dhcp_t     dhcp;
#endif
    eth_addr_t eth_addr;
    struct
    {
        uint16 arp;
#if LWIP_DHCP
        uint16 dhcp_coarse;
        uint16 dhcp_fine;
#endif
        uint16 tcp_fast;
        uint16 tcp_slow;
        uint16 link;
    }               timer;

    volatile uint16 timerFlags;
} Ifx_Lwip;

Ifx_Lwip    g_Lwip;

/ * The followings are executed: */
void Ifx_Lwip_init(eth_addr_t ethAddr)
{
    ...

    /** - initialise and add a \ref netif */
    g_Lwip.eth_addr = ethAddr;
    netif_add(&g_Lwip.netif, &default_ipaddr, &default_netmask, &default_gw,
        (void *)0, ifx_netif_init, ethernet_input);

    ...
}

2、概念说明

3、代码解析

3.1、MAC地址赋值

3.1.1、原始代码

cs 复制代码
ethAddr.addr[0] = 0xDE;
ethAddr.addr[1] = 0xAD;
ethAddr.addr[2] = 0xBE;
ethAddr.addr[3] = 0xEF;
ethAddr.addr[4] = 0xFE;
ethAddr.addr[5] = 0xED;

g_Lwip.eth_addr = ethAddr;

3.1.2、代码说明

即将0xDE、0xAD、0xBE、0xEF、0xFE、0xED赋值给g_Lwip.eth_addr。

3.2、增加网络接口

3.2.1、原始代码

cs 复制代码
netif_add(&g_Lwip.netif, &default_ipaddr, &default_netmask, &default_gw,
(void *)0, ifx_netif_init, ethernet_input);
cs 复制代码
IP4_ADDR(&default_gw, 192,168,3,1);
IP4_ADDR(&default_ipaddr, 192,168,3,123);
IP4_ADDR(&default_netmask, 255,255,255,0);
cs 复制代码
struct netif *
netif_add(struct netif *netif,
          const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
          void *state, netif_init_fn init, netif_input_fn input)
{

  LWIP_ASSERT_CORE_LOCKED();

  LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL);
  LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL);

  if (ipaddr == NULL) {
    ipaddr = ip_2_ip4(IP4_ADDR_ANY);
  }
  if (netmask == NULL) {
    netmask = ip_2_ip4(IP4_ADDR_ANY);
  }
  if (gw == NULL) {
    gw = ip_2_ip4(IP4_ADDR_ANY);
  }

  /* reset new interface configuration state */
  ip_addr_set_zero_ip4(&netif->ip_addr);
  ip_addr_set_zero_ip4(&netif->netmask);
  ip_addr_set_zero_ip4(&netif->gw);
  netif->output = netif_null_output_ip4;

  NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
  netif->mtu = 0;
  netif->flags = 0;

  memset(netif->client_data, 0, sizeof(netif->client_data));

  /* remember netif specific state information data */
  netif->state = state;
  netif->num = netif_num;
  netif->input = input;

  netif_set_addr(netif, ipaddr, netmask, gw);

  /* call user specified initialization function for netif */
  if (init(netif) != ERR_OK) {
    return NULL;
  }

  /* Assign a unique netif number in the range [0..254], so that (num+1) can
     serve as an interface index that fits in a u8_t.
     We assume that the new netif has not yet been added to the list here.
     This algorithm is O(n^2), but that should be OK for lwIP.
     */
  {
    struct netif *netif2;
    int num_netifs;
    do {
      if (netif->num == 255) {
        netif->num = 0;
      }
      num_netifs = 0;
      for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {
        LWIP_ASSERT("netif already added", netif2 != netif);
        num_netifs++;
        LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);
        if (netif2->num == netif->num) {
          netif->num++;
          break;
        }
      }
    } while (netif2 != NULL);
  }
  if (netif->num == 254) {
    netif_num = 0;
  } else {
    netif_num = (u8_t)(netif->num + 1);
  }

  /* add this netif to the list */
  netif->next = netif_list;
  netif_list = netif;

  mib2_netif_added(netif);

  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
                            netif->name[0], netif->name[1]));
  LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
  ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
  ip4_addr_debug_print(NETIF_DEBUG, netmask);
  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
  ip4_addr_debug_print(NETIF_DEBUG, gw);

  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));

  netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);

  return netif;
}

3.2.2、代码说明

① LWIP_ASSERT_CORE_LOCKED();

cs 复制代码
#if !defined LWIP_ASSERT_CORE_LOCKED || defined __DOXYGEN__
#define LWIP_ASSERT_CORE_LOCKED()
#endif

啥也没干

② LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL);

cs 复制代码
/* if "expression" isn't true, then print "message" and execute "handler" expression */
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
  LWIP_PLATFORM_ERROR(message); handler;}} while(0)
#endif /* LWIP_ERROR */

如果netif != NULL是假的(即网络接口是没有的),则输出信息"netif_add: invalid netif"。反之返回NULL,即什么也不干。因为入口传入参数&g_Lwip.netif,故意味着什么也不干。

③ LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL);

如果init != NULL是假的(即网络接口初始化没做),则输出信息"netif_add: No init function given"。反之返回NULL,即什么也不干。因为入口传入参数ifx_netif_init,故意味着什么也不干。

④ if (ipaddr == NULL) { ipaddr = ip_2_ip4(IP4_ADDR_ANY);}

if (netmask == NULL) { netmask = ip_2_ip4(IP4_ADDR_ANY);}

if (gw == NULL) { gw = ip_2_ip4(IP4_ADDR_ANY);}

cs 复制代码
#define IPADDR_ANY ((u32_t)0x00000000UL)
#define IPADDR4_INIT(u32val) { u32val }
#define IP4_ADDR_ANY (&ip_addr_any)
const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);

即如果IP地址、子网掩码地址和网关地址为NULL时,则各自赋值0x00000000,即地址都为0.0.0.0.

因为本例传入参数default_gw(192,168,3,1)、default_ipaddr(192,168,3,123)、default_netmask(255,255,255,0)都不为NULL,故不会进入if的条件。

⑤ ip_addr_set_zero_ip4(&netif->ip_addr);ip_addr_set_zero_ip4(&netif->netmask);

ip_addr_set_zero_ip4(&netif->gw);

cs 复制代码
#define ip_addr_set_zero_ip4(ipaddr)            ip4_addr_set_zero(ipaddr)
#define ip4_addr_set_zero(ipaddr)     ((ipaddr)->addr = 0)

初始化netif结构体中的IP地址、子网掩码地址和网关地址为0.0.0.0

⑥ netif->output = netif_null_output_ip4;

cs 复制代码
static err_t
netif_null_output_ip4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
{
  LWIP_UNUSED_ARG(netif);
  LWIP_UNUSED_ARG(p);
  LWIP_UNUSED_ARG(ipaddr);

  return ERR_IF;
}
#endif /* LWIP_IPV4 */

不支持IP4情况下处理为void,并返回ERR_IF。暂未理解含义。

⑦ NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);

cs 复制代码
#define LWIP_CHECKSUM_CTRL_PER_NETIF    0

#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)

#if LWIP_CHECKSUM_CTRL_PER_NETIF
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \
  (netif)->chksum_flags = chksumflags; } while(0)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0))
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */

因为LWIP_CHECKSUM_CTRL_PER_NETIF定义为0,故此代码啥也没干。

⑧ netif->mtu = 0;netif->flags = 0;

最大传输初始化为0,标志位初始化为0

⑨ memset(netif->client_data, 0, sizeof(netif->client_data));

指向用户数据

⑩ netif->state = state;netif->num = netif_num;netif->input = input;

state传入参数是0;static u8_t netif_num;外部传入;ethernet_input传入input

① struct netif *netif2;

定义网路接口2

② int num_netifs;

定义网络接口数量变量

③ do { if (netif->num == 255) {netif->num = 0;} num_netifs = 0;for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {LWIP_ASSERT("netif already added", netif2 != netif);num_netifs++;

LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);if (netif2->num == netif->num) {netif->num++;break;}}} while (netif2 != NULL);

相关推荐
梁朝辉4 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者5 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间6 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious6 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng10 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计11 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机
☆cwlulu1 天前
调试排查工具介绍(gdb、strace、Valgrind等)
开发语言·c++·嵌入式硬件·ubuntu
lzqrzpt1 天前
LED驱动电源选型标准与工程应用技术要点解析
python·单片机·嵌入式硬件·物联网