STM32连接以太网失败自动重新连接
连接失败LED0不亮,连接成功LED0亮;
STM32连接以太网失败自动重新连接
连上之后,断开也可以自动重连,我想创建一个任务,这个任务专门来连接网络,然后在芯片上电的时候,先执行这个任务,这个任务
程序刚进入进行开始创建一个函数任务(想象成手机开机键),然后这个函数开始创建注册函数任务(负责可以让任务可以创建执行),第一个任务是连接tcp(要去一:自动连接tcp)
tcp任务
就是检测tcp是否连接成功是一个任务每一段时间都要进行的:如果未连接上,LED0亮,没有连接上就尝试去连接,直到连接成功,LED0熄灭;如果连接上,LED0灭;如果通信成功就创建开始创建的任务,如果没有创建成功就杀死所有任务,也就是只进行这个连接tcp的任务;
void freertos_demo(void)
{
/* start_task任务 */
xTaskCreate((TaskFunction_t )start_task,
(const char * )"start_task",
(uint16_t )START_STK_SIZE,
(void * )NULL,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t * )&StartTask_Handler);
vTaskStartScheduler(); /* 开启任务调度 */
}
这个demo里面创建的任务是tcp,然后这个start_task任务当tcp连接成功的时候创建;
创建任务
/******************************************************************************************************* @file freertos_demo.c* @author 正点原子团队(ALIENTEK)* @version V1.0* @date 2022-01-11* @brief lwIP Netconn TCPServer 实验* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司***************************************************************************************************** @attention** 实验平台:正点原子 探索者 F407开发板* 在线视频:www.yuanzige.com* 技术论坛:www.openedv.com* 公司网址:www.alientek.com* 购买地址:openedv.taobao.com******************************************************************************************************/#include "freertos_demo.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
#include "./BSP/KEY/key.h"
#include "lwip_comm.h"
#include "lwip_demo.h"
#include "lwipopts.h"
#include "stdio.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 5 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 *//* LWIP_DEMO 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define LWIP_DMEO_TASK_PRIO 11 /* 任务优先级 */
#define LWIP_DMEO_STK_SIZE 1024 /* 任务堆栈大小 */
TaskHandle_t LWIP_Task_Handler; /* 任务句柄 */
void lwip_demo_task(void *pvParameters); /* 任务函数 *//* LED_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define LED_TASK_PRIO 10 /* 任务优先级 */
#define LED_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t LEDTask_Handler; /* 任务句柄 */
void led_task(void *pvParameters); /* 任务函数 *//* KEY_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define KEY_TASK_PRIO 11 /* 任务优先级 */
#define KEY_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t KEYTask_Handler; /* 任务句柄 */
void key_task(void *pvParameters); /* 任务函数 *//* DISPLAY_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define DISPLAY_TASK_PRIO 12 /* 任务优先级 */
#define DISPLAY_STK_SIZE 512 /* 任务堆栈大小 */
TaskHandle_t DISPLAYTask_Handler; /* 任务句柄 */
void display_task(void *pvParameters); /* 任务函数 *//* NETWORK_STATUS_TASK 网络状态检测任务 配置* 包括: 任务句柄、优先级、堆栈大小、任务函数声明*/
#define NETWORK_STATUS_TASK_PRIO 11 /* 任务优先级(适中) */
#define NETWORK_STATUS_STK_SIZE 1024 /* 任务堆栈大小 */
TaskHandle_t NetworkStatusTask_Handler; /* 任务句柄 */void network_status_task(void *pvParameters); /* 任务函数声明 *//* 显示消息队列的数量 */
#define DISPLAYMSG_Q_NUM 20 /* 显示消息队列的数量 */
QueueHandle_t g_display_queue; /* 显示消息队列句柄 *//******************************************************************************************************//*** @breif 加载UI* @param mode : bit0:0,不加载;1,加载前半部分UI* bit1:0,不加载;1,加载后半部分UI* @retval 无*/
void lwip_test_ui(uint8_t mode)
{uint8_t speed;uint8_t buf[30];if (mode & 1<< 0){lcd_show_string(6, 10, 200, 32, 32, "STM32", DARKBLUE);lcd_show_string(6, 40, lcddev.width, 24, 24, "lwIP TCPServer Test", DARKBLUE);lcd_show_string(6, 70, 200, 16, 16, "ATOM@ALIENTEK", DARKBLUE);}if (mode & 1 << 1){lcd_show_string(5, 110, 200, 16, 16, "lwIP Init Successed", MAGENTA);if (g_lwipdev.dhcpstatus == 2){sprintf((char*)buf,"DHCP IP:%d.%d.%d.%d",g_lwipdev.ip[0],g_lwipdev.ip[1],g_lwipdev.ip[2],g_lwipdev.ip[3]); /* 显示动态IP地址 */}else{sprintf((char*)buf,"Static IP:%d.%d.%d.%d",g_lwipdev.ip[0],g_lwipdev.ip[1],g_lwipdev.ip[2],g_lwipdev.ip[3]); /* 打印静态IP地址 */}lcd_show_string(5, 130, 200, 16, 16, (char*)buf, MAGENTA);speed = ethernet_chip_get_speed(); /* 得到网速 */if (speed){lcd_show_string(5, 150, 200, 16, 16, "Ethernet Speed:100M", MAGENTA);}else{lcd_show_string(5, 150, 200, 16, 16, "Ethernet Speed:10M", MAGENTA);}lcd_show_string(5, 170, 200, 16, 16, "KEY0:Send data", MAGENTA);lcd_show_string(5, 190, lcddev.width - 30, lcddev.height - 190, 16, "Receive Data:", BLUE); /* 提示消息 */}
}/*** @breif freertos_demo* @param 无* @retval 无*/
void freertos_demo(void)
{/* start_task任务 */xTaskCreate((TaskFunction_t )start_task,(const char * )"start_task",(uint16_t )START_STK_SIZE,(void * )NULL,(UBaseType_t )START_TASK_PRIO,(TaskHandle_t * )&StartTask_Handler);vTaskStartScheduler(); /* 开启任务调度 */
}/*** @brief start_task* @param pvParameters : 传入参数(未用到)* @retval 无*/
void start_task(void *pvParameters)
{pvParameters = pvParameters;/* 防止编译器警告(未使用参数),这行没实际意义 */g_lwipdev.lwip_display_fn = lwip_test_ui;lwip_test_ui(1); /* 加载后前部分UI */while (1){LED0_ON;/* 尝试初始化lwIP */if (lwip_comm_init() == 0){printf("lwIP 初始化成功!\r\n");break; /* 成功则跳出循环 */}/* 检查PHY是否连接 */if (ethernet_read_phy(PHY_SR)){printf("检测到PHY芯片响应,准备重新初始化...\r\n");}else{printf("PHY芯片未响应,等待连接...\r\n");LED0_OFF;}vTaskDelay(1000); /* 每1秒检测一次 */}while((g_lwipdev.dhcpstatus != 2)&&(g_lwipdev.dhcpstatus != 0XFF)) /* 等待DHCP获取成功/超时溢出 */{vTaskDelay(5);}taskENTER_CRITICAL(); /* 进入临界区 */g_display_queue = xQueueCreate(DISPLAYMSG_Q_NUM,200); /* 创建消息Message_Queue,队列项长度是200长度 *//* 网络连接状态检测任务 */xTaskCreate((TaskFunction_t )network_status_task,(const char* )"network_status_task",(uint16_t )NETWORK_STATUS_STK_SIZE, (void* )NULL,(UBaseType_t )NETWORK_STATUS_TASK_PRIO, // 优先级适中(TaskHandle_t* )NetworkStatusTask_Handler);//
// /* 创建lwIP任务 */
// xTaskCreate((TaskFunction_t )lwip_demo_task,
// (const char* )"lwip_demo_task",
// (uint16_t )LWIP_DMEO_STK_SIZE,
// (void* )NULL,
// (UBaseType_t )LWIP_DMEO_TASK_PRIO,
// (TaskHandle_t* )&LWIP_Task_Handler);// /* key任务 */
// xTaskCreate((TaskFunction_t )key_task,
// (const char * )"key_task",
// (uint16_t )KEY_STK_SIZE,
// (void * )NULL,
// (UBaseType_t )KEY_TASK_PRIO,
// (TaskHandle_t * )&KEYTask_Handler);// /* LED测试任务 */
// xTaskCreate((TaskFunction_t )led_task,
// (const char* )"led_task",
// (uint16_t )LED_STK_SIZE,
// (void* )NULL,
// (UBaseType_t )LED_TASK_PRIO,
// (TaskHandle_t* )&LEDTask_Handler);// /* 显示任务 */
// xTaskCreate((TaskFunction_t )display_task,
// (const char* )"display_task",
// (uint16_t )DISPLAY_STK_SIZE,
// (void* )NULL,
// (UBaseType_t )DISPLAY_TASK_PRIO,
// (TaskHandle_t* )&DISPLAYTask_Handler);vTaskDelete(StartTask_Handler); /* 删除开始任务 */taskEXIT_CRITICAL(); /* 退出临界区 */}/*** @brief lwIP运行例程* @param pvParameters : 传入参数(未用到)* @retval 无*/
void lwip_demo_task(void *pvParameters)
{pvParameters = pvParameters;lwip_demo(); /* lwip测试代码 */while(1){vTaskDelay(5);}
}/*** @brief key_task* @param pvParameters : 传入参数(未用到)* @retval 无*/
void key_task(void *pvParameters)
{pvParameters = pvParameters;uint8_t key;while (1){key = key_scan(0);if (KEY0_PRES ==key){g_lwip_send_flag |= LWIP_SEND_DATA; /* 标记LWIP有数据要发送 */}vTaskDelay(10);}
}/*** @brief 系统再运行* @param pvParameters : 传入参数(未用到)* @retval 无*/
void led_task(void *pvParameters)
{pvParameters = pvParameters;while(1){// LED0_TOGGLE(); LED1_TOGGLE();vTaskDelay(100);}
}/*** @brief 显示任务* @param pvParameters : 传入参数(未用到)* @retval 无*/
void display_task(void *pvParameters)
{pvParameters = pvParameters;uint8_t *buffer;while(1){buffer = mymalloc(SRAMIN,200);if(g_display_queue != NULL){memset(buffer,0,200); /* 清除缓冲区 */if (xQueueReceive(g_display_queue,buffer,portMAX_DELAY)){lcd_fill(30, 220, lcddev.width - 1, lcddev.height - 1, WHITE); /* 清上一次数据 *//* 显示接收到的数据 */lcd_show_string(30, 220, lcddev.width - 30, lcddev.height - 230, 16, (char *)buffer, RED); }}myfree(SRAMIN,buffer); /*释放内存 */vTaskDelay(5);}
}void network_status_task(void *pvParameters)
{pvParameters = pvParameters;while (1){uint16_t phy_reg = ethernet_read_phy(PHY_SR);uint8_t link_status = (phy_reg & (1 << 2)) ? 0 : 1; // 1=连接, 0=断开if (link_status) // 连接上:关闭 LED0{LED0_OFF;printf("网络连接成功\r\n");}else // 未连接:打开 LED0,并重新初始化 lwIP{LED0_ON;printf("网络断开\r\n");lwip_comm_init();}vTaskDelay(500); // 每 500ms 检查一次}
}
/******************************************************************************************************* @file lwip_comm.c* @author 正点原子团队(ALIENTEK)* @version V1.0* @date 2021-12-02* @brief LWIP配置驱动代码* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司***************************************************************************************************** @attention** 实验平台:正点原子 探索者 F407开发板* 在线视频:www.yuanzige.com* 技术论坛:www.openedv.com* 公司网址:www.alientek.com* 购买地址:openedv.taobao.com** 修改说明* V1.0 20211202* 第一次发布******************************************************************************************************/#include "lwip_comm.h"
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/init.h"
#include "ethernetif.h"
#include "lwip/timeouts.h"
#include "lwip/tcpip.h"
#include "./MALLOC/malloc.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"__lwip_dev g_lwipdev; /* lwip控制结构体 */
struct netif g_lwip_netif; /* 定义一个全局的网络接口 */#if LWIP_DHCP
__IO uint8_t g_lwip_dhcp_state = LWIP_DHCP_OFF; /* DHCP状态初始化 */
#endif/* LINK线程配置 */
#define LWIP_LINK_TASK_PRIO 3 /* 任务优先级 */
#define LWIP_LINK_STK_SIZE 128 * 2 /* 任务堆栈大小 */
void lwip_link_thread( void * argument ); /* 链路线程 *//* DHCP线程配置 */
#define LWIP_DHCP_TASK_PRIO 4 /* 任务优先级 */
#define LWIP_DHCP_STK_SIZE 128 * 2 /* 任务堆栈大小 */
void lwip_periodic_handle(void *argument); /* DHCP线程 */
void lwip_link_status_updated(struct netif *netif); /* DHCP状态回调函数 *//*** @breif lwip 默认IP设置* @param lwipx : lwip控制结构体指针* @retval 无*/
void lwip_comm_default_ip_set(__lwip_dev *lwipx)
{/* 默认远端IP为:192.168.1.134 */lwipx->remoteip[0] = 192;lwipx->remoteip[1] = 168;lwipx->remoteip[2] = 1;lwipx->remoteip[3] = 30;/* MAC地址设置 */lwipx->mac[0] = 0xB8;lwipx->mac[1] = 0xAE;lwipx->mac[2] = 0x1D;lwipx->mac[3] = 0x00;lwipx->mac[4] = 0x01;lwipx->mac[5] = 0x00;/* 默认本地IP为:192.168.1.30 */lwipx->ip[0] = 192;lwipx->ip[1] = 168;lwipx->ip[2] = 1;lwipx->ip[3] = 33;/* 默认子网掩码:255.255.255.0 */lwipx->netmask[0] = 255;lwipx->netmask[1] = 255;lwipx->netmask[2] = 255;lwipx->netmask[3] = 0;/* 默认网关:192.168.1.1 */lwipx->gateway[0] = 192;lwipx->gateway[1] = 168;lwipx->gateway[2] = 1;lwipx->gateway[3] = 1;lwipx->dhcpstatus = 0; /* 没有DHCP */
}/*** @breif LWIP初始化(LWIP启动的时候使用)* @param 无* @retval 0,成功* 1,内存错误* 2,以太网芯片初始化失败* 3,网卡添加失败.*/
uint8_t lwip_comm_init(void)
{uint8_t retry = 0;struct netif *netif_init_flag; /* 调用netif_add()函数时的返回值,用于判断网络初始化是否成功 */ip_addr_t ipaddr; /* ip地址 */ip_addr_t netmask; /* 子网掩码 */ip_addr_t gw; /* 默认网关 */tcpip_init(NULL, NULL);if (ethernet_mem_malloc())return 1; /* 内存申请失败*/lwip_comm_default_ip_set(&g_lwipdev); /* 设置默认IP等信息 */while (ethernet_init()) /* 初始化以太网芯片,如果失败的话就重试5次 */{retry++;if (retry > 5){retry = 0; /* 以太网芯片初始化失败 */return 3;}}#if LWIP_DHCP /* 使用动态IP */ip_addr_set_zero_ip4(&ipaddr); /* 对IP地址、子网掩码及网关清零 */ip_addr_set_zero_ip4(&netmask);ip_addr_set_zero_ip4(&gw);
#else /* 使用静态IP */IP4_ADDR(&ipaddr, g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);IP4_ADDR(&netmask, g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);IP4_ADDR(&gw, g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n", g_lwipdev.mac[0], g_lwipdev.mac[1], g_lwipdev.mac[2], g_lwipdev.mac[3], g_lwipdev.mac[4], g_lwipdev.mac[5]);printf("静态IP地址........................%d.%d.%d.%d\r\n", g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);printf("子网掩码..........................%d.%d.%d.%d\r\n", g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);printf("默认网关..........................%d.%d.%d.%d\r\n", g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);g_lwipdev.dhcpstatus = 0XFF;
#endif /* 向网卡列表中添加一个网口 */netif_init_flag = netif_add(&g_lwip_netif, (const ip_addr_t *)&ipaddr, (const ip_addr_t *)&netmask, (const ip_addr_t *)&gw, NULL, ðernetif_init, &tcpip_input);if (netif_init_flag == NULL){return 4; /* 网卡添加失败 */}else /* 网口添加成功后,设置netif为默认值,并且打开netif网口 */{netif_set_default(&g_lwip_netif); /* 设置netif为默认网口 */if (netif_is_link_up(&g_lwip_netif)){netif_set_up(&g_lwip_netif); /* 打开netif网口 */}else{netif_set_down(&g_lwip_netif);}#if LWIP_NETIF_LINK_CALLBACKlwip_link_status_updated(&g_lwip_netif); /* DHCP链接状态更新函数 */netif_set_link_callback(&g_lwip_netif, lwip_link_status_updated);/* 查询PHY连接状态任务 */sys_thread_new("eth_link",lwip_link_thread, /* 任务入口函数 */&g_lwip_netif, /* 任务入口函数参数 */LWIP_LINK_STK_SIZE, /* 任务栈大小 */LWIP_LINK_TASK_PRIO); /* 任务的优先级 */
#endif}g_lwipdev.link_status = LWIP_LINK_OFF; /* 链接标记为0 */
#if LWIP_DHCP /* 如果使用DHCP的话 */g_lwipdev.dhcpstatus = 0; /* DHCP标记为0 *//* DHCP轮询任务 */sys_thread_new("eth_dhcp",lwip_periodic_handle, /* 任务入口函数 */&g_lwip_netif, /* 任务入口函数参数 */LWIP_DHCP_STK_SIZE, /* 任务栈大小 */LWIP_DHCP_TASK_PRIO); /* 任务的优先级 */
#endifreturn 0; /* 操作OK. */
}/*** @brief 通知用户网络接口配置状态* @param netif:网卡控制块* @retval 无*/
void lwip_link_status_updated(struct netif *netif)
{if (netif_is_up(netif)){
#if LWIP_DHCP/* Update DHCP state machine */g_lwip_dhcp_state = LWIP_DHCP_START;printf ("The network cable is connected \r\n");
#endif /* LWIP_DHCP */}else{
#if LWIP_DHCP/* Update DHCP state machine */g_lwip_dhcp_state = LWIP_DHCP_LINK_DOWN;printf ("The network cable is not connected \r\n");
#endif /* LWIP_DHCP */}
}extern xSemaphoreHandle g_rx_semaphore; /* 定义一个信号量 */
/*** @breif 当接收到数据后调用* @param 无* @retval 无*/
void lwip_pkt_handle(void)
{BaseType_t xHigherPriorityTaskWoken;/* 获取信号量 */xSemaphoreGiveFromISR(g_rx_semaphore,&xHigherPriorityTaskWoken);/* 释放二值信号量 */portYIELD_FROM_ISR(xHigherPriorityTaskWoken); /* 如果需要的话进行一次任务切换 */
}/* 如果使能DHCP */
#if LWIP_DHCP/*** @breif DHCP进程* @param argument:传入的形参* @retval 无*/
void lwip_periodic_handle(void *argument)
{struct netif *netif = (struct netif *) argument;uint32_t ip = 0;uint32_t netmask = 0;uint32_t gw = 0;struct dhcp *dhcp;uint8_t iptxt[20];while (1){switch (g_lwip_dhcp_state){case LWIP_DHCP_START:{/* 对IP地址、网关地址及子网页码清零操作 */ip_addr_set_zero_ip4(&netif->ip_addr);ip_addr_set_zero_ip4(&netif->netmask);ip_addr_set_zero_ip4(&netif->gw);ip_addr_set_zero_ip4(&netif->ip_addr);ip_addr_set_zero_ip4(&netif->netmask);ip_addr_set_zero_ip4(&netif->gw);g_lwip_dhcp_state = LWIP_DHCP_WAIT_ADDRESS;printf ("State: Looking for DHCP server ...\r\n");dhcp_start(netif);}break;case LWIP_DHCP_WAIT_ADDRESS:{if (dhcp_supplied_address(netif)){g_lwip_dhcp_state = LWIP_DHCP_ADDRESS_ASSIGNED;ip = g_lwip_netif.ip_addr.addr; /* 读取新IP地址 */netmask = g_lwip_netif.netmask.addr; /* 读取子网掩码 */gw = g_lwip_netif.gw.addr; /* 读取默认网关 */sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));printf ("IP address assigned by a DHCP server: %s\r\n", iptxt);if (ip != 0){g_lwipdev.dhcpstatus = 2; /* DHCP成功 */printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n", g_lwipdev.mac[0], g_lwipdev.mac[1], g_lwipdev.mac[2], g_lwipdev.mac[3], g_lwipdev.mac[4], g_lwipdev.mac[5]);/* 解析出通过DHCP获取到的IP地址 */g_lwipdev.ip[3] = (uint8_t)(ip >> 24);g_lwipdev.ip[2] = (uint8_t)(ip >> 16);g_lwipdev.ip[1] = (uint8_t)(ip >> 8);g_lwipdev.ip[0] = (uint8_t)(ip);printf("通过DHCP获取到IP地址..............%d.%d.%d.%d\r\n", g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);/* 解析通过DHCP获取到的子网掩码地址 */g_lwipdev.netmask[3] = (uint8_t)(netmask >> 24);g_lwipdev.netmask[2] = (uint8_t)(netmask >> 16);g_lwipdev.netmask[1] = (uint8_t)(netmask >> 8);g_lwipdev.netmask[0] = (uint8_t)(netmask);printf("通过DHCP获取到子网掩码............%d.%d.%d.%d\r\n", g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);/* 解析出通过DHCP获取到的默认网关 */g_lwipdev.gateway[3] = (uint8_t)(gw >> 24);g_lwipdev.gateway[2] = (uint8_t)(gw >> 16);g_lwipdev.gateway[1] = (uint8_t)(gw >> 8);g_lwipdev.gateway[0] = (uint8_t)(gw);printf("通过DHCP获取到的默认网关..........%d.%d.%d.%d\r\n", g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);g_lwipdev.lwip_display_fn(2);}}else{dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);/* DHCP timeout */if (dhcp->tries > LWIP_MAX_DHCP_TRIES){g_lwip_dhcp_state = LWIP_DHCP_TIMEOUT;g_lwipdev.dhcpstatus = 0XFF;/* 使用静态IP地址 */IP4_ADDR(&(g_lwip_netif.ip_addr), g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);IP4_ADDR(&(g_lwip_netif.netmask), g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);IP4_ADDR(&(g_lwip_netif.gw), g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);netif_set_addr(netif, &g_lwip_netif.ip_addr, &g_lwip_netif.netmask, &g_lwip_netif.gw);sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));printf ("DHCP Timeout !! \r\n");printf ("Static IP address: %s\r\n", iptxt);g_lwipdev.lwip_display_fn(2);}}}break;case LWIP_DHCP_LINK_DOWN:{g_lwip_dhcp_state = LWIP_DHCP_OFF;}break;default: break;}/* wait 1000 ms */vTaskDelay(1000);}
}
#endif#if LWIP_NETIF_LINK_CALLBACK
/*** @brief 检查ETH链路状态,更新netif* @param argument: netif* @retval 无*/
void lwip_link_thread( void * argument )
{uint32_t regval = 0;struct netif *netif = (struct netif *) argument;int link_again_num = 0;while(1){/* 读取PHY状态寄存器,获取链接信息 */HAL_ETH_ReadPHYRegister(&g_eth_handler,PHY_BSR, ®val);/* 判断链接状态 */if((regval & PHY_LINKED_STATUS) == 0){g_lwipdev.link_status = LWIP_LINK_OFF;link_again_num ++ ;if (link_again_num >= 2) /* 网线一段时间没有插入 */{continue;}else /* 关闭虚拟网卡及以太网中断 */{
#if LWIP_DHCP /* 如果使用DHCP的话 */g_lwip_dhcp_state = LWIP_DHCP_LINK_DOWN;dhcp_stop(netif);
#endifHAL_ETH_Stop(&g_eth_handler);netif_set_down(netif);netif_set_link_down(netif);}}else /* 网线插入检测 */{link_again_num = 0;if (g_lwipdev.link_status == LWIP_LINK_OFF)/* 开启以太网及虚拟网卡 */{g_lwipdev.link_status = LWIP_LINK_ON;HAL_ETH_Start(&g_eth_handler);netif_set_up(netif);netif_set_link_up(netif);}}vTaskDelay(100);}
}
#endif
