LWIP
LWIP
今天要谈的不是LWIP协议栈的内容,只是简单谈谈关于STM32F407快速使用LWIP做网络通讯的一些经历。
我是一个网络小白,对网络知识一窍不通,仅仅是知道有IP地址、网关这玩意,也从来没有做过嵌入式网络这块内容,那么要如何在2周内实现网络通讯呢,我要实现的功能很简单,只有几十字节的数据量,而且发送不频繁,但是要做到随时拔插网线,随时连接网络,网络中断能尽快连接。
首先,LWIP已经被广泛应用,在网上有很多教程,我个人偏爱上淘宝找,因为在淘宝找对应的开发板,可以快速地验证驱动程序是否能用。我使用的是原子哥的探索者开发板,正点原子的配套教程资料非常齐全,我学stm32也是一路跟着他们的教程走过来的,真心感谢正点原子对嵌入式教育的贡献。这次的实验是把开发板作为TCP的客户端,直接把例程烧到对应的开发板上,非常完美地与服务器通讯了,验证完毕,接下来不要急着去看程序,先去看人家录制的教学视频。第一次看视频的时候,不急于求成,快速浏览一边,知道个大致的框架,如果仔细的看每一个知识点,保证你中途就睡着了。看了第一遍视频后,了解了整个硬件流程,就是STM32F407自带了一个MAC介质层,具体是什么,我也不知道暂时也不用知道,只需要知道LWIP协议栈需要通过MAC层来读取数据,而MAC层的数据是通过几根线,用MII或者RMII协议来从PHY层读取数据,PHY又是什么?同样,不理会它,只要知道这次用的PHY芯片型号叫做LAN8720,听起来这么牛逼的芯片当然要配置一下,这个芯片是通过2根线叫SMI接口与STM32通讯。再然后这个PHY层的数据就是从水晶头(带变压器)那里得来的了。大致流程就是这样。
整理了数据流向后,开始分模块去学习,最开始程序是通过LWIP协议栈读取,这个协议栈是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈,驱动呢就是去人家官网下。然后LWIP怎么操作MAC层,这个是STM32的东西,自然是去ST官网下载MAC的驱动,而操作PHY是通过SMI接口的,这个国际通用的接口ST给出来的驱动有了。到这里用到的文件大致就清楚了。
接下来可以去看程序了,认真的再回去看视频,仔细分析怎么移植这两个驱动文件,不需要明白文件的内容,但必须得知道哪些文件是属于哪个驱动的,这个可以慢慢品味两三天了。了解驱动移植之后就从main函数开始跟踪,去查看怎么实现LWIP和各种硬件的初始化,还有怎么发数据接收数据。
最后开始改造工程,原子哥的例程里,如果上电没有插网线,程序就会死掉,先解决这个最大的问题,如图1-1,这是源程序,初始化一直在死循环,所以把死循环去掉就好。
图1-1
程序是不死了,但是初始化的过程好久啊,那得改一下官方驱动了,如图1-2,把LAN8720初始化等待时间改小了,如图1-3,把LWIP的DHCP等待时间改小了。
图1-2
图1-3
现在速度快了,但是还是不能上电后随时插网线随时上网,后来发现网上说的读取LAN8720的BSR寄存器中的bit2位或者bit4位可以检测网线,那都是鬼扯,我每个位都试过了,发现是bit1位叫jabber检测才有用。通过检测这个可以实现网线拔插的监控,如图1-4是jabber位读取函数。
图1-4
可以正常检测了,但发现连不上网,这个就一言难尽了,需要注意的是原子哥使用的是动态内存管理,有申请就要有释放,可以把动态内存换为静态的,但是要改的地方有点多,也就不想去搞它了,如图1-5,把一直需要用的两个内存申请放外面,不再释放和申请,LWIP内核就初始化一次,因为重复初始化鬼知道它会闹出什么事来,因为LWIP里面也有使用动态内存。
图1-5
最后,tcp_client_open函数就是初始化成功后进去申请一个PCB块的,断网就要释放PCB块太麻烦了,所以我这里把这部分改成了静态的。断网之后其实只要重新申请一个PCB块就能连接上,但是考虑到拔网线很长时间或者重置了路由器,PCB块可能连接不上,所以断网后直接退出tcp_client_open函数,重新进行初始化和DHCP获取。因为我不懂DHCP和LWIP内核,所以经常重连失败,最后瞎摸出几个函数,如图1-6。断网后要断开PCB块的连接,停止DHCP,移除lwip_netif网卡。我也不知道是否正确,这是试出来没有问题的,缺乏理论依据,治标不治本,到最后的最后要去学习一下网络知识,深入学习LWIP内核才能把网络通讯这块灵活运用。
图1-6
以上就是快速上手STM32F407的LWIP网络通讯,首先能粗糙地运用,后面才会有信心去优化,去做得更好,不要一次就最求完美。有空的话就去图书馆看看原子哥推荐的那本书《嵌入式网络那些事:LWIP协议深度剖析与实战演练》作者朱升林。
LWIP的更多相关文章
- LWIP总结
介绍 Lwip,light weight IP:是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈:目前已经为全球共同开发的开源协议:支持TCPIP协议族的核心协议:包括:ARP/I ...
- LwIP移植和使用
LwIP移植和使用 本手册基于lwip-1.4.x编写,本人没有移植过1.4.0之前的版本,更早的版本或许有差别.如果看官发现问题欢迎联系<QQ: 937431539 email: 93743 ...
- 关于lwip移植到ucsos-ii平台的遇到的问题(一)
移植的步骤参照<Day_Day_Up笔记之uCOS-II_LwIP_在_STM32F107_上移植>,<uCOS平台下的LwIP移植笔记>,<嵌入式网络那些事>. ...
- rt—移植笔记2(Lwip)
首先参考f107已经有的目录结构添加Lwip这一组,添加各种.c文件及.文件. 还有drive下边的很重要的eth.c 到此,工程编译通过.(刚开始,小编是一个一个 的比对...一个一个错误排查... ...
- TCP/IP协议学习(二) LWIP用户自定义配置文件解析
LWIP协议支持用户配置,可以通过用户裁剪实现最优化配置,LWIP默认包含opts.h作为系统默认配置,不过通过添加lwipopts.h文件并包含在opts.h头文件之前就可以对lwip进行用户裁剪, ...
- TCP/IP协议学习(一) LWIP实现网络远程IAP下载更新
最近需要实现通过TCP/IP远程IAP在线更新功能,忙了2周终于在原有嵌入式服务器的基础上实现了该功能,这里就记录下实现的过程. IAP又称在应用编程,其实说简单点就是实现不需要jlink,仅通过芯片 ...
- LWIP协议中tcp_seg结构相关指针的个人理解
我曾经写在新浪博客上面,后来复制到这,图片就不行了. 原文地址转载 LWIP协议中tcp_seg结构相关指针的个人理解(http://blog.sina.com.cn/s/blog_7e586985 ...
- LwIP情景示例
1. 你使用UDP作为探测包,但被探测的主机不在网络上. 在发送UDP packet之前,LwIP要将其保存下来(分配一个RAM类型的pbuf),并首先发送ARP Request,但得不到回应.如果你 ...
- lwip初始化过程
首先应该看下源码包中的doc/rawapi.txt,这篇文档中介绍了初始化流程. 初始化过程的前半部分主要针对lwip的内存管理和各个协议层,在src/core/init.c中有一个lwip_init ...
- Lwip的相关资料
文件资料 Lwip编程指南 Lwip协议栈的设计与实现 分析Lwip
随机推荐
- “MSDTC 事务的导入失败: Result Code = 0x8004d00e。
今天搞数据库移植,也把分布式程序移植了一下,一直报上面的错误,差点要重装了 %>_<%,网上看了几篇文章偶然间用DPCPING工具测试了下连接,发现不行.想到host文件的配置,发现其中 ...
- matplotlib —— 添加文本信息(text)
[详细]http://hyry.dip.jp/tech/book/page/scipy/matplotlib_fast_plot.html http://blog.csdn.net/lanchunhu ...
- binary tree
一.中序线索化 二叉树节点定义: class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; int isle ...
- JQuery常用函数及功能
JQuery常用函数及功能小结 来源:http://blog.csdn.net/screensky/article/details/7831000 1.文档加载完成执行函数 $(document).r ...
- ORA-01795: maximum number of expressions in a list is 1000
今天发现查询Oracle用In查询In的元素不可以超过1000个还需要分成多个1000查询记录博客备忘!! Load Test的时候发现这么如下这个错误.... ORA-01795: maximum ...
- basicHttpBinding
表示一个绑定,Windows Communication Foundation (WCF) 服务可以使用此绑定配置和公开能够与基于 ASMX 的 Web 服务和客户端通信的终结点以及符合 WS-I B ...
- static变量和static函数
在C语言编程中,static的一个作用是信息屏蔽! 比方说,你自己定义了一个文件 -- 该文件中有一系列的函数以及变量的声明和定义! 你希望该文件中的一些函数和变量只能被该文件中的函数使用,那么,你可 ...
- JavaScript事件 DOMNodeInserted DOMNodeRemoved
JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定交互的瞬间.可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码. 13.1 事件流 ...
- wCF 问题收集页
1.设置最大序列化集合元素个数 http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.datacontractser ...
- Kubernetes基本原理与示例
1. Kubernetes介绍 基本概念 Pod Pod是Kubernetes的基本操作单元,把相关的一个或多个容器构成一个Pod,通常Pod里的容器运行相同的应用.Pod包含的容器运行在同一个Nod ...