51 |
/** \defgroup avr_stdio <stdio.h>: Standard IO facilities |
/** \defgroup avr_stdio <stdio.h>: Standard IO facilities |
52 |
\code #include <stdio.h> \endcode |
\code #include <stdio.h> \endcode |
53 |
|
|
54 |
\warning |
<h3>Introduction to the Standard IO facilities</h3> |
|
This implementation of the standard IO facilities is new to |
|
|
avr-libc. It is not yet expected to remain stable, so some |
|
|
aspects of the API might change in a future release. |
|
55 |
|
|
56 |
This file declares the standard IO facilities that are implemented |
This file declares the standard IO facilities that are implemented |
57 |
in \c avr-libc. Due to the nature of the underlying hardware, |
in \c avr-libc. Due to the nature of the underlying hardware, |
74 |
offered by avr-libc will usually cost much less in terms of speed |
offered by avr-libc will usually cost much less in terms of speed |
75 |
and code size. |
and code size. |
76 |
|
|
77 |
|
<h3>Tunable options for code size vs. feature set</h3> |
78 |
|
|
79 |
In order to allow programmers a code size vs. functionality tradeoff, |
In order to allow programmers a code size vs. functionality tradeoff, |
80 |
the function vfprintf() which is the heart of the printf family can be |
the function vfprintf() which is the heart of the printf family can be |
81 |
selected in different flavours using linker options. See the |
selected in different flavours using linker options. See the |
82 |
documentation of vfprintf() for a detailed description. The same |
documentation of vfprintf() for a detailed description. The same |
83 |
applies to vfscanf() and the \c scanf family of functions. |
applies to vfscanf() and the \c scanf family of functions. |
84 |
|
|
85 |
|
<h3>Outline of the chosen API</h3> |
86 |
|
|
87 |
The standard streams \c stdin, \c stdout, and \c stderr are |
The standard streams \c stdin, \c stdout, and \c stderr are |
88 |
provided, but contrary to the C standard, since avr-libc has no |
provided, but contrary to the C standard, since avr-libc has no |
89 |
knowledge about applicable devices, these streams are not already |
knowledge about applicable devices, these streams are not already |
100 |
the linefeed, its \c put() routine must implement this (see |
the linefeed, its \c put() routine must implement this (see |
101 |
\ref stdio_note2 "note 2"). |
\ref stdio_note2 "note 2"). |
102 |
|
|
103 |
|
As an alternative method to fdevopen(), the macro |
104 |
|
fdev_setup_stream() might be used to setup a user-supplied FILE |
105 |
|
structure. |
106 |
|
|
107 |
It should be noted that the automatic conversion of a newline |
It should be noted that the automatic conversion of a newline |
108 |
character into a carriage return - newline sequence breaks binary |
character into a carriage return - newline sequence breaks binary |
109 |
transfers. If binary transfers are desired, no automatic |
transfers. If binary transfers are desired, no automatic |
120 |
each other, thus calling \c fclose() on such a stream will also |
each other, thus calling \c fclose() on such a stream will also |
121 |
effectively close all of its aliases (\ref stdio_note3 "note 3"). |
effectively close all of its aliases (\ref stdio_note3 "note 3"). |
122 |
|
|
123 |
|
It is possible to tie additional user data to a stream, using |
124 |
|
fdev_set_udata(). The backend put and get functions can then |
125 |
|
extract this user data using fdev_get_udata(), and act |
126 |
|
appropriately. For example, a single put function could be used |
127 |
|
to talk to two different UARTs that way, or the put and get |
128 |
|
functions could keep internal state between calls there. |
129 |
|
|
130 |
|
<h3>Format strings in flash ROM</h3> |
131 |
|
|
132 |
All the \c printf and \c scanf family functions come in two flavours: the |
All the \c printf and \c scanf family functions come in two flavours: the |
133 |
standard name, where the format string is expected to be in |
standard name, where the format string is expected to be in |
134 |
SRAM, as well as a version with the suffix "_P" where the format |
SRAM, as well as a version with the suffix "_P" where the format |
136 |
\c PSTR (explained in \ref avr_pgmspace) becomes very handy |
\c PSTR (explained in \ref avr_pgmspace) becomes very handy |
137 |
for declaring these format strings. |
for declaring these format strings. |
138 |
|
|
139 |
|
\anchor stdio_without_malloc |
140 |
|
<h3>Running stdio without malloc()</h3> |
141 |
|
|
142 |
|
By default, fdevopen() as well as the floating-point versions of |
143 |
|
the printf and scanf family require malloc(). As this is often |
144 |
|
not desired in the limited environment of a microcontroller, an |
145 |
|
alternative option is provided to run completely without malloc(). |
146 |
|
|
147 |
|
The macro fdev_setup_stream() is provided to prepare a |
148 |
|
user-supplied FILE buffer for operation with stdio. If |
149 |
|
floating-point operation is desired, a user-supplied buffer can as |
150 |
|
well be passed for the internal buffering for the floating-point |
151 |
|
numbers (and processing of \%[ scanf data). |
152 |
|
|
153 |
|
<h4>Example</h4> |
154 |
|
|
155 |
|
\code |
156 |
|
#include <stdio.h> |
157 |
|
|
158 |
|
static int uart_putchar(char c, FILE *stream); |
159 |
|
|
160 |
|
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, |
161 |
|
_FDEV_SETUP_WRITE); |
162 |
|
|
163 |
|
static int |
164 |
|
uart_putchar(char c, FILE *stream) |
165 |
|
{ |
166 |
|
|
167 |
|
if (c == '\n') |
168 |
|
uart_putchar('\r'); |
169 |
|
loop_until_bit_is_set(UCSRA, UDRE); |
170 |
|
UDR = c; |
171 |
|
return 0; |
172 |
|
} |
173 |
|
|
174 |
|
int |
175 |
|
main(void) |
176 |
|
{ |
177 |
|
init_uart(); |
178 |
|
stdout = &mystdout; |
179 |
|
printf("Hello, world!\n"); |
180 |
|
|
181 |
|
return 0; |
182 |
|
} |
183 |
|
\endcode |
184 |
|
|
185 |
|
This example uses the initializer form FDEV_SETUP_STREAM() rather |
186 |
|
than the function-like fdev_setup_stream(), so all data |
187 |
|
initialization happens during C start-up. |
188 |
|
|
189 |
|
<h3>Notes</h3> |
190 |
|
|
191 |
\anchor stdio_note1 \par Note 1: |
\anchor stdio_note1 \par Note 1: |
192 |
It might have been possible to implement a device abstraction that |
It might have been possible to implement a device abstraction that |
193 |
is compatible with \c fopen() but since this would have required |
is compatible with \c fopen() but since this would have required |
204 |
|
|
205 |
\code |
\code |
206 |
int |
int |
207 |
uart_putchar(char c) |
uart_putchar(char c, FILE *stream) |
208 |
{ |
{ |
209 |
|
|
210 |
if (c == '\n') |
if (c == '\n') |
226 |
them in registers for functions that take a fixed number of |
them in registers for functions that take a fixed number of |
227 |
parameters), the ability to pass one parameter less by implying |
parameters), the ability to pass one parameter less by implying |
228 |
\c stdin will also save some execution time. |
\c stdin will also save some execution time. |
|
|
|
229 |
*/ |
*/ |
230 |
|
|
231 |
struct __file; |
#if !defined(DOXYGEN) |
232 |
|
|
233 |
|
/* |
234 |
|
* This is an internal structure of the library that is subject to be |
235 |
|
* changed without warnings at any time. Please do *never* reference |
236 |
|
* elements of it beyond by using the official interfaces provided. |
237 |
|
*/ |
238 |
|
struct __file { |
239 |
|
char *buf; /* buffer pointer */ |
240 |
|
unsigned char unget; /* ungetc() buffer */ |
241 |
|
uint8_t flags; /* flags, see below */ |
242 |
|
#define __SRD 0x0001 /* OK to read */ |
243 |
|
#define __SWR 0x0002 /* OK to write */ |
244 |
|
#define __SSTR 0x0004 /* this is an sprintf/snprintf string */ |
245 |
|
#define __SPGM 0x0008 /* fmt string is in progmem */ |
246 |
|
#define __SERR 0x0010 /* found error */ |
247 |
|
#define __SEOF 0x0020 /* found EOF */ |
248 |
|
#define __SUNGET 0x040 /* ungetc() happened */ |
249 |
|
#if 0 |
250 |
|
/* possible future extensions, will require uint16_t flags */ |
251 |
|
#define __SRW 0x0080 /* open for reading & writing */ |
252 |
|
#define __SLBF 0x0100 /* line buffered */ |
253 |
|
#define __SNBF 0x0200 /* unbuffered */ |
254 |
|
#define __SMBF 0x0400 /* buf is from malloc */ |
255 |
|
#endif |
256 |
|
int size; /* size of buffer */ |
257 |
|
int len; /* characters read or written so far */ |
258 |
|
int (*put)(char, struct __file *); /* function to write one char to device */ |
259 |
|
int (*get)(struct __file *); /* function to read one char from device */ |
260 |
|
void *udata; /* User defined and accessible data. */ |
261 |
|
}; |
262 |
|
|
263 |
|
#endif /* not DOXYGEN */ |
264 |
|
|
265 |
/*@{*/ |
/*@{*/ |
266 |
/** |
/** |
306 |
*/ |
*/ |
307 |
#define EOF (-1) |
#define EOF (-1) |
308 |
|
|
309 |
|
/** This macro inserts a pointer to user defined data into a FILE |
310 |
|
stream object. |
311 |
|
|
312 |
|
The user data can be useful for tracking state in the put and get |
313 |
|
functions supplied to the fdevopen() function. */ |
314 |
|
#define fdev_set_udata(stream, u) do { (stream)->udata = u; } while(0) |
315 |
|
|
316 |
|
/** This macro retrieves a pointer to user defined data from a FILE |
317 |
|
stream object. */ |
318 |
|
#define fdev_get_udata(stream) ((stream)->udata) |
319 |
|
|
320 |
|
#if defined(DOXYGEN) |
321 |
|
/** |
322 |
|
\brief Setup a user-supplied buffer as an stdio stream |
323 |
|
|
324 |
|
This macro takes a user-supplied buffer \c stream, and sets it up |
325 |
|
as a stream that is valid for stdio operations, similar to one that |
326 |
|
has been obtained dynamically from fdevopen(). The buffer to setup |
327 |
|
must be of type FILE. |
328 |
|
|
329 |
|
The arguments \c put and \c get are identical to those that need to |
330 |
|
be passed to fdevopen(). |
331 |
|
|
332 |
|
The \c rwflag argument can take one of the values _FDEV_SETUP_READ, |
333 |
|
_FDEV_SETUP_WRITE, or _FDEV_SETUP_RW, for read, write, or read/write |
334 |
|
intent, respectively. |
335 |
|
|
336 |
|
\note No assignments to the standard streams will be performed by |
337 |
|
fdev_setup_stream(). If standard streams are to be used, these |
338 |
|
need to be assigned by the user. See also under |
339 |
|
\ref stdio_without_malloc "Running stdio without malloc()". |
340 |
|
*/ |
341 |
|
#define fdev_setup_stream(stream, put, get, rwflag) |
342 |
|
#else /* !DOXYGEN */ |
343 |
|
#define fdev_setup_stream(stream, p, g, f) \ |
344 |
|
do { \ |
345 |
|
(stream)->put = p; \ |
346 |
|
(stream)->get = g; \ |
347 |
|
(stream)->flags = f; \ |
348 |
|
(stream)->udata = 0; \ |
349 |
|
} while(0) |
350 |
|
#endif /* DOXYGEN */ |
351 |
|
|
352 |
|
#define _FDEV_SETUP_READ __SRD /**< fdev_setup_stream() with read intent */ |
353 |
|
#define _FDEV_SETUP_WRITE __SWR /**< fdev_setup_stream() with write intent */ |
354 |
|
#define _FDEV_SETUP_RW (__SRD|__SWR) /**< fdev_setup_stream() with read/write intent */ |
355 |
|
|
356 |
|
/** |
357 |
|
* Return code for an error condition during device read. |
358 |
|
* |
359 |
|
* To be used in the get function of fdevopen(). |
360 |
|
*/ |
361 |
|
#define _FDEV_ERR (-1) |
362 |
|
|
363 |
|
/** |
364 |
|
* Return code for an end-of-file condition during device read. |
365 |
|
* |
366 |
|
* To be used in the get function of fdevopen(). |
367 |
|
*/ |
368 |
|
#define _FDEV_EOF (-2) |
369 |
|
|
370 |
|
#if defined(DOXYGEN) |
371 |
|
/** |
372 |
|
\brief Initializer for a user-supplied stdio stream |
373 |
|
|
374 |
|
This macro acts similar to fdev_setup_stream(), but it is to be |
375 |
|
used as the initializer of a variable of type FILE. |
376 |
|
|
377 |
|
The remaining arguments are to be used as explained in |
378 |
|
fdev_setup_stream(). |
379 |
|
*/ |
380 |
|
#define FDEV_SETUP_STREAM(put, get, rwflag) |
381 |
|
#else /* !DOXYGEN */ |
382 |
|
#define FDEV_SETUP_STREAM(p, g, f) \ |
383 |
|
{ \ |
384 |
|
.put = p, \ |
385 |
|
.get = g, \ |
386 |
|
.flags = f, \ |
387 |
|
.udata = 0, \ |
388 |
|
} |
389 |
|
#endif /* DOXYGEN */ |
390 |
|
|
391 |
#ifdef __cplusplus |
#ifdef __cplusplus |
392 |
extern "C" { |
extern "C" { |
393 |
#endif |
#endif |
394 |
|
|
395 |
#if !defined(DOXYGEN) |
#if !defined(DOXYGEN) |
396 |
|
/* |
397 |
|
* Doxygen documentation can be found in fdevopen.c. |
398 |
|
*/ |
399 |
|
|
400 |
extern struct __file *__iob[]; |
extern struct __file *__iob[]; |
401 |
|
|
402 |
extern FILE *fdevopen(int (*__put)(char), int (*__get)(void), int __opts); |
#if defined(__STDIO_FDEVOPEN_COMPAT_12) |
403 |
|
/* |
404 |
|
* Declare prototype for the discontinued version of fdevopen() that |
405 |
|
* has been in use up to avr-libc 1.2.x. The new implementation has |
406 |
|
* some backwards compatibility with the old version. |
407 |
|
*/ |
408 |
|
extern FILE *fdevopen(int (*__put)(char), int (*__get)(void), |
409 |
|
int __opts __attribute__((unused))); |
410 |
|
#else /* !defined(__STDIO_FDEVOPEN_COMPAT_12) */ |
411 |
|
/* New prototype for avr-libc 1.4 and above. */ |
412 |
|
extern FILE *fdevopen(int (*__put)(char, FILE*), int (*__get)(FILE*)); |
413 |
|
#endif /* defined(__STDIO_FDEVOPEN_COMPAT_12) */ |
414 |
|
|
415 |
#endif /* not DOXYGEN */ |
#endif /* not DOXYGEN */ |
416 |
|
|
798 |
*/ |
*/ |
799 |
extern void clearerr(FILE *__stream); |
extern void clearerr(FILE *__stream); |
800 |
|
|
801 |
|
#if !defined(DOXYGEN) |
802 |
|
/* fast inlined version of clearerr() */ |
803 |
|
#define clearerror(s) do { (s)->flags &= ~(__SERR | __SEOF); } while(0) |
804 |
|
#endif /* !defined(DOXYGEN) */ |
805 |
|
|
806 |
/** |
/** |
807 |
Test the end-of-file flag of \c stream. This flag can only be cleared |
Test the end-of-file flag of \c stream. This flag can only be cleared |
808 |
by a call to clearerr(). |
by a call to clearerr(). |
|
|
|
|
\note |
|
|
Since there is currently no notion for end-of-file on a device, this |
|
|
function will always return a false value. |
|
809 |
*/ |
*/ |
810 |
extern int feof(FILE *__stream); |
extern int feof(FILE *__stream); |
811 |
|
|
812 |
|
#if !defined(DOXYGEN) |
813 |
|
/* fast inlined version of feof() */ |
814 |
|
#define feof(s) ((s)->flags & __SEOF) |
815 |
|
#endif /* !defined(DOXYGEN) */ |
816 |
|
|
817 |
/** |
/** |
818 |
Test the error flag of \c stream. This flag can only be cleared |
Test the error flag of \c stream. This flag can only be cleared |
819 |
by a call to clearerr(). |
by a call to clearerr(). |
820 |
*/ |
*/ |
821 |
extern int ferror(FILE *__stream); |
extern int ferror(FILE *__stream); |
822 |
|
|
823 |
|
#if !defined(DOXYGEN) |
824 |
|
/* fast inlined version of ferror() */ |
825 |
|
#define ferror(s) ((s)->flags & __SERR) |
826 |
|
#endif /* !defined(DOXYGEN) */ |
827 |
|
|
828 |
/** |
/** |
829 |
Formatted input. This function is the heart of the \c scanf |
Formatted input. This function is the heart of the \c scanf |
830 |
family of functions. |
family of functions. |
936 |
completed is returned. |
completed is returned. |
937 |
|
|
938 |
By default, all the conversions described above are available |
By default, all the conversions described above are available |
939 |
except the floating-point conversions, and the <tt>%[</tt> conversion. |
except the floating-point conversions, and the <tt>\%[</tt> conversion. |
940 |
These conversions will be available in the extended version |
These conversions will be available in the extended version |
941 |
provided by the library \c libscanf_flt.a. Note that either of |
provided by the library \c libscanf_flt.a. Note that either of |
942 |
these conversions requires the availability of a buffer that |
these conversions requires the availability of a buffer that |