Я работаю с FreeRTOS (newlib )в небольшой встроенной системе и обнаружил, что printf и семейство тратят огромное количество пространства стека. У меня много задач, и мне не хватает оперативной памяти, чтобы сделать стек для каждой достаточно большим для поддержки вызовов printf (). Чтобы обойти это, я работаю над созданием задачи «сервер printf», которая будет иметь большой стек и выполнять все printf ()от имени других задач.
Итак, мой вопрос: как правильно перенести список va _в другой поток (task )? В приведенном ниже примере создаются параметры мусора.
Коротко о том, как это работает :task _printf ()запишет свои параметры в статические переменные, а затем подаст сигнал задаче сервера _для выполнения фактической печати. Когда задача сервера _выполнена, она сигнализирует клиенту продолжить работу.
// 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);
...
}