$treeview $search $mathjax $extrastylesheet
avr-libc  2.0.0
$projectbrief
$projectbrief
$searchbox

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

pgmspace.h

Go to the documentation of this file.
00001 /* Copyright (c) 2002-2007  Marek Michalkiewicz
00002    Copyright (c) 2006, Carlos Lamas
00003    Copyright (c) 2009-2010, Jan Waclawek
00004    All rights reserved.
00005 
00006    Redistribution and use in source and binary forms, with or without
00007    modification, are permitted provided that the following conditions are met:
00008 
00009    * Redistributions of source code must retain the above copyright
00010      notice, this list of conditions and the following disclaimer.
00011    * Redistributions in binary form must reproduce the above copyright
00012      notice, this list of conditions and the following disclaimer in
00013      the documentation and/or other materials provided with the
00014      distribution.
00015    * Neither the name of the copyright holders nor the names of
00016      contributors may be used to endorse or promote products derived
00017      from this software without specific prior written permission.
00018 
00019   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029   POSSIBILITY OF SUCH DAMAGE. */
00030 
00031 /* $Id$ */
00032 
00033 /*
00034    pgmspace.h
00035 
00036    Contributors:
00037      Created by Marek Michalkiewicz <marekm@linux.org.pl>
00038      Eric B. Weddington <eric@ecentral.com>
00039      Wolfgang Haidinger <wh@vmars.tuwien.ac.at> (pgm_read_dword())
00040      Ivanov Anton <anton@arc.com.ru> (pgm_read_float())
00041  */
00042 
00043 /** \file */
00044 /** \defgroup avr_pgmspace <avr/pgmspace.h>: Program Space Utilities
00045     \code
00046     #include <avr/io.h>
00047     #include <avr/pgmspace.h>
00048     \endcode
00049 
00050     The functions in this module provide interfaces for a program to access
00051     data stored in program space (flash memory) of the device.  In order to
00052     use these functions, the target device must support either the \c LPM or
00053     \c ELPM instructions.
00054 
00055     \note These functions are an attempt to provide some compatibility with
00056     header files that come with IAR C, to make porting applications between
00057     different compilers easier.  This is not 100% compatibility though (GCC
00058     does not have full support for multiple address spaces yet).
00059 
00060     \note If you are working with strings which are completely based in ram,
00061     use the standard string functions described in \ref avr_string.
00062 
00063     \note If possible, put your constant tables in the lower 64 KB and use
00064     pgm_read_byte_near() or pgm_read_word_near() instead of
00065     pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
00066     way, and you can still use the upper 64K for executable code.
00067     All functions that are suffixed with a \c _P \e require their
00068     arguments to be in the lower 64 KB of the flash ROM, as they do
00069     not use ELPM instructions.  This is normally not a big concern as
00070     the linker setup arranges any program space constants declared
00071     using the macros from this header file so they are placed right after
00072     the interrupt vectors, and in front of any executable code.  However,
00073     it can become a problem if there are too many of these constants, or
00074     for bootloaders on devices with more than 64 KB of ROM.
00075     <em>All these functions will not work in that situation.</em>
00076 
00077     \note For <b>Xmega</b> devices, make sure the NVM controller
00078     command register (\c NVM.CMD or \c NVM_CMD) is set to 0x00 (NOP)
00079     before using any of these functions.
00080 */
00081 
00082 #ifndef __PGMSPACE_H_
00083 #define __PGMSPACE_H_ 1
00084 
00085 #ifndef __DOXYGEN__
00086 #define __need_size_t
00087 #endif
00088 #include <inttypes.h>
00089 #include <stddef.h>
00090 #include <avr/io.h>
00091 
00092 #ifndef __DOXYGEN__
00093 #ifndef __ATTR_CONST__
00094 #define __ATTR_CONST__ __attribute__((__const__))
00095 #endif
00096 
00097 #ifndef __ATTR_PROGMEM__
00098 #define __ATTR_PROGMEM__ __attribute__((__progmem__))
00099 #endif
00100 
00101 #ifndef __ATTR_PURE__
00102 #define __ATTR_PURE__ __attribute__((__pure__))
00103 #endif
00104 #endif  /* !__DOXYGEN__ */
00105 
00106 /**
00107    \ingroup avr_pgmspace
00108    \def PROGMEM
00109 
00110    Attribute to use in order to declare an object being located in
00111    flash ROM.
00112  */
00113 #define PROGMEM __ATTR_PROGMEM__
00114 
00115 #ifdef __cplusplus
00116 extern "C" {
00117 #endif
00118 
00119 #if defined(__DOXYGEN__)
00120 /*
00121  * Doxygen doesn't grok the appended attribute syntax of
00122  * GCC, and confuses the typedefs with function decls, so
00123  * supply a doxygen-friendly view.
00124  */
00125 
00126 /**
00127    \ingroup avr_pgmspace
00128    \typedef prog_void
00129    \note DEPRECATED
00130 
00131    This typedef is now deprecated because the usage of the __progmem__ 
00132    attribute on a type is not supported in GCC. However, the use of the 
00133    __progmem__ attribute on a variable declaration is supported, and this is 
00134    now the recommended usage.
00135 
00136    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00137    has been defined before including <avr/pgmspace.h> (either by a
00138    \c \#define directive, or by a -D compiler option.)
00139 
00140    Type of a "void" object located in flash ROM.  Does not make much
00141    sense by itself, but can be used to declare a "void *" object in
00142    flash ROM.
00143 */
00144 typedef void PROGMEM prog_void;
00145 
00146 /**
00147    \ingroup avr_pgmspace
00148    \typedef prog_char
00149    \note DEPRECATED
00150 
00151    This typedef is now deprecated because the usage of the __progmem__ 
00152    attribute on a type is not supported in GCC. However, the use of the 
00153    __progmem__ attribute on a variable declaration is supported, and this is 
00154    now the recommended usage.
00155 
00156    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00157    has been defined before including <avr/pgmspace.h> (either by a
00158    \c \#define directive, or by a -D compiler option.)
00159 
00160    Type of a "char" object located in flash ROM.
00161 */
00162 typedef char PROGMEM prog_char;
00163 
00164 /**
00165    \ingroup avr_pgmspace
00166    \typedef prog_uchar
00167    \note DEPRECATED
00168 
00169    This typedef is now deprecated because the usage of the __progmem__ 
00170    attribute on a type is not supported in GCC. However, the use of the 
00171    __progmem__ attribute on a variable declaration is supported, and this is 
00172    now the recommended usage.
00173 
00174    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00175    has been defined before including <avr/pgmspace.h> (either by a
00176    \c \#define directive, or by a -D compiler option.)
00177 
00178    Type of an "unsigned char" object located in flash ROM.
00179 */
00180 typedef unsigned char PROGMEM prog_uchar;
00181 
00182 /**
00183    \ingroup avr_pgmspace
00184    \typedef prog_int8_t
00185    \note DEPRECATED
00186 
00187    This typedef is now deprecated because the usage of the __progmem__ 
00188    attribute on a type is not supported in GCC. However, the use of the 
00189    __progmem__ attribute on a variable declaration is supported, and this is 
00190    now the recommended usage.
00191 
00192    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00193    has been defined before including <avr/pgmspace.h> (either by a
00194    \c \#define directive, or by a -D compiler option.)
00195 
00196    Type of an "int8_t" object located in flash ROM.
00197 */
00198 typedef int8_t PROGMEM prog_int8_t;
00199 
00200 /**
00201    \ingroup avr_pgmspace
00202    \typedef prog_uint8_t
00203    \note DEPRECATED
00204 
00205    This typedef is now deprecated because the usage of the __progmem__ 
00206    attribute on a type is not supported in GCC. However, the use of the 
00207    __progmem__ attribute on a variable declaration is supported, and this is 
00208    now the recommended usage.
00209 
00210    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00211    has been defined before including <avr/pgmspace.h> (either by a
00212    \c \#define directive, or by a -D compiler option.)
00213 
00214    Type of an "uint8_t" object located in flash ROM.
00215 */
00216 typedef uint8_t PROGMEM prog_uint8_t;
00217 
00218 /**
00219    \ingroup avr_pgmspace
00220    \typedef prog_int16_t
00221    \note DEPRECATED
00222 
00223    This typedef is now deprecated because the usage of the __progmem__ 
00224    attribute on a type is not supported in GCC. However, the use of the 
00225    __progmem__ attribute on a variable declaration is supported, and this is 
00226    now the recommended usage.
00227 
00228    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00229    has been defined before including <avr/pgmspace.h> (either by a
00230    \c \#define directive, or by a -D compiler option.)
00231 
00232    Type of an "int16_t" object located in flash ROM.
00233 */
00234 typedef int16_t PROGMEM prog_int16_t;
00235 
00236 /**
00237    \ingroup avr_pgmspace
00238    \typedef prog_uint16_t
00239    \note DEPRECATED
00240 
00241    This typedef is now deprecated because the usage of the __progmem__ 
00242    attribute on a type is not supported in GCC. However, the use of the 
00243    __progmem__ attribute on a variable declaration is supported, and this is 
00244    now the recommended usage.
00245 
00246    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00247    has been defined before including <avr/pgmspace.h> (either by a
00248    \c \#define directive, or by a -D compiler option.)
00249 
00250    Type of an "uint16_t" object located in flash ROM.
00251 */
00252 typedef uint16_t PROGMEM prog_uint16_t;
00253 
00254 /**
00255    \ingroup avr_pgmspace
00256    \typedef prog_int32_t
00257    \note DEPRECATED
00258 
00259    This typedef is now deprecated because the usage of the __progmem__ 
00260    attribute on a type is not supported in GCC. However, the use of the 
00261    __progmem__ attribute on a variable declaration is supported, and this is 
00262    now the recommended usage.
00263 
00264    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00265    has been defined before including <avr/pgmspace.h> (either by a
00266    \c \#define directive, or by a -D compiler option.)
00267 
00268    Type of an "int32_t" object located in flash ROM.
00269 */
00270 typedef int32_t PROGMEM prog_int32_t;
00271 
00272 /**
00273    \ingroup avr_pgmspace
00274    \typedef prog_uint32_t
00275    \note DEPRECATED
00276 
00277    This typedef is now deprecated because the usage of the __progmem__ 
00278    attribute on a type is not supported in GCC. However, the use of the 
00279    __progmem__ attribute on a variable declaration is supported, and this is 
00280    now the recommended usage.
00281 
00282    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00283    has been defined before including <avr/pgmspace.h> (either by a
00284    \c \#define directive, or by a -D compiler option.)
00285 
00286    Type of an "uint32_t" object located in flash ROM.
00287 */
00288 typedef uint32_t PROGMEM prog_uint32_t;
00289 
00290 /**
00291    \ingroup avr_pgmspace
00292    \typedef prog_int64_t
00293    \note DEPRECATED
00294 
00295    This typedef is now deprecated because the usage of the __progmem__ 
00296    attribute on a type is not supported in GCC. However, the use of the 
00297    __progmem__ attribute on a variable declaration is supported, and this is 
00298    now the recommended usage.
00299 
00300    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00301    has been defined before including <avr/pgmspace.h> (either by a
00302    \c \#define directive, or by a -D compiler option.)
00303 
00304    Type of an "int64_t" object located in flash ROM.
00305 
00306    \note This type is not available when the compiler
00307    option -mint8 is in effect.
00308 */
00309 typedef int64_t PROGMEM prog_int64_t;
00310 
00311 /**
00312    \ingroup avr_pgmspace
00313    \typedef prog_uint64_t
00314    \note DEPRECATED
00315 
00316    This typedef is now deprecated because the usage of the __progmem__ 
00317    attribute on a type is not supported in GCC. However, the use of the 
00318    __progmem__ attribute on a variable declaration is supported, and this is 
00319    now the recommended usage.
00320 
00321    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
00322    has been defined before including <avr/pgmspace.h> (either by a
00323    \c \#define directive, or by a -D compiler option.)
00324 
00325    Type of an "uint64_t" object located in flash ROM.
00326 
00327    \note This type is not available when the compiler
00328    option -mint8 is in effect.
00329 */
00330 typedef uint64_t PROGMEM prog_uint64_t;
00331 
00332 /** \ingroup avr_pgmspace
00333     \def PGM_P
00334 
00335     Used to declare a variable that is a pointer to a string in program
00336     space. */
00337 
00338 #ifndef PGM_P
00339 #define PGM_P const char *
00340 #endif
00341 
00342 /** \ingroup avr_pgmspace
00343     \def PGM_VOID_P
00344 
00345     Used to declare a generic pointer to an object in program space. */
00346 
00347 #ifndef PGM_VOID_P
00348 #define PGM_VOID_P const void *
00349 #endif
00350 
00351 #elif defined(__PROG_TYPES_COMPAT__)  /* !DOXYGEN */
00352 
00353 typedef void prog_void __attribute__((__progmem__,deprecated("prog_void type is deprecated.")));
00354 typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
00355 typedef unsigned char prog_uchar __attribute__((__progmem__,deprecated("prog_uchar type is deprecated.")));
00356 typedef int8_t    prog_int8_t   __attribute__((__progmem__,deprecated("prog_int8_t type is deprecated.")));
00357 typedef uint8_t   prog_uint8_t  __attribute__((__progmem__,deprecated("prog_uint8_t type is deprecated.")));
00358 typedef int16_t   prog_int16_t  __attribute__((__progmem__,deprecated("prog_int16_t type is deprecated.")));
00359 typedef uint16_t  prog_uint16_t __attribute__((__progmem__,deprecated("prog_uint16_t type is deprecated.")));
00360 typedef int32_t   prog_int32_t  __attribute__((__progmem__,deprecated("prog_int32_t type is deprecated.")));
00361 typedef uint32_t  prog_uint32_t __attribute__((__progmem__,deprecated("prog_uint32_t type is deprecated.")));
00362 #if !__USING_MINT8
00363 typedef int64_t   prog_int64_t  __attribute__((__progmem__,deprecated("prog_int64_t type is deprecated.")));
00364 typedef uint64_t  prog_uint64_t __attribute__((__progmem__,deprecated("prog_uint64_t type is deprecated.")));
00365 #endif
00366 
00367 #ifndef PGM_P
00368 #define PGM_P const prog_char *
00369 #endif
00370 
00371 #ifndef PGM_VOID_P
00372 #define PGM_VOID_P const prog_void *
00373 #endif
00374 
00375 #else /* !defined(__DOXYGEN__), !defined(__PROG_TYPES_COMPAT__) */
00376 
00377 #ifndef PGM_P
00378 #define PGM_P const char *
00379 #endif
00380 
00381 #ifndef PGM_VOID_P
00382 #define PGM_VOID_P const void *
00383 #endif
00384 #endif /* defined(__DOXYGEN__), defined(__PROG_TYPES_COMPAT__) */
00385 
00386 /* Although in C, we can get away with just using __c, it does not work in
00387    C++. We need to use &__c[0] to avoid the compiler puking. Dave Hylands
00388    explaned it thusly,
00389 
00390      Let's suppose that we use PSTR("Test"). In this case, the type returned
00391      by __c is a prog_char[5] and not a prog_char *. While these are
00392      compatible, they aren't the same thing (especially in C++). The type
00393      returned by &__c[0] is a prog_char *, which explains why it works
00394      fine. */
00395 
00396 #if defined(__DOXYGEN__)
00397 /*
00398  * The #define below is just a dummy that serves documentation
00399  * purposes only.
00400  */
00401 /** \ingroup avr_pgmspace
00402     \def PSTR(s)
00403 
00404     Used to declare a static pointer to a string in program space. */
00405 # define PSTR(s) ((const PROGMEM char *)(s))
00406 #else  /* !DOXYGEN */
00407 /* The real thing. */
00408 # define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
00409 #endif /* DOXYGEN */
00410 
00411 #ifndef __DOXYGEN__ /* Internal macros, not documented. */
00412 #define __LPM_classic__(addr)   \
00413 (__extension__({                \
00414     uint16_t __addr16 = (uint16_t)(addr); \
00415     uint8_t __result;           \
00416     __asm__ __volatile__        \
00417     (                           \
00418         "lpm" "\n\t"            \
00419         "mov %0, r0" "\n\t"     \
00420         : "=r" (__result)       \
00421         : "z" (__addr16)        \
00422         : "r0"                  \
00423     );                          \
00424     __result;                   \
00425 }))
00426 
00427 #define __LPM_tiny__(addr)      \
00428 (__extension__({                \
00429     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00430     uint8_t __result;           \
00431     __asm__                     \
00432     (                           \
00433         "ld %0, z" "\n\t"       \
00434         : "=r" (__result)       \
00435         : "z" (__addr16)        \
00436     );                          \
00437     __result;                   \
00438 }))
00439 
00440 #define __LPM_enhanced__(addr)  \
00441 (__extension__({                \
00442     uint16_t __addr16 = (uint16_t)(addr); \
00443     uint8_t __result;           \
00444     __asm__ __volatile__        \
00445     (                           \
00446         "lpm %0, Z" "\n\t"      \
00447         : "=r" (__result)       \
00448         : "z" (__addr16)        \
00449     );                          \
00450     __result;                   \
00451 }))
00452 
00453 #define __LPM_word_classic__(addr)          \
00454 (__extension__({                            \
00455     uint16_t __addr16 = (uint16_t)(addr);   \
00456     uint16_t __result;                      \
00457     __asm__ __volatile__                    \
00458     (                                       \
00459         "lpm"           "\n\t"              \
00460         "mov %A0, r0"   "\n\t"              \
00461         "adiw r30, 1"   "\n\t"              \
00462         "lpm"           "\n\t"              \
00463         "mov %B0, r0"   "\n\t"              \
00464         : "=r" (__result), "=z" (__addr16)  \
00465         : "1" (__addr16)                    \
00466         : "r0"                              \
00467     );                                      \
00468     __result;                               \
00469 }))
00470 
00471 #define __LPM_word_tiny__(addr)             \
00472 (__extension__({                            \
00473     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00474     uint16_t __result;                      \
00475     __asm__                                 \
00476     (                                       \
00477         "ld %A0, z+"     "\n\t"             \
00478         "ld %B0, z"      "\n\t"             \
00479         : "=r" (__result), "=z" (__addr16)  \
00480         : "1" (__addr16)                    \
00481     );                                      \
00482     __result;                               \
00483 }))
00484 
00485 #define __LPM_word_enhanced__(addr)         \
00486 (__extension__({                            \
00487     uint16_t __addr16 = (uint16_t)(addr);   \
00488     uint16_t __result;                      \
00489     __asm__ __volatile__                    \
00490     (                                       \
00491         "lpm %A0, Z+"   "\n\t"              \
00492         "lpm %B0, Z"    "\n\t"              \
00493         : "=r" (__result), "=z" (__addr16)  \
00494         : "1" (__addr16)                    \
00495     );                                      \
00496     __result;                               \
00497 }))
00498 
00499 #define __LPM_dword_classic__(addr)         \
00500 (__extension__({                            \
00501     uint16_t __addr16 = (uint16_t)(addr);   \
00502     uint32_t __result;                      \
00503     __asm__ __volatile__                    \
00504     (                                       \
00505         "lpm"           "\n\t"              \
00506         "mov %A0, r0"   "\n\t"              \
00507         "adiw r30, 1"   "\n\t"              \
00508         "lpm"           "\n\t"              \
00509         "mov %B0, r0"   "\n\t"              \
00510         "adiw r30, 1"   "\n\t"              \
00511         "lpm"           "\n\t"              \
00512         "mov %C0, r0"   "\n\t"              \
00513         "adiw r30, 1"   "\n\t"              \
00514         "lpm"           "\n\t"              \
00515         "mov %D0, r0"   "\n\t"              \
00516         : "=r" (__result), "=z" (__addr16)  \
00517         : "1" (__addr16)                    \
00518         : "r0"                              \
00519     );                                      \
00520     __result;                               \
00521 }))
00522 
00523 #define __LPM_dword_tiny__(addr)            \
00524 (__extension__({                            \
00525     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00526     uint32_t __result;                      \
00527     __asm__                                 \
00528     (                                       \
00529         "ld %A0, z+"    "\n\t"              \
00530         "ld %B0, z+"    "\n\t"              \
00531         "ld %C0, z+"    "\n\t"              \
00532         "ld %D0, z"     "\n\t"              \
00533         : "=r" (__result), "=z" (__addr16)  \
00534         : "1" (__addr16)                    \
00535     );                                      \
00536     __result;                               \
00537 }))
00538 
00539 #define __LPM_dword_enhanced__(addr)        \
00540 (__extension__({                            \
00541     uint16_t __addr16 = (uint16_t)(addr);   \
00542     uint32_t __result;                      \
00543     __asm__ __volatile__                    \
00544     (                                       \
00545         "lpm %A0, Z+"   "\n\t"              \
00546         "lpm %B0, Z+"   "\n\t"              \
00547         "lpm %C0, Z+"   "\n\t"              \
00548         "lpm %D0, Z"    "\n\t"              \
00549         : "=r" (__result), "=z" (__addr16)  \
00550         : "1" (__addr16)                    \
00551     );                                      \
00552     __result;                               \
00553 }))
00554 
00555 #define __LPM_float_classic__(addr)         \
00556 (__extension__({                            \
00557     uint16_t __addr16 = (uint16_t)(addr);   \
00558     float __result;                         \
00559     __asm__ __volatile__                    \
00560     (                                       \
00561         "lpm"           "\n\t"              \
00562         "mov %A0, r0"   "\n\t"              \
00563         "adiw r30, 1"   "\n\t"              \
00564         "lpm"           "\n\t"              \
00565         "mov %B0, r0"   "\n\t"              \
00566         "adiw r30, 1"   "\n\t"              \
00567         "lpm"           "\n\t"              \
00568         "mov %C0, r0"   "\n\t"              \
00569         "adiw r30, 1"   "\n\t"              \
00570         "lpm"           "\n\t"              \
00571         "mov %D0, r0"   "\n\t"              \
00572         : "=r" (__result), "=z" (__addr16)  \
00573         : "1" (__addr16)                    \
00574         : "r0"                              \
00575     );                                      \
00576     __result;                               \
00577 }))
00578 
00579 #define __LPM_float_tiny__(addr)            \
00580 (__extension__({                            \
00581     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00582     float __result;                         \
00583     __asm__                                 \
00584     (                                       \
00585         "ld %A0, z+"   "\n\t"               \
00586         "ld %B0, z+"   "\n\t"               \
00587         "ld %C0, z+"   "\n\t"               \
00588         "ld %D0, z"    "\n\t"               \
00589         : "=r" (__result), "=z" (__addr16)  \
00590         : "1" (__addr16)                    \
00591     );                                      \
00592     __result;                               \
00593 }))
00594 
00595 #define __LPM_float_enhanced__(addr)        \
00596 (__extension__({                            \
00597     uint16_t __addr16 = (uint16_t)(addr);   \
00598     float __result;                         \
00599     __asm__ __volatile__                    \
00600     (                                       \
00601         "lpm %A0, Z+"   "\n\t"              \
00602         "lpm %B0, Z+"   "\n\t"              \
00603         "lpm %C0, Z+"   "\n\t"              \
00604         "lpm %D0, Z"    "\n\t"              \
00605         : "=r" (__result), "=z" (__addr16)  \
00606         : "1" (__addr16)                    \
00607     );                                      \
00608     __result;                               \
00609 }))
00610 
00611 #if defined (__AVR_HAVE_LPMX__)
00612 #define __LPM(addr)         __LPM_enhanced__(addr)
00613 #define __LPM_word(addr)    __LPM_word_enhanced__(addr)
00614 #define __LPM_dword(addr)   __LPM_dword_enhanced__(addr)
00615 #define __LPM_float(addr)   __LPM_float_enhanced__(addr)
00616 /*
00617 Macro to read data from program memory for avr tiny parts(tiny 4/5/9/10/20/40).
00618 why:
00619 - LPM instruction is not available in AVR_TINY instruction set.
00620 - Programs are executed starting from address 0x0000 in program memory.
00621 But it must be addressed starting from 0x4000 when accessed via data memory.
00622 Reference: TINY device (ATTiny 4,5,9,10,20 and 40) datasheets
00623 Bug: avrtc-536
00624 */
00625 #elif defined (__AVR_TINY__)
00626 #define __LPM(addr)         __LPM_tiny__(addr)
00627 #define __LPM_word(addr)    __LPM_word_tiny__(addr)
00628 #define __LPM_dword(addr)   __LPM_dword_tiny__(addr)
00629 #define __LPM_float(addr)   __LPM_float_tiny__(addr)
00630 #else
00631 #define __LPM(addr)         __LPM_classic__(addr)
00632 #define __LPM_word(addr)    __LPM_word_classic__(addr)
00633 #define __LPM_dword(addr)   __LPM_dword_classic__(addr)
00634 #define __LPM_float(addr)   __LPM_float_classic__(addr)
00635 #endif
00636 
00637 #endif  /* !__DOXYGEN__ */
00638 
00639 /** \ingroup avr_pgmspace
00640     \def pgm_read_byte_near(address_short)
00641     Read a byte from the program space with a 16-bit (near) address. 
00642     \note The address is a byte address.
00643     The address is in the program space. */
00644 
00645 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
00646 
00647 /** \ingroup avr_pgmspace
00648     \def pgm_read_word_near(address_short)
00649     Read a word from the program space with a 16-bit (near) address. 
00650     \note The address is a byte address. 
00651     The address is in the program space. */
00652 
00653 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
00654 
00655 /** \ingroup avr_pgmspace
00656     \def pgm_read_dword_near(address_short)
00657     Read a double word from the program space with a 16-bit (near) address. 
00658     \note The address is a byte address. 
00659     The address is in the program space. */
00660 
00661 #define pgm_read_dword_near(address_short) \
00662     __LPM_dword((uint16_t)(address_short))
00663 
00664 /** \ingroup avr_pgmspace
00665     \def pgm_read_float_near(address_short)
00666     Read a float from the program space with a 16-bit (near) address. 
00667     \note The address is a byte address. 
00668     The address is in the program space. */
00669 
00670 #define pgm_read_float_near(address_short) \
00671     __LPM_float((uint16_t)(address_short))
00672 
00673 /** \ingroup avr_pgmspace
00674     \def pgm_read_ptr_near(address_short)
00675     Read a pointer from the program space with a 16-bit (near) address. 
00676     \note The address is a byte address. 
00677     The address is in the program space. */
00678 
00679 #define pgm_read_ptr_near(address_short) \
00680     (void*)__LPM_word((uint16_t)(address_short))
00681 
00682 #if defined(RAMPZ) || defined(__DOXYGEN__)
00683 
00684 /* Only for devices with more than 64K of program memory.
00685    RAMPZ must be defined (see iom103.h, iom128.h).
00686 */
00687 
00688 /* The classic functions are needed for ATmega103. */
00689 #ifndef __DOXYGEN__     /* These are internal macros, avoid "is
00690                    not documented" warnings. */
00691 #define __ELPM_classic__(addr)      \
00692 (__extension__({                    \
00693     uint32_t __addr32 = (uint32_t)(addr); \
00694     uint8_t __result;               \
00695     __asm__ __volatile__            \
00696     (                               \
00697         "out %2, %C1" "\n\t"        \
00698         "mov r31, %B1" "\n\t"       \
00699         "mov r30, %A1" "\n\t"       \
00700         "elpm" "\n\t"               \
00701         "mov %0, r0" "\n\t"         \
00702         : "=r" (__result)           \
00703         : "r" (__addr32),           \
00704           "I" (_SFR_IO_ADDR(RAMPZ)) \
00705         : "r0", "r30", "r31"        \
00706     );                              \
00707     __result;                       \
00708 }))
00709 
00710 #define __ELPM_enhanced__(addr)     \
00711 (__extension__({                    \
00712     uint32_t __addr32 = (uint32_t)(addr); \
00713     uint8_t __result;               \
00714     __asm__ __volatile__            \
00715     (                               \
00716         "out %2, %C1" "\n\t"        \
00717         "movw r30, %1" "\n\t"       \
00718         "elpm %0, Z+" "\n\t"        \
00719         : "=r" (__result)           \
00720         : "r" (__addr32),           \
00721           "I" (_SFR_IO_ADDR(RAMPZ)) \
00722         : "r30", "r31"              \
00723     );                              \
00724     __result;                       \
00725 }))
00726 
00727 #define __ELPM_xmega__(addr)        \
00728 (__extension__({                    \
00729     uint32_t __addr32 = (uint32_t)(addr); \
00730     uint8_t __result;               \
00731     __asm__ __volatile__            \
00732     (                               \
00733         "in __tmp_reg__, %2" "\n\t" \
00734         "out %2, %C1" "\n\t"        \
00735         "movw r30, %1" "\n\t"       \
00736         "elpm %0, Z+" "\n\t"        \
00737         "out %2, __tmp_reg__"       \
00738         : "=r" (__result)           \
00739         : "r" (__addr32),           \
00740           "I" (_SFR_IO_ADDR(RAMPZ)) \
00741         : "r30", "r31"              \
00742     );                              \
00743     __result;                       \
00744 }))
00745 
00746 #define __ELPM_word_classic__(addr)     \
00747 (__extension__({                        \
00748     uint32_t __addr32 = (uint32_t)(addr); \
00749     uint16_t __result;                  \
00750     __asm__ __volatile__                \
00751     (                                   \
00752         "out %2, %C1"   "\n\t"          \
00753         "mov r31, %B1"  "\n\t"          \
00754         "mov r30, %A1"  "\n\t"          \
00755         "elpm"          "\n\t"          \
00756         "mov %A0, r0"   "\n\t"          \
00757         "in r0, %2"     "\n\t"          \
00758         "adiw r30, 1"   "\n\t"          \
00759         "adc r0, __zero_reg__" "\n\t"   \
00760         "out %2, r0"    "\n\t"          \
00761         "elpm"          "\n\t"          \
00762         "mov %B0, r0"   "\n\t"          \
00763         : "=r" (__result)               \
00764         : "r" (__addr32),               \
00765           "I" (_SFR_IO_ADDR(RAMPZ))     \
00766         : "r0", "r30", "r31"            \
00767     );                                  \
00768     __result;                           \
00769 }))
00770 
00771 #define __ELPM_word_enhanced__(addr)    \
00772 (__extension__({                        \
00773     uint32_t __addr32 = (uint32_t)(addr); \
00774     uint16_t __result;                  \
00775     __asm__ __volatile__                \
00776     (                                   \
00777         "out %2, %C1"   "\n\t"          \
00778         "movw r30, %1"  "\n\t"          \
00779         "elpm %A0, Z+"  "\n\t"          \
00780         "elpm %B0, Z"   "\n\t"          \
00781         : "=r" (__result)               \
00782         : "r" (__addr32),               \
00783           "I" (_SFR_IO_ADDR(RAMPZ))     \
00784         : "r30", "r31"                  \
00785     );                                  \
00786     __result;                           \
00787 }))
00788 
00789 #define __ELPM_word_xmega__(addr)       \
00790 (__extension__({                        \
00791     uint32_t __addr32 = (uint32_t)(addr); \
00792     uint16_t __result;                  \
00793     __asm__ __volatile__                \
00794     (                                   \
00795         "in __tmp_reg__, %2" "\n\t"     \
00796         "out %2, %C1"   "\n\t"          \
00797         "movw r30, %1"  "\n\t"          \
00798         "elpm %A0, Z+"  "\n\t"          \
00799         "elpm %B0, Z"   "\n\t"          \
00800         "out %2, __tmp_reg__"           \
00801         : "=r" (__result)               \
00802         : "r" (__addr32),               \
00803           "I" (_SFR_IO_ADDR(RAMPZ))     \
00804         : "r30", "r31"                  \
00805     );                                  \
00806     __result;                           \
00807 }))
00808 
00809 #define __ELPM_dword_classic__(addr)      \
00810 (__extension__({                          \
00811     uint32_t __addr32 = (uint32_t)(addr); \
00812     uint32_t __result;                    \
00813     __asm__ __volatile__                  \
00814     (                                     \
00815         "out %2, %C1"          "\n\t"     \
00816         "mov r31, %B1"         "\n\t"     \
00817         "mov r30, %A1"         "\n\t"     \
00818         "elpm"                 "\n\t"     \
00819         "mov %A0, r0"          "\n\t"     \
00820         "in r0, %2"            "\n\t"     \
00821         "adiw r30, 1"          "\n\t"     \
00822         "adc r0, __zero_reg__" "\n\t"     \
00823         "out %2, r0"           "\n\t"     \
00824         "elpm"                 "\n\t"     \
00825         "mov %B0, r0"          "\n\t"     \
00826         "in r0, %2"            "\n\t"     \
00827         "adiw r30, 1"          "\n\t"     \
00828         "adc r0, __zero_reg__" "\n\t"     \
00829         "out %2, r0"           "\n\t"     \
00830         "elpm"                 "\n\t"     \
00831         "mov %C0, r0"          "\n\t"     \
00832         "in r0, %2"            "\n\t"     \
00833         "adiw r30, 1"          "\n\t"     \
00834         "adc r0, __zero_reg__" "\n\t"     \
00835         "out %2, r0"           "\n\t"     \
00836         "elpm"                 "\n\t"     \
00837         "mov %D0, r0"          "\n\t"     \
00838         : "=r" (__result)                 \
00839         : "r" (__addr32),                 \
00840           "I" (_SFR_IO_ADDR(RAMPZ))       \
00841         : "r0", "r30", "r31"              \
00842     );                                    \
00843     __result;                             \
00844 }))
00845 
00846 #define __ELPM_dword_enhanced__(addr)     \
00847 (__extension__({                          \
00848     uint32_t __addr32 = (uint32_t)(addr); \
00849     uint32_t __result;                    \
00850     __asm__ __volatile__                  \
00851     (                                     \
00852         "out %2, %C1"   "\n\t"            \
00853         "movw r30, %1"  "\n\t"            \
00854         "elpm %A0, Z+"  "\n\t"            \
00855         "elpm %B0, Z+"  "\n\t"            \
00856         "elpm %C0, Z+"  "\n\t"            \
00857         "elpm %D0, Z"   "\n\t"            \
00858         : "=r" (__result)                 \
00859         : "r" (__addr32),                 \
00860           "I" (_SFR_IO_ADDR(RAMPZ))       \
00861         : "r30", "r31"                    \
00862     );                                    \
00863     __result;                             \
00864 }))
00865 
00866 #define __ELPM_dword_xmega__(addr)        \
00867 (__extension__({                          \
00868     uint32_t __addr32 = (uint32_t)(addr); \
00869     uint32_t __result;                    \
00870     __asm__ __volatile__                  \
00871     (                                     \
00872         "in __tmp_reg__, %2" "\n\t"       \
00873         "out %2, %C1"   "\n\t"            \
00874         "movw r30, %1"  "\n\t"            \
00875         "elpm %A0, Z+"  "\n\t"            \
00876         "elpm %B0, Z+"  "\n\t"            \
00877         "elpm %C0, Z+"  "\n\t"            \
00878         "elpm %D0, Z"   "\n\t"            \
00879         "out %2, __tmp_reg__"             \
00880         : "=r" (__result)                 \
00881         : "r" (__addr32),                 \
00882           "I" (_SFR_IO_ADDR(RAMPZ))       \
00883         : "r30", "r31"                    \
00884     );                                    \
00885     __result;                             \
00886 }))
00887 
00888 #define __ELPM_float_classic__(addr)      \
00889 (__extension__({                          \
00890     uint32_t __addr32 = (uint32_t)(addr); \
00891     float __result;                       \
00892     __asm__ __volatile__                  \
00893     (                                     \
00894         "out %2, %C1"          "\n\t"     \
00895         "mov r31, %B1"         "\n\t"     \
00896         "mov r30, %A1"         "\n\t"     \
00897         "elpm"                 "\n\t"     \
00898         "mov %A0, r0"          "\n\t"     \
00899         "in r0, %2"            "\n\t"     \
00900         "adiw r30, 1"          "\n\t"     \
00901         "adc r0, __zero_reg__" "\n\t"     \
00902         "out %2, r0"           "\n\t"     \
00903         "elpm"                 "\n\t"     \
00904         "mov %B0, r0"          "\n\t"     \
00905         "in r0, %2"            "\n\t"     \
00906         "adiw r30, 1"          "\n\t"     \
00907         "adc r0, __zero_reg__" "\n\t"     \
00908         "out %2, r0"           "\n\t"     \
00909         "elpm"                 "\n\t"     \
00910         "mov %C0, r0"          "\n\t"     \
00911         "in r0, %2"            "\n\t"     \
00912         "adiw r30, 1"          "\n\t"     \
00913         "adc r0, __zero_reg__" "\n\t"     \
00914         "out %2, r0"           "\n\t"     \
00915         "elpm"                 "\n\t"     \
00916         "mov %D0, r0"          "\n\t"     \
00917         : "=r" (__result)                 \
00918         : "r" (__addr32),                 \
00919           "I" (_SFR_IO_ADDR(RAMPZ))       \
00920         : "r0", "r30", "r31"              \
00921     );                                    \
00922     __result;                             \
00923 }))
00924 
00925 #define __ELPM_float_enhanced__(addr)     \
00926 (__extension__({                          \
00927     uint32_t __addr32 = (uint32_t)(addr); \
00928     float __result;                       \
00929     __asm__ __volatile__                  \
00930     (                                     \
00931         "out %2, %C1"   "\n\t"            \
00932         "movw r30, %1"  "\n\t"            \
00933         "elpm %A0, Z+"  "\n\t"            \
00934         "elpm %B0, Z+"  "\n\t"            \
00935         "elpm %C0, Z+"  "\n\t"            \
00936         "elpm %D0, Z"   "\n\t"            \
00937         : "=r" (__result)                 \
00938         : "r" (__addr32),                 \
00939           "I" (_SFR_IO_ADDR(RAMPZ))       \
00940         : "r30", "r31"                    \
00941     );                                    \
00942     __result;                             \
00943 }))
00944 
00945 #define __ELPM_float_xmega__(addr)        \
00946 (__extension__({                          \
00947     uint32_t __addr32 = (uint32_t)(addr); \
00948     float __result;                       \
00949     __asm__ __volatile__                  \
00950     (                                     \
00951         "in __tmp_reg__, %2" "\n\t"       \
00952         "out %2, %C1"   "\n\t"            \
00953         "movw r30, %1"  "\n\t"            \
00954         "elpm %A0, Z+"  "\n\t"            \
00955         "elpm %B0, Z+"  "\n\t"            \
00956         "elpm %C0, Z+"  "\n\t"            \
00957         "elpm %D0, Z"   "\n\t"            \
00958         "out %2, __tmp_reg__"             \
00959         : "=r" (__result)                 \
00960         : "r" (__addr32),                 \
00961           "I" (_SFR_IO_ADDR(RAMPZ))       \
00962         : "r30", "r31"                    \
00963     );                                    \
00964     __result;                             \
00965 }))
00966 
00967 /*
00968 Check for architectures that implement RAMPD (avrxmega5, avrxmega7)
00969 as they need to save/restore RAMPZ for ELPM macros so it does
00970 not interfere with data accesses.
00971 */
00972 #if defined (__AVR_HAVE_RAMPD__)
00973 
00974 #define __ELPM(addr)        __ELPM_xmega__(addr)
00975 #define __ELPM_word(addr)   __ELPM_word_xmega__(addr)
00976 #define __ELPM_dword(addr)  __ELPM_dword_xmega__(addr)
00977 #define __ELPM_float(addr)  __ELPM_float_xmega__(addr)
00978 
00979 #else
00980 
00981 #if defined (__AVR_HAVE_LPMX__)
00982 
00983 #define __ELPM(addr)        __ELPM_enhanced__(addr)
00984 #define __ELPM_word(addr)   __ELPM_word_enhanced__(addr)
00985 #define __ELPM_dword(addr)  __ELPM_dword_enhanced__(addr)
00986 #define __ELPM_float(addr)  __ELPM_float_enhanced__(addr)
00987 
00988 #else
00989 
00990 #define __ELPM(addr)        __ELPM_classic__(addr)
00991 #define __ELPM_word(addr)   __ELPM_word_classic__(addr)
00992 #define __ELPM_dword(addr)  __ELPM_dword_classic__(addr)
00993 #define __ELPM_float(addr)  __ELPM_float_classic__(addr)
00994 
00995 #endif  /* __AVR_HAVE_LPMX__ */
00996 
00997 #endif  /* __AVR_HAVE_RAMPD__ */
00998 
00999 #endif  /* !__DOXYGEN__ */
01000 
01001 /** \ingroup avr_pgmspace
01002     \def pgm_read_byte_far(address_long)
01003     Read a byte from the program space with a 32-bit (far) address. 
01004 
01005     \note The address is a byte address. 
01006     The address is in the program space. */
01007 
01008 #define pgm_read_byte_far(address_long)  __ELPM((uint32_t)(address_long))
01009 
01010 /** \ingroup avr_pgmspace
01011     \def pgm_read_word_far(address_long)
01012     Read a word from the program space with a 32-bit (far) address. 
01013 
01014     \note The address is a byte address.
01015     The address is in the program space. */
01016 
01017 #define pgm_read_word_far(address_long)  __ELPM_word((uint32_t)(address_long))
01018 
01019 /** \ingroup avr_pgmspace
01020     \def pgm_read_dword_far(address_long)
01021     Read a double word from the program space with a 32-bit (far) address. 
01022 
01023     \note The address is a byte address.
01024     The address is in the program space. */
01025 
01026 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
01027 
01028 /** \ingroup avr_pgmspace
01029     \def pgm_read_float_far(address_long)
01030     Read a float from the program space with a 32-bit (far) address. 
01031 
01032     \note The address is a byte address.
01033     The address is in the program space. */
01034 
01035 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
01036 
01037 /** \ingroup avr_pgmspace
01038     \def pgm_read_ptr_far(address_long)
01039     Read a pointer from the program space with a 32-bit (far) address. 
01040 
01041     \note The address is a byte address.
01042     The address is in the program space. */
01043 
01044 #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
01045 
01046 #endif /* RAMPZ or __DOXYGEN__ */
01047 
01048 /** \ingroup avr_pgmspace
01049     \def pgm_read_byte(address_short)
01050     Read a byte from the program space with a 16-bit (near) address. 
01051 
01052     \note The address is a byte address. 
01053     The address is in the program space. */
01054 
01055 #define pgm_read_byte(address_short)    pgm_read_byte_near(address_short)
01056 
01057 /** \ingroup avr_pgmspace
01058     \def pgm_read_word(address_short)
01059     Read a word from the program space with a 16-bit (near) address. 
01060 
01061     \note The address is a byte address. 
01062     The address is in the program space. */
01063 
01064 #define pgm_read_word(address_short)    pgm_read_word_near(address_short)
01065 
01066 /** \ingroup avr_pgmspace
01067     \def pgm_read_dword(address_short)
01068     Read a double word from the program space with a 16-bit (near) address. 
01069 
01070     \note The address is a byte address. 
01071     The address is in the program space. */
01072 
01073 #define pgm_read_dword(address_short)   pgm_read_dword_near(address_short)
01074 
01075 /** \ingroup avr_pgmspace
01076     \def pgm_read_float(address_short)
01077     Read a float from the program space with a 16-bit (near) address. 
01078 
01079     \note The address is a byte address. 
01080     The address is in the program space. */
01081 
01082 #define pgm_read_float(address_short)   pgm_read_float_near(address_short)
01083 
01084 /** \ingroup avr_pgmspace
01085     \def pgm_read_ptr(address_short)
01086     Read a pointer from the program space with a 16-bit (near) address. 
01087 
01088     \note The address is a byte address. 
01089     The address is in the program space. */
01090 
01091 #define pgm_read_ptr(address_short)     pgm_read_ptr_near(address_short)
01092 
01093 /** \ingroup avr_pgmspace
01094     \def pgm_get_far_address(var)
01095 
01096    This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
01097    used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
01098    is similar to the '&' operator, with some limitations.
01099 
01100    Comments:
01101 
01102    - The overhead is minimal and it's mainly due to the 32 bit size operation.
01103 
01104    - 24 bit sizes guarantees the code compatibility for use in future devices.
01105 
01106    - hh8() is an undocumented feature but seems to give the third significant byte
01107      of a 32 bit data and accepts symbols, complementing the functionality of hi8()
01108      and lo8(). There is not an equivalent assembler function to get the high
01109      significant byte.
01110 
01111    - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
01112      type variable name, an array name (not an indexed element of the array, if the
01113      index is a constant the compiler does not complain but fails to get the address
01114      if optimization is enabled), a struct name or a struct field name, a function
01115      identifier, a linker defined identifier,...
01116 
01117    - The returned value is the identifier's VMA (virtual memory address) determined
01118      by the linker and falls in the corresponding memory region. The AVR Harvard
01119      architecture requires non overlapping VMA areas for the multiple address spaces
01120      in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
01121      0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
01122      script used and linker options. The value returned can be seen then as a
01123      universal pointer.
01124 */
01125 
01126 #define pgm_get_far_address(var)                          \
01127 ({                                                    \
01128     uint_farptr_t tmp;                                \
01129                                                       \
01130     __asm__ __volatile__(                             \
01131                                                       \
01132             "ldi    %A0, lo8(%1)"           "\n\t"    \
01133             "ldi    %B0, hi8(%1)"           "\n\t"    \
01134             "ldi    %C0, hh8(%1)"           "\n\t"    \
01135             "clr    %D0"                    "\n\t"    \
01136         :                                             \
01137             "=d" (tmp)                                \
01138         :                                             \
01139             "p"  (&(var))                             \
01140     );                                                \
01141     tmp;                                              \
01142 })
01143 
01144 
01145 
01146 /** \ingroup avr_pgmspace
01147     \fn const void * memchr_P(const void *s, int val, size_t len)
01148     \brief Scan flash memory for a character.
01149 
01150     The memchr_P() function scans the first \p len bytes of the flash
01151     memory area pointed to by \p s for the character \p val.  The first
01152     byte to match \p val (interpreted as an unsigned character) stops
01153     the operation.
01154 
01155     \return The memchr_P() function returns a pointer to the matching
01156     byte or \c NULL if the character does not occur in the given memory
01157     area.   */
01158 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01159 
01160 /** \ingroup avr_pgmspace
01161     \fn int memcmp_P(const void *s1, const void *s2, size_t len)
01162     \brief Compare memory areas
01163 
01164     The memcmp_P() function compares the first \p len bytes of the memory
01165     areas \p s1 and flash \p s2. The comparision is performed using unsigned
01166     char operations.
01167 
01168     \returns The memcmp_P() function returns an integer less than, equal
01169     to, or greater than zero if the first \p len bytes of \p s1 is found,
01170     respectively, to be less than, to match, or be greater than the first
01171     \p len bytes of \p s2.  */
01172 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
01173 
01174 /** \ingroup avr_pgmspace
01175     \fn void *memccpy_P (void *dest, const void *src, int val, size_t len)
01176 
01177     This function is similar to memccpy() except that \p src is pointer
01178     to a string in program space.   */
01179 extern void *memccpy_P(void *, const void *, int __val, size_t);
01180 
01181 /** \ingroup avr_pgmspace
01182     \fn void *memcpy_P(void *dest, const void *src, size_t n)
01183 
01184     The memcpy_P() function is similar to memcpy(), except the src string
01185     resides in program space.
01186 
01187     \returns The memcpy_P() function returns a pointer to dest.  */
01188 extern void *memcpy_P(void *, const void *, size_t);
01189 
01190 /** \ingroup avr_pgmspace
01191     \fn void *memmem_P(const void *s1, size_t len1, const void *s2, size_t len2)
01192 
01193     The memmem_P() function is similar to memmem() except that \p s2 is
01194     pointer to a string in program space.   */
01195 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
01196 
01197 /** \ingroup avr_pgmspace
01198     \fn const void +memrchr_P(const void *src, int val, size_t len)
01199 
01200     The memrchr_P() function is like the memchr_P() function, except
01201     that it searches backwards from the end of the \p len bytes pointed
01202     to by \p src instead of forwards from the front. (Glibc, GNU extension.)
01203 
01204     \return The memrchr_P() function returns a pointer to the matching
01205     byte or \c NULL if the character does not occur in the given memory
01206     area.   */
01207 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01208 
01209 /** \ingroup avr_pgmspace
01210     \fn char *strcat_P(char *dest, const char *src)
01211 
01212     The strcat_P() function is similar to strcat() except that the \e src
01213     string must be located in program space (flash).
01214 
01215     \returns The strcat() function returns a pointer to the resulting string
01216     \e dest. */
01217 extern char *strcat_P(char *, const char *);
01218 
01219 /** \ingroup avr_pgmspace
01220     \fn const char *strchr_P(const char *s, int val)
01221     \brief Locate character in program space string.
01222 
01223     The strchr_P() function locates the first occurrence of \p val
01224     (converted to a char) in the string pointed to by \p s in program
01225     space. The terminating null character is considered to be part of
01226     the string.
01227 
01228     The strchr_P() function is similar to strchr() except that \p s is
01229     pointer to a string in program space.
01230 
01231     \returns The strchr_P() function returns a pointer to the matched
01232     character or \c NULL if the character is not found. */
01233 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
01234 
01235 /** \ingroup avr_pgmspace
01236     \fn const char *strchrnul_P(const char *s, int c)
01237 
01238     The strchrnul_P() function is like strchr_P() except that if \p c is
01239     not found in \p s, then it returns a pointer to the null byte at the
01240     end of \p s, rather than \c NULL. (Glibc, GNU extension.)
01241 
01242     \return The strchrnul_P() function returns a pointer to the matched
01243     character, or a pointer to the null byte at the end of \p s (i.e.,
01244     \c s+strlen(s)) if the character is not found.  */
01245 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
01246 
01247 /** \ingroup avr_pgmspace
01248     \fn int strcmp_P(const char *s1, const char *s2)
01249 
01250     The strcmp_P() function is similar to strcmp() except that \p s2 is
01251     pointer to a string in program space.
01252 
01253     \returns The strcmp_P() function returns an integer less than, equal
01254     to, or greater than zero if \p s1 is found, respectively, to be less
01255     than, to match, or be greater than \p s2. A consequence of the
01256     ordering used by strcmp_P() is that if \p s1 is an initial substring
01257     of \p s2, then \p s1 is considered to be "less than" \p s2. */
01258 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
01259 
01260 /** \ingroup avr_pgmspace
01261     \fn char *strcpy_P(char *dest, const char *src)
01262 
01263     The strcpy_P() function is similar to strcpy() except that src is a
01264     pointer to a string in program space.
01265 
01266     \returns The strcpy_P() function returns a pointer to the destination
01267     string dest. */
01268 extern char *strcpy_P(char *, const char *);
01269 
01270 /** \ingroup avr_pgmspace
01271     \fn int strcasecmp_P(const char *s1, const char *s2)
01272     \brief Compare two strings ignoring case.
01273 
01274     The strcasecmp_P() function compares the two strings \p s1 and \p s2,
01275     ignoring the case of the characters.
01276 
01277     \param s1 A pointer to a string in the devices SRAM.
01278     \param s2 A pointer to a string in the devices Flash.
01279 
01280     \returns The strcasecmp_P() function returns an integer less than,
01281     equal to, or greater than zero if \p s1 is found, respectively, to
01282     be less than, to match, or be greater than \p s2. A consequence of
01283     the ordering used by strcasecmp_P() is that if \p s1 is an initial
01284     substring of \p s2, then \p s1 is considered to be "less than" \p s2. */
01285 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
01286 
01287 /** \ingroup avr_pgmspace
01288     \fn char *strcasestr_P(const char *s1, const char *s2)
01289 
01290     This funtion is similar to strcasestr() except that \p s2 is pointer
01291     to a string in program space.   */
01292 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
01293 
01294 /** \ingroup avr_pgmspace
01295     \fn size_t strcspn_P(const char *s, const char *reject)
01296 
01297     The strcspn_P() function calculates the length of the initial segment
01298     of \p s which consists entirely of characters not in \p reject. This
01299     function is similar to strcspn() except that \p reject is a pointer
01300     to a string in program space.
01301 
01302     \return The strcspn_P() function returns the number of characters in
01303     the initial segment of \p s which are not in the string \p reject.
01304     The terminating zero is not considered as a part of string. */
01305 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
01306 
01307 /** \ingroup avr_pgmspace
01308     \fn size_t strlcat_P(char *dst, const char *src, size_t siz)
01309     \brief Concatenate two strings.
01310 
01311     The strlcat_P() function is similar to strlcat(), except that the \p src
01312     string must be located in program space (flash).
01313 
01314     Appends \p src to string \p dst of size \p siz (unlike strncat(),
01315     \p siz is the full size of \p dst, not space left).  At most \p siz-1
01316     characters will be copied.  Always NULL terminates (unless \p siz <=
01317     \p strlen(dst)).
01318 
01319     \returns The strlcat_P() function returns strlen(src) + MIN(siz,
01320     strlen(initial dst)).  If retval >= siz, truncation occurred.   */
01321 extern size_t strlcat_P (char *, const char *, size_t );
01322 
01323 /** \ingroup avr_pgmspace
01324     \fn size_t strlcpy_P(char *dst, const char *src, size_t siz)
01325     \brief Copy a string from progmem to RAM.
01326 
01327     Copy \p src to string \p dst of size \p siz.  At most \p siz-1
01328     characters will be copied.  Always NULL terminates (unless \p siz == 0).
01329     The strlcpy_P() function is similar to strlcpy() except that the
01330     \p src is pointer to a string in memory space.
01331 
01332     \returns The strlcpy_P() function returns strlen(src). If
01333     retval >= siz, truncation occurred.  */
01334 extern size_t strlcpy_P (char *, const char *, size_t );
01335 
01336 /** \ingroup avr_pgmspace
01337     \fn size_t strnlen_P(const char *src, size_t len)
01338     \brief Determine the length of a fixed-size string.
01339 
01340     The strnlen_P() function is similar to strnlen(), except that \c src is a
01341     pointer to a string in program space.
01342 
01343     \returns The strnlen_P function returns strlen_P(src), if that is less than
01344     \c len, or \c len if there is no '\\0' character among the first \c len
01345     characters pointed to by \c src. */
01346 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
01347 
01348 /** \ingroup avr_pgmspace
01349     \fn int strncmp_P(const char *s1, const char *s2, size_t n)
01350 
01351     The strncmp_P() function is similar to strcmp_P() except it only compares
01352     the first (at most) n characters of s1 and s2.
01353 
01354     \returns The strncmp_P() function returns an integer less than, equal to,
01355     or greater than zero if s1 (or the first n bytes thereof) is found,
01356     respectively, to be less than, to match, or be greater than s2.  */
01357 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01358 
01359 /** \ingroup avr_pgmspace
01360     \fn int strncasecmp_P(const char *s1, const char *s2, size_t n)
01361     \brief Compare two strings ignoring case.
01362 
01363     The strncasecmp_P() function is similar to strcasecmp_P(), except it
01364     only compares the first \p n characters of \p s1.
01365 
01366     \param s1 A pointer to a string in the devices SRAM.
01367     \param s2 A pointer to a string in the devices Flash.
01368     \param n The maximum number of bytes to compare.
01369 
01370     \returns The strncasecmp_P() function returns an integer less than,
01371     equal to, or greater than zero if \p s1 (or the first \p n bytes
01372     thereof) is found, respectively, to be less than, to match, or be
01373     greater than \p s2. A consequence of the ordering used by
01374     strncasecmp_P() is that if \p s1 is an initial substring of \p s2,
01375     then \p s1 is considered to be "less than" \p s2.  */
01376 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01377 
01378 /** \ingroup avr_pgmspace
01379     \fn char *strncat_P(char *dest, const char *src, size_t len)
01380     \brief Concatenate two strings.
01381 
01382     The strncat_P() function is similar to strncat(), except that the \e src
01383     string must be located in program space (flash).
01384 
01385     \returns The strncat_P() function returns a pointer to the resulting string
01386     dest.  */
01387 extern char *strncat_P(char *, const char *, size_t);
01388 
01389 /** \ingroup avr_pgmspace
01390     \fn char *strncpy_P(char *dest, const char *src, size_t n)
01391 
01392     The strncpy_P() function is similar to strcpy_P() except that not more
01393     than n bytes of src are copied.  Thus, if there is no null byte among the
01394     first n bytes of src, the result will not be null-terminated.
01395 
01396     In the case where the length of src is less than that of n, the remainder
01397     of dest will be padded with nulls.
01398 
01399     \returns The strncpy_P() function returns a pointer to the destination
01400     string dest.  */
01401 extern char *strncpy_P(char *, const char *, size_t);
01402 
01403 /** \ingroup avr_pgmspace
01404     \fn char *strpbrk_P(const char *s, const char *accept)
01405 
01406     The strpbrk_P() function locates the first occurrence in the string
01407     \p s of any of the characters in the flash string \p accept. This
01408     function is similar to strpbrk() except that \p accept is a pointer
01409     to a string in program space.
01410 
01411     \return  The strpbrk_P() function returns a pointer to the character
01412     in \p s that matches one of the characters in \p accept, or \c NULL
01413     if no such character is found. The terminating zero is not considered
01414     as a part of string: if one or both args are empty, the result will
01415     \c NULL. */
01416 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
01417 
01418 /** \ingroup avr_pgmspace
01419     \fn const char *strrchr_P(const char *s, int val)
01420     \brief Locate character in string.
01421 
01422     The strrchr_P() function returns a pointer to the last occurrence of
01423     the character \p val in the flash string \p s.
01424 
01425     \return The strrchr_P() function returns a pointer to the matched
01426     character or \c NULL if the character is not found. */
01427 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
01428 
01429 /** \ingroup avr_pgmspace
01430     \fn char *strsep_P(char **sp, const char *delim)
01431     \brief Parse a string into tokens.
01432 
01433     The strsep_P() function locates, in the string referenced by \p *sp,
01434     the first occurrence of any character in the string \p delim (or the
01435     terminating '\\0' character) and replaces it with a '\\0'.  The
01436     location of the next character after the delimiter character (or \c
01437     NULL, if the end of the string was reached) is stored in \p *sp. An
01438     ``empty'' field, i.e. one caused by two adjacent delimiter
01439     characters, can be detected by comparing the location referenced by
01440     the pointer returned in \p *sp to '\\0'. This function is similar to
01441     strsep() except that \p delim is a pointer to a string in program
01442     space.
01443 
01444     \return The strsep_P() function returns a pointer to the original
01445     value of \p *sp. If \p *sp is initially \c NULL, strsep_P() returns
01446     \c NULL. */
01447 extern char *strsep_P(char **__sp, const char * __delim);
01448 
01449 /** \ingroup avr_pgmspace
01450     \fn size_t strspn_P(const char *s, const char *accept)
01451 
01452     The strspn_P() function calculates the length of the initial segment
01453     of \p s which consists entirely of characters in \p accept. This
01454     function is similar to strspn() except that \p accept is a pointer
01455     to a string in program space.
01456 
01457     \return  The strspn_P() function returns the number of characters in
01458     the initial segment of \p s which consist only of characters from \p
01459     accept. The terminating zero is not considered as a part of string. */
01460 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
01461 
01462 /** \ingroup avr_pgmspace
01463     \fn char *strstr_P(const char *s1, const char *s2)
01464     \brief Locate a substring.
01465 
01466     The strstr_P() function finds the first occurrence of the substring
01467     \p s2 in the string \p s1.  The terminating '\\0' characters are not
01468     compared. The strstr_P() function is similar to strstr() except that
01469     \p s2 is pointer to a string in program space.
01470 
01471     \returns The strstr_P() function returns a pointer to the beginning
01472     of the substring, or NULL if the substring is not found. If \p s2
01473     points to a string of zero length, the function returns \p s1. */
01474 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
01475 
01476 /** \ingroup avr_pgmspace
01477     \fn char *strtok_P(char *s, const char * delim)
01478     \brief Parses the string into tokens.
01479 
01480     strtok_P() parses the string \p s into tokens. The first call to
01481     strtok_P() should have \p s as its first argument. Subsequent calls
01482     should have the first argument set to NULL. If a token ends with a
01483     delimiter, this delimiting character is overwritten with a '\\0' and a
01484     pointer to the next character is saved for the next call to strtok_P().
01485     The delimiter string \p delim may be different for each call.
01486 
01487     The strtok_P() function is similar to strtok() except that \p delim
01488     is pointer to a string in program space.
01489 
01490     \returns The strtok_P() function returns a pointer to the next token or
01491     NULL when no more tokens are found.
01492 
01493     \note strtok_P() is NOT reentrant. For a reentrant version of this
01494     function see strtok_rP().
01495  */
01496 extern char *strtok_P(char *__s, const char * __delim);
01497 
01498 /** \ingroup avr_pgmspace
01499     \fn char *strtok_rP (char *string, const char *delim, char **last)
01500     \brief Parses string into tokens.
01501 
01502     The strtok_rP() function parses \p string into tokens. The first call to
01503     strtok_rP() should have string as its first argument. Subsequent calls
01504     should have the first argument set to NULL. If a token ends with a
01505     delimiter, this delimiting character is overwritten with a '\\0' and a
01506     pointer to the next character is saved for the next call to strtok_rP().
01507     The delimiter string \p delim may be different for each call. \p last is
01508     a user allocated char* pointer. It must be the same while parsing the
01509     same string. strtok_rP() is a reentrant version of strtok_P().
01510 
01511     The strtok_rP() function is similar to strtok_r() except that \p delim
01512     is pointer to a string in program space.
01513 
01514     \returns The strtok_rP() function returns a pointer to the next token or
01515     NULL when no more tokens are found. */
01516 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
01517 
01518 /** \ingroup avr_pgmspace
01519     \fn size_t strlen_PF(uint_farptr_t s)
01520     \brief Obtain the length of a string
01521 
01522     The strlen_PF() function is similar to strlen(), except that \e s is a
01523     far pointer to a string in program space.
01524 
01525     \param s A far pointer to the string in flash
01526 
01527     \returns The strlen_PF() function returns the number of characters in
01528     \e s. The contents of RAMPZ SFR are undefined when the function returns. */
01529 extern size_t strlen_PF(uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
01530 
01531 /** \ingroup avr_pgmspace
01532     \fn size_t strnlen_PF(uint_farptr_t s, size_t len)
01533     \brief Determine the length of a fixed-size string
01534 
01535     The strnlen_PF() function is similar to strnlen(), except that \e s is a
01536     far pointer to a string in program space.
01537 
01538     \param s A far pointer to the string in Flash
01539     \param len The maximum number of length to return
01540 
01541     \returns The strnlen_PF function returns strlen_P(\e s), if that is less
01542     than \e len, or \e len if there is no '\\0' character among the first \e
01543     len characters pointed to by \e s. The contents of RAMPZ SFR are
01544     undefined when the function returns. */
01545 extern size_t strnlen_PF(uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
01546 
01547 /** \ingroup avr_pgmspace
01548     \fn void *memcpy_PF(void *dest, uint_farptr_t src, size_t n)
01549     \brief Copy a memory block from flash to SRAM
01550 
01551     The memcpy_PF() function is similar to memcpy(), except the data
01552     is copied from the program space and is addressed using a far pointer.
01553 
01554     \param dest A pointer to the destination buffer
01555     \param src A far pointer to the origin of data in flash memory
01556     \param n The number of bytes to be copied
01557 
01558     \returns The memcpy_PF() function returns a pointer to \e dst. The contents
01559     of RAMPZ SFR are undefined when the function returns. */
01560 extern void *memcpy_PF(void *dest, uint_farptr_t src, size_t len);
01561 
01562 /** \ingroup avr_pgmspace
01563     \fn char *strcpy_PF(char *dst, uint_farptr_t src)
01564     \brief Duplicate a string
01565 
01566     The strcpy_PF() function is similar to strcpy() except that \e src is a far
01567     pointer to a string in program space.
01568 
01569     \param dst A pointer to the destination string in SRAM
01570     \param src A far pointer to the source string in Flash
01571 
01572     \returns The strcpy_PF() function returns a pointer to the destination
01573     string \e dst. The contents of RAMPZ SFR are undefined when the funcion
01574     returns. */
01575 extern char *strcpy_PF(char *dest, uint_farptr_t src);
01576 
01577 /** \ingroup avr_pgmspace
01578     \fn char *strncpy_PF(char *dst, uint_farptr_t src, size_t n)
01579     \brief Duplicate a string until a limited length
01580 
01581     The strncpy_PF() function is similar to strcpy_PF() except that not more
01582     than \e n bytes of \e src are copied.  Thus, if there is no null byte among
01583     the first \e n bytes of \e src, the result will not be null-terminated.
01584 
01585     In the case where the length of \e src is less than that of \e n, the
01586     remainder of \e dst will be padded with nulls.
01587 
01588     \param dst A pointer to the destination string in SRAM
01589     \param src A far pointer to the source string in Flash
01590     \param n The maximum number of bytes to copy
01591 
01592     \returns The strncpy_PF() function returns a pointer to the destination
01593     string \e dst. The contents of RAMPZ SFR are undefined when the function
01594     returns. */
01595 extern char *strncpy_PF(char *dest, uint_farptr_t src, size_t len);
01596 
01597 /** \ingroup avr_pgmspace
01598     \fn char *strcat_PF(char *dst, uint_farptr_t src)
01599     \brief Concatenates two strings
01600 
01601     The strcat_PF() function is similar to strcat() except that the \e src
01602     string must be located in program space (flash) and is addressed using
01603     a far pointer
01604 
01605     \param dst A pointer to the destination string in SRAM
01606     \param src A far pointer to the string to be appended in Flash
01607 
01608     \returns The strcat_PF() function returns a pointer to the resulting
01609     string \e dst. The contents of RAMPZ SFR are undefined when the function
01610     returns */
01611 extern char *strcat_PF(char *dest, uint_farptr_t src);
01612 
01613 /** \ingroup avr_pgmspace
01614     \fn size_t strlcat_PF(char *dst, uint_farptr_t src, size_t n)
01615     \brief Concatenate two strings
01616 
01617     The strlcat_PF() function is similar to strlcat(), except that the \e src
01618     string must be located in program space (flash) and is addressed using
01619     a far pointer.
01620 
01621     Appends src to string dst of size \e n (unlike strncat(), \e n is the
01622     full size of \e dst, not space left).  At most \e n-1 characters
01623     will be copied.  Always NULL terminates (unless \e n <= strlen(\e dst)).
01624 
01625     \param dst A pointer to the destination string in SRAM
01626     \param src A far pointer to the source string in Flash
01627     \param n The total number of bytes allocated to the destination string
01628 
01629     \returns The strlcat_PF() function returns strlen(\e src) + MIN(\e n,
01630     strlen(initial \e dst)).  If retval >= \e n, truncation occurred. The
01631     contents of RAMPZ SFR are undefined when the funcion returns. */
01632 extern size_t strlcat_PF(char *dst, uint_farptr_t src, size_t siz);
01633 
01634 /** \ingroup avr_pgmspace
01635     \fn char *strncat_PF(char *dst, uint_farptr_t src, size_t n)
01636     \brief Concatenate two strings
01637 
01638     The strncat_PF() function is similar to strncat(), except that the \e src
01639     string must be located in program space (flash) and is addressed using a
01640     far pointer.
01641 
01642     \param dst A pointer to the destination string in SRAM
01643     \param src A far pointer to the source string in Flash
01644     \param n The maximum number of bytes to append
01645 
01646     \returns The strncat_PF() function returns a pointer to the resulting
01647     string \e dst. The contents of RAMPZ SFR are undefined when the function
01648     returns. */
01649 extern char *strncat_PF(char *dest, uint_farptr_t src, size_t len);
01650 
01651 /** \ingroup avr_pgmspace
01652     \fn int strcmp_PF(const char *s1, uint_farptr_t s2)
01653     \brief Compares two strings
01654 
01655     The strcmp_PF() function is similar to strcmp() except that \e s2 is a far
01656     pointer to a string in program space.
01657 
01658     \param s1 A pointer to the first string in SRAM
01659     \param s2 A far pointer to the second string in Flash
01660 
01661     \returns The strcmp_PF() function returns an integer less than, equal to,
01662     or greater than zero if \e s1 is found, respectively, to be less than, to
01663     match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
01664     when the function returns. */
01665 extern int strcmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01666 
01667 /** \ingroup avr_pgmspace
01668     \fn int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n)
01669     \brief Compare two strings with limited length
01670 
01671     The strncmp_PF() function is similar to strcmp_PF() except it only
01672     compares the first (at most) \e n characters of \e s1 and \e s2.
01673 
01674     \param s1 A pointer to the first string in SRAM
01675     \param s2 A far pointer to the second string in Flash
01676     \param n The maximum number of bytes to compare
01677 
01678     \returns The strncmp_PF() function returns an integer less than, equal
01679     to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
01680     respectively, to be less than, to match, or be greater than \e s2. The
01681     contents of RAMPZ SFR are undefined when the function returns. */
01682 extern int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01683 
01684 /** \ingroup avr_pgmspace
01685     \fn int strcasecmp_PF(const char *s1, uint_farptr_t s2)
01686     \brief Compare two strings ignoring case
01687 
01688     The strcasecmp_PF() function compares the two strings \e s1 and \e s2, ignoring
01689     the case of the characters.
01690 
01691     \param s1 A pointer to the first string in SRAM
01692     \param s2 A far pointer to the second string in Flash
01693 
01694     \returns The strcasecmp_PF() function returns an integer less than, equal
01695     to, or greater than zero if \e s1 is found, respectively, to be less than, to
01696     match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
01697     when the function returns. */
01698 extern int strcasecmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01699 
01700 /** \ingroup avr_pgmspace
01701     \fn int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n)
01702     \brief Compare two strings ignoring case
01703 
01704     The strncasecmp_PF() function is similar to strcasecmp_PF(), except it
01705     only compares the first \e n characters of \e s1 and the string in flash is
01706     addressed using a far pointer.
01707 
01708     \param s1 A pointer to a string in SRAM
01709     \param s2 A far pointer to a string in Flash
01710     \param n The maximum number of bytes to compare
01711 
01712     \returns The strncasecmp_PF() function returns an integer less than, equal
01713     to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
01714     respectively, to be less than, to match, or be greater than \e s2. The
01715     contents of RAMPZ SFR are undefined when the function returns.  */
01716 extern int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01717 
01718 /** \ingroup avr_pgmspace
01719     \fn char *strstr_PF(const char *s1, uint_farptr_t s2)
01720     \brief Locate a substring.
01721 
01722     The strstr_PF() function finds the first occurrence of the substring \c s2
01723     in the string \c s1.  The terminating '\\0' characters are not
01724     compared.
01725     The strstr_PF() function is similar to strstr() except that \c s2 is a
01726     far pointer to a string in program space.
01727 
01728     \returns The strstr_PF() function returns a pointer to the beginning of the
01729     substring, or NULL if the substring is not found.
01730     If \c s2 points to a string of zero length, the function returns \c s1. The
01731     contents of RAMPZ SFR are undefined when the function returns. */
01732 extern char *strstr_PF(const char *s1, uint_farptr_t s2);
01733 
01734 /** \ingroup avr_pgmspace
01735     \fn size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz)
01736     \brief Copy a string from progmem to RAM.
01737 
01738     Copy src to string dst of size siz.  At most siz-1 characters will be
01739     copied. Always NULL terminates (unless siz == 0).
01740 
01741     \returns The strlcpy_PF() function returns strlen(src). If retval >= siz,
01742     truncation occurred.  The contents of RAMPZ SFR are undefined when the
01743     function returns. */
01744 extern size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz);
01745 
01746 /** \ingroup avr_pgmspace
01747     \fn int memcmp_PF(const void *s1, uint_farptr_t s2, size_t len)
01748     \brief Compare memory areas
01749 
01750     The memcmp_PF() function compares the first \p len bytes of the memory
01751     areas \p s1 and flash \p s2. The comparision is performed using unsigned
01752     char operations. It is an equivalent of memcmp_P() function, except
01753     that it is capable working on all FLASH including the exteded area
01754     above 64kB.
01755 
01756     \returns The memcmp_PF() function returns an integer less than, equal
01757     to, or greater than zero if the first \p len bytes of \p s1 is found,
01758     respectively, to be less than, to match, or be greater than the first
01759     \p len bytes of \p s2.  */
01760 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
01761 
01762 #ifdef __DOXYGEN__
01763 /** \ingroup avr_pgmspace
01764     \fn size_t strlen_P(const char *src)
01765 
01766     The strlen_P() function is similar to strlen(), except that src is a
01767     pointer to a string in program space.
01768 
01769     \returns The strlen_P() function returns the number of characters in src.
01770 
01771     \note strlen_P() is implemented as an inline function in the avr/pgmspace.h
01772     header file, which will check if the length of the string is a constant
01773     and known at compile time. If it is not known at compile time, the macro
01774     will issue a call to __strlen_P() which will then calculate the length
01775     of the string as normal.
01776 */
01777 static inline size_t strlen_P(const char * s);
01778 #else
01779 extern size_t __strlen_P(const char *) __ATTR_CONST__;  /* internal helper function */
01780 __attribute__((__always_inline__)) static __inline__ size_t strlen_P(const char * s);
01781 static __inline__ size_t strlen_P(const char *s) {
01782   return __builtin_constant_p(__builtin_strlen(s))
01783      ? __builtin_strlen(s) : __strlen_P(s);
01784 }
01785 #endif
01786 
01787 #ifdef __cplusplus
01788 }
01789 #endif
01790 
01791 #endif /* __PGMSPACE_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Defines