You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-IDF 5.4.2删除ping会话时出现send error=0错误求解决方案

ESP-IDF 5.4.2 Ping功能偶发send error=0问题排查思路

问题描述

在ESP-IDF 5.4.2中实现Ping功能,偶尔会出现错误日志:E (185212) ping_sock: send error=0。尝试使用SemaphoreHandle_t同步但效果不佳,当前通过调用PingIp(192.168.1.23, 2, 100, 2000)获取Ping结果。

实现代码

static E_COMMON_Status ping_result;

static void on_ping_success(esp_ping_handle_t hdl, void *args)
{
    ping_result = COMMON_STATUS_OK;
}

static void on_ping_timeout(esp_ping_handle_t hdl, void *args)
{

}

static void on_ping_end(esp_ping_handle_t hdl, void *args)
{
uint32_t transmitted;
uint32_t received;
uint32_t total_time_ms;

esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, 

sizeof(total_time_ms));
}

E_COMMON_Status PingIp(char *ip_string, uint8_t pingCount, uint8_t pingInterval, uint8_t pingTimeout)
{
ping_result = COMMON_STATUS_KO;
MY_LOGI_MQTT(TAG, "PING:AVVIO DEL PING SU %s", ip_string);
ip_addr_t target_addr;
if (!inet_aton(ip_string, &target_addr))
{
    MY_LOGI_MQTT(TAG, "Conversione IP \"%s\" fallita", ip_string);
    return COMMON_STATUS_KO;
}

esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
config.target_addr = target_addr;
config.count = pingCount;
config.interval_ms = pingInterval;
config.timeout_ms = pingTimeout;

esp_ping_callbacks_t cbs = {
    .on_ping_success = on_ping_success,
    .on_ping_timeout = on_ping_timeout,
    .on_ping_end = on_ping_end,
    .cb_args = NULL};
// ping_result = COMMON_STATUS_KO;

esp_ping_handle_t ping;
esp_err_t err = esp_ping_new_session(&config, &cbs, &ping);
if (err != ESP_OK)
{
    MY_LOGI_MQTT(TAG, "esp_ping_new_session errore: %d", err);
    return COMMON_STATUS_KO;
}

err = esp_ping_start(ping);
if (err != ESP_OK)
{
    MY_LOGI_MQTT(TAG, "esp_ping_start errore: %d", err);
    esp_ping_delete_session(ping);
    return COMMON_STATUS_KO;
}
vTaskDelay((config.timeout_ms * config.count + 500) / portTICK_PERIOD_MS);
esp_ping_stop(ping);
esp_ping_delete_session(ping);
if (ping_result == COMMON_STATUS_OK)
{
    MY_LOGI_MQTT(TAG, "STATO DEL PING: OK");
}
else
{
    MY_LOGI_MQTT(TAG, "STATO DEL PING: KO");
}
return ping_result;
}

解决思路

  • 修正任务延迟计算逻辑:当前vTaskDelay的时间计算错误,总耗时应该是(pingCount-1)*pingInterval + pingTimeout,而不是pingTimeout*pingCount。错误的延迟会导致Ping会话还在发送数据包时就被强制停止,引发send error=0(发送操作因Socket关闭被中断)。
  • 正确使用信号量同步:之前信号量效果差是因为使用方式不正确。应该在on_ping_end回调中释放信号量,让主线程精准等待Ping会话结束,避免提前终止。示例代码:
    static SemaphoreHandle_t ping_sem;
    
    static void on_ping_end(esp_ping_handle_t hdl, void *args)
    {
        uint32_t transmitted;
        uint32_t received;
        uint32_t total_time_ms;
    
        esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
        esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
        esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
        
        xSemaphoreGive(ping_sem); // 会话结束后释放信号量
    }
    
    E_COMMON_Status PingIp(char *ip_string, uint8_t pingCount, uint8_t pingInterval, uint8_t pingTimeout)
    {
        ping_result = COMMON_STATUS_KO;
        MY_LOGI_MQTT(TAG, "PING:AVVIO DEL PING SU %s", ip_string);
        ip_addr_t target_addr;
        if (!inet_aton(ip_string, &target_addr))
        {
            MY_LOGI_MQTT(TAG, "Conversione IP \"%s\" fallita", ip_string);
            return COMMON_STATUS_KO;
        }
    
        esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
        config.target_addr = target_addr;
        config.count = pingCount;
        config.interval_ms = pingInterval;
        config.timeout_ms = pingTimeout;
    
        esp_ping_callbacks_t cbs = {
            .on_ping_success = on_ping_success,
            .on_ping_timeout = on_ping_timeout,
            .on_ping_end = on_ping_end,
            .cb_args = NULL};
    
        // 创建二进制信号量
        ping_sem = xSemaphoreCreateBinary();
        if (!ping_sem) {
            MY_LOGI_MQTT(TAG, "Failed to create semaphore");
            return COMMON_STATUS_KO;
        }
    
        esp_ping_handle_t ping;
        esp_err_t err = esp_ping_new_session(&config, &cbs, &ping);
        if (err != ESP_OK)
        {
            MY_LOGI_MQTT(TAG, "esp_ping_new_session errore: %d", err);
            vSemaphoreDelete(ping_sem);
            return COMMON_STATUS_KO;
        }
    
        err = esp_ping_start(ping);
        if (err != ESP_OK)
        {
            MY_LOGI_MQTT(TAG, "esp_ping_start errore: %d", err);
            esp_ping_delete_session(ping);
            vSemaphoreDelete(ping_sem);
            return COMMON_STATUS_KO;
        }
    
        // 等待Ping会话结束,超时时间设为总预估耗时+1000ms
        TickType_t wait_time = ((config.timeout_ms + config.interval_ms*(config.count-1)) + 1000) / portTICK_PERIOD_MS;
        if (xSemaphoreTake(ping_sem, wait_time) != pdTRUE) {
            MY_LOGI_MQTT(TAG, "Ping session timeout");
            esp_ping_stop(ping);
        }
    
        esp_ping_delete_session(ping);
        vSemaphoreDelete(ping_sem);
    
        if (ping_result == COMMON_STATUS_OK)
        {
            MY_LOGI_MQTT(TAG, "STATO DEL PING: OK");
        }
        else
        {
            MY_LOGI_MQTT(TAG, "STATO DEL PING: KO");
        }
        return ping_result;
    }
    
  • 添加错误回调捕获细节:在esp_ping_callbacks_t中添加.on_ping_error回调,获取具体错误码,帮助定位问题:
    static void on_ping_error(esp_ping_handle_t hdl, void *args, esp_err_t err_code)
    {
        MY_LOGI_MQTT(TAG, "Ping error occurred: %d", err_code);
    }
    
    // 更新回调结构体
    esp_ping_callbacks_t cbs = {
        .on_ping_success = on_ping_success,
        .on_ping_timeout = on_ping_timeout,
        .on_ping_end = on_ping_end,
        .on_ping_error = on_ping_error,
        .cb_args = NULL};
    
  • 检查资源释放逻辑:确保每次Ping会话无论成功失败,esp_ping_delete_session和信号量都被正确释放,避免Socket资源泄漏。
  • 调整Ping参数合理性:当前调用的PingIp(192.168.1.23, 2, 100, 2000)中,间隔100ms小于超时2000ms,可能导致前一个Ping包未回复就发送下一个,尝试将间隔调整为大于超时时间,验证是否还出现错误。

内容的提问来源于stack exchange,提问作者scorona85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 13:44:53