use va_list from another thread

Viewed 1360

I am working with FreeRTOS (newlib) on a small embedded system and have found that printf and family waste a tremendous amount of stack space. I have many tasks, and I do not have enough ram to make the stack for each large enough to support printf() calls. To work around this, I am working to create a "printf server" task that will have a large stack and do all printf()s on the behalf of other tasks.

So my question is, what is the proper way to transport the va_list to the other thread(task)? The example below produces garbage params.

A quick word about how this works: task_printf() will plop its parameters into static variables and then signal the server_task to perform the actual print. When the server_task is done, it signals the client to continue.

// 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);

    ...
}
1 Answers
Related