A tiny printf for embedded applications - by Kustaa Nyholm

Dependents:   lpc1768-picotcp-demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers printf.h Source File

printf.h

00001 /*
00002 File: printf.h
00003 
00004 Copyright (C) 2004  Kustaa Nyholm
00005 
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public
00017 License along with this library; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 This library is realy just two files: 'printf.h' and 'printf.c'.
00021 
00022 They provide a simple and small (+200 loc) printf functionality to
00023 be used in embedded systems.
00024 
00025 I've found them so usefull in debugging that I do not bother with a
00026 debugger at all.
00027 
00028 They are distributed in source form, so to use them, just compile them
00029 into your project.
00030 
00031 Two printf variants are provided: printf and sprintf.
00032 
00033 The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'.
00034 
00035 Zero padding and field width are also supported.
00036 
00037 If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the
00038 long specifier is also
00039 supported. Note that this will pull in some long math routines (pun intended!)
00040 and thus make your executable noticably longer.
00041 
00042 The memory foot print of course depends on the target cpu, compiler and
00043 compiler options, but a rough guestimate (based on a H8S target) is about
00044 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space.
00045 Not too bad. Your milage may vary. By hacking the source code you can
00046 get rid of some hunred bytes, I'm sure, but personally I feel the balance of
00047 functionality and flexibility versus  code size is close to optimal for
00048 many embedded systems.
00049 
00050 To use the printf you need to supply your own character output function,
00051 something like :
00052 
00053 void putc ( void* p, char c)
00054 {
00055     while (!SERIAL_PORT_EMPTY) ;
00056     SERIAL_PORT_TX_REGISTER = c;
00057 }
00058 
00059 Before you can call printf you need to initialize it to use your
00060 character output function with something like:
00061 
00062 init_printf(NULL,putc);
00063 
00064 Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
00065 the NULL (or any pointer) you pass into the 'init_printf' will eventually be
00066 passed to your 'putc' routine. This allows you to pass some storage space (or
00067 anything realy) to the character output function, if necessary.
00068 This is not often needed but it was implemented like that because it made
00069 implementing the sprintf function so neat (look at the source code).
00070 
00071 The code is re-entrant, except for the 'init_printf' function, so it
00072 is safe to call it from interupts too, although this may result in mixed output.
00073 If you rely on re-entrancy, take care that your 'putc' function is re-entrant!
00074 
00075 The printf and sprintf functions are actually macros that translate to
00076 'tfp_printf' and 'tfp_sprintf'. This makes it possible
00077 to use them along with 'stdio.h' printf's in a single source file.
00078 You just need to undef the names before you include the 'stdio.h'.
00079 Note that these are not function like macros, so if you have variables
00080 or struct members with these names, things will explode in your face.
00081 Without variadic macros this is the best we can do to wrap these
00082 fucnction. If it is a problem just give up the macros and use the
00083 functions directly or rename them.
00084 
00085 For further details see source code.
00086 
00087 regs Kusti, 23.10.2004
00088 */
00089 
00090 #ifndef __TFP_PRINTF__
00091 #define __TFP_PRINTF__
00092 
00093 #include <stdarg.h>
00094 
00095 void init_printf(void *putp, void (*putf) (void *, char));
00096 
00097 void tfp_printf(char *fmt, ...);
00098 void tfp_sprintf(char *s, char *fmt, ...);
00099 
00100 void tfp_format(void *putp, void (*putf) (void *, char), char *fmt, va_list va);
00101 
00102 #define mprintf tfp_printf
00103 #define msprintf tfp_sprintf
00104 
00105 #define PRINTF_LONG_SUPPORT
00106 
00107 #endif