ARM® Compiler v5.06 for µVision® ARM C and C++ Libraries and Floating-Point Support User Guide
Version 5
Home > The ARM C and C++ Libraries > Redefining low-level library functions to enable direct use of high-level library functions in the C library
1.16 Redefining low-level library functions to enable direct use of high-level library functions in the C library
If you define your own version of __FILE, your own fputc() and ferror() functions, and the __stdout object, you can use all of the printf() family, fwrite(), fputs(), puts() and the C++ object std::cout unchanged from the library.
These examples show you how
to do this. However, consider modifying the system I/O functions
instead of these low-level library functions if you require real
file handling.
You are not required to re-implement every function shown
in these examples. Only re-implement the functions that are used
in your application.
Retargeting printf()
#include <stdio.h>
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’d in stdio.h. */
FILE __stdout;
int fputc(int ch, FILE *f)
{
/* Your implementation of fputc(). */
return ch;
}
int ferror(FILE *f)
{
/* Your implementation of ferror(). */
return 0;
}
void test(void)
{
printf("Hello world\n");
}
Note
Be aware of endianness with fputc(). fputc() takes
an int parameter, but contains only a character.
Whether the character is in the first or the last byte of the integer
variable depends on the endianness. The following code sample avoids
problems with endianness:
extern void sendchar(char *ch);
int fputc(int ch, FILE *f)
{
/* example: write a character to an LCD */
char tempch = ch; // temp char avoids endianness issue
sendchar(&tempch); // sendchar(&ch) would not work everywhere
return ch;
}
Retargeting cout
File 1: Re-implement any functions that require re-implementation.
#include <stdio.h>
namespace std {
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
FILE __stdout;
FILE __stdin;
FILE __stderr;
int fgetc(FILE *f)
{
/* Your implementation of fgetc(). */
return 0;
}
int fputc(int c, FILE *stream)
{
/* Your implementation of fputc(). */
}
int ferror(FILE *stream)
{
/* Your implementation of ferror(). */
}
long int ftell(FILE *stream)
{
/* Your implementation of ftell(). */
}
int fclose(FILE *f)
{
/* Your implementation of fclose(). */
return 0;
}
int fseek(FILE *f, long nPos, int nMode)
{
/* Your implementation of fseek(). */
return 0;
}
int fflush(FILE *f)
{
/* Your implementation of fflush(). */
return 0;
}
}
File 2: Print "Hello world" using your re-implemented functions.
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world\n";
return 0;
}
By default, fread() and fwrite() call
fast block input/output functions that are part of the ARM stream
implementation. If you define your own __FILE structure
instead of using the ARM stream implementation, fread() and fwrite() call fgetc() instead
of calling the block input/output functions.
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers of your data.