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

ESP32中使用LVGL与FreeRTOS时Queue接收值异常问题

问题:ESP32上LVGL+FreeRTOS队列发送msgID正常,但接收始终为0

在ESP32上使用LVGL和FreeRTOS实现GUI任务时,发送队列消息的msgID日志显示正常,但任务处理函数中接收到的msgID始终为0。

日志信息

I (105690) wifi_app: WIFI_APP_MSG_STA_DISCONNECTED: USER REQUESTED DISCONNECTION
I (105700) LVGL: SEND MESSAGE
I (105700) LVGL: SENDING msgID 4 // when send
I (105710) LVGL: RECEVING msgID: 0 // read message in handler
I (105710) LVGL: Get NTU from sensor
I (105720) http_server: HTTP_MSG_WIFI_USER_DISCONNECT

处理函数代码

static void cmd_parsing(void *arg)
{
    lvgl_queue_message_t lvglMsg;

    for (;;)
    {

        if (xQueueReceive(lvgl_queue_handle, &lvglMsg, portMAX_DELAY))
        {

            ESP_LOGI(TAG, "Recieving msgID: %d", lvglMsg.msgID);
            switch (lvglMsg.msgID)
            {
                case LVGL_MSG_SEND_NTU:
                        ESP_LOGI(TAG, "Get NTU from sensor");
                        //                    lv_label_set_text(label_ntu, evt.string1);
                        lv_label_set_text_fmt(label_ntu, "%0.3f NTU", lvglMsg.valueFloat);
                        break;
                case LVGL_MSG_WIFI_CONNECT_INIT:
                        ESP_LOGI(TAG, "Create spinner for connecting Wi-Fi");

                        create_spinner();

                        xSemaphoreGive(xGuiSemaphore);
                    break;
                case LVGL_MSG_WIFI_USER_DISCONNECT:

                        ESP_LOGI(TAG, "WIFI_USER_DISCONNECT");

                        lv_obj_clean(settings_tab);
                        create_list_settings();
                    break;
                default:
                    break;
            }
        }
    }
}

发送函数代码

BaseType_t lvgl_send_message(lvgl_message_e msgID)
{
    ESP_LOGI(TAG, "SEND MESSAGE");
    ESP_LOGI(TAG, "Sending msgID %d", msgID);
    lvgl_queue_message_t lvglMsg;
    lvglMsg.msgID = msgID;
    return xQueueSend(lvgl_queue_handle, &lvglMsg, portMAX_DELAY);
}

排查与解决方法

1. 验证队列创建的元素大小

创建队列时必须指定正确的元素大小,即sizeof(lvgl_queue_message_t),否则会导致数据拷贝不完整:

// 正确的队列创建方式
lvgl_queue_handle = xQueueCreate(8, sizeof(lvgl_queue_message_t));

如果元素大小设置为sizeof(lvgl_message_e)或其他错误值,会截断结构体数据,导致msgID解析错误。

2. 确保结构体定义全局一致

发送和接收任务所在的所有文件中,lvgl_queue_message_t的结构体定义必须完全相同,包括成员顺序、类型:

// 示例结构体定义
typedef enum {
    LVGL_MSG_SEND_NTU,
    LVGL_MSG_WIFI_CONNECT_INIT,
    LVGL_MSG_WIFI_USER_DISCONNECT,
    // 其他枚举值
} lvgl_message_e;

typedef struct {
    lvgl_message_e msgID;
    float valueFloat;
    // 其他成员(如果有)
} lvgl_queue_message_t;

若结构体定义不一致,接收时会错误解析内存中的数据,导致msgID为0。

3. 检查队列句柄有效性

确保lvgl_queue_handle是全局变量或通过正确方式传递,未被意外覆盖或未初始化。无效句柄可能导致队列操作异常,进而引发数据错误。

4. 增大GUI任务栈大小

如果GUI任务栈空间不足,局部变量lvglMsg可能被栈溢出覆盖。尝试增大任务栈大小,例如:

// 创建GUI任务时增大栈大小
xTaskCreate(cmd_parsing, "lvgl_cmd_task", 4096, NULL, 5, NULL);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:25:28