【问题标题】:Guru Meditation Error: Core 1 panic'ed when using sprintfGuru Meditation 错误:使用 sprintf 时核心 1 出现恐慌
【发布时间】:2021-07-31 07:32:58
【问题描述】:

我正在使用 Ardunio/ESP32,而且我对 FreeRTOS 非常陌生。我正在尝试将一个 int 值转换为std::string,因为我没有to_string,所以我使用了sprintf

我注意到当我在如下任务函数中调用 sprintf 时,ESP32 崩溃了,我找不到原因。

bool PushMessageToSerial(const std::string &source, const std::string &message, log_t log)

void SensorActions(void *parameters)
{
    PushMessageToSerial("Setup", "Sensors Monitor task is initialized", LOG_INFO);

    while (1)
    {
        while (xQueueReceive(queue_sensors, (void *)&action, 10) == pdTRUE)
        {
            switch (action)
            {
            case actions_t::ACTION_SENSOR_VERSION:
            {
                uint8_t version[4] = {0};
                sensor.GetVersions(version);

                uint8_t length = sprintf(NULL, 0, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);
                assert(length >= 0);
                char *buf = new char[length + 1];
                sprintf(buf, length + 1, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);
                std::string text(buf);
                free(buf);
                PushMessageToSerial("Sensors", text, LOG_INFO);
            }
            break;

            default:
                break;
            }
        }
        vTaskSuspend(NULL); // Auto suspend the task to not blocking the other lower priority tasks
    }
}

能否请您给我一个提示以了解问题所在?

【问题讨论】:

  • sprintf() 的参数错误,sprintf() 没有缓冲区大小参数。这段代码甚至不应该编译。如果要指定缓冲区的大小,请使用 sprintf_s()snprintf()
  • 感谢雷米的回复。但是snprintf() 也有同样的问题。
  • 为什么要 vTaskSuspend 以及为什么要定时 xQueueReceive ?消息的 std::string 副本有什么好处?
  • 嗯,这个任务有高优先级,当队列中没有任何东西时会暂停自己,所以不会打扰低优先级的任务。我不太了解您关于定时 xQueueReceive 的问题!队列部分的定时部分?和你上一个问题一样!

标签: c++ arduino freertos


【解决方案1】:

这行有问题:

uint8_t length = sprintf(NULL, 0, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);

您不能将NULL 作为第一个参数传递给sprintf();相反,您必须传递一个指向缓冲区的指针,该缓冲区足够大以容纳您希望sprintf() 写入的文本。如上所示,代码告诉sprintf() 通过NULL 指针写入其输出,这会导致分段错误。第二个参数(0)也是错误的,应该删除; sprintf() 的第二个参数应该是格式字符串 ("%d.%d.%d.%d")。

【讨论】:

    猜你喜欢
    • 2021-10-09
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多