STM32_网络通信

文章目录

    • 初始化底层网卡等配置
    • 写网络通信
      • 进程控制块
      • 联系计网所学UDP网络通信
        • socket()
        • bind()
        • recv()

初始化底层网卡等配置

/* Configure ethernet (GPIOs, clocks, MAC, DMA) */ 
Eth_init();
	/* Initilaize the LwIP stack */
LwIP_Init();

写网络通信

进程控制块

struct udp_pcb {
/* Common members of all PCB types */
  IP_PCB;

/* Protocol specific PCB members */

  struct udp_pcb *next;

  u8_t flags;
  /* ports are in host byte order */
  u16_t local_port, remote_port;
 /* receive callback function
   * addr and port are in same byte order as in the pcb
   * The callback is responsible for freeing the pbuf
   * if it's not used any more.
   *
   * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf
   *            makes 'addr' invalid, too.
   *
   * @param arg user supplied argument (udp_pcb.recv_arg)
   * @param pcb the udp_pcb which received data
   * @param p the packet buffer that was received
   * @param addr the remote IP address from which the packet was received
   * @param port the remote port from which the packet was received
   */
  void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
    struct ip_addr *addr, u16_t port);
  /* user-supplied argument for the recv callback */
  void *recv_arg;  
#if LWIP_IGMP
  /* outgoing network interface for multicast packets */
  struct ip_addr multicast_ip;
#endif /* LWIP_IGMP */

#if LWIP_UDPLITE
  /* used for UDP_LITE only */
  u16_t chksum_len_rx, chksum_len_tx;
#endif /* LWIP_UDPLITE */
};

重点关注结构体中的receive callback 函数

联系计网所学UDP网络通信

STM32_网络通信_第1张图片
STM32_网络通信_第2张图片
在这里,板卡上没有操作系统提供库函数,需要自己定义

socket()
struct udp_pcb * udp_new(void)//相当于自定义的socket
{
  struct udp_pcb *pcb;
  pcb = memp_malloc(MEMP_UDP_PCB);
  /* could allocate UDP PCB? */
  if (pcb != NULL) {
    /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0
     * which means checksum is generated over the whole datagram per default
     * (recommended as default by RFC 3828). */
    /* initialize PCB to all zeroes */
    memset(pcb, 0, sizeof(struct udp_pcb));
    pcb->ttl = UDP_TTL;
  }
  return pcb;
}
bind()

绊定地址和端口号

recv()

第一次接触到这种C语法——函数指针,函数b作为函数A参数,函数A的其他参数可以被函数b直接调用
然后再函数A中将函数b的数据赋值给结构体中的函数指针。

如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。

  void udp_recv(struct udp_pcb *pcb,
         void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                       struct ip_addr *addr, u16_t port),
         void *recv_arg)
{
  /* remember recv() callback and user data */
  pcb->recv = recv;
  pcb->recv_arg = recv_arg;
}
 udp_recv(upcb_debug, udp_echoserver_receive_callback, NULL);

void udp_recv(struct udp_pcb *pcb,
         void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                       struct ip_addr *addr, u16_t port),
         void *recv_arg)
{
  /* remember recv() callback and user data */
  pcb->recv = recv;    //recv为函数指针
  pcb->recv_arg = recv_arg;
}

upcb_debug是udp进程控制块,结构体内定义了函数(?所以才可以被参数函数b调用?)

struct pbuf {
  /** next pbuf in singly linked pbuf chain */
  struct pbuf *next;

  /** pointer to the actual data in the buffer */
  void *payload;
  
  /**
   * total length of this buffer and all next buffers in chain
   * belonging to the same packet.
   *
   * For non-queue packet chains this is the invariant:
   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
   */
  u16_t tot_len;
  
  /** length of this buffer */
  u16_t len;  

  /** pbuf_type as u8_t instead of enum to save space */
  u8_t /*pbuf_type*/ type;

  /** misc flags */
  u8_t flags;

  /**
   * the reference count always equals the number of pointers
   * that refer to this pbuf. This can be pointers from an application,
   * the stack itself, or pbuf->next pointers from a chain.
   */
  u16_t ref;
  
};

你可能感兴趣的:(STM32)