1、lwip启用LWIP_NETIF_CALLBACK 宏,cubeMX会自动生成相关函数()。

  /* Set the link callback function, this function is called on change of link status*/netif_set_link_callback(&gnetif, ethernetif_update_config);

回调函数在void ethernetif_update_config(struct netif *netif),其中主要完成通信协商之类的初始化。

最后调用__weak void ethernetif_notify_conn_changed(struct netif *netif),用户的代码在这里边实现。

比如,我是每当发现网卡出现插拔后,重新执行DHCP,动态获取IP,代码如下:

__weak void ethernetif_notify_conn_changed(struct netif *netif)
{/* NOTE : This is function could be implemented in user filewhen the callback is needed,*/int err;ipaddr.addr = 0;if (netif_is_link_up(&gnetif)){DEBUG("net link is up\r\n");DEBUG("starting dhcp...\n");err = dhcp_start(&gnetif);if (err == ERR_OK) {DEBUG("starting dhcp success!\n");} else {DEBUG("starting dhcp fail!\n");}int res = 0;do{res = ip_addr_cmp(&(gnetif.ip_addr),&ipaddr);if (res){osDelay(1000);DEBUG("wait dhcp...\r\n");}} while (res);DEBUG("dhcp get local ip :%d.%d.%d.%d\n\n",  \((gnetif.ip_addr.addr)&0x000000ff),       \(((gnetif.ip_addr.addr)&0x0000ff00)>>8),  \(((gnetif.ip_addr.addr)&0x00ff0000)>>16), \((gnetif.ip_addr.addr)&0xff000000)>>24);} else {DEBUG("net link is down\r\n");}
}

2、开机没接网线,无法初始化网卡,程序崩溃问题。

程序开机运行时如果由网线连接,那么正常初始化后按照上面的配置是可以实现热插拔的。但是,如果在初始化网卡之前没有连接网线,则程序会运行失败,甚至崩溃。

网卡初始化,调用HAL库的 hal_eth_init_status = HAL_ETH_Init(&heth); 进一步可以发现该函数中由以下内容:

  if((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE){/* Get tick */tickstart = HAL_GetTick();/* We wait for linked status */do{HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);/* Check for the Timeout */if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_LINKED_STATE){/* In case of write timeout */err = ETH_ERROR;/* Config MAC and DMA */ETH_MACDMAConfig(heth, err);heth->State= HAL_ETH_STATE_READY;/* Process Unlocked */__HAL_UNLOCK(heth);return HAL_TIMEOUT;}} while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));

该部分描述的是如果启用了速率自协商,那么会一直判断读取PHY芯片的BSR寄存器当前是否由连接,否则等待直到超时。超时时间是ETH_TIMEOUT_LINKED_STATE,也即5s。程序一直卡在这里,如果启用了操作系统,那么这个任务将阻塞其他的任务,导致报错。

解决方案是在网卡初始化和LWIP初始化之前,检查是否由网线连接,读PHY_BSR寄存器,然后判断即可。当然,需要先初始化网卡的基本接口,保证寄存器能够读取。

等待网络连接的接口如下:


int waitNetLink(uint32_t timeout_s)
{ETH_HandleTypeDef heth;heth.Instance = ETH;heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;heth.Init.PhyAddress = LAN8720_PHY_ADDRESS;heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;HAL_ETH_MspInit(&heth);osDelay(PHY_RESET_DELAY);uint32_t checkCnt = 0;if((heth.Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) {uint32_t tickstart = HAL_GetTick();uint32_t phyreg = 0U;do {HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &phyreg);osDelay(1000);if (0 == (checkCnt++ % 3)) {DEBUG("wait net link, timeout %u s, now %u s...\r\n", timeout_s, checkCnt);}if (checkCnt >= timeout_s - 1) {if (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS)) {HAL_ETH_MspDeInit(&heth);return -1;}}} while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));}HAL_ETH_MspDeInit(&heth);if (checkCnt <= timeout_s - 1) { return 0; }else { return 1; }
}

使用方法:

/* USER CODE END Header_lwIPAppTaskFunc */
void lwIPAppTaskFunc(void *argument)
{/* USER CODE BEGIN lwIPAppTaskFunc */DEBUG("lwip app task started\r\n");/* init code for LWIP */int link_res = waitNetLink(osWaitForever);if (0 != link_res){DEBUG("wait net link timeout\r\n");} else {/*! lwip init */MX_LWIP_Init();/*! creat socket client */int creat_res = creat_tcp_client(&client_id,SOCKET_SERVER_ADDR,SOCKET_SERVER_PORT);if (creat_res != 0) {DEBUG("creat_tcp_client error: res = %d\r\n", creat_res);} else {DEBUG("creat_tcp_client success\r\n");}}/* Infinite loop */for(;;){osDelay(1);}/* USER CODE END lwIPAppTaskFunc */
}

