思路
- 参考文章修改bsp,重新新建工程,确保宏定义生效
- 只有callback的宏定义生效,回调函数才能有用
- link down释放所有资源,link up先检测dhcp,如果超时在用静态ip
实现
/* * Xilinx/Vitis lwIP RAW API netif event callback demo. * * BSP requirements: * - standalone OS * - lwip211 RAW_API mode * - lwipopts.h enables: * #define LWIP_NETIF_STATUS_CALLBACK 1 * #define LWIP_NETIF_LINK_CALLBACK 1 * * This demo prints netif up/down, link up/down, and IPv4 address changes over * the UART through xil_printf(). */#include"platform.h"#include"platform_config.h"#include"xil_printf.h"#include"xparameters.h"#include"lwip/init.h"#include"lwip/dhcp.h"#include"lwip/ip4_addr.h"#include"lwip/netif.h"#include"lwip/tcp.h"#include"netif/xadapter.h"#if!defined(LWIP_NETIF_STATUS_CALLBACK)||(LWIP_NETIF_STATUS_CALLBACK!=1)#error"Enable LWIP_NETIF_STATUS_CALLBACK in lwipopts.h"#endif#if!defined(LWIP_NETIF_LINK_CALLBACK)||(LWIP_NETIF_LINK_CALLBACK!=1)#error"Enable LWIP_NETIF_LINK_CALLBACK in lwipopts.h"#endif#if!defined(LWIP_DHCP)||(LWIP_DHCP!=1)#error"Enable LWIP_DHCP in lwipopts.h"#endif#ifndefPLATFORM_EMAC_BASEADDR#error"PLATFORM_EMAC_BASEADDR is not defined. Check platform_config.h."#endif#defineDHCP_TIMEOUT_SLOW_TICKS20U#defineDHCP_COARSE_TIMER_SLOW_TICKS120UexternvolatileintTcpFastTmrFlag;externvolatileintTcpSlowTmrFlag;externvoidtcp_fasttmr(void);externvoidtcp_slowtmr(void);structnetifserver_netif;structnetif_event_state{ip4_addr_told_ip;ip4_addr_told_netmask;ip4_addr_told_gw;u8_told_is_up;u8_told_link_up;};enumip_addr_source{IP_ADDR_SOURCE_UNKNOWN=0,IP_ADDR_SOURCE_DHCP,IP_ADDR_SOURCE_STATIC};staticstructnetif_event_statenetif_state;staticunsignedintdhcp_coarse_timer_tick;staticenumip_addr_sourcecurrent_ip_addr_source=IP_ADDR_SOURCE_UNKNOWN;staticvolatileintlink_down_release_requested;staticvolatileintlink_up_address_probe_requested;staticconstchar*ip_addr_source_name(void){switch(current_ip_addr_source){caseIP_ADDR_SOURCE_DHCP:return"dhcp";caseIP_ADDR_SOURCE_STATIC:return"static";default:return"unknown";}}staticvoidprint_ip4_addr(constchar*name,constip4_addr_t*addr){xil_printf("%s%d.%d.%d.%d",name,ip4_addr1(addr),ip4_addr2(addr),ip4_addr3(addr),ip4_addr4(addr));}staticvoidprint_netif_addr(structnetif*netif){print_ip4_addr(" ip=",netif_ip4_addr(netif));print_ip4_addr(" mask=",netif_ip4_netmask(netif));print_ip4_addr(" gw=",netif_ip4_gw(netif));xil_printf("\r\n");}staticintip4_changed(constip4_addr_t*old_addr,constip4_addr_t*new_addr){return!ip4_addr_cmp(old_addr,new_addr);}staticvoidsave_netif_state(structnetif*netif){ip4_addr_copy(netif_state.old_ip,*netif_ip4_addr(netif));ip4_addr_copy(netif_state.old_netmask,*netif_ip4_netmask(netif));ip4_addr_copy(netif_state.old_gw,*netif_ip4_gw(netif));netif_state.old_is_up=netif_is_up(netif)?1U:0U;netif_state.old_link_up=netif_is_link_up(netif)?1U:0U;}staticvoidnetif_status_callback(structnetif*netif){u8_tis_up=netif_is_up(netif)?1U:0U;intip_changed=ip4_changed(&netif_state.old_ip,netif_ip4_addr(netif));intmask_changed=ip4_changed(&netif_state.old_netmask,netif_ip4_netmask(netif));intgw_changed=ip4_changed(&netif_state.old_gw,netif_ip4_gw(netif));if(is_up!=netif_state.old_is_up){xil_printf("[lwIP] netif %c%c status: %s\r\n",netif->name[0],netif->name[1],is_up?"UP":"DOWN");}if(ip_changed||mask_changed||gw_changed){xil_printf("[lwIP] netif %c%c IPv4 changed:",netif->name[0],netif->name[1]);print_netif_addr(netif);}save_netif_state(netif);}staticvoidnetif_link_callback(structnetif*netif){u8_tlink_up=netif_is_link_up(netif)?1U:0U;if(link_up!=netif_state.old_link_up){xil_printf("[lwIP] netif %c%c link: %s\r\n",netif->name[0],netif->name[1],link_up?"UP":"DOWN");if(link_up){xil_printf("[lwIP] netif %c%c current IPv4 (%s):",netif->name[0],netif->name[1],ip_addr_source_name());print_netif_addr(netif);link_up_address_probe_requested=1;}else{link_down_release_requested=1;}}netif_state.old_link_up=link_up;}staticvoidregister_netif_callbacks(structnetif*netif){save_netif_state(netif);netif_set_status_callback(netif,netif_status_callback);netif_set_link_callback(netif,netif_link_callback);xil_printf("[lwIP] netif %c%c callbacks registered:",netif->name[0],netif->name[1]);print_netif_addr(netif);}staticintservice_lwip(void){intslow_tick=0;if(TcpFastTmrFlag){tcp_fasttmr();TcpFastTmrFlag=0;}if(TcpSlowTmrFlag){tcp_slowtmr();dhcp_fine_tmr();dhcp_coarse_timer_tick++;if(dhcp_coarse_timer_tick>=DHCP_COARSE_TIMER_SLOW_TICKS){dhcp_coarse_timer_tick=0;dhcp_coarse_tmr();}TcpSlowTmrFlag=0;slow_tick=1;}xemacif_input(&server_netif);returnslow_tick;}staticintnetif_has_ipv4_addr(structnetif*netif){returnip4_addr_get_u32(netif_ip4_addr(netif))!=0U;}staticvoidclear_netif_addr_for_dhcp(structnetif*netif){ip4_addr_tzero;IP4_ADDR(&zero,0,0,0,0);current_ip_addr_source=IP_ADDR_SOURCE_UNKNOWN;netif_set_addr(netif,&zero,&zero,&zero);}staticvoidrelease_netif_address(structnetif*netif){xil_printf("[lwIP] link down, release DHCP/address resources\r\n");dhcp_stop(netif);clear_netif_addr_for_dhcp(netif);dhcp_coarse_timer_tick=0;}staticintwait_for_dhcp_or_timeout(structnetif*netif){unsignedinttimeout_ticks=0;xil_printf("[lwIP] DHCP start\r\n");clear_netif_addr_for_dhcp(netif);dhcp_start(netif);while(timeout_ticks<DHCP_TIMEOUT_SLOW_TICKS){if(service_lwip()){timeout_ticks++;}if(!netif_is_link_up(netif)){xil_printf("[lwIP] DHCP stopped: link down\r\n");dhcp_stop(netif);return0;}if(netif_has_ipv4_addr(netif)){current_ip_addr_source=IP_ADDR_SOURCE_DHCP;xil_printf("[lwIP] DHCP acquired:");print_netif_addr(netif);return1;}}xil_printf("[lwIP] DHCP timeout after 10 seconds\r\n");dhcp_stop(netif);return0;}staticvoiduse_static_fallback_addr(structnetif*netif){ip4_addr_tipaddr;ip4_addr_tnetmask;ip4_addr_tgw;IP4_ADDR(&ipaddr,192,168,1,10);IP4_ADDR(&netmask,255,255,255,0);IP4_ADDR(&gw,192,168,1,1);current_ip_addr_source=IP_ADDR_SOURCE_STATIC;netif_set_addr(netif,&ipaddr,&netmask,&gw);xil_printf("[lwIP] static fallback address:");print_netif_addr(netif);}intmain(void){ip4_addr_tipaddr;ip4_addr_tnetmask;ip4_addr_tgw;unsignedcharmac_ethernet_address[]={0x00,0x0A,0x35,0x00,0x01,0x02};init_platform();xil_printf("\r\n");xil_printf("lwIP RAW API netif event callback demo\r\n");lwip_init();IP4_ADDR(&ipaddr,0,0,0,0);IP4_ADDR(&netmask,0,0,0,0);IP4_ADDR(&gw,0,0,0,0);if(!xemac_add(&server_netif,&ipaddr,&netmask,&gw,mac_ethernet_address,PLATFORM_EMAC_BASEADDR)){xil_printf("ERROR: failed to add network interface\r\n");cleanup_platform();return-1;}netif_set_default(&server_netif);register_netif_callbacks(&server_netif);platform_enable_interrupts();netif_set_up(&server_netif);xil_printf("[lwIP] netif set up requested\r\n");if(netif_is_link_up(&server_netif)){link_up_address_probe_requested=1;}xil_printf("[lwIP] waiting for netif status/link/address events...\r\n");while(1){if(link_down_release_requested){link_down_release_requested=0;release_netif_address(&server_netif);}if(link_up_address_probe_requested){link_up_address_probe_requested=0;if(!wait_for_dhcp_or_timeout(&server_netif)){if(netif_is_link_up(&server_netif)){use_static_fallback_addr(&server_netif);}}}service_lwip();}cleanup_platform();return0;}- platform_zynqmp.c里面也要修改,timer_callback函数
/* For detecting Ethernet phy link status periodically */if(DetectEthLinkStatus==ETH_LINK_DETECT_INTERVAL){externstructnetifserver_netif;eth_link_detect(&server_netif);DetectEthLinkStatus=0;}