use va_list from another thread

c, freertos, printf, variadic-functions

Solution

Well, the above actually works now. I messed up on semaphore initialization (not shown) which allowed the caller's stack to trash the args before the printf server could use them.

Problem

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); ... } ```

Original source