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