Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
关于rtt1.1.0+enc28j60+lwip使用DHCP时IP续约的问题
发布于 2014-07-22 19:44:58 浏览:5922
订阅该版
前面一个帖子(https://club.rt-thread.org/ask/question/3688.html)提到【STM32+RT-Thread+ENC28J60+LWIP用DHCP时网卡不能从掉电模式恢复】的问题,折腾了非常长一段时间,经最新调试发现:dhcp.c中,只有dhcp_timeout和dhcp_t2_timeout会被执行,dhcp_t1_timeout却没有被执行,而dhcp_t1_timeout正是负责dhcp_renew的超时函数,请问这是什么原因?是rtt1.1.0中lwip移植不完善导致的吗? 此外,由于在网卡进入掉电模式后,lwip的dhcp仍然会执行一些需要网络连接的事务,这也是导致我之前遇到网卡掉电后不能正常恢复通信的另一个原因,目前我在以上提到的几个timeout中首先调用enc28j60_powersave_exit()让网卡退出掉电模式后再让dhcp执行后续的网络操作,似乎基本能够正常恢复通信了,但也是此时我才发现dhcp_t1_timeout没有被调用,而dhcp_t2_timeout却被调用了。 求解答。 ``` extern void enc28j60_powersave_exit(void); static void dhcp_timeout(struct netif *netif) { struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout() ")); enc28j60_powersave_exit();/*modified by xhly to solve the enc28j60 powersave problem*/ /* back-off period has passed, or server selection timed out */ if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery ")); dhcp_discover(netif); /* receiving the requested lease timed out */ } else if (dhcp->state == DHCP_REQUESTING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out ")); if (dhcp->tries <= 5) { dhcp_select(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting ")); dhcp_release(netif); dhcp_discover(netif); } #if DHCP_DOES_ARP_CHECK /* received no ARP reply for the offered address (which is good) */ } else if (dhcp->state == DHCP_CHECKING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out ")); if (dhcp->tries <= 1) { dhcp_check(netif); /* no ARP replies on the offered address, looks like the IP address is indeed free */ } else { /* bind the interface to the offered address */ dhcp_bind(netif); } #endif /* DHCP_DOES_ARP_CHECK */ } /* did not get response to renew request? */ else if (dhcp->state == DHCP_RENEWING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out ")); /* just retry renewal */ /* note that the rebind timer will eventually time-out if renew does not work */ dhcp_renew(netif); /* did not get response to rebind request? */ } else if (dhcp->state == DHCP_REBINDING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out ")); if (dhcp->tries <= 8) { dhcp_rebind(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING ")); dhcp_release(netif); dhcp_discover(netif); } } else if (dhcp->state == DHCP_REBOOTING) { if (dhcp->tries < REBOOT_TRIES) { dhcp_reboot(netif); } else { dhcp_discover(netif); } } } /** * The renewal period has timed out. * * @param netif the netif under DHCP control */ static void dhcp_t1_timeout(struct netif *netif) { struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout() ")); enc28j60_powersave_exit(); if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { /* just retry to renew - note that the rebind timer (t2) will * eventually time-out if renew tries fail. */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew ")); /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_RENEWING, not DHCP_BOUND */ dhcp_renew(netif); } } /** * The rebind period has timed out. * * @param netif the netif under DHCP control */ static void dhcp_t2_timeout(struct netif *netif) { struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout() ")); enc28j60_powersave_exit(); if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { /* just retry to rebind */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind ")); /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_REBINDING, not DHCP_BOUND */ dhcp_rebind(netif); } } ```
查看更多
7
个回答
默认排序
按发布时间排序
xhly
2014-07-22
这家伙很懒,什么也没写!
我把路由器的DHCP地址租期设为1min,在超过30s时,lwip并没有续约,而在大约55s(差5s就过期了)时,IP被重新续约;这跟调试时发现只调用了t2却没有调用t1是吻合的
xhly
2014-07-22
这家伙很懒,什么也没写!
哈哈,找到原因了: ``` /** period (in seconds) of the application calling dhcp_coarse_tmr() */ #define DHCP_COARSE_TIMER_SECS 60 //60s为单位,导致t1只有等60+s才会被执行。。。。,改为30就行了 /* temporary DHCP lease? */ if (dhcp->offered_t1_renew != 0xffffffffUL) { /* set renewal period timer */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs ", dhcp->offered_t1_renew)); timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; if(timeout > 0xffff) { timeout = 0xffff; } dhcp->t1_timeout = (u16_t)timeout; if (dhcp->t1_timeout == 0) { dhcp->t1_timeout = 1; } LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs ", dhcp->offered_t1_renew*1000)); } /* set renewal period timer */ if (dhcp->offered_t2_rebind != 0xffffffffUL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs ", dhcp->offered_t2_rebind)); timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; if(timeout > 0xffff) { timeout = 0xffff; } dhcp->t2_timeout = (u16_t)timeout; if (dhcp->t2_timeout == 0) { dhcp->t2_timeout = 1; } LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs ", dhcp->offered_t2_rebind*1000)); } ```
aozima
2014-07-22
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
也就是说 租期 久于两分钟就不会有这个问题是吗?
xhly
2014-07-23
这家伙很懒,什么也没写!
>也就是说 租期 久于两分钟就不会有这个问题是吗? --- 应该是的,因为测试太费时间,所以直接设为最小值1min了,此外也得在执行timeout之前让网卡退出掉电模式
嵌入式工程师
2016-12-17
这家伙很懒,什么也没写!
楼主你好,不知为何我的IP租约在60s时并没有执行续约,能否提供下你的demo? 我现在这样处理才能执行dhcp_t1_timeout(netif); ``` if(timer_expired(&last_dhcp_coarse_time,DHCP_COARSE_TIMER_MSECS/CLOCKTICKS_PER_MS)) { u8_t temp = enc28j60_netif.dhcp->state; enc28j60_netif.dhcp->t1_timeout = 1; enc28j60_netif.dhcp->state = DHCP_RENEWING; dhcp_coarse_tmr(); enc28j60_netif.dhcp->state = temp; } ``` 但这么做很不安全,随意修改DHCP的状态不知道会不会导致状态错乱?
嵌入式工程师
2016-12-19
这家伙很懒,什么也没写!
找到问题所在了,原来我在DHCP获取到IP之后就调用了dhcp_stop(&enc28j60_netif); 这是关闭DHCP的API,不能调用,否则IP无法续约!
撰写答案
登录
注册新账号
关注者
0
被浏览
5.9k
关于作者
xhly
这家伙很懒,什么也没写!
提问
4
回答
16
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【NXP-MCXA153】 定时器驱动移植
2
GD32F450 看门狗驱动适配
3
【NXP-MCXA153】看门狗驱动移植
4
RT-Thread Studio V2.2.9 Release Note
5
CherryUSB的bootuf2配置
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
16
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
9
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部