cancel
Showing results for 
Search instead for 
Did you mean: 

How to retarget printf on UART?

MKora
Associate II

Hi All,

I am new on STM32 and want to use printf on UART.

I could run the printf on uart in the example folder.

But couldnt find how does it work, actually couldnt find any comment in it about enabling printf on uart.

I am useing STM32CubeMx and want to enable printf on its projects.

I have tried some suggestion like adding following function that didnt work:

void __io_putchar(uint8_t ch) {

/**

* \brief __io_putchar - A routine to transmit a single character out the serial port

* \return void

* \param[in] ch - uint8_t the character to transmit

* \author andreichichak

* \date Oct 16, 2015

* \details This routine assumes that we will be using UART2. A timeout value of 1ms (4th parameter)

* gives a retry if the transmit buffer is full when back to back characters are transmitted,

* avoiding dropping characters.

*/

HAL_UART_Transmit(&huart2, &ch, 1, 1);

}

Could someone help me on this issue?

I am using NUCLEO-L011K4 board.

Mostafa

1 ACCEPTED SOLUTION

Accepted Solutions
MKora
Associate II

Hi All,

I found a very usefull video on youtube about it from an indian guy.

The only thing that you need is to add following lines to the main.c

#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

PUTCHAR_PROTOTYPE

{

HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);

}

/******************************************************************************

 *

I dont know why ST didnt mention it in the example!!!

Hope no one else spend time on this issue.

Mostafa

View solution in original post

5 REPLIES 5

What toolchain?

You'd still need to initialize the clocks, pins and peripheral for the specific U(S)ART involved.

On the Nucleo-32 only ONE UART is available to go to the ST-LINK VCP, and SB2/SB3 would need to be made.

PA2 (USART2_TX, AF4) and PA15 (USART2_RX, AF4) are used

https://www.st.com/content/ccc/resource/technical/document/user_manual/e3/0e/88/05/e8/74/43/a0/DM00231744.pdf/files/DM00231744.pdf/jcr:content/translations/en.DM00231744.pdf

https://www.st.com/resource/en/datasheet/stm32l011k4.pdf

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MKora
Associate II

Hi All,

I found a very usefull video on youtube about it from an indian guy.

The only thing that you need is to add following lines to the main.c

#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

PUTCHAR_PROTOTYPE

{

HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);

}

/******************************************************************************

 *

I dont know why ST didnt mention it in the example!!!

Hope no one else spend time on this issue.

Mostafa

ST has very little to do with this issue. The compiler and version of newlib or its equivalent take care of printf, then you have to point a function (like _io_putchar or putchar or io_putchar) within the printf stack to the UART registers that you want. But the syntax and semantics of that function are set by the compiler writers.

ST provides the UART register hardware. Your compiler writers (Keil, IAR, GCC, Greenhills, ICC) provide the hooks to point printf at the registers. Your compiler writer MUST provide the documentation for making that connection, not ST.

That and there are many links in the chain, any one of which could cause the feature to "not work"

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
cakira
Associate

The code, as posted, worked but generated some warnings. I fixed them adding a return value to the function. The result:

 

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}