秦九音 发表于 2021-3-9 10:18 牛啊 ,知道关注 |
| 我移植LWIP2.1.2+UCOS II 原子例程里 DHCP获取后不要关闭DHCP也就是dhcp_stop();这个函数即可 只有删除获取的线程 |
| 遇到与楼主一样的问题,dhcp获取地址成功后,netif重置ip为0,无法ping通,还没有找到问题根源....... |
ZHDX 发表于 2019-3-8 12:14 请问移植2.1.2的?跟1.4.1有什么区别?或者说升级怎么升级?能否出一个教程? |
hpdell 发表于 2019-3-8 19:10 我也遇到这个现象,检查了一下是添加网络端口函数:netif_add 内部不正常返回了: struct netif * netif_add(struct netif *netif, #if LWIP_IPV4 const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, #endif /* LWIP_IPV4 */ void *state, netif_init_fn init, netif_input_fn input) { #if LWIP_IPV6 s8_t i; #endif LWIP_ASSERT_CORE_LOCKED(); //我的板子上只有一个网口,在这边直接就return了,就没有了后面的对网络接口netif结构初始化 // #if LWIP_SINGLE_NETIF // if (netif_default != NULL) { // LWIP_ASSERT("single netif already set", 0); // return NULL; // } // #endif LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL); LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL); #if LWIP_IPV4 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; #endif /* LWIP_IPV4 */ #if LWIP_IPV6 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { ip_addr_set_zero_ip6(&netif->ip6_addr); netif->ip6_addr_state = IP6_ADDR_INVALID; #if LWIP_IPV6_ADDRESS_LIFETIMES netif->ip6_addr_valid_life = IP6_ADDR_LIFE_STATIC; netif->ip6_addr_pref_life = IP6_ADDR_LIFE_STATIC; #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ } netif->output_ip6 = netif_null_output_ip6; #endif /* LWIP_IPV6 */ NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL); netif->mtu = 0; netif->flags = 0; #ifdef netif_get_client_data memset(netif->client_data, 0, sizeof(netif->client_data)); #endif /* LWIP_NUM_NETIF_CLIENT_DATA */ #if LWIP_IPV6 #if LWIP_IPV6_AUTOCONFIG /* IPv6 address autoconfiguration not enabled by default */ netif->ip6_autoconfig_enabled = 0; #endif /* LWIP_IPV6_AUTOCONFIG */ nd6_restart_netif(netif); #endif /* LWIP_IPV6 */ #if LWIP_NETIF_STATUS_CALLBACK netif->status_callback = NULL; #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK netif->link_callback = NULL; #endif /* LWIP_NETIF_LINK_CALLBACK */ #if LWIP_IGMP netif->igmp_mac_filter = NULL; #endif /* LWIP_IGMP */ #if LWIP_IPV6 && LWIP_IPV6_MLD netif->mld_mac_filter = NULL; #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ #if ENABLE_LOOPBACK netif->loop_first = NULL; netif->loop_last = NULL; #endif /* ENABLE_LOOPBACK */ /* remember netif specific state information data */ netif->state = state; netif->num = netif_num; netif->input = input; NETIF_RESET_HINTS(netif); #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS netif->loop_cnt_current = 0; #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ #if LWIP_IPV4 netif_set_addr(netif, ipaddr, netmask, gw); #endif /* LWIP_IPV4 */ /* call user specified initialization function for netif */ if (init(netif) != ERR_OK) { return NULL; } #if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES /* Initialize the MTU for IPv6 to the one set by the netif driver. This can be updated later by RA. */ netif->mtu6 = netif->mtu; #endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */ #if !LWIP_SINGLE_NETIF /* 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; #endif /* "LWIP_SINGLE_NETIF */ mib2_netif_added(netif); #if LWIP_IGMP /* start IGMP processing */ if (netif->flags & NETIF_FLAG_IGMP) { igmp_start(netif); } #endif /* LWIP_IGMP */ LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP", netif->name[0], netif->name[1])); #if LWIP_IPV4 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); #endif /* LWIP_IPV4 */ LWIP_DEBUGF(NETIF_DEBUG, ("\n")); netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL); return netif; } |
ZHDX 发表于 2019-3-8 12:14 你好,请教一下,我现在也是使用的是LwIP2.1.2+RTThread的stm32f4环境,在使用TCP通信的最好总是会卡死在read函数大概一分钟左右,知道这是什么问题吗? |
| 你好,我和其他工程师通过不同渠道发现2.1.2版本的快慢定时器存在问题 您使用什么接口编程 raw netconn还是socket? |
lijianh1006 发表于 2019-4-10 22:19 我是自己捣鼓的,跟开发板没有关系的, |
| 请问下,LWIP2.1.2是原子已经做好,还是楼主自己移植的?对应哪款开发板呢? |
|
要找找原因为什么ip地址结构那么长, 产生那么多个0x00000000000000000000了. 目前怀疑这些0x00000000000把IP地址挤掉, 就是产生 0.0.0.0 的元凶. |
ZHDX 发表于 2019-3-9 18:56 ipv6 我没有开启呀 |
|
你的DHCP数据挺反常的. 是不是因为开启了IPv6?? 不然怎么会有那么长串的地址. 我这边活得地址的消息是这么短的 dhcp_bind(): IP: 0x0300a8c0 SN: 0x00ffffff GW: 0x0100a8c0 |
|
另外你可以开启 #define LWIP_DEBUG #define DHCP_DEBUG 0x80U 看看DHCP在搞什么. |
|
DHCP起效果, 那么网卡IP就不应该为0.0.0.0 建议你在DHCP流程的所有步骤里, 都打印一次 printf("netif_ip4_addr(netif) : %s \r\n",ip4addr_ntoa(netif_ip4_addr(netif))); 看看DHCP到底有没有成功修改网卡的地址. 看看哪个环节出问题. 我这边的LWIP配置代码和ethernetif.c全是CubeMX自动生成的 |
|
返回0.0.0.0肯定就是不对的. 这就是所谓的 any 地址. 你有没有定义默认IP? 有没有使用DHCP? 如果使用DHCP, 有没有等待DHCP成功获取IP? |
本帖最后由 hpdell 于 2019-3-8 20:47 编辑 ZHDX 发表于 2019-3-8 12:14 你好,我的 打印出来的IP 地址为 printf("netif_ip4_addr(netif) : %s \r\n",ip4addr_ntoa(netif_ip4_addr(netif))); netif_ip4_addr(netif) : 0.0.0.0 // LwIP V2.1.x 版本里面输出的是貌似全部都是 0 ??????????、 输出地址为0 的话,是哪个地方没有设置对呀 ?? LwIP V2.0.x 版本里面输出的是 netif_ip4_addr(netif) : 245.9.9.9 这个IP,但是数据收发正常 // 我的 socket udp 相关函数如下 // socket udp 连接初始化,开发板初始化为服务器端 uint8_t Socket_UDP_ServerConnectInit(void) { int ret; //,err; struct sockaddr_in ServerAddr; USART_OS_Printf("%s\n", "STATUS isconnected ...\r\n"); TCP_CONNECT_BREAK_FLAG; while(1) { //第一步: 创建socket对象 xSocket.s = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//IPV4 SOCK_DGRAM 数据报套接字(UDP协议) //IPPROTO_UDP //当第三个参数为 0时,自动选择协议 if(xSocket.s == -1 ){ continue; } //第二步: 创建网络通信对象,绑定客户端 ip 及端口 memset(&ServerAddr, 0, sizeof(ServerAddr)); ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(TCP_LOCAL_PORT ); // 服务器端绑定的是本地端口 ServerAddr.sin_addr.s_addr = //htonl(INADDR_ANY); // 服务器端绑定的是本地任意ip地址 inet_addr(ip4addr_ntoa((const ip4_addr_t *) & lwipdev.Local_IpAddr[0])); /* socket udp 设置的是本地的 ip 地址及端口号 也可以使用 htonl(INADDR_ANY); */ //第三步: 开发板为服务器端绑定Socket对象,本地IP与端口号链接 ret = bind(xSocket.s, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); // 服务器端绑定的是本地任意ip地址 if(0 > ret) //说明绑定失败 ? { USART_OS_Printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); // ???? lwip_close(xSocket.s); // close(xClientSocket.s); return 2; } else // 绑定成功 { ClientAddr.sin_family = AF_INET; ClientAddr.sin_port = htons(TCP_REMOTE_PORT); // 连接客户端的端口 ,开发板为服务器端,客户端即是远程端了 ClientAddr.sin_addr.s_addr = inet_addr(ip4addr_ntoa((const ip4_addr_t *) & lwipdev.Remote_IpAddr[0])); // 连接客户端 IP // err = connect(xSocket.s, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr)); // 连接远程ip地址,这个连接不需要,只需要上面的设置即可 // if(err == ERR_OK) { TCP_CONNECT_SUCCESS_FLAG; USART_OS_Printf("远程 IP:%d.%d.%d.%d Port:%d\r\n", // Remote lwipdev.Remote_IpAddr[0], lwipdev.Remote_IpAddr[1], lwipdev.Remote_IpAddr[2], lwipdev.Remote_IpAddr[3], TCP_REMOTE_PORT); USART_OS_Printf("本地 IP:%d.%d.%d.%d Port:%d\r\n", // Local lwipdev.Local_IpAddr[0], lwipdev.Local_IpAddr[1], lwipdev.Local_IpAddr[2], lwipdev.Local_IpAddr[3], TCP_LOCAL_PORT); USART_OS_Printf("%s\n", "STATUS:Connect OK\n"); } break ; // 连接成功后退出 } } return 0; // 成功 } //服务器端接收,也就是开发板端,电脑端为客户端 void Socket_UDP_ServerRX(void) { if(ReadConnectStatus()) // 如果连接成功才运行程序 { CPU_SR_ALLOC(); int _s; socklen_t len; { len = sizeof(ClientAddr); //返回值:以字节计数的消息长度,若无可用消息或对方已经按序结束则返回0,出错返回-1. _s = recvfrom(xSocket.s, &Socket_RecvBuf,TCP_RX_BUFSIZE,0,(struct sockaddr*)&ClientAddr,&len); if(_s > 0) //接收的数据 { CPU_CRITICAL_ENTER(); //进入临界段 //打印客户端的 IP 地址 及端口号 // USART_OS_Printf( "receive from Client IP: %s, Port:%d\r\n", inet_ntoa( ClientAddr.sin_addr ), htons(ClientAddr.sin_port)); Socket_RecvBuf[_s] = '\0'; USART_OS_Printf("%s\r\n",Socket_RecvBuf); //打印接收到的数据 CPU_CRITICAL_EXIT(); //退出临界段 } else //if(_s <= 0) // 客户端断开, 为0时为超时,小于0时为错误 { } } } } const char *Socket_SendBuf = "LwIP RTOS STM32F7 Socket udp Server demo send data\r\n"; //服务器端发送,也就是开发板端,电脑端为客户端 void Socket_UDP_ServerTX(void) { volatile u8 _KeyCode; if(ReadConnectStatus()) // 如果连接成功才运行程序 { socklen_t len; TCA6424_KeyScan(); //这个是 FreeRTOS 系统没有启动前调用的 _KeyCode = TCA6424_GetKey(); if(_KeyCode != KEY_NONE) { if(_KeyCode == KEY_DOWN_UP) // 确认键按下,发送数据 { int err; len = sizeof(ClientAddr); err = sendto( xSocket.s, Socket_SendBuf, strlen((char*)Socket_SendBuf), 0, (struct sockaddr*)&ClientAddr, len ); if(err > 0) { USART_OS_Printf("lwip socket send state OK = %d\r\n", err); } else { USART_OS_Printf("lwip socket send state ERR = %d ?\r\n", err); } } } } } |
ZHDX 发表于 2019-3-8 12:14 好的,我试试看 你使用的也是 socket 的 udp 吗 ? |
|
我现在用的就是 2.1.2 完全没问题. 建议你那个函数执行的时候, 输出一下地址: printf("netif_ip4_addr(netif_default) : %s \r\n",ip4addr_ntoa(netif_ip4_addr(netif_default))); 我这边显示的是: netif_ip4_addr(netif_default) : 192.168.0.3 很正常, ip4_addr_isany_val的逻辑不会出现问题. |
ZHDX 发表于 2019-3-8 11:06 你好,我的 IP 地址设置为 192.168.3.3 struct netif LWIP_Netif_Handle; // netif 是这样定义的, struct netif * ip4_route(const ip4_addr_t *dest) { #if !LWIP_SINGLE_NETIF struct netif *netif; LWIP_ASSERT_CORE_LOCKED(); #if LWIP_MULTICAST_TX_OPTIONS /* Use administratively selected interface for multicast by default */ if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { return ip4_default_multicast_netif; } #endif /* LWIP_MULTICAST_TX_OPTIONS */ /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */ LWIP_UNUSED_ARG(dest); /* iterate through netifs */ NETIF_FOREACH(netif) { /* is the netif up, does it have a link and a valid address? */ if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { /* network mask matches? */ if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { /* return netif on which to forward IP packet */ return netif; } /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { /* return netif on which to forward IP packet */ return netif; } } } ... ... } |
hpdell 发表于 2019-3-8 10:20 你要访问的IP是多少? netif设置的是多少? 前面这段话没返回你的netif吗?? /* iterate through netifs */ NETIF_FOREACH(netif) { /* is the netif up, does it have a link and a valid address? */ if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { /* network mask matches? */ if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { /* return netif on which to forward IP packet */ return netif; } /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { /* return netif on which to forward IP packet */ return netif; } } } |
ZHDX 发表于 2019-3-6 23:08 你好,我这个程序之前使用 LwIP V2.0.x 版本的是完全可以的,sys_arch.c 这个也没有更改过 应用层的驱动也都完全一样,只是 升级了 LwIP 的底层驱动而且,根据最新的 仿真结果查看如下: #define IPADDR_ANY ((u32_t)0x00000000UL) #define INADDR_ANY IPADDR_ANY #define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr) #define ip4_addr_isany_val(addr1) ((addr1).addr == IPADDR_ANY) #define ip_2_ip4(ipaddr) (ipaddr) #define netif_ip4_addr(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr))) if(!ip4_addr_isany_val(*netif_ip4_addr(netif))) // 问题就出现在这句上了 ?????????????? 这句对应的代码如下 : 进一步查看发现是这句 !ip4_addr_isany_val(*netif_ip4_addr(netif)) 这个条件不成立 ? 这句 绕了一大圈 ip4_addr_isany_val ,他奶奶的,不过还是没有明白 // ****************************************************************************** 我绑定的也是类型的 //第二步: 创建网络通信对象,绑定客户端 ip 及端口 memset(&ServerAddr, 0, sizeof(ServerAddr)); ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(TCP_LOCAL_PORT ); // 服务器端绑定的是本地端口 ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 服务器端绑定的是本地任意ip地址 不知道是不是这个版本 LwIP 的底层有问题呀 ??? |
|
这个代码的意思, 是寻找一个合适的路由吧. 例如你的地址是 192.168.0.2, 路由器地址是 192.168.0.1 , 你访问的IP是 200.200.200.200 , 那么他就会找一个合适的路由. 如果找不到就返回NULL. 你有没有执行 netif_set_default ?? |
|
目前看来,这个 lwip v2.1 版本的使用的人们还很少啊, |
| 帮顶 |
ZHDX 发表于 2019-3-10 13:26 折腾了几天了,哎 还是使用 v2.0.3 版本的好了,这个问题 貌似 他们已经给出了是 bug 了,等他们以后升级再看看吧 |
/1
|手机版|OpenEdv-开源电子网
( 粤ICP备12000418号-1 )
GMT+8, 2026-8-22 17:39
Powered by OpenEdv-开源电子网
© 2001-2030 OpenEdv-开源电子网