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

ESP32-S3(ESP-IDF)FreeRTOS回调函数未触发问题求助

排查ESP32-S3 FreeRTOS任务回调未执行的问题

核心问题1:回调函数指针传递错误

你在app_main中调用xTaskCreate时,传递的是&Task_NMEA_cb——但Task_NMEA_cb作为函数名本身就是一个函数指针,取它的地址会变成二级指针。而Nmea_Task里直接将arg赋值给nmea_cb_t类型的callback,类型完全不匹配,导致回调调用时出现未定义行为(根本没正确指向你写的Task_NMEA_cb函数)。

修复代码:
修改app_main中的任务创建语句,直接传递函数名即可:

xTaskCreate(Nmea_Task, "task_nmea", 2048, Task_NMEA_cb, 10, &taskNMEAHandle);

核心问题2:USB Serial JTAG与标准IO的绑定问题

你用usb_serial_jtag_read_bytes读取USB JTAG串口的数据,但回调里用printf输出到stdout——默认情况下ESP-IDF的stdout并未绑定到USB Serial JTAG(通常默认是UART0),就算回调执行了,你也看不到输出。

两种修复方案:

方案A:重定向标准IO到USB Serial JTAG

在app_main开头添加重定向代码,让stdin/stdout和USB JTAG串口关联:

#include <esp_vfs_dev.h>
#include <stdio.h>

void app_main(void)
{
    // 绑定标准IO到USB Serial JTAG
    esp_vfs_usb_serial_jtag_use_stdio();
    // 禁用缓冲,确保输出实时显示
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    xTaskCreate(Nmea_Task, "task_nmea", 2048, Task_NMEA_cb, 10, &taskNMEAHandle);
    while (1)
    {
        vTaskDelay(1);
    }    
}

方案B:回调中直接用USB串口API输出

如果不想修改标准IO,直接在回调里用usb_serial_jtag_write_bytes输出:

void Task_NMEA_cb(char *line)
{
    usb_serial_jtag_write_bytes(line, strlen(line), portMAX_DELAY);
}

额外优化建议

  • 全局data数组存在线程安全风险:如果回调还在处理数据时,Nmea_Task又读取了新内容,会直接覆盖缓冲区。可以改为在任务内部分配缓冲区,或者用互斥锁保护data数组。
  • 超时参数用FreeRTOS宏更清晰:把20 / portTICK_PERIOD_MS替换成pdMS_TO_TICKS(20),可读性更强:
int len = usb_serial_jtag_read_bytes(data, (NMEA_BUFFER_SIZE - 1), pdMS_TO_TICKS(20));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:32:09