lwip+freeRTOS 实现热插拔功能相关推荐

  1. 野火挑战者V2开发板CubeMX+LWIP+FreeRTOS+TCP_Server+TCP_Client实现

    首先说一下开发环境:MDK5版本为5.26.2.0,CubeMX版本为6.6.1,FreeRTOS API选择的是 CMSIS v1,LWIP版本为2.1.2.单片机型号为STM32F429IGT6, ...

  2. lwip+freeRTOS 故障容错 客户端主动发起连接

    1.简单的需求 STM32终端为tcp客户端,主动向TCP服务器发起连接,然后进行通信. 流程:STM32网卡初始化-----lwIP初始化--------DHCP-------------creat ...

  3. STM32cubeMX将STM32F767+LAN8720+LwIP+FreeRTOS的以太网实现

    通过STM32cubeMX将STM32F767+LAN8720+LwIP+FreeRTOS的以太网实现 本文使用了正点原子的阿波罗开发板,接下来我将粗略的对STM32F767通过STM32cubeMX ...

  4. stm32f407+lwip+freertos程序附PCB图

    stm32f407+lwip+freertos程序附PCB图 提供上位机与本设备的通信协议文档 描述:程序和电路原理图和PCB都是本人亲手设计,亲测可用,独一无二,相信对想要入手以太网的工程师有极高的 ...

  5. stm32f407+lwip+freertos程序

    stm32f407+lwip+freertos程序附PCB图 描述:程序和电路原理图和PCB都是本人亲手设计,亲测可用,独一无二,相信对想要入手以太网的工程师有极高的参考价值<font colo ...

  6. STM32CubeMX+LAN8720+LWIP+FreeRTOS实现网络通讯

    STM32CubeMX+LAN8720+LWIP+FreeRTOS实现网络通讯 使用STM32CubeMX可以非常方便的将FreeRTOS+LWIP移植到工程中,本文就是介绍如何利用STM32Cube ...

  7. mfc 实现 设备 热插拔功能

    开发windows MFC 应用程序时,经常会操作一些硬件设备,那么如何实现设备的热插拔功能呢,下面给出具体操作步骤: 1,给要实现设备热插拔的窗体/界面 添加  ON_WM_DEVICECHANGE ...

  8. Vmware Workstation 6.5试用之二—支持设备的热插拔功能

    Vmware Workstation 6.5试用之二-支持设备的热插拔功能 在Vmware Workstation 6.5中,如果虚拟机硬件是6.5的格式,在Windows XP.Windows Se ...

  9. Stm32CubeMx lwip+freeRTOS TCP 服务

    如何添加lwip参照上一篇   stm32CubeMx lwip + freeRTOS 今天讲一下,如何添加TCP服务 LwIP 提供了三种编程接口,分别为 RAW/Callback API.NETC ...

最新文章

  1. scikit-learn kmeans++
  2. flash socket通信问题
  3. Android数据的存储方式简介
  4. 【Win 10 应用开发】RTM版的UAP项目解剖
  5. java中的mod运算_Java源码中Integer类位运算分析
  6. 为什么黑客都用python-python为什么会作为黑客的首选语言?这几本书给你答案(已集齐)...
  7. 如何处理出差或放假在家办公加密文件打不开?
  8. r7c刷机android6.0,OPPOR7c官方固件刷机教程_线刷|救砖教程图解
  9. win7 升级IE11报错(无法安装)
  10. 传输线应用基础,阻抗匹配与谐波控制
  11. Arduino AFMotor 电机扩展板概述
  12. Caused by: java.io.IOException: ZIP entry size is too large
  13. java给服务器创建文件夹,java服务器创建文件夹
  14. 【PyQt5与Requests爬虫】设计图形界面(GUI)实现小说下载器-进度条显示
  15. xcode7.3.1升级iOS10 SDK
  16. 解决方案:“Project1.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。无法查找或打开 PDB 文件。
  17. python第一章(下)
  18. 使用SQL语句创建数据库和数据库表
  19. OCCT学习003-----MFC单文档工程
  20. 【Dart 教程系列第 21 篇】Dart 之 firstWhere 返回数组中第一个满足条件的元素

热门文章

  1. 二进制文件更新程序_APR 6.17程序文件更新
  2. linux中initrd的含义,Linux2.6 内核的 Initrd 机制解析
  3. python函数对变量的作用_python函数对变量的作用及遵循的原则
  4. linux内核怎么修改屏幕旋转方向_树莓派4—屏幕旋转
  5. java字符函数_java字符串函数用法汇总
  6. 在java中图片随机播放_java-以相同顺序随机播放多个文件
  7. 自动清理归档日志_从MYSQL 数据库归档 到 归档设计
  8. 王道操作系统考研笔记——1.1.1 操作系统的概念、功能和目标
  9. CC254x--BLE
  10. Exynos4412 所用内存 —— DDR2