Global training solutions for engineers creating the world's electronics

Retargeting a C Library Function

Overview

In this tutorial we will look at printing messages on a text console.

Background Information

In a typical C application messages are printed onto the computer screen via printf(). However, in the case of an embedded device, the printf() functionality would have to be altered to redirect the characters from a computer screen to a console. Since there is no true console attached, STDOUT will be emulated using Cortex-M3 ITM (Instrumentation Trace Microcell). ITM is output-only, so STDIN will be emulated by a special protocol defined by CMSIS and hardwired into µVision. The main advantage of STDIN/STDOUT emulation is that it works in exactly the same way in the simulator as on every Cortex-M3 device.

To get the best out of this tutorial you may decide to download the following support files. In exchange, we will ask you to enter some personal details. To read about how we use your details, click here. On the registration form, you will be asked whether you want us to send you further information concerning other Doulos products and services in the subject area concerned.

Download the files for this tutorial »
Download the required software »

Actions

  • Invoke μVision and navigate to the \intro\session1 directory: File > Open.

  • Open the provided project file called session1.uproj.

  • Ensure that project session1 is active (highlighted). Otherwise right-click the project name and select: Set as Active Project.

Starting from the files provided for our previous tutorial, we have now added a printf() statement inside the loop to print the value of the variable .

int main(void) {
	int j = 0;
	unsigned char i =0;

	while (1) {
		j++;
		if (j==1000000) {
			j = 0;
			if (i==0xFFFF) i = 0;
			printf("Value of i: %d\n", i);
			i++;
		}
	}
}

The provided file \intro\common\retarget.c has been added inside the User group. This file redefines functions used by printf() for outputting characters. The printf() function ultimately relies on the fputc() function to operate. The fputc() has been implemented using the CMSIS standard function ITM_SendChar().

int fputc(int ch, FILE *f) {
    return ITM_SendChar(ch);
}

In contrast the fgetc() function relies on the CMSIS standard function ITM_ReceiveChar().

int fgetc(FILE *f)
{
    int r;
    
    /* if we just backspaced, then return the backspaced character */
    /* otherwise output the next character in the stream */
    if (backspace_called == 1)
    {
      backspace_called = 0;
    }
    else {
        do {
            r = ITM_ReceiveChar();
        } while (r == -1);
        last_char_read = (unsigned char)r;
#ifdef ECHO_FGETC
        ITM_SendChar(r);
#endif
    }
    return last_char_read;
}

The declaration of the ITM_SendChar() can be found inside the core_cm3.h file and is as follows:

static __INLINE uint32_t ITM_SendChar (uint32_t ch)

To complete the separation from the standard I/O library we also have had to redefine __stdout and __stdin. These can be found inside the retarget.c file below the declaration of the __FILE structure.

FILE __stdin;
FILE __stdout;
  • You will have to rebuild the project and re-invoke the debugger (see previous tutorial).

  • In order to watch the program output we will need a text console. If the Debug (printf) Viewer is not visible, it can be activated via the menu: View > Serial Windows > Debug (printf) Viewer.

  • Execute the program and observe the message printed on the terminal.

This concludes this second part of the series. In the final tutorial we will look at proving that our program is working adequately by executing it on a hardware evaluation board.

Back to "Getting Started with Cortex-M3 CMSIS Programming"