|ARM Technical Support Knowledge Articles|
The compiler normally translates "printfs" in application source code into calls to optimized versions in the ARM-supplied C libraries. This optimization can be disabled by recompiling with the compiler switch
-Ono_fp_formats (for RVCT 2.x) or
--library_interface=aeabi_clib (for RVCT 3.0 or later) as described by the article: How do the ARM Compilers handle printf, sprintf, fprintf and scanf?. But if the programmer would like to use their own printf implementation without having to recompile their application source code (e.g. because the object code was provided by a third-party and cannot be changed), a different approach is needed.
All internal optimized "printfs" are linked-in from the ARM-supplied C libraries at link-time. During compilation, when the compiler sees a call to one of the
printf functions and it recognizes the format string or arguments, it will change the call to
__Nprintf (where N depends on the ARM Compiler version). The compiler may also need to import various symbols depending on the format string and arguments.
For RVCT 2.x/3.0, the renamed symbol is
__0printf. It is
__1printf for RVCT 3.1 and
__2printf for RVCT 4.0 and later versions. Beware that this naming scheme may change in future releases of ARM Compiler Tools.
The user should reimplement these renamed symbols to redirect them to their own version of
The recommended way is to use an assembly file, for example:
AREA retarget_Nprintf, CODE, READONLY IMPORT printf EXPORT __0printf EXPORT __1printf EXPORT __2printf __0printf __1printf __2printf B printf END
This assembly file would then work for third party objects that are built using any current version of ARM Compiler.
scanf() can be handled in the same way.
Did you find this article helpful? Yes No
How can we improve this article?