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

ESP32-S3连接AWS IoT Core时MQTT连接失败问题排查

ESP-IDF连接AWS IoT Core MQTT失败问题排查

问题描述

我使用ESP-IDF编写了与AWS IoT Core进行MQTT通信的测试代码,实现了事件处理逻辑,将根CA存入全局CA存储,并配置了MQTT参数,但连接时出现错误。

测试代码

const char *mqtt_broker_url = "xxxxxxxxxxxxx.iot.ap-northeast-2.amazonaws.com";
const char *mqtt_client_id = "ESP-TEST";
const uint16_t mqtt_port = 8883;

extern const uint8_t root_ca_pem_start[] asm("_binary_root_ca_pem_start");
extern const uint8_t root_ca_pem_end[] asm("_binary_root_ca_pem_end");
extern const uint8_t device_cert_crt_start[] asm("_binary_certificate_pem_crt_start");
extern const uint8_t device_cert_crt_end[] asm("_binary_certificate_pem_crt_end");
extern const uint8_t device_private_key_start[] asm("_binary_private_pem_key_start");
extern const uint8_t device_private_key_end[] asm("_binary_private_pem_key_end");

void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%ld", base, event_id);
}

void app_main(void)
{
    ...WIFI CONNECT...
    //Wait for WiFi to connect
    vTaskDelay(5000 / portTICK_PERIOD_MS);

    ESP_ERROR_CHECK(esp_tls_init_global_ca_store());
    ESP_ERROR_CHECK(esp_tls_set_global_ca_store(
        (const unsigned char *)root_ca_pem_start,
        root_ca_pem_end - root_ca_pem_start
    ));
    vTaskDelay(5000 / portTICK_PERIOD_MS);

    esp_mqtt_client_config_t mqtt_cfg = {
        .broker.address.hostname = mqtt_broker_url,
        .broker.address.port = mqtt_port,
        .broker.address.transport = MQTT_TRANSPORT_OVER_SSL,
        .broker.verification.use_global_ca_store = true,
        .credentials.authentication.certificate = (const char *)device_cert_crt_start,
        .credentials.authentication.certificate_len = device_cert_crt_end - device_cert_crt_start,
        .credentials.authentication.key = (const char *)device_private_key_start, 
        .credentials.authentication.key_len = device_private_key_end - device_private_key_start,
        .task.priority = MAX_PRIROTY - 2,
        .task.stack_size = 1024 * 8,
    };

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);
}

错误日志

E (489371) esp-tls-mbedtls: read error :-0x004C:
E (489371) transport_base: esp_tls_conn_read error, errno=Socket is not connected
E (489381) mqtt_client: esp_mqtt_handle_transport_read_error: transport_read() error: errno=128
E (489391) mqtt_client: esp_mqtt_connect: mqtt_message_receive() returned -1
E (489391) mqtt_client: MQTT connect failed

问题排查与修复方案

1. WiFi连接检查不可靠

硬编码vTaskDelay(5000)等待WiFi连接非常不可靠,实际环境中WiFi建立连接的时间不确定,可能导致MQTT客户端在WiFi未完全就绪时发起连接,引发socket错误。

修复:
替换硬等待逻辑,改为循环检查连接状态:

// 循环等待WiFi连接完成
while (wifi_sta_get_connect_status() != WIFI_CONNECTED) {
    vTaskDelay(100 / portTICK_PERIOD_MS);
}

2. 任务优先级拼写错误

配置中MAX_PRIROTY是拼写错误,正确应为MAX_PRIORITY,错误的宏会导致任务优先级设置异常,可能影响MQTT任务的正常运行。

修复:
将.task.priority = MAX_PRIROTY - 2改为.task.priority = MAX_PRIORITY - 2

3. 证书/密钥未正确嵌入固件

如果CMakeLists.txt中未配置嵌入证书和密钥文件,_binary_xxx_start等符号会无效,导致加载的证书/密钥为空,引发TLS验证失败。

修复:
在项目的CMakeLists.txt中添加EMBED_FILES指令,将所需的PEM文件嵌入固件:

idf_component_register(SRCS "main.c"
                       EMBED_FILES "root_ca.pem" "certificate.pem.crt" "private.pem.key")

4. TLS证书验证失败(错误码-0x004C)

错误码-0x004C对应MBEDTLS的MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,说明证书链验证不通过,可能的原因及修复:

  • 根CA错误:确认使用AWS官方提供的根CA(如Amazon Root CA 1,可从AWS IoT控制台下载)
  • 证书未激活:登录AWS IoT控制台,检查设备证书状态为「激活」
  • 策略权限不足:验证IoT策略包含允许iot:Connect的权限,资源需覆盖当前客户端ID:
    {
        "Effect": "Allow",
        "Action": "iot:Connect",
        "Resource": "arn:aws:iot:ap-northeast-2:你的AWS账号ID:client/ESP-TEST"
    }
    

5. 增强事件处理函数排查细节

当前事件处理函数仅打印基础事件信息,无法获取连接失败的具体错误细节,建议扩展函数以输出更多调试信息:

void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    esp_mqtt_event_t *event = (esp_mqtt_event_t *)event_data;
    switch (event_id) {
        case MQTT_EVENT_ERROR:
            ESP_LOGE(TAG, "MQTT错误类型: 0x%x", event->error_handle->error_type);
            if (event->error_handle->esp_tls_last_esp_err != 0) {
                ESP_LOGE(TAG, "ESP TLS错误码: 0x%x", event->error_handle->esp_tls_last_esp_err);
            }
            if (event->error_handle->esp_tls_stack_err != 0) {
                ESP_LOGE(TAG, "TLS栈错误码: 0x%x", event->error_handle->esp_tls_stack_err);
            }
            break;
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT连接成功");
            break;
        default:
            ESP_LOGD(TAG, "事件来源: %s, 事件ID: %ld", base, event_id);
            break;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:55