6

小さな組み込みシステムで FreeRTOS (newlib) を使用していますが、printf とファミリが大量のスタック スペースを浪費していることに気付きました。多くのタスクがあり、それぞれのスタックを printf() 呼び出しをサポートするのに十分な大きさにするのに十分な RAM がありません。これを回避するために、大きなスタックを持ち、他のタスクに代わってすべての 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);

    ...
}
4

1 に答える 1

5

さて、上記は実際に機能します。セマフォの初期化 (表示されていません) を台無しにしてしまい、printf サーバーが引数を使用する前に、呼び出し元のスタックが引数を破棄してしまいました。

于 2012-07-20T20:36:46.217 に答える