I am trying to delegate the actual execution of printf()'s to a seperate task. The call to my variant of printf() should only queue a message for the printf()-task. Does anyone know of a portable way to pass the caller’s arguments using a queue (both ends)? Preferably without the need of examining the format-string on both sides.
Have the task that creates the string sprintf() the string to a buffer, then pass a pointer to the buffer on the queue to the task delegated with the actual output.
Check your sprintf() function is thread safe. Should be if it targets embedded.
The buffers can be pre allocated if you have enough RAM, with the task that actually does the output marking the buffer as free, or adding it to a free list, once its contents have been completely output.
Just one idea. There are probably other ways of achieving the same thing. If your output only contains constant strings then there is no problem of course, you only get issues when the strings are created dynamically.
I would like to have the “formatstring+argument”-processing done by the printf-task as well.
well the question is how careful you want to be, and if you don’t have to be completely general.
I have just done this, but I simplified it by limiting the # of arguments to a reasonable size (I chose 6 - but then I’m writing to a 2x16 character display!).
On the transmitting side you use a variadic function and copy the maximum # of arguments you want to support (remember longs and floats count double and of course doubles count 4 times)
On the receiving side you can just create a function call
fprintf( fmt, arg1, arg2, arg3 , argn );
fprintf will not care if there are extra arguments and the longs and long longs will “reassemble” themselves.
In my case I assumed - specified/restricted - the formats to be constant and universally accessible and passed a pointer to the format and then the actual arguments in a single struct through a queue.
Because you are fetching a fixed number of arguments it is possible that this can cause a problem, but on most machines they are stored on the stack and unless you go crazy you shouldn’t be accessing outside the stack