从另一个线程使用va_list

goe*_*tor 5 c printf variadic-functions freertos

我在一个小型嵌入式系统上使用FreeRTOS(newlib),发现printf和family浪费了大量的堆栈空间.我有很多任务,而且我没有足够的ram来使每个大的堆栈足以支持printf()调用.为了解决这个问题,我正在创建一个"printf服务器"任务,它将拥有一个大堆栈并代表其他任务执行所有printf().

所以我的问题是,将va_list传输到另一个线程(任务)的正确方法是什么?以下示例生成垃圾参数.

关于这是如何工作的快速说法:task_printf()将其参数填充到静态变量中,然后发出server_task信号以执行实际打印.当server_task完成时,它会通知客户端继续.

// printf parameters
static va_list static_args;
static const char *static_format;
static int static_result;


// printf server task.  Processes printf requests forever
void server_task(void *pvParameters)
{
    while(1)
    {
        xSemaphoreTake(printf_start, portMAX_DELAY);  // wait for start command
        static_result = vprintf(static_format, static_args);
        xSemaphoreGive(printf_finished);  // give finish signal
    }
}


// get server task to print something for us
int task_printf(const char *format, ...)
{
    int result;

    xSemaphoreTake(printf_mutex, portMAX_DELAY); // lock

    va_start(static_args, format);
    static_format = format;

    xSemaphoreGive(printf_start);  // give start signal
    xSemaphoreTake(printf_finished, portMAX_DELAY);  // wait for completion

    va_end(static_args);

    ...
}
Run Code Online (Sandbox Code Playgroud)

goe*_*tor 5

好吧,以上实际上现在有效。我搞砸了信号量初始化(未显示),它允许调用者的堆栈在 printf 服务器可以使用它们之前丢弃参数。