| 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 |