Redlib v2 Notes
The Code Red IDE v4 provides an enhanced version of Code Red's C library, Redlib, sometimes referred to as "Redlib_v2". This new version of Redlib contains a number of code size and functional improvements, including increased speed of semihosted printfs, over the version of Redlib shipped with the Windows versions of LPCXpresso and Red Suite (versions 3.6.x and earlier).
Note - LPCXpresso for Linux (v3.7.x/v3.8.x) included an initial release of the new "Redlib_v2" C library, though the functionality provided in Code Red IDE v4 has been extended compared to this initial version.
Below are a number of notes regarding the use of this new library:
Startup code needs updating
Due to changes in structure of Redlib v2 (required as a result of library code/data size reductions), projects created using versions of the tools prior to Red Suite / LPCXpresso 3.4.6 will need their startup code replacing with the startup code created with version 3.4.6 or later. If this is not done the Redlib_v2 initialisation code (__main) will not get pulled in, leading to potential runtime problems - such as the output from printf() calls not being displayed in the console.
Semihosting interface layer has changed
Some of the examples provided with previous versions of Red Suite / LPCXpresso have directly accessed some of the functions in the bottom layer of the C library used to provide the semihosting interface from the target to the host PC.
The semihosting interface layer has been reworked in Redlib_v2, in particular the following functions used by example code have changed their names:
__write -> __sys_write
__readc -> __sys_readc
If you are calling these stub interfaces from your code (for example to write to stdout from your own 'print' function), then aliases for the old names are provided within the library, so your code should continue to work (though we would recommend changing to the new names for future compatibilility).
However if you have provided your own version of these interface functions (for example so that the output from printf function is sent to a serial port instead of the debug console), you will need to modify your code to use the new interface function names. This change will be required, for example, if you have code based on the RDB1768cmsis_UART_printf example.
The printf() and puts() functions have been modified in Redlib_v2 in order to improve the speed with which strings are written to the debug console. This speed improvement is provided due to a single semihosted operation being carried out per string displayed (in a similar manner to the "consoleprint" example provided for some MCUs with earlier versions of the tools), rather than one semihosted operation per character.
For printf(), this speed improvement applies to both the full floating compatible version and also the integer only version, as controlled using the CR_INTEGER_PRINTF build define (which should be set at the project level).
Note that the new versions of printf()/puts() make use of malloc() to provide a temporary buffer on the heap in order to generate the string to be displayed. It is possible to switch back to using the old "character-by-character" versions of these functions (which do not require additional heap space) by specifying the build define "CR_PRINTF_CHAR" (which should be set at the project level). This can be useful, for example, if you are retargeting printf() to write out over a UART - as in this case it is pointless creating a temporary buffer to store the whole string, only to then print it out over the UART one character at a time.
By default, the heap used by Redlib_v2's malloc family of routines grows upwards from the end of the user data in RAM up towards the stack (a "one region memory model").
When a new block of memory is requested, the memory allocation code will make a call to the following function:
unsigned __check_heap_overflow (void * new_end_of_heap)
The default version of this function compares the value of the proposed new end of the heap against the stack pointer and will return one of the following values...
1 - Heap will overflow into stack
0 - Heap still OK
If 1 is returned, malloc will set errno to ENOMEM and return a null pointer to the caller
It is possible for the user to modify heap setup such that the heap is placed in different region of memory to the stack (a "two region memory model"). To do this, the user will need to...
Modify the setting of the "_pvHeapStart" variable created within the managed linker script, which is used to mark the starting location for the heap.
Provide their own implementation of __check_heap_overflow(), to replace the one pulled in from the Redlib nohost/semihost library variant.
Note that Redlib_v2 uses the variable "__end_of_heap" to keep track of the end of the heap. Be aware though that this does not necessarily detail the maximum extent of the heap, only its current extent.
User modified linker scripts need updating
If you have turned off the managed linker script mechanism and are maintaining the linker scripts for your project yourself, then be aware that if you are linking with the Redlib(semihost) or Redlib(nohost) variants of the c library, then you may need to update your linker script.
For Redlib (Nohost), ensure that your library list is as follows (order is important):
GROUP(libcr_nohost.a libcr_c.a libcr_eabihelpers.a)
For Redlib (Semihost), ensure that your library list is as follows (order is important):
GROUP(libcr_semihost.a libcr_c.a libcr_eabihelpers.a)
If you based your linker script on one created by the managed linker script mechanism in Red Suite/LPCXpresso 3.5.0 or later, then you should find that the order is as specified above.
Modified behavior of assert
Previously, when an assert was caught, the application would simply enter a while(1) loop. In Redlib_v2 this has been changed and the semihosting stub function __sys_appexit() is now called. If you are linking with Redlib(semihost), then this will cause your application to terminate execution and return control to the debugger. If you are linking with Redlib(nohost), then __sys_appexit() will simply enter a while(1) loop. This change has been implemented to improve the usefulness of Redlib's assert macro in the early stages of application development.
Number of open files reduced
Previously Redlib allowed upto 16 open files (including stdin,stdout,stdout). In Redlib_v2 this is reduced down to a maximum of 8 open files (again including stdin,stdout,stdout).
The use of errno, either directly from user code or from within C library functions, required that the application be linked with either the nohost or semihost variants of Redlib. If the none variant of Redlib was used, then the link step would result in "unresolved reference to errno" error messages. This is no longer the case with Redlib_v2.
Extensions to C90 support
Redlib is primarily a C90 compatible C library. However the Redlib_v2 included in Code Red IDE v4 provides a number of extensions...
Single precision math functions
Single precision implementations of the math.h functions such as sinf() and cosf() are now provided.
An implementation of the C99 stdbool.h header is now provided.
itoa() is non-standard library function which is provided in many other toolchains to convert an integer to a string. To ease porting, an implementation of this function is now provided, accessible via stdlib.h. For more details, please see the FAQ itoa() and uitoa() in Redlib.