Library 41- STDIO implementation for STM32F4

After I made a tutorial on how to use printf with STM32F4, I decided to make a library for printf and other functions that are able to output data to the stream. This library allows you to basically use unlimited different output streams, but just one can be use with printf at a time. You can use other output functions, like fprintf, which accepts stream pointer as parameter to know where to output data.

Library

Features

  • Output strings using printf or any other function, like fprintf, etc
  • Any function which is able to output data to the stream can be used
  • Basically unlimited output streams can be used
  • Version 1.1 – October 19, 2014
    • Added support to read from standard input (stdin) stream or user defined

Dependencies

  • CMSIS
    • STM32F4xx
  • TM
    • defines.h
    • attributes.h

Output format

According to the ARM stdio library, you can use printf or any other output stream fuctions. Proper use of different possible output types is described on ARM site.

Printf format

Printf

Main function in this section is probably printf. With just simple call, you can at the same time convert your string and send it to your desired output. This can be like USARTs, LCDs, SPI, …, and any others which are on your mind. But with printf, you can only output data to one stream, let’s say just USART1. If you now want to display data to LCD too, you need another method for this, like using fprintf. In this section, I will describe how to proper use printf with my library.

Basically, you just need to include my library and create a function, that will output data to your location. You can create function anywhere in your project, it’s important that have the correct name and parameters. Function must be like this below.

So if you want to output with printf data to USART1, you first need to initialize it in main, but then you should create a function like this:

Now you can use anywhere in your project printf function.

More output streams

If you want to use more output streams, then you have to split them somehow, so you will know on which stream you have to output data. This can be done with fprintf, vfprintf and maybe any more. First argument to this function is output stream pointer, so when you use stream output function you know to which stream you have to output.

For that purpose, I make some additions in my library. First, you have to create as many variables as different output streams you will use.

If you want to use output streams for USART and LCD now, you can use printf method (default) for USART and another method (with custom output streams) for LCD.

First, you need to create a variable.

Then, you have to create a function, with your custom name but parameters must match these in example below.

But stream still doesn’t know which function to call. You have to tell him. Do this with function like this below.

If you now call function like in example below, then you will be able to output data to LCD.

Input stream

As of version 1.1, you are also able to get data from stream. For that purpose, you have again one standard function name for stdin (standard input) and also possibility for other custom function names for other functions. For handle stdin action, you need function like this:

So you can now call fgets function to get string from stream.

For custom streams, like let’s say USART6 Stream, you have to create a custom function that will handler USART6 Stream input data. You can give it a name you want, it’s important that structure is valid.

And you have to link input function with actual stream. In the beginning of the main, you have to add something like this:

And you are ready. You can now use standard input functions. For detailed, look Example 2.

Functions and enumerations

Example 1

In example below, data is going out on 3 different USART channels.

  • USART1
    • You can print to USART1 using printf
  • USART2
    • You can print to USART2 using fprintf with custom output channel
  • USART6
    • You can print to USART6 using fprintf with another custom output channel

Example 2

In example below, data is going out on 3 different USART channels.

  • USART1
    • You can print to USART1 using printf
    • If you send data to USART1, it will return the same data back
  • USART2
    • You can print to USART2 using fprintf with custom output channel
    • If you send data to USART6, it will return the same data back
  • USART6
    • You can print to USART6 using fprintf with another custom output channel
    • If you send data to USART16 it will return the same data back

Projects are available on Github, download library here.

Icon
TM STM32F4 STDIO Library

Use printf and fprintf functions to output data to the stream

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Pingback: All STM32F4 libraries - STM32F4 Discovery()

  • Victor

    Hi buddy, Have you tested this function on Coocox IDE? I got two errors on build:
    “FILE has no member outputFuncPointer” and “FILE has no member inputFuncPointer”. I’m using STM32F4-Discovery board. What I’m doing wrong?

    • Hello Victor,

      well I didn’t tested this on GCC based compilers because they need some workaround before streams will work properly and I don’t like this.
      So it may happen that it does not work.

      • Milar

        So is it somewhere that I can find the code for gcc compiler?
        Thank you very much!

      • Milan

        Oh I am sorry I have left a wrong email and I really want to know how to run it use gcc…
        Thank you so much!!!

    • Milan

      Hi I have met the same problem and have you solved that?
      Thank you!

  • Victor

    Which compiler you are using? I’m using arm-none-eabi-gcc linked with CooCox

  • zotya701

    Hello!

    Why is scanf not wait until i hit enter in putty?
    Here’s my code: http://pastebin.com/rBVR9YgF

    If i am fast and for example type 777 in terminal, next it would print 7770, but even if a do nothing, this will continuously print a=b=a*b=100 every second.

    As i know it should wait until i hit enter, but this do not wait for anything.

    Do you have any idea?

    • That’s logical.

      STDIN handler function checks for data in buffer, if there is no data in buffer, -1 is returned.
      You should know that reading STDIN continuously is faster than data can flow through USART.
      And function returns that buffer is empty directly. You should first check if buffer has n (end of line) and then call scanf.

      • zotya701

        Thank you, it is working now, altough i am searching for ‘r’ becouse as it turned out, putty sends ‘r’ when i hit the enter button. But now i can normally read in numbers, and program waits for the input, thanks again.