Skip to main content
gae089
Associate
September 1, 2015
Question

How to use printf() function with stm32cubeMX + sw4stm32

  • September 1, 2015
  • 12 replies
  • 7449 views
Posted on September 01, 2015 at 19:13

Hi to every one,

It's the first time that I use the STM32CubeMX + SWSTM32 to program a stm32f401RE board. I have done already some example project but I can't use the printf() function to communicate  with a terminal ( Tera Term) on the PC. Somebody can explain me how I can do it?

Thank you in advance!!
This topic has been closed for replies.

12 replies

mile milestone
Visitor II
October 18, 2017
Posted on October 18, 2017 at 13:05

PLEASE ALLOW ME TO ADD DETAILS OF WHAT I'VE DONE, TESTED ON NUCLEO F401RET

1. Using CUBEMX, I configures USART 2 as my serial communication (set as Asynchronous) and let it (cubemx) generate all initilial files and folders

   CUBEMX USART2 SETUP:

   - Asynchronous

   -Parameter Setting by Default, except  Baud Rate is 115200 

   -NVIC Setting, uncheck the UART global interrupt

   -Did not touch the rest

   - Finally, hit the Generate Code Icon !!

2. Opening the project with AC6 Workbench we should see something like this

0690X00000608fQQAQ.png

3. NOW LET'S DO THE ADDITIONAL CODES AND SOME STEPS

Step 1 Let's add the following two function in our main.c - you can place them above the main() function 

in my case i paste it on /* USER CODE BEGIN PV */ see highlighted

#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

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

#endif /* __GNUC__ */

PUTCHAR_PROTOTYPE

{

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

return ch;

}

see pic below

0690X00000608fzQAA.png

Step 2 : Modify the linker flag in the project properties.

2.1 Go to Menu: Project\Properties\

2.2 Expand  C\C++ Build on left pane, select Settings

2.3 On middel expand MCU GCC Linker drop down menu, and select Miscellaneous

2.4 Now on the rightside you can see the the ''Linker Flag'' text box.

2.5 Replace/update  the text to 

      -specs=nosys.specs -specs=nano.specs -u _printf_float

Hit Ok

0690X00000608crQAA.png

Step 3: Locate the file ''

syscalls.c

'' and place it on startup folder i.e. together with 

startup_stm32f401xe.s

 

It should appear in the ''project explorer'' under ''startup'' folder

I found  syscall.c in the repository of example folder of CubeMX . i.e. C:\Users\My\STM32Cube\Repository\STM32Cube_FW_F4_V1.16.0

STEP 4: I did check on STM32F401RETx_FLASH.ld  file (on file exporer, its the file on the last - see picture) as suggest in the comment above and it is 

0x20018000 by default so i leave it as is.

/* Highest address of the user mode stack */

_estack = 0x20018000; /* end of RAM */0690X00000608gJQAQ.png

FINAL STEP. Finally I tried and run inside loop 

printf

(

''%f\t  %i\n''

, 0.1250f, 12345); It woks.

Hope will be useful for future user. I wish printf() would be a straightforward feature of the IDE so we don't have to work around.

If there is better approach, please share.

I Thank you for all the inputs mentioned in this forum.

Zt Liu
Senior III
November 20, 2017
Posted on November 20, 2017 at 05:08

Good job, mile! 

:)

Just a quick reminder.

The core of this retargeting is using HAL_UART_Transmit(), 

which works in blocking mode and strings are sent 

character

by character.

If your application needs to do some heavy task without much resource for debug print, you may consider use DMA.

.Zt

Tesla DeLorean
Guru
November 20, 2017
Posted on November 20, 2017 at 05:29

Buffering to a FIFO and using an IRQ are also extremely effective. Where that is not practical a very high baud rate can help.

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