How to use the printf function on STM32

cmicrocontrollerstm32stm32cubemxstm32f4

I am trying to figure out how to use the printf function to print to the serial port.

My current setup is STM32CubeMX generated code and SystemWorkbench32 with the STM32F407 discovery board.

I see in stdio.h that the printf prototype is defined as:

int _EXFUN(printf, (const char *__restrict, ...)
               _ATTRIBUTE ((__format__ (__printf__, 1, 2))));

What does it mean? Where is the exact location of this function definition? What would be general point of finding out how to use this kind of function to output?

Best Answer

I got the first method from this page working on my STM32F072.

http://www.openstm32.org/forumthread1055

As stated there,

The way I got printf (and all other console-oriented stdio functions) to work was by creating custom implementations of the low-level I/O functions like _read() and _write().

The GCC C library makes calls to the following functions to perform low-level I/O :

int _read(int file, char *data, int len)
int _write(int file, char *data, int len)
int _close(int file)
int _lseek(int file, int ptr, int dir)
int _fstat(int file, struct stat *st)
int _isatty(int file)

These functions are implemented witihin the GCC C library as stub routines with "weak" linkage. If a declaration of any of the above functions appears in your own code, your substitute routine will override the declaration in the library and be used instead of the default (non-functional) routine.

I used STM32CubeMX to setup USART1 (huart1) as a serial port. Since I only wanted printf(), I only needed to populate the _write() function, which I did as follows. This is conventionally contained in syscalls.c.

#include  <errno.h>
#include  <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO

int _write(int file, char *data, int len)
{
   if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
   {
      errno = EBADF;
      return -1;
   }

   // arbitrary timeout 1000
   HAL_StatusTypeDef status =
      HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 1000);

   // return # of bytes written - as best we can tell
   return (status == HAL_OK ? len : 0);
}