Using printf in your applications (Semihosting)
What is semihosting
When creating a new embedded application, it can sometimes be useful during the early stages of development to be able to output debug status messages to indicate what is happening as your application executes.
Traditionally, this might be done by piping the messages over, say, a serial cable connected to a terminal program running on your PC. Code Red's IDE also offers an alternative to this, called semihosting. Semihosting provides a mechanism for code running on the target board to use the facilities of the PC running the IDE. The most common example of this is for the strings passed to a printf being displayed in the IDE's console view.
Some more information on Semihosting can be found here.
Building your code for semihosting
In order to make use of the semihosting functionality, your project needs to link with a version of the C library which contains semihosting support. Both of the supplied C libraries, Newlib and Redlib, have semihosted variants available. To change the library variant being used:
Open the Project properties. There are a number of ways of doing this. For example, make sure the Project is highlighted in the Project Explorer view then open the menu "Project -> Properties".
- In the left-hand list of the Properties window, open "C/C++ Build" and select "Settings" and then the "Tool Settings" tab.
- Choose "MCU Linker - Target"
- In "Use C library" field, select either "Redlib (semihost)" or "Newlib (semihost)"
This will cause the appropriate low level library stubs, which implement the semihosting support, to be pulled into your application build.
Note that when linking against Redlib, you MUST ensure that your startup code calls the Redlib initialisation function __main(). If your application does not do this, then you will see no output in the console window. The default startup code generated by the project wizard does this, but if you have supplied your own version of the startup code, then make sure you call __main() rather than calling main() directly.
Reducing codesize of printf
The printf() routine incorporated into Redlib is much smaller than that in Newlib. Thus if code size is an issue, then always try to use Redlib if possible In addition if your application does not pass floating point numbers to printf, you can also select a variant of non-floating point variant of printf. This will reduce code size further.
To enable the non-floating-point printf from Redlib, define the symbol "CR_INTEGER_PRINTF" (at the project level).
Note that if you only require the display of fixed strings, then using puts() rather than printf() will noticeably reduce the code size of your application.
Configuring your debug session for semihosting
In order for the output of your printf to be displayed in the IDE console, the debug connection must have semihosting support enabled. In version 3.0 and later of the Code Red IDE, this will be automatically be done if the debugger detects the use of semihosting as it loads the image. In this case, "Semihosting enabled" will be briefly displayed in the IDE status bar (bottom left of window), as the image load to the target completes.
If you are using version 2.0 of the Code Red IDE, then you will need to enable semihosting support in the debug configuration for each build of each project that makes use of semihosting. To enable semihosting support, select the menu:
Run -> Open Debug Dialog
Now select the debug configuration for your project/build configuration on the left side of the Configurations window. Then select the "Debugger" tab on the right hand side. Select the "Semihosting support" configuration option and set this to "On".
Other semihosting operations
Semihosting also provides support for a number of other I/O operations. For example it provides the ability for scanf to read its input from the IDE console. It also allows file operations, such that fopen can open a file on your PC's hard drive, and fscanf can then be used to read from that file.
Important notes about semihosting
- When you have linked with the semihosting library, your application will no longer work standalone - it will only work when connected to the debugger.
Semihosting operations cause the CPU to drop into "debug state", which means that for the duration of the data transfer between the target and the host PC no code (including interrupts) will get executed on the target. Thus if you application uses interrupts, then it is normally advisable to avoid the use of semihosting. If you still need to use printf, then you can retarget the bottom level of the C library to use an alternative communication channel, such as a UART. For more details see the FAQ Retargeting printf/scanf to use a UART.