Which library are you using?
Many libraries that try to be C standard compliant (eg: newlib-nano) provide a vprintf function, which takes a
va_list argument, instead of being variadic as printf.
In fact, printf is often implemented using vprintf.
vprintf() can easily be used to build your own special printf(), exactly as the one you prototyped in the OP - well, apart from the syntax error...
/* Global variable to hold the UART in use */
extern UART_HandleTypeDef *currentUart;
int printfUart(UART_HandleTypeDef *uart, const char *format, ...)
{
/* Assign the passed UARAT handle to a global variable, to be used in printchar */
currentUart = uart;
va_list va;
va_start(va, format);
const int returnValue = vprintf(format, va);
va_end(va);
return returnValue;
}
The
currentUart variable (of type UART_HandleTypeDef *) should be visible and used by your
putchar() to send the character to the right UART.
[...]
UART_HandleTypeDef *currentUart;
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(currentUart, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
Reentrancy is not supported by the simple implementation above (important if you have a degree of parallelism, or if you want to call the function from an ISR - you shouldn't in any case, though).
If you do not have a vprintf, I often use
this very small implementation of the printf family.
Note: code not tested. I take no liability if your toothbrush catches fire or your cat becomes green.