以太网IP,UDP协议传输的数据是逐级包含的关系如下图,

以太网帧:

以太网帧头+以太网数据

       IP帧头+IP数据                        ARP数据包      

         ICMP帧头+ICMP数据 / UDP帧头+UDP数据

                         用户数据

 

UDP数据如何被接收的:

  网口芯片有数据后,发出中断给stm32。

  stm32在中断调用ethernet.c中的ethernetif_input(),也传入了当前的netif结构;

  ethernetif_input调用了同一个文件下的low_level_input();

         low_level_output调用了同一个文件下的PacketReceive();

         PacketReceive调用网口芯片接口,读取网口芯片中暂存的1500个数据;申请一个pbuf,将1500个数据存入pbuf,返回该pbuf指针。

  根据返回pbuf指针的payload(帧头:有目的地址,源地址,帧类型),判断帧类型:是IP?ARP?ETHTYPE_PPPOEDISC?还是ETHTYPE_PPPOE?

    判断之后就调用netif->input(),它在初始化时已经注册为etharp.c中的ethernet_input()

    ethernet_input去掉以太帧首部,调用ip.c中的ip_input();

    ip_input调用udp.c中的udp_input();

    udp_input去掉IP首部,调用pcb->recv(),并将以太帧中的用户数据递交,而pcb->recv在初始化时注册为:udp_demo_callback();这样用户程序udp_demo_callback就能获得用户数据。

UDP数据如何发送的:

  用户程序分配tansport类型的pbuf,pbuf中有预留的ethhdr,iphdr,和udphdr,同样也包含了用户数据。调用udp_sendto();

  udp_sendto调用udp.c中的udp_sendto_if(),

  udp_sendto_if填充udp的首部,计算校验和后,调用ip.c中的ip_output_if()

  ip_output_if填充ip的首部,计算校验和,调用netif->output(),而它在ethernetif_init()时,已经注册为etharp.c中的etharp_output();

  etharp_output调用同一文件下的etharp_send_ip()

  etharp_send_ip填充ethhdr后,调用netif->linkoutput(),而它在ethernetif.c的ethernetif_init()时,已经注册为ethernetif.c下的low_level_output()

  low_level_output调用同一文件下的PacketSend();

  PacketSend通过spi接口把数据发送给外部网口。

  

 

例程是基于stm32f103ze的,资源充足是c8的3倍;移植到c8上需要做如下工作:

1、更改spi文件,spi的接口,其中spi总线用到spi1是PA5,PA6,PA7,rst管脚不需要接,针对我的板子,更换cs引脚为PA9

  注意更改spi速率SPI_BaudRatePrescaler。实测256无法连接,改为4就能连接了,这个卡了好久;

2、main,NVIC中的中断使能很多例程都是关断的,作者用的都是查询方式处理,这里可以更改为中断处理,但是要注意while(1)中的处理屏蔽掉

  更改为EXTI_Line1,source更改为A 1,IRQChannnel跟改为EXTI1_IRQn,总之都更改到相应的通道就行。共5个地方

  _IT.c文件中的EXTI_IRQ也更改为相应的名字,还有清楚标志位的语句;共3个地方

3、GPIO初始化函数,A0改为输入,它和NVIC函数共同作用,作为中断

4、更改lwip_init_task中的网关,子网掩码,I;

5、更改lwipopts.h中的选项,MEM_SIZE更改成2*1024,debugprintf选项,opts.h中PBUF_POOL_SIZE改为8

6、lwip,主机ping通板卡,但是板卡ping不到主机,原因很可能是主机防火墙打开了,关闭既能双向ping通