Retargetting a C Library Function
Overview Following on from (Getting started with Cortex-M3 CMSIS programming >>). In this tutorial we will look at printing messages on a text console.
Background Information
In a typical C application messages are printed to 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. 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.