完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
第一篇 DHCP自动获取功能的实现
DHCP在电脑中经常用到,因为我们并不关心我们电脑的IP是多少 只要能连上网络就行了。在嵌入式的产品设备中,DHCP用到的比较少,因为很多的操作是通过ip来进行的。除非那种有服务器的系统设备会用到。这里我们只能简单说一下流程,设计的代码太多了,具体的需要学习者自己去慢慢研究。 dhcp模块: dhcp模块用于获取设备ip地址的相关信息。其处理入口主要有这么几个dpch的启动、dpch的接收报文处理以及定时器模块的处理。 主要的接口原型如下: err_t dhcp_start(struct netif *netif) 该接口用于设备启动dhcp模块,主要是客户端的功能。该模块实现设备dhcp描述结构生成,并将dhcp的端口绑定到udp协议中,以及将本dhcp模块跟远端服务器端口进行绑定。最后启动dhcp申请。 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) 该接口为一个注册接口,用于dhcp报文接收。在start dhcp时,该接口通过dhcp的udp pcb注册到udp协议层。Udp进行报文处理后,根据端口调用该注册接口。该接口中,实现dhcp报文的协议处理。 Void dhcp_fine_tmr() Void dhcp_coarse_tmr() 这两个函数接口实现了dhcp的相关超时处理监控。上面一个用于请求应答超时处理。下面一个用于地址租用情况的到期处理。 从源码分析看,上述的接口在应用lwip的协议栈时,需要重点关注。对于小内存应用的场合,该协议栈的内存管理以及pbuf应用部分需要自行改写。 打开工程《科星F107开发板网络应用篇之DHCP自动获取功能》 进入主函数 int main(void) { System_Setup(); LwIP_Init(); while (1) { /* Periodic tasks */ System_Periodic_Handle(); } } 主要看一下 DHCP和静态的时候配置有哪些不同 进入函数LwIP_Init(); void LwIP_Init(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; uint8_t macaddress[6]={0,0,0,0,0,1}; mem_init(); memp_init(); ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; IP 网关 子网掩码 我们设置为0,就是没有值。需要我们自动获取到。 Set_MAC_Address(macaddress);设置MAC地址,这个不管任何时候都要设置。 //创建一个网络接口 netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); netif_set_default(&netif); dhcp_start(&netif);主要是这句,这一句就开始了自动获取的进程,以2,4,8,16秒为间隔,加上1-1000毫秒之间随机长度的时间 netif_set_up(&netif); } DHCP获取IP的简单过程 当DHCP客户机第一次登录网络的时候(也就是客户机上没有任何IP地址数据时),它会通过UDP 67端口向网络上发出一个DHCPDISCOVER数据包(包中包含客户机的MAC地址和计算机名等信息)。因为客户机还不知道自己属于哪一个网络,所以封包的源地址为0.0.0.0,目标地址为255.255.255.255,然后再附上DHCP discover的信息,向网络进行广播。 DHCP discover的等待时间预设为1秒,也就是当客户机将第一个DHCP discover封包送出去之后,在1秒之内没有得到回应的话,就会进行第二次DHCP discover广播。若一直没有得到回应,客户机会将这一广播包重新发送四次(以2,4,8,16秒为间隔,加上1-1000毫秒之间随机长度的时间)。 执行完dhcp_start(&netif);这个函数,开发板就开始和所接的路由器获取IP的进程。 那么我们程序怎么知道是否获取到了没有呢 接着看函数 System_Periodic_Handle(); 进入 void System_Periodic_Handle(void) { GET_DHCP_IP(LocalTime); LwIP_Periodic_Handle(LocalTime); } 进入函数GET_DHCP_IP(LocalTime); void GET_DHCP_IP(__IO uint32_t localtime) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* 250 ms */ if (localtime - DisplayTimer 》= GET_DHCP_MSECS) 每250ms检测一次是否得到IP { DisplayTimer = localtime; /* We have got a new IP address so update the display */ if (IPaddress != netif.ip_addr.addr) { __IO uint8_t iptab[4]; /* Read the new IP address */ IPaddress = netif.ip_addr.addr; iptab[0] = (uint8_t)(IPaddress 》》 24); iptab[1] = (uint8_t)(IPaddress 》》 16); iptab[2] = (uint8_t)(IPaddress 》》 8); iptab[3] = (uint8_t)(IPaddress); if (netif.flags & NETIF_FLAG_DHCP)如果得到IP的话 建立端口连接 { iptab[0] = (uint8_t)(IPaddress 》》 24); iptab[1] = (uint8_t)(IPaddress 》》 16); iptab[2] = (uint8_t)(IPaddress 》》 8); iptab[3] = (uint8_t)(IPaddress); server_init();初始化UDP端口,其实到这里DHCP已经成功了 这里初始化这个端口 是为了增加UDP扫描,以便我们能知道得到的ip是什么。这个函数 还有扫描的功能就不在讲了 前面刚刚讲过。可以自己点进去看一下程序。 } } else if (IPaddress == 0) { if (netif.dhcp-》tries 》 MAX_DHCP_TRIES) 如果是超时进入超时处理 { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw dhcp_stop(&netif); IP4_ADDR(&ipaddr, 192, 168, 1, 8); IP4_ADDR(&netmask, 255, 255, 255, 0); IP4_ADDR(&gw, 192, 168, 1, 1); netif_set_addr(&netif, &ipaddr , &netmask, &gw); } } } 上面的函数主要是检测是不是获取到IP 再看另一个主函数LwIP_Periodic_Handle(LocalTime); 进入 主要看和DHCP有关的两个函数 void LwIP_Periodic_Handle(__IO uint32_t localtime) { /* TCP periodic process every 250 ms */ if (localtime - TCPTimer 》= TCP_TMR_INTERVAL) { TCPTimer = localtime; tcp_tmr(); } /* ARP periodic process every 5s */ if (localtime - ARPTimer 》= ARP_TMR_INTERVAL) { ARPTimer = localtime; etharp_tmr(); } #if LWIP_DHCP /* Fine DHCP periodic process every 500ms */ if (localtime - DHCPfineTimer 》= DHCP_FINE_TIMER_MSECS) { DHCPfineTimer = localtime; dhcp_fine_tmr();请求应答超时处理 }。 /* DHCP Coarse periodic process every 60s */ if (localtime - DHCPcoarseTimer 》= DHCP_COARSE_TIMER_MSECS) { DHCPcoarseTimer = localtime; dhcp_coarse_tmr();地址租用情况的到期处理 } #endif } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 05:38 , Processed in 0.766854 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号