c - STM32F1 上的 lwIP:未调用 tcp_accept 回调函数
问题描述
我将在 STM32f107RCT6 和 DP83848 上设置 lwIP。我使用 CubeMX 生成主要代码。使用命令将代码下载到 MCU 后,ping
结果arp –a
为:
(MCU IP: 192.168.1.57 * Subnet: 255.255.255.0 * GW:192.168.1.1 *** MAC: 00-80-e1-00-00-00)
C:\Users\GmtK>ping 192.168.1.57
Pinging 192.168.1.57 with 32 bytes of data:
Reply from 192.168.1.11: Destination host unreachable.
Reply from 192.168.1.11: Destination host unreachable.
Reply from 192.168.1.11: Destination host unreachable.
Reply from 192.168.1.11: Destination host unreachable.
Ping statistics for 192.168.1.57:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
C:\Users\GmtK>arp -a
Interface: 192.168.1.11 --- 0x16
Internet Address Physical Address Type
192.168.1.1 74-da-da-64-6a-59 dynamic
192.168.1.7 2c-fd-a1-5c-3e-99 dynamic
192.168.1.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
224.0.0.251 01-00-5e-00-00-fb static
224.0.0.252 01-00-5e-00-00-fc static
239.255.255.250 01-00-5e-7f-ff-fa static
255.255.255.255 ff-ff-ff-ff-ff-ff static
但是,通过重置 MCU 并再次使用arp –a
:
C:\Users\GmtK>arp -a
Interface: 192.168.1.11 --- 0x16
Internet Address Physical Address Type
192.168.1.1 74-da-da-64-6a-59 dynamic
192.168.1.7 2c-fd-a1-5c-3e-99 dynamic
192.168.1.57 00-80-e1-00-00-00 dynamic //this my MCU
192.168.1.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
224.0.0.251 01-00-5e-00-00-fb static
224.0.0.252 01-00-5e-00-00-fc static
239.255.255.250 01-00-5e-7f-ff-fa static
255.255.255.255 ff-ff-ff-ff-ff-ff static
重复此循环,并通过重置 MCU 返回到arp -a
命令提供的列表。我认为该ping
命令为什么不起作用是可以理解的。因为也许它不是由 lwIP 实现的。TCP Client
所以我用 Hercules
Madule IP = 192.168.1.57 and Port = 7
并按下Connect
按钮。结果是:
Connecting to 192.168.1.57 ...
TCP connection timeout
我已经使用了两个 LED 来调试它,并且由于它RUNNING_LED
被打开,所以tcp_echoserver_init()
它被执行。但是,AUX_LED
从未打开意味着tcp_echoserver_accept()
永远不会调用回调函数!问题是什么?为什么不叫它?
这是我从 ST TCP ECHO SERVER 示例中采用的代码:
/**
* @brief Initializes the tcp echo server
* @param None
* @retval None
*/
void tcp_echoserver_init(void)
{
/* create new tcp pcb */
tcp_echoserver_pcb = tcp_new();
if (tcp_echoserver_pcb != NULL)
{
err_t err;
/* bind echo_pcb to port 7 (ECHO protocol) */
err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7);
if (err == ERR_OK)
{
/* start tcp listening for echo_pcb */
tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
/* initialize LwIP tcp_accept callback function */
tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
HAL_GPIO_WritePin(RUNNING_LED, 0); //RUNNING_LED Will be turned on here
}
else
{
/* deallocate the pcb */
memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);
}
}
}
/**
* @brief This function is the implementation of tcp_accept LwIP callback
* @param arg: not used
* @param newpcb: pointer on tcp_pcb struct for the newly created tcp connection
* @param err: not used
* @retval err_t: error status
*/
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
HAL_GPIO_WritePin(AUx_LED, 0); //AUX_LED will be turned on here
err_t ret_err;
struct tcp_echoserver_struct *es;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
/* set priority for the newly accepted tcp connection newpcb */
tcp_setprio(newpcb, TCP_PRIO_MIN);
/* allocate structure es to maintain tcp connection informations */
es = (struct tcp_echoserver_struct *)mem_malloc(sizeof(struct tcp_echoserver_struct));
if (es != NULL)
{
es->state = ES_ACCEPTED;
es->pcb = newpcb;
es->retries = 0;
es->p = NULL;
/* pass newly allocated es structure as argument to newpcb */
tcp_arg(newpcb, es);
/* initialize lwip tcp_recv callback function for newpcb */
tcp_recv(newpcb, tcp_echoserver_recv);
/* initialize lwip tcp_err callback function for newpcb */
tcp_err(newpcb, tcp_echoserver_error);
/* initialize lwip tcp_poll callback function for newpcb */
tcp_poll(newpcb, tcp_echoserver_poll, 0);
ret_err = ERR_OK;
}
else
{
/* close tcp connection */
tcp_echoserver_connection_close(newpcb, es);
/* return memory error */
ret_err = ERR_MEM;
}
return ret_err;
}
解决方案
正如我在评论中提到的,Raw API 实现在轮询模式下工作,因此您必须确保持续的软件轮询是否收到新数据包。据我所知,我在无限循环体的代码中添加了这两行:
while (1)
{
ethernetif_input(&gnetif);
sys_check_timeouts();
}
有关详细信息,请通读 ST,UM1713提供的内容丰富的用户手册。
推荐阅读
- maven - 提供范围和编译范围带来的传递依赖被计算为编译范围
- javascript - 添加后退按钮或指向图像文件页面的链接
- java - com.jayway.jsonpath.InvalidPathException:路径中不允许有空格
- scala - 如何使用我的平等比较器 GroupBy Spark DataFrame?
- angular - 无法更改当前节点的展开/折叠图标
- c# - C# 类没有打印出来
- c++ - 在 Windows 上使用 CLION 使用 openMP 编译程序
- node.js - npm 对等安装错误是什么意思?
- python - Anaconda tensorflow 包不完整?(只有几千字节的文件大小)
- asp.net-core - 如何在 Kestrel 网络服务器中使用更新的服务证书