精华内容
下载资源
问答
  • LWIP

    2019-03-22 11:38:00
    LWIP  今天要谈的不是LWIP协议栈的内容,只是简单谈谈关于STM32F407快速使用LWIP做网络通讯的一些经历。  我是一个网络小白,对网络知识一窍不通,仅仅是知道有IP地址、网关这玩意,也从来没有做过嵌入式网络...

                                          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协议深度剖析与实战演练》作者朱升林。

    转载于:https://www.cnblogs.com/wcw12580/p/10573821.html

    展开全文
  • lwip

    千次阅读 2015-08-25 09:48:02
    PPP from an application perspective ...There are two ways to use lwIP with PPP support. Either PPPoE (PPP over Ethernet) or PPP-over-serial. lwIP supports being run in a threaded environment, where pp

    PPP from an application perspective

    There are two ways to use lwIP with PPP support. Either PPPoE (PPP over Ethernet) or PPP-over-serial. lwIP supports being run in a threaded environment, where ppp is a separate task that runs alongside the main lwIP thread. lwIP also supports being run from a main loop, with lwIP functions being called from the main loop.

    PPP over serial Edit

    To setup a PPP connection over a serial link you will need to provide the Serial IO functions.

    Both the thread environment and a main loop require implemented sio_write() to be implemented.

    /**
     * Writes to the serial device.
     * 
     * @param fd serial device handle
     * @param data pointer to data to send
     * @param len length (in bytes) of data to send
     * @return number of bytes actually sent
     * 
     * @note This function will block until all data can be sent.
     */
    u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);
    


    With Task Support Edit

    In addition to sio_write(), sio_read(), sio_read_abort() and the linkStatusCB are required to be implemented by you. The first 2 functions are statically linked, while the last function is defined through a function pointer (so the name can be different, and could be dynamically created as well).

    The function sio_read() is called from the pppInputThread, repeatedly. It blocks until it fills the requested buffer size or times-out, reading data from the serial device. It must abort itself if there is a call to sio_read_abort(). The soft link between sio_read and sio_read_abort must be implemented by you, either via a global variable, RTOS event, etc. The timeout should be relatively small, just large enough so that data is actually buffered in more than 1 byte chunks but small enough to make the ppp stack responsive. A timeout of about 2 ms is reasonable.

    /**
     * Reads from the serial device.
     * 
     * @param fd serial device handle
     * @param data pointer to data buffer for receiving
     * @param len maximum length (in bytes) of data to receive
     * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
     * 
     */
    u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len);
    

    The sio_read_abort() function must cause the sio_read command to exit immediately. This command is called by the tcpip_thread, mostly when ending a PPP session (terminated, link down or explicit close).

    /**
     * Aborts a blocking sio_read() call.
     * 
     * @param fd serial device handle
     */
    void  sio_read_abort(sio_fd_t fd);
    

    Required callback function Edit

    The callback

     void (*linkStatusCB)(void *ctx, int errCode, void *arg)
    

    is called under the following events:

    • Link Terminated. errCode is nonzero, arg is null.
    • sifup (Interface Up).errCode is PPPERR_NONE, and arg is pointer to ppp_addrs structure, which contains IP address.
    • sifdown (Interace Down). errCode is PPPERR_CONNECT, and arg is null.

    The errCode can be one of the following

    #define PPPERR_NONE      0 /* No error. */
    #define PPPERR_PARAM    -1 /* Invalid parameter. */
    #define PPPERR_OPEN     -2 /* Unable to open PPP session. */
    #define PPPERR_DEVICE   -3 /* Invalid I/O device for PPP. */
    #define PPPERR_ALLOC    -4 /* Unable to allocate resources. */
    #define PPPERR_USER     -5 /* User interrupt. */
    #define PPPERR_CONNECT  -6 /* Connection lost. */
    #define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */
    #define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */
    

    The ctx pointer is an optional user defined pointer that is defined as an argument in the call topppOverSerialOpen, which can point to user defined data.

    With no Task Support Edit

    You need to receive the serial data in your main thread, then from your main thread call

    pppos_input(int pd, u_char* data, int len);
    


    Example Task Application code Edit

    This example shows the initialization of the TCP and PPP threads. It assumes that you will do your socket handling in the context of the main() function.

    
    #include "ppp/ppp.h"
    
    #define PPP_SERIAL_PORT 0
    
    static void linkStatusCB(void* ctx, int errCode, void* arg);
    
    int main(void) {
        int connected = 0;
        int setup = 0;
        int pd;
        const char *username = "myuser";
        const char *password = "mypassword";
        
        /* initialise lwIP. This creates a new thread, tcpip_thread, that 
         * communicates with the pppInputThread (see below) */
        tcpip_init(tcpip_init_done, &setup);
        while (!setup) {
            sleep(1);
        }
    
        /* initialise PPP. This needs to be done only once after boot up, to 
         * initialize global variables, etc. */
        pppInit();
    
        /* set the method of authentication. Use PPPAUTHTYPE_PAP, or
         * PPPAUTHTYPE_CHAP for more security .
         * If this is not called, the default is PPPAUTHTYPE_NONE. 
         */
        pppSetAuth(PPPAUTHTYPE_ANY, username, password);
    
    
    
        /* call the board specific function that will open the specific serial
         * port hardware, for example, configuring pins, I/Os, UART, USART, 
         * clocks, etc. This function is not part of lwip or ppp.  You need to
         * supply this or find an example for your hardware.
         */ 
         OpenMySerialPortOrUART(PPP_SERIAL_PORT, ...);
    
    
    
        /* call the board specific function that will connect to the modem,
         * ie dialing phone numbers, sending configuration AT commands, etc. 
         * This function is not part of lwip or ppp. You need to supply this
        if (DialOutMyModem(PPP_SERIAL_PORT, ...) != 0) {
           printf("can't dial out");
        } else {
             
        /** Open a new PPP connection using the given I/O device.
         * This initializes the PPP control block but does not
         * attempt to negotiate the LCP session.  
         * Return a new PPP connection descriptor on success or
         * an error code (negative) on failure. 
         * This call creates one new thread per call, to service the particular
         * serial port, serviced by the pppInputThread function.
         */
           pd = pppOverSerialOpen(PPP_SERIAL_PORT, linkStatusCB, &connected);
           if (pd >= 0) {
            // the thread was successfully started.
            while (!connected && timeout(60 seconds)) {
              sleep(100 ms);
            }
            
            if (!timeout) {
                // We are connected on lwIP over PPP!
         
                while (working) {
                /* create some socket connections, 
                 * do writes and reads on the sockets, close them, etc */
                }
            }
            /* calling pppClose will end the pppInputThread associated with pd*/
            pppClose(pd);
        }
    
       // shut down the rest of your hardware.
    }
    
    static void tcpip_init_done(void *arg)
    {
        if (arg) {
            *((bool *)arg) = 1;
        }
    }
    
    
    static void linkStatusCB(void *ctx, int errCode, void *arg) {
       //DTRACE("ctx = 0x%04X, errCode = %d arg = 0x%04X", ctx, errCode, arg);
       int *connected = (int *) ctx;
    
       struct ppp_addrs *addrs = arg;
    
    
       if (errCode == PPPERR_NONE) {
           /* We are connected */
           *connected = 1;
           syslog(LOG_DEBUG, "ip_addr = %s", inet_ntoa(addrs->our_ipaddr));
           syslog(LOG_DEBUG, "netmask = %s", inet_ntoa(addrs->netmask));
           syslog(LOG_DEBUG, "dns1    = %s", inet_ntoa(addrs->dns1));
           syslog(LOG_DEBUG, "dns2    = %s", inet_ntoa(addrs->dns2));
       } else {
           /* We have lost connection */
       }
    }
    
    

    Debug Support Edit

    Add this to lwipopts.h

     #define PPP_THREAD_NAME             "ppp"
     #define PPP_THREAD_STACKSIZE    200
     #define PPP_THREAD_PRIO               2
    
    
     #define LWIP_DEBUG              1
     #define PPP_DEBUG               LWIP_DBG_ON
    
    

    PPP support history in lwIPEdit

    HEADUnspecified.
    1.2Unspecified.

    External referencesEdit

    • RFC 1661 The Point-to-Point Protocol (PPP)
    展开全文
  • STM32移植LWIP

    万次阅读 2018-04-06 11:56:50
    本文使用的是STM32F207VCT6平台,MII接口的RTL8201EL网络芯片,LWIP版本是1.4.1基础工程是:已经实现了10ms定时,led灯1s闪烁,还有串口打印欢迎查看本文所在的系列,STM32的LWIP应用,点击跳转本文使用的IDE是IAR7.2...

    目录

    01、IAR工程移植

    02、修改Keil工程


    在上篇文章《LWIP初体验-修改ST官方demo》中我们已经在自己的开发板上实现了简单的TCPsever和TCPclient功能。验证完了硬件,接下来的工作就是优化代码,添加应用程序。

    有些同学想学习一下,如果下载LWIP的代码,然后移植到自己的代码中,下面我们聊聊移植问题。

    我们需要的基础工程是已经实现了10ms定时,led灯1s闪烁,实现了串口打印工程。还需要一份LWIP1.4.1的源码,需要STM32F2系列的以太网驱动。

    移植前和移植后源码资料,还有LWIP的源码下载链接

    链接:https://pan.baidu.com/s/1u-QZye_HB1PAiBOykFlNqQ

    提取码:4hiw

     

    01、IAR工程移植

     

    首先是IAR工程的移植操作。

    添加以太网驱动库,注意,以太网驱动库并不在标准外设库中,需要大家自行到网上或ST官网下载。

    图片

    把以太网驱动库添加进工程

    图片

    增加新库的头文件路径

    图片

    将LWIP源码放入目录中,我的个人习惯放到了Third_Party文件夹中,属于第三方库,以后用到其他类似FATFS这样的第三方库,都会放入次文件夹内。

    图片

    我们把stm32f2x7_eth_conf_template.h文件剪切到文件夹中,并重命名为stm32f2x7_eth_conf.h

    图片

    修改文件名称

    图片

    当然新加的头文件,要添加新的头文件路径。

    图片

    注意:这个文件是只读文件,要把对勾去掉,不然的话在IDE中无法修改代码。

    图片

    添加以太网RTL8201EL的驱动程序

    我们首先拷贝官方历程驱动,这部分主要是硬件层的初始化,在《LWIP初体验-修改ST官方demo》中,我们已经修改完代码,直接拷贝过来就行。

    图片

    放入对应的位置

    图片

    然后把BSP硬件驱动添加进入工程

    图片

    添加lwip源代码,直接按照LWIP源码目录结构添加即可,不用全部添加,按下图所示接口

    图片

    添加API相关文件

    图片

    添加Netif相关文件

    图片

    添加IPV4相关文件

    图片

    当然,还要添加头文件路径,这是必不可少的

    图片

    添加中间文件

    图片

    添加lwipopts.h

    图片

    编译出错

    图片

    这些文件主要是官方开发板的lcd相关文件,把他们屏蔽掉

    图片

    再编译,出新的错误,再次屏蔽这些现实部分的代码。

    图片

    修改之后,编译没有问题

    图片

    复制驱动,直接使用官方demo的文件,

    图片

    拷贝ethernetif.c文件

    图片

    拷贝lwipopts.h文件。

    图片

    把原来的文件删除掉

    图片

    重新添加我们新添加的文件(注意解除只读属性)

    修改文件

    图片

    新建lwip_app.c和lwip_app.h文件

    图片

    添加LwIP_Init函数接口。

    图片

    增加LwIP_Pkt_Handle函数。

    图片

    定义一下宏

    图片

    包头文件包含一下

    图片

    修改函数

    图片

    修改主函数

    图片

    使用PC端ping一下开发板的IP

    图片

    移植成功,可以正常响应ping。

    这只是个简单的移植,就是个流水账,想看具体修改内容的,可以到文章开头下载工程代码,对比修改前和修改后的区别。网络部分有很多知识,想深入了解,还需要自己多看看代码。

     

    02、修改Keil工程

     

    添加文件,这些基本和IAR一样。

    图片

    添加头文件路径

    图片

    编译代码,有1个错误

    图片

    在timers.c添加

    图片

    代码如下

    #if defined   (__CC_ARM) /*!< ARM Compiler */ 
        u32_tsys_now(void){} 
    #endif
    ​​​​编译下载,发现ping会死机修改代码优化等级就好了

    图片

    测试成功

    图片

    总结:这是一篇流水账的移植记录,深入了解LWIP网络开发,还是要动手自己移植多多研究源码

     

    点击查看本文所在的专辑,STM32F207网络开发

     

    关注公众号,第一时间收到文章更新

     

    展开全文
  • Lwip
  • lwIP

    2006-02-23 09:05:59
    完备的TCP/IP协议栈!
  • LWIP_LwIP_源码

    2021-09-30 06:31:40
    实现了客户端网络连接,实现了串口打印,LCD显示状态,LWIP移植
  • modified lwip for esp32
  • lwip源码 lwip-1.4.1

    2015-12-01 11:27:08
    lwip源码 lwip-1.4.1 公司已经实战过,望大家下载学习。
  • lwIP 2.1.1

    2018-11-13 22:40:20
    2018年11月8日最新更新:lwIP 2.1.1 lwIP 2.1.1 released posted by goldsimon, Thu 08 Nov 2018 09:34:54 PM UTC - 0 replies lwIP 2.1.1 is now available from the lwIP download area or via git (using the ...
  • lwip移植加tcpip客户端功能代码,在ucos系统基础上移植lwip,并使用raw接口进行客户端服务编写
  • STM32F4 LWIP开发手册_V2.1
  • lwIP.lwIP.2.1.1.pack

    2020-05-15 17:31:36
    keil的lwIP.lwIP.2.1.1.pack包,由于网络的原因,官网可能下不了,我这里有,哈哈哈,大家可以直接下载了
  • lwIP.lwIP.1.4.1.pack

    2019-06-16 16:58:49
    这个是MDK的LWIP支持包,为方便大家在国内使用下载,现上传上来给大家共享,keil uv5上使用,下载后打开mdk - project - manage - pack installer,然后 file - import即可导入mdk。
  • 这里作为一个汇总帖把,把以前写过的LWIP相关的博客文章汇总到一起,方便自己这边查找一些资料。 LWIP协议 【LWIPLWIP网络通信流程 【LWIPLWIP动态内存管理 【LWIP】原始套接字(SOCK_RAW) 【LWIP】AF_PACKET...
    展开全文
  • LwIP详解卷

    2018-02-01 11:31:51
    压缩包内包含有4个文件:《LwIP编程指南》《LwIP协议详解》《LwIP协议栈源码详解》《LWIP中文手册》
  • esp-lwip ESP8266 的 LwIP 库。 这项工作基于 Espressif 在其 SDK 0.9.4 中完成的 LwIP 代码删除。 乐鑫特定的更改经过审查,分成小的、干净的补丁并应用到官方 LwIP git 存储库之上。 Espressif 的原始代码基于 ...
  • LWIP中文手册

    2019-03-20 10:08:24
    本文结构如下编排:第2,3和4部分对lwIP栈作一个概述,第5部分叙述操作系统模拟层, 第6部分叙述缓存和存储管理。第7部分介绍lwIP抽象的网络接口,第8,9,和10部分叙述IP, UDP,和TCP协议的实现。第11和12部分叙述...
  • lwip学习资料

    2018-03-18 11:31:30
    lwip学习资料,里面有lwip源代码详细解答及分析,lwip协议栈的详解中文版,以太网PHY寄存器分析
  • lwip1.4.1 升级到 lwip2.1.2

    千次阅读 2019-10-14 11:13:45
    STM32F407、lwip1.4.1、 1 lwip 移植 升级前肯定要知道一点 lwip 是怎么移植的,网上有挺多博客写移植教程,在此就不做介绍了。主要就是将 ethernetif.c 文件里的几个函数给实现下就可以了。 2 lwip1.4.1 ...
  • lwip学习教程

    2019-01-14 16:15:20
    lwip 1.4协议栈源码code,包含李林老师的一本《嵌入式网络那些事LwIP协议深度剖析与实战演练》
  • ZLG LwIP V1.01(配置:lwip 1.4.1+ucosII 2.92)
  • lwip开发使用

    2018-07-08 14:16:57
    stm32以太网LWIP移植使用,详细介绍LWIP协议栈的移植和API使用。
  • lwip 学习资料

    2018-03-08 09:36:51
    lwip学习含金量比较高的文档,想学好lwip这些足够了。
  • LWIP协议栈 1. LWIP协议介绍 LWIP 是瑞典计算机科学院(SICS)的Adam Dunkels 等开发的一个小型开源的TCP/IP 协议栈。LWIP 是轻量级 IP 协议,有无操作系统的支持都可以运行, LWIP 实现的重点是在保持 TCP 协议主要...
  • 在STM32F103 + ENC28J60上实现LWIP移植,使用CubeMX生成代码,清晰简洁
  • ZLG移值的一个Lwip网络编程,可以马上使用

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,716
精华内容 4,286
关键字:

lwIP