2022-02-24 12:34 AM
Hi,
I know the question has been asked before, and there is some information (to some extent) on the internet, though I cannot seem to make it happen. My question is:
How can I use print() for debugging purpose? I have an UART peripheral up and running fine. I have a syscalls.c file that has a _write() function defined:
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}
So to my understanding, I should have the UART transmit implementation inside my _write function. So the modified _write function would look like this:
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
// __io_putchar(*ptr++);
while (!LL_USART_IsActiveFlag_TXE(USART2)) {}
LL_USART_TransmitData8(USART2, ptr[DataIdx]);
}
return len;
}
So when using
printf("Hello, world");
somewhere in my code, I would expect my _write function to be called.
However, doing step-by-step debugging, I can see that my printf() never calls the _write function.
Please find below my linker arguments:
-mcpu=$(MACH) -mthumb -mfloat-abi=soft --specs=nano.specs --specs=nosys.specs -TSTM32G031K8TX_FLASH.ld -Wl,-Map=$(OUTPUT)/$(BIN).map -Wl,--gc-sections -static
Can anyone guide me on what I am doing wrong?
Thank you,
Solved! Go to Solution.
2022-02-24 01:14 AM
Depending on the compiler, printf uses the function __io_putchar() or fputc.
If you use e.g. STM32CubeIDE (based on GNU GCC), you would have to adapt the function __io_putchar.
Please note that __io_putchar has the attribute weak, so you should define the new __io_putchar in your main.c for example.
Good luck!
Regards
/Peter
2022-02-24 01:14 AM
Depending on the compiler, printf uses the function __io_putchar() or fputc.
If you use e.g. STM32CubeIDE (based on GNU GCC), you would have to adapt the function __io_putchar.
Please note that __io_putchar has the attribute weak, so you should define the new __io_putchar in your main.c for example.
Good luck!
Regards
/Peter
2022-02-24 02:35 AM
Thank you, Peter. It somewhat works, but not entirely. I have posted my full minimalistic code below, where I also show my modification of __io_putchar(). I am using arm-none-eabi-gcc as you mentioned
2022-02-24 02:36 AM
Managed to got it work. Following __io_putchar(int ch) implementation does the job:
int __io_putchar(int ch)
{
while (!LL_USART_IsActiveFlag_TXE(USART2)) {}
LL_USART_TransmitData8(USART2, ch);
return ch;
}
Thank you,
2023-10-05 09:26 AM
This guide and a video I found on YouTube suggest overring weak functions _write or __io_putchar() or fputc.
I have done that and cant get UART output using printf but it is working with
HAL_UART_Transmit(&huart1, (uint8_t *)szMsg, counter++, 1000);
User defined versions of _write or __io_putchar never get hit.
I walked through the disassembly of printf and these functions are never called. ANy Ideas?
2023-10-05 11:41 AM
Started working when I added fflush(stdout);
2023-10-05 12:00 PM
2024-06-18 11:32 AM
Thank you! I was pulling my hair out trying to override __io_putchar() and _write() and fputc() and not seeing any of those functions getting called by printf(). Adding fflush(stdout) made it work.
2024-06-18 12:52 PM
> Adding fflush(stdout) made it work.
Just disable buffering stdout.
setbuf(stdin, NULL);
setbuf(stdout, NULL);
Also, the GNU library has function dprintf. It is like printf but prints to a file descriptor instead of FILE, without any buffering.