连接失败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_CALLBACK
lwip_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); /* 任务的优先级 */
#endif
return 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);
#endif
HAL_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