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

Output 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.

Handle printf output characters

C

1

2

3

4

5

6

7

8

9

10

/* Handle printf actions */

intTM_STDIO_StdoutHandler(intch,FILE*f){

/* Do with your character what you need here */

/* Return ch, it means OK */

returnch;

/* If you want to return error, then you have to send EOF (-1) */

//return -1;

}

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:

Printf send data to USART

C

1

2

3

4

5

6

7

8

9

10

/* Handle printf actions */

intTM_STDIO_StdoutHandler(intch,FILE*f){

/* Send data to USART1 */

TM_USART_Putc(USART1,(char)ch);

/* Return ch, it means OK */

returnch;

/* If you want to return error, then you have to send EOF (-1) */

//return -1;

}

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.

More output streams variable

C

1

FILE LCD_Stream;

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

1

2

3

4

5

6

7

8

intLCD_Stream_OutputFunction(intch,FILE*f){

/* Do your stuff here with new character */

/* Return ch, it means OK */

returnch;

/* If you want to return error, then you have to send EOF (-1) */

//return -1;

}

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

Add output stream function for LCD

C

1

2

/* Add output function for LCD_Stream */

TM_STDIO_SetOutputFunction(&LCD_Stream,LCD_Stream_OutputFunction);

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

Print data using fprintf

C

1

2

/* Print something on LCD */

fprintf(&LCD_Stream,"Hello world");

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:

Default stdin handler

C

1

2

3

4

5

6

7

8

/* Handle stdin actions */

intTM_STDIO_StdinHandler(FILE*f){

/* Return your data here */

/* End of data, string is valid */

/* You have to send -1 at the end of string */

return-1;

}

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.