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的更多相关文章

  1. LWIP总结

    介绍 Lwip,light weight IP:是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈:目前已经为全球共同开发的开源协议:支持TCPIP协议族的核心协议:包括:ARP/I ...

  2. LwIP移植和使用

    LwIP移植和使用 本手册基于lwip-1.4.x编写,本人没有移植过1.4.0之前的版本,更早的版本或许有差别.如果看官发现问题欢迎联系<QQ: 937431539  email: 93743 ...

  3. 关于lwip移植到ucsos-ii平台的遇到的问题(一)

    移植的步骤参照<Day_Day_Up笔记之uCOS-II_LwIP_在_STM32F107_上移植>,<uCOS平台下的LwIP移植笔记>,<嵌入式网络那些事>. ...

  4. rt—移植笔记2(Lwip)

    首先参考f107已经有的目录结构添加Lwip这一组,添加各种.c文件及.文件. 还有drive下边的很重要的eth.c 到此,工程编译通过.(刚开始,小编是一个一个 的比对...一个一个错误排查... ...

  5. TCP/IP协议学习(二) LWIP用户自定义配置文件解析

    LWIP协议支持用户配置,可以通过用户裁剪实现最优化配置,LWIP默认包含opts.h作为系统默认配置,不过通过添加lwipopts.h文件并包含在opts.h头文件之前就可以对lwip进行用户裁剪, ...

  6. TCP/IP协议学习(一) LWIP实现网络远程IAP下载更新

    最近需要实现通过TCP/IP远程IAP在线更新功能,忙了2周终于在原有嵌入式服务器的基础上实现了该功能,这里就记录下实现的过程. IAP又称在应用编程,其实说简单点就是实现不需要jlink,仅通过芯片 ...

  7. LWIP协议中tcp_seg结构相关指针的个人理解

    我曾经写在新浪博客上面,后来复制到这,图片就不行了. 原文地址转载  LWIP协议中tcp_seg结构相关指针的个人理解(http://blog.sina.com.cn/s/blog_7e586985 ...

  8. LwIP情景示例

    1. 你使用UDP作为探测包,但被探测的主机不在网络上. 在发送UDP packet之前,LwIP要将其保存下来(分配一个RAM类型的pbuf),并首先发送ARP Request,但得不到回应.如果你 ...

  9. lwip初始化过程

    首先应该看下源码包中的doc/rawapi.txt,这篇文档中介绍了初始化流程. 初始化过程的前半部分主要针对lwip的内存管理和各个协议层,在src/core/init.c中有一个lwip_init ...

  10. Lwip的相关资料

    文件资料 Lwip编程指南 Lwip协议栈的设计与实现 分析Lwip

随机推荐

  1. Maven(四-1) Maven的配置文件settings.xml

    转载于:http://www.cnblogs.com/yakov/archive/2011/11/26/maven2_settings.html 概览 当Maven运行过程中的各种配置,例如pom.x ...

  2. 【转】dijkstra算法

    来自:https://blog.csdn.net/tw_345/article/details/50109375#comments 2015年11月30日 10:55:08 阅读数:1241 说到di ...

  3. dom4j读取XML文件内容

    <?xml version="1.0" encoding="UTF-8"?> <RESULT> <VALUE> <NO ...

  4. gradle 刷新缓存

    gradle build --refresh-dependencies -x test

  5. mysql安装版卸载,解压版安装

    卸载:https://blog.csdn.net/cxy_summer/article/details/70142322 解压版安装:https://blog.csdn.net/recky_wiers ...

  6. wcf将一个服务同时绑定到http和tcp的写法

    服务器端:<?xml version="1.0" encoding="utf-8" ?><configuration>  <con ...

  7. JavaScript Math.floor() 方法

    定义和用法: floor() 方法可对一个数进行下舍入. 语法: Math.floor(x); x:必须参数,可以是任意数值或表达式: 返回值: 小于等于 x,且与 x 最接近的整数. 说明: flo ...

  8. parseInt(string, radix)

    参数 描述 string 必需.要被解析的字符串. radix 可选.表示要解析的数字的基数.该值介于 2 ~ 36 之间. 如果省略该参数或其值为 0,则数字将以 10 为基础来解析.如果它以 “0 ...

  9. PHP(十)字符串

  10. Python + Robotframework + Appium 之APP自动化测试小试牛刀(Android)

    Robotframework如何好?这里先不说了~ Python更不用说了~ Appium前面的文章有介绍~ 今天直接来Python+Robotframework+Appium 三者结合起来,对And ...