$extrastylesheet
avr-libc  2.0.0
Standard C library for AVR-GCC

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: pgmspace.h 2503 2016-02-07 22:59:47Z joerg_wunsch $ */
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_enhanced__(addr)  \
00428 (__extension__({                \
00429     uint16_t __addr16 = (uint16_t)(addr); \
00430     uint8_t __result;           \
00431     __asm__ __volatile__        \
00432     (                           \
00433         "lpm %0, Z" "\n\t"      \
00434         : "=r" (__result)       \
00435         : "z" (__addr16)        \
00436     );                          \
00437     __result;                   \
00438 }))
00439 
00440 #define __LPM_word_classic__(addr)          \
00441 (__extension__({                            \
00442     uint16_t __addr16 = (uint16_t)(addr);   \
00443     uint16_t __result;                      \
00444     __asm__ __volatile__                    \
00445     (                                       \
00446         "lpm"           "\n\t"              \
00447         "mov %A0, r0"   "\n\t"              \
00448         "adiw r30, 1"   "\n\t"              \
00449         "lpm"           "\n\t"              \
00450         "mov %B0, r0"   "\n\t"              \
00451         : "=r" (__result), "=z" (__addr16)  \
00452         : "1" (__addr16)                    \
00453         : "r0"                              \
00454     );                                      \
00455     __result;                               \
00456 }))
00457 
00458 #define __LPM_word_enhanced__(addr)         \
00459 (__extension__({                            \
00460     uint16_t __addr16 = (uint16_t)(addr);   \
00461     uint16_t __result;                      \
00462     __asm__ __volatile__                    \
00463     (                                       \
00464         "lpm %A0, Z+"   "\n\t"              \
00465         "lpm %B0, Z"    "\n\t"              \
00466         : "=r" (__result), "=z" (__addr16)  \
00467         : "1" (__addr16)                    \
00468     );                                      \
00469     __result;                               \
00470 }))
00471 
00472 #define __LPM_dword_classic__(addr)         \
00473 (__extension__({                            \
00474     uint16_t __addr16 = (uint16_t)(addr);   \
00475     uint32_t __result;                      \
00476     __asm__ __volatile__                    \
00477     (                                       \
00478         "lpm"           "\n\t"              \
00479         "mov %A0, r0"   "\n\t"              \
00480         "adiw r30, 1"   "\n\t"              \
00481         "lpm"           "\n\t"              \
00482         "mov %B0, r0"   "\n\t"              \
00483         "adiw r30, 1"   "\n\t"              \
00484         "lpm"           "\n\t"              \
00485         "mov %C0, r0"   "\n\t"              \
00486         "adiw r30, 1"   "\n\t"              \
00487         "lpm"           "\n\t"              \
00488         "mov %D0, r0"   "\n\t"              \
00489         : "=r" (__result), "=z" (__addr16)  \
00490         : "1" (__addr16)                    \
00491         : "r0"                              \
00492     );                                      \
00493     __result;                               \
00494 }))
00495 
00496 #define __LPM_dword_enhanced__(addr)        \
00497 (__extension__({                            \
00498     uint16_t __addr16 = (uint16_t)(addr);   \
00499     uint32_t __result;                      \
00500     __asm__ __volatile__                    \
00501     (                                       \
00502         "lpm %A0, Z+"   "\n\t"              \
00503         "lpm %B0, Z+"   "\n\t"              \
00504         "lpm %C0, Z+"   "\n\t"              \
00505         "lpm %D0, Z"    "\n\t"              \
00506         : "=r" (__result), "=z" (__addr16)  \
00507         : "1" (__addr16)                    \
00508     );                                      \
00509     __result;                               \
00510 }))
00511 
00512 #define __LPM_float_classic__(addr)         \
00513 (__extension__({                            \
00514     uint16_t __addr16 = (uint16_t)(addr);   \
00515     float __result;                         \
00516     __asm__ __volatile__                    \
00517     (                                       \
00518         "lpm"           "\n\t"              \
00519         "mov %A0, r0"   "\n\t"              \
00520         "adiw r30, 1"   "\n\t"              \
00521         "lpm"           "\n\t"              \
00522         "mov %B0, r0"   "\n\t"              \
00523         "adiw r30, 1"   "\n\t"              \
00524         "lpm"           "\n\t"              \
00525         "mov %C0, r0"   "\n\t"              \
00526         "adiw r30, 1"   "\n\t"              \
00527         "lpm"           "\n\t"              \
00528         "mov %D0, r0"   "\n\t"              \
00529         : "=r" (__result), "=z" (__addr16)  \
00530         : "1" (__addr16)                    \
00531         : "r0"                              \
00532     );                                      \
00533     __result;                               \
00534 }))
00535 
00536 #define __LPM_float_enhanced__(addr)        \
00537 (__extension__({                            \
00538     uint16_t __addr16 = (uint16_t)(addr);   \
00539     float __result;                         \
00540     __asm__ __volatile__                    \
00541     (                                       \
00542         "lpm %A0, Z+"   "\n\t"              \
00543         "lpm %B0, Z+"   "\n\t"              \
00544         "lpm %C0, Z+"   "\n\t"              \
00545         "lpm %D0, Z"    "\n\t"              \
00546         : "=r" (__result), "=z" (__addr16)  \
00547         : "1" (__addr16)                    \
00548     );                                      \
00549     __result;                               \
00550 }))
00551 
00552 #if defined (__AVR_HAVE_LPMX__)
00553 #define __LPM(addr)         __LPM_enhanced__(addr)
00554 #define __LPM_word(addr)    __LPM_word_enhanced__(addr)
00555 #define __LPM_dword(addr)   __LPM_dword_enhanced__(addr)
00556 #define __LPM_float(addr)   __LPM_float_enhanced__(addr)
00557 #else
00558 #define __LPM(addr)         __LPM_classic__(addr)
00559 #define __LPM_word(addr)    __LPM_word_classic__(addr)
00560 #define __LPM_dword(addr)   __LPM_dword_classic__(addr)
00561 #define __LPM_float(addr)   __LPM_float_classic__(addr)
00562 #endif
00563 
00564 #endif  /* !__DOXYGEN__ */
00565 
00566 /** \ingroup avr_pgmspace
00567     \def pgm_read_byte_near(address_short)
00568     Read a byte from the program space with a 16-bit (near) address. 
00569     \note The address is a byte address.
00570     The address is in the program space. */
00571 
00572 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
00573 
00574 /** \ingroup avr_pgmspace
00575     \def pgm_read_word_near(address_short)
00576     Read a word from the program space with a 16-bit (near) address. 
00577     \note The address is a byte address. 
00578     The address is in the program space. */
00579 
00580 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
00581 
00582 /** \ingroup avr_pgmspace
00583     \def pgm_read_dword_near(address_short)
00584     Read a double word from the program space with a 16-bit (near) address. 
00585     \note The address is a byte address. 
00586     The address is in the program space. */
00587 
00588 #define pgm_read_dword_near(address_short) \
00589     __LPM_dword((uint16_t)(address_short))
00590 
00591 /** \ingroup avr_pgmspace
00592     \def pgm_read_float_near(address_short)
00593     Read a float from the program space with a 16-bit (near) address. 
00594     \note The address is a byte address. 
00595     The address is in the program space. */
00596 
00597 #define pgm_read_float_near(address_short) \
00598     __LPM_float((uint16_t)(address_short))
00599 
00600 /** \ingroup avr_pgmspace
00601     \def pgm_read_ptr_near(address_short)
00602     Read a pointer from the program space with a 16-bit (near) address. 
00603     \note The address is a byte address. 
00604     The address is in the program space. */
00605 
00606 #define pgm_read_ptr_near(address_short) \
00607     (void*)__LPM_word((uint16_t)(address_short))
00608 
00609 #if defined(RAMPZ) || defined(__DOXYGEN__)
00610 
00611 /* Only for devices with more than 64K of program memory.
00612    RAMPZ must be defined (see iom103.h, iom128.h).
00613 */
00614 
00615 /* The classic functions are needed for ATmega103. */
00616 #ifndef __DOXYGEN__     /* These are internal macros, avoid "is
00617                    not documented" warnings. */
00618 #define __ELPM_classic__(addr)      \
00619 (__extension__({                    \
00620     uint32_t __addr32 = (uint32_t)(addr); \
00621     uint8_t __result;               \
00622     __asm__ __volatile__            \
00623     (                               \
00624         "out %2, %C1" "\n\t"        \
00625         "mov r31, %B1" "\n\t"       \
00626         "mov r30, %A1" "\n\t"       \
00627         "elpm" "\n\t"               \
00628         "mov %0, r0" "\n\t"         \
00629         : "=r" (__result)           \
00630         : "r" (__addr32),           \
00631           "I" (_SFR_IO_ADDR(RAMPZ)) \
00632         : "r0", "r30", "r31"        \
00633     );                              \
00634     __result;                       \
00635 }))
00636 
00637 #define __ELPM_enhanced__(addr)     \
00638 (__extension__({                    \
00639     uint32_t __addr32 = (uint32_t)(addr); \
00640     uint8_t __result;               \
00641     __asm__ __volatile__            \
00642     (                               \
00643         "out %2, %C1" "\n\t"        \
00644         "movw r30, %1" "\n\t"       \
00645         "elpm %0, Z+" "\n\t"        \
00646         : "=r" (__result)           \
00647         : "r" (__addr32),           \
00648           "I" (_SFR_IO_ADDR(RAMPZ)) \
00649         : "r30", "r31"              \
00650     );                              \
00651     __result;                       \
00652 }))
00653 
00654 #define __ELPM_xmega__(addr)        \
00655 (__extension__({                    \
00656     uint32_t __addr32 = (uint32_t)(addr); \
00657     uint8_t __result;               \
00658     __asm__ __volatile__            \
00659     (                               \
00660         "in __tmp_reg__, %2" "\n\t" \
00661         "out %2, %C1" "\n\t"        \
00662         "movw r30, %1" "\n\t"       \
00663         "elpm %0, Z+" "\n\t"        \
00664         "out %2, __tmp_reg__"       \
00665         : "=r" (__result)           \
00666         : "r" (__addr32),           \
00667           "I" (_SFR_IO_ADDR(RAMPZ)) \
00668         : "r30", "r31"              \
00669     );                              \
00670     __result;                       \
00671 }))
00672 
00673 #define __ELPM_word_classic__(addr)     \
00674 (__extension__({                        \
00675     uint32_t __addr32 = (uint32_t)(addr); \
00676     uint16_t __result;                  \
00677     __asm__ __volatile__                \
00678     (                                   \
00679         "out %2, %C1"   "\n\t"          \
00680         "mov r31, %B1"  "\n\t"          \
00681         "mov r30, %A1"  "\n\t"          \
00682         "elpm"          "\n\t"          \
00683         "mov %A0, r0"   "\n\t"          \
00684         "in r0, %2"     "\n\t"          \
00685         "adiw r30, 1"   "\n\t"          \
00686         "adc r0, __zero_reg__" "\n\t"   \
00687         "out %2, r0"    "\n\t"          \
00688         "elpm"          "\n\t"          \
00689         "mov %B0, r0"   "\n\t"          \
00690         : "=r" (__result)               \
00691         : "r" (__addr32),               \
00692           "I" (_SFR_IO_ADDR(RAMPZ))     \
00693         : "r0", "r30", "r31"            \
00694     );                                  \
00695     __result;                           \
00696 }))
00697 
00698 #define __ELPM_word_enhanced__(addr)    \
00699 (__extension__({                        \
00700     uint32_t __addr32 = (uint32_t)(addr); \
00701     uint16_t __result;                  \
00702     __asm__ __volatile__                \
00703     (                                   \
00704         "out %2, %C1"   "\n\t"          \
00705         "movw r30, %1"  "\n\t"          \
00706         "elpm %A0, Z+"  "\n\t"          \
00707         "elpm %B0, Z"   "\n\t"          \
00708         : "=r" (__result)               \
00709         : "r" (__addr32),               \
00710           "I" (_SFR_IO_ADDR(RAMPZ))     \
00711         : "r30", "r31"                  \
00712     );                                  \
00713     __result;                           \
00714 }))
00715 
00716 #define __ELPM_word_xmega__(addr)       \
00717 (__extension__({                        \
00718     uint32_t __addr32 = (uint32_t)(addr); \
00719     uint16_t __result;                  \
00720     __asm__ __volatile__                \
00721     (                                   \
00722         "in __tmp_reg__, %2" "\n\t"     \
00723         "out %2, %C1"   "\n\t"          \
00724         "movw r30, %1"  "\n\t"          \
00725         "elpm %A0, Z+"  "\n\t"          \
00726         "elpm %B0, Z"   "\n\t"          \
00727         "out %2, __tmp_reg__"           \
00728         : "=r" (__result)               \
00729         : "r" (__addr32),               \
00730           "I" (_SFR_IO_ADDR(RAMPZ))     \
00731         : "r30", "r31"                  \
00732     );                                  \
00733     __result;                           \
00734 }))
00735 
00736 #define __ELPM_dword_classic__(addr)      \
00737 (__extension__({                          \
00738     uint32_t __addr32 = (uint32_t)(addr); \
00739     uint32_t __result;                    \
00740     __asm__ __volatile__                  \
00741     (                                     \
00742         "out %2, %C1"          "\n\t"     \
00743         "mov r31, %B1"         "\n\t"     \
00744         "mov r30, %A1"         "\n\t"     \
00745         "elpm"                 "\n\t"     \
00746         "mov %A0, r0"          "\n\t"     \
00747         "in r0, %2"            "\n\t"     \
00748         "adiw r30, 1"          "\n\t"     \
00749         "adc r0, __zero_reg__" "\n\t"     \
00750         "out %2, r0"           "\n\t"     \
00751         "elpm"                 "\n\t"     \
00752         "mov %B0, r0"          "\n\t"     \
00753         "in r0, %2"            "\n\t"     \
00754         "adiw r30, 1"          "\n\t"     \
00755         "adc r0, __zero_reg__" "\n\t"     \
00756         "out %2, r0"           "\n\t"     \
00757         "elpm"                 "\n\t"     \
00758         "mov %C0, r0"          "\n\t"     \
00759         "in r0, %2"            "\n\t"     \
00760         "adiw r30, 1"          "\n\t"     \
00761         "adc r0, __zero_reg__" "\n\t"     \
00762         "out %2, r0"           "\n\t"     \
00763         "elpm"                 "\n\t"     \
00764         "mov %D0, r0"          "\n\t"     \
00765         : "=r" (__result)                 \
00766         : "r" (__addr32),                 \
00767           "I" (_SFR_IO_ADDR(RAMPZ))       \
00768         : "r0", "r30", "r31"              \
00769     );                                    \
00770     __result;                             \
00771 }))
00772 
00773 #define __ELPM_dword_enhanced__(addr)     \
00774 (__extension__({                          \
00775     uint32_t __addr32 = (uint32_t)(addr); \
00776     uint32_t __result;                    \
00777     __asm__ __volatile__                  \
00778     (                                     \
00779         "out %2, %C1"   "\n\t"            \
00780         "movw r30, %1"  "\n\t"            \
00781         "elpm %A0, Z+"  "\n\t"            \
00782         "elpm %B0, Z+"  "\n\t"            \
00783         "elpm %C0, Z+"  "\n\t"            \
00784         "elpm %D0, Z"   "\n\t"            \
00785         : "=r" (__result)                 \
00786         : "r" (__addr32),                 \
00787           "I" (_SFR_IO_ADDR(RAMPZ))       \
00788         : "r30", "r31"                    \
00789     );                                    \
00790     __result;                             \
00791 }))
00792 
00793 #define __ELPM_dword_xmega__(addr)        \
00794 (__extension__({                          \
00795     uint32_t __addr32 = (uint32_t)(addr); \
00796     uint32_t __result;                    \
00797     __asm__ __volatile__                  \
00798     (                                     \
00799         "in __tmp_reg__, %2" "\n\t"       \
00800         "out %2, %C1"   "\n\t"            \
00801         "movw r30, %1"  "\n\t"            \
00802         "elpm %A0, Z+"  "\n\t"            \
00803         "elpm %B0, Z+"  "\n\t"            \
00804         "elpm %C0, Z+"  "\n\t"            \
00805         "elpm %D0, Z"   "\n\t"            \
00806         "out %2, __tmp_reg__"             \
00807         : "=r" (__result)                 \
00808         : "r" (__addr32),                 \
00809           "I" (_SFR_IO_ADDR(RAMPZ))       \
00810         : "r30", "r31"                    \
00811     );                                    \
00812     __result;                             \
00813 }))
00814 
00815 #define __ELPM_float_classic__(addr)      \
00816 (__extension__({                          \
00817     uint32_t __addr32 = (uint32_t)(addr); \
00818     float __result;                       \
00819     __asm__ __volatile__                  \
00820     (                                     \
00821         "out %2, %C1"          "\n\t"     \
00822         "mov r31, %B1"         "\n\t"     \
00823         "mov r30, %A1"         "\n\t"     \
00824         "elpm"                 "\n\t"     \
00825         "mov %A0, 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 %B0, 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 %C0, r0"          "\n\t"     \
00838         "in r0, %2"            "\n\t"     \
00839         "adiw r30, 1"          "\n\t"     \
00840         "adc r0, __zero_reg__" "\n\t"     \
00841         "out %2, r0"           "\n\t"     \
00842         "elpm"                 "\n\t"     \
00843         "mov %D0, r0"          "\n\t"     \
00844         : "=r" (__result)                 \
00845         : "r" (__addr32),                 \
00846           "I" (_SFR_IO_ADDR(RAMPZ))       \
00847         : "r0", "r30", "r31"              \
00848     );                                    \
00849     __result;                             \
00850 }))
00851 
00852 #define __ELPM_float_enhanced__(addr)     \
00853 (__extension__({                          \
00854     uint32_t __addr32 = (uint32_t)(addr); \
00855     float __result;                       \
00856     __asm__ __volatile__                  \
00857     (                                     \
00858         "out %2, %C1"   "\n\t"            \
00859         "movw r30, %1"  "\n\t"            \
00860         "elpm %A0, Z+"  "\n\t"            \
00861         "elpm %B0, Z+"  "\n\t"            \
00862         "elpm %C0, Z+"  "\n\t"            \
00863         "elpm %D0, Z"   "\n\t"            \
00864         : "=r" (__result)                 \
00865         : "r" (__addr32),                 \
00866           "I" (_SFR_IO_ADDR(RAMPZ))       \
00867         : "r30", "r31"                    \
00868     );                                    \
00869     __result;                             \
00870 }))
00871 
00872 #define __ELPM_float_xmega__(addr)        \
00873 (__extension__({                          \
00874     uint32_t __addr32 = (uint32_t)(addr); \
00875     float __result;                       \
00876     __asm__ __volatile__                  \
00877     (                                     \
00878         "in __tmp_reg__, %2" "\n\t"       \
00879         "out %2, %C1"   "\n\t"            \
00880         "movw r30, %1"  "\n\t"            \
00881         "elpm %A0, Z+"  "\n\t"            \
00882         "elpm %B0, Z+"  "\n\t"            \
00883         "elpm %C0, Z+"  "\n\t"            \
00884         "elpm %D0, Z"   "\n\t"            \
00885         "out %2, __tmp_reg__"             \
00886         : "=r" (__result)                 \
00887         : "r" (__addr32),                 \
00888           "I" (_SFR_IO_ADDR(RAMPZ))       \
00889         : "r30", "r31"                    \
00890     );                                    \
00891     __result;                             \
00892 }))
00893 
00894 /*
00895 Check for architectures that implement RAMPD (avrxmega3, avrxmega5,
00896 avrxmega7) as they need to save/restore RAMPZ for ELPM macros so it does
00897 not interfere with data accesses.
00898 */
00899 #if defined (__AVR_HAVE_RAMPD__)
00900 
00901 #define __ELPM(addr)        __ELPM_xmega__(addr)
00902 #define __ELPM_word(addr)   __ELPM_word_xmega__(addr)
00903 #define __ELPM_dword(addr)  __ELPM_dword_xmega__(addr)
00904 #define __ELPM_float(addr)  __ELPM_float_xmega__(addr)
00905 
00906 #else
00907 
00908 #if defined (__AVR_HAVE_LPMX__)
00909 
00910 #define __ELPM(addr)        __ELPM_enhanced__(addr)
00911 #define __ELPM_word(addr)   __ELPM_word_enhanced__(addr)
00912 #define __ELPM_dword(addr)  __ELPM_dword_enhanced__(addr)
00913 #define __ELPM_float(addr)  __ELPM_float_enhanced__(addr)
00914 
00915 #else
00916 
00917 #define __ELPM(addr)        __ELPM_classic__(addr)
00918 #define __ELPM_word(addr)   __ELPM_word_classic__(addr)
00919 #define __ELPM_dword(addr)  __ELPM_dword_classic__(addr)
00920 #define __ELPM_float(addr)  __ELPM_float_classic__(addr)
00921 
00922 #endif  /* __AVR_HAVE_LPMX__ */
00923 
00924 #endif  /* __AVR_HAVE_RAMPD__ */
00925 
00926 #endif  /* !__DOXYGEN__ */
00927 
00928 /** \ingroup avr_pgmspace
00929     \def pgm_read_byte_far(address_long)
00930     Read a byte from the program space with a 32-bit (far) address. 
00931 
00932     \note The address is a byte address. 
00933     The address is in the program space. */
00934 
00935 #define pgm_read_byte_far(address_long)  __ELPM((uint32_t)(address_long))
00936 
00937 /** \ingroup avr_pgmspace
00938     \def pgm_read_word_far(address_long)
00939     Read a word from the program space with a 32-bit (far) address. 
00940 
00941     \note The address is a byte address.
00942     The address is in the program space. */
00943 
00944 #define pgm_read_word_far(address_long)  __ELPM_word((uint32_t)(address_long))
00945 
00946 /** \ingroup avr_pgmspace
00947     \def pgm_read_dword_far(address_long)
00948     Read a double word from the program space with a 32-bit (far) address. 
00949 
00950     \note The address is a byte address.
00951     The address is in the program space. */
00952 
00953 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
00954 
00955 /** \ingroup avr_pgmspace
00956     \def pgm_read_float_far(address_long)
00957     Read a float from the program space with a 32-bit (far) address. 
00958 
00959     \note The address is a byte address.
00960     The address is in the program space. */
00961 
00962 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
00963 
00964 /** \ingroup avr_pgmspace
00965     \def pgm_read_ptr_far(address_long)
00966     Read a pointer from the program space with a 32-bit (far) address. 
00967 
00968     \note The address is a byte address.
00969     The address is in the program space. */
00970 
00971 #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
00972 
00973 #endif /* RAMPZ or __DOXYGEN__ */
00974 
00975 /** \ingroup avr_pgmspace
00976     \def pgm_read_byte(address_short)
00977     Read a byte from the program space with a 16-bit (near) address. 
00978 
00979     \note The address is a byte address. 
00980     The address is in the program space. */
00981 
00982 #define pgm_read_byte(address_short)    pgm_read_byte_near(address_short)
00983 
00984 /** \ingroup avr_pgmspace
00985     \def pgm_read_word(address_short)
00986     Read a word from the program space with a 16-bit (near) address. 
00987 
00988     \note The address is a byte address. 
00989     The address is in the program space. */
00990 
00991 #define pgm_read_word(address_short)    pgm_read_word_near(address_short)
00992 
00993 /** \ingroup avr_pgmspace
00994     \def pgm_read_dword(address_short)
00995     Read a double word from the program space with a 16-bit (near) address. 
00996 
00997     \note The address is a byte address. 
00998     The address is in the program space. */
00999 
01000 #define pgm_read_dword(address_short)   pgm_read_dword_near(address_short)
01001 
01002 /** \ingroup avr_pgmspace
01003     \def pgm_read_float(address_short)
01004     Read a float from the program space with a 16-bit (near) address. 
01005 
01006     \note The address is a byte address. 
01007     The address is in the program space. */
01008 
01009 #define pgm_read_float(address_short)   pgm_read_float_near(address_short)
01010 
01011 /** \ingroup avr_pgmspace
01012     \def pgm_read_ptr(address_short)
01013     Read a pointer from the program space with a 16-bit (near) address. 
01014 
01015     \note The address is a byte address. 
01016     The address is in the program space. */
01017 
01018 #define pgm_read_ptr(address_short)     pgm_read_ptr_near(address_short)
01019 
01020 /** \ingroup avr_pgmspace
01021     \def pgm_get_far_address(var)
01022 
01023    This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
01024    used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
01025    is similar to the '&' operator, with some limitations.
01026 
01027    Comments:
01028 
01029    - The overhead is minimal and it's mainly due to the 32 bit size operation.
01030 
01031    - 24 bit sizes guarantees the code compatibility for use in future devices.
01032 
01033    - hh8() is an undocumented feature but seems to give the third significant byte
01034      of a 32 bit data and accepts symbols, complementing the functionality of hi8()
01035      and lo8(). There is not an equivalent assembler function to get the high
01036      significant byte.
01037 
01038    - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
01039      type variable name, an array name (not an indexed element of the array, if the
01040      index is a constant the compiler does not complain but fails to get the address
01041      if optimization is enabled), a struct name or a struct field name, a function
01042      identifier, a linker defined identifier,...
01043 
01044    - The returned value is the identifier's VMA (virtual memory address) determined
01045      by the linker and falls in the corresponding memory region. The AVR Harvard
01046      architecture requires non overlapping VMA areas for the multiple address spaces
01047      in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
01048      0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
01049      script used and linker options. The value returned can be seen then as a
01050      universal pointer.
01051 */
01052 
01053 #define pgm_get_far_address(var)                          \
01054 ({                                                    \
01055     uint_farptr_t tmp;                                \
01056                                                       \
01057     __asm__ __volatile__(                             \
01058                                                       \
01059             "ldi    %A0, lo8(%1)"           "\n\t"    \
01060             "ldi    %B0, hi8(%1)"           "\n\t"    \
01061             "ldi    %C0, hh8(%1)"           "\n\t"    \
01062             "clr    %D0"                    "\n\t"    \
01063         :                                             \
01064             "=d" (tmp)                                \
01065         :                                             \
01066             "p"  (&(var))                             \
01067     );                                                \
01068     tmp;                                              \
01069 })
01070 
01071 
01072 
01073 /** \ingroup avr_pgmspace
01074     \fn const void * memchr_P(const void *s, int val, size_t len)
01075     \brief Scan flash memory for a character.
01076 
01077     The memchr_P() function scans the first \p len bytes of the flash
01078     memory area pointed to by \p s for the character \p val.  The first
01079     byte to match \p val (interpreted as an unsigned character) stops
01080     the operation.
01081 
01082     \return The memchr_P() function returns a pointer to the matching
01083     byte or \c NULL if the character does not occur in the given memory
01084     area.   */
01085 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01086 
01087 /** \ingroup avr_pgmspace
01088     \fn int memcmp_P(const void *s1, const void *s2, size_t len)
01089     \brief Compare memory areas
01090 
01091     The memcmp_P() function compares the first \p len bytes of the memory
01092     areas \p s1 and flash \p s2. The comparision is performed using unsigned
01093     char operations.
01094 
01095     \returns The memcmp_P() function returns an integer less than, equal
01096     to, or greater than zero if the first \p len bytes of \p s1 is found,
01097     respectively, to be less than, to match, or be greater than the first
01098     \p len bytes of \p s2.  */
01099 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
01100 
01101 /** \ingroup avr_pgmspace
01102     \fn void *memccpy_P (void *dest, const void *src, int val, size_t len)
01103 
01104     This function is similar to memccpy() except that \p src is pointer
01105     to a string in program space.   */
01106 extern void *memccpy_P(void *, const void *, int __val, size_t);
01107 
01108 /** \ingroup avr_pgmspace
01109     \fn void *memcpy_P(void *dest, const void *src, size_t n)
01110 
01111     The memcpy_P() function is similar to memcpy(), except the src string
01112     resides in program space.
01113 
01114     \returns The memcpy_P() function returns a pointer to dest.  */
01115 extern void *memcpy_P(void *, const void *, size_t);
01116 
01117 /** \ingroup avr_pgmspace
01118     \fn void *memmem_P(const void *s1, size_t len1, const void *s2, size_t len2)
01119 
01120     The memmem_P() function is similar to memmem() except that \p s2 is
01121     pointer to a string in program space.   */
01122 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
01123 
01124 /** \ingroup avr_pgmspace
01125     \fn const void +memrchr_P(const void *src, int val, size_t len)
01126 
01127     The memrchr_P() function is like the memchr_P() function, except
01128     that it searches backwards from the end of the \p len bytes pointed
01129     to by \p src instead of forwards from the front. (Glibc, GNU extension.)
01130 
01131     \return The memrchr_P() function returns a pointer to the matching
01132     byte or \c NULL if the character does not occur in the given memory
01133     area.   */
01134 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01135 
01136 /** \ingroup avr_pgmspace
01137     \fn char *strcat_P(char *dest, const char *src)
01138 
01139     The strcat_P() function is similar to strcat() except that the \e src
01140     string must be located in program space (flash).
01141 
01142     \returns The strcat() function returns a pointer to the resulting string
01143     \e dest. */
01144 extern char *strcat_P(char *, const char *);
01145 
01146 /** \ingroup avr_pgmspace
01147     \fn const char *strchr_P(const char *s, int val)
01148     \brief Locate character in program space string.
01149 
01150     The strchr_P() function locates the first occurrence of \p val
01151     (converted to a char) in the string pointed to by \p s in program
01152     space. The terminating null character is considered to be part of
01153     the string.
01154 
01155     The strchr_P() function is similar to strchr() except that \p s is
01156     pointer to a string in program space.
01157 
01158     \returns The strchr_P() function returns a pointer to the matched
01159     character or \c NULL if the character is not found. */
01160 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
01161 
01162 /** \ingroup avr_pgmspace
01163     \fn const char *strchrnul_P(const char *s, int c)
01164 
01165     The strchrnul_P() function is like strchr_P() except that if \p c is
01166     not found in \p s, then it returns a pointer to the null byte at the
01167     end of \p s, rather than \c NULL. (Glibc, GNU extension.)
01168 
01169     \return The strchrnul_P() function returns a pointer to the matched
01170     character, or a pointer to the null byte at the end of \p s (i.e.,
01171     \c s+strlen(s)) if the character is not found.  */
01172 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
01173 
01174 /** \ingroup avr_pgmspace
01175     \fn int strcmp_P(const char *s1, const char *s2)
01176 
01177     The strcmp_P() function is similar to strcmp() except that \p s2 is
01178     pointer to a string in program space.
01179 
01180     \returns The strcmp_P() function returns an integer less than, equal
01181     to, or greater than zero if \p s1 is found, respectively, to be less
01182     than, to match, or be greater than \p s2. A consequence of the
01183     ordering used by strcmp_P() is that if \p s1 is an initial substring
01184     of \p s2, then \p s1 is considered to be "less than" \p s2. */
01185 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
01186 
01187 /** \ingroup avr_pgmspace
01188     \fn char *strcpy_P(char *dest, const char *src)
01189 
01190     The strcpy_P() function is similar to strcpy() except that src is a
01191     pointer to a string in program space.
01192 
01193     \returns The strcpy_P() function returns a pointer to the destination
01194     string dest. */
01195 extern char *strcpy_P(char *, const char *);
01196 
01197 /** \ingroup avr_pgmspace
01198     \fn int strcasecmp_P(const char *s1, const char *s2)
01199     \brief Compare two strings ignoring case.
01200 
01201     The strcasecmp_P() function compares the two strings \p s1 and \p s2,
01202     ignoring the case of the characters.
01203 
01204     \param s1 A pointer to a string in the devices SRAM.
01205     \param s2 A pointer to a string in the devices Flash.
01206 
01207     \returns The strcasecmp_P() function returns an integer less than,
01208     equal to, or greater than zero if \p s1 is found, respectively, to
01209     be less than, to match, or be greater than \p s2. A consequence of
01210     the ordering used by strcasecmp_P() is that if \p s1 is an initial
01211     substring of \p s2, then \p s1 is considered to be "less than" \p s2. */
01212 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
01213 
01214 /** \ingroup avr_pgmspace
01215     \fn char *strcasestr_P(const char *s1, const char *s2)
01216 
01217     This funtion is similar to strcasestr() except that \p s2 is pointer
01218     to a string in program space.   */
01219 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
01220 
01221 /** \ingroup avr_pgmspace
01222     \fn size_t strcspn_P(const char *s, const char *reject)
01223 
01224     The strcspn_P() function calculates the length of the initial segment
01225     of \p s which consists entirely of characters not in \p reject. This
01226     function is similar to strcspn() except that \p reject is a pointer
01227     to a string in program space.
01228 
01229     \return The strcspn_P() function returns the number of characters in
01230     the initial segment of \p s which are not in the string \p reject.
01231     The terminating zero is not considered as a part of string. */
01232 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
01233 
01234 /** \ingroup avr_pgmspace
01235     \fn size_t strlcat_P(char *dst, const char *src, size_t siz)
01236     \brief Concatenate two strings.
01237 
01238     The strlcat_P() function is similar to strlcat(), except that the \p src
01239     string must be located in program space (flash).
01240 
01241     Appends \p src to string \p dst of size \p siz (unlike strncat(),
01242     \p siz is the full size of \p dst, not space left).  At most \p siz-1
01243     characters will be copied.  Always NULL terminates (unless \p siz <=
01244     \p strlen(dst)).
01245 
01246     \returns The strlcat_P() function returns strlen(src) + MIN(siz,
01247     strlen(initial dst)).  If retval >= siz, truncation occurred.   */
01248 extern size_t strlcat_P (char *, const char *, size_t );
01249 
01250 /** \ingroup avr_pgmspace
01251     \fn size_t strlcpy_P(char *dst, const char *src, size_t siz)
01252     \brief Copy a string from progmem to RAM.
01253 
01254     Copy \p src to string \p dst of size \p siz.  At most \p siz-1
01255     characters will be copied.  Always NULL terminates (unless \p siz == 0).
01256     The strlcpy_P() function is similar to strlcpy() except that the
01257     \p src is pointer to a string in memory space.
01258 
01259     \returns The strlcpy_P() function returns strlen(src). If
01260     retval >= siz, truncation occurred.  */
01261 extern size_t strlcpy_P (char *, const char *, size_t );
01262 
01263 /** \ingroup avr_pgmspace
01264     \fn size_t strnlen_P(const char *src, size_t len)
01265     \brief Determine the length of a fixed-size string.
01266 
01267     The strnlen_P() function is similar to strnlen(), except that \c src is a
01268     pointer to a string in program space.
01269 
01270     \returns The strnlen_P function returns strlen_P(src), if that is less than
01271     \c len, or \c len if there is no '\\0' character among the first \c len
01272     characters pointed to by \c src. */
01273 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
01274 
01275 /** \ingroup avr_pgmspace
01276     \fn int strncmp_P(const char *s1, const char *s2, size_t n)
01277 
01278     The strncmp_P() function is similar to strcmp_P() except it only compares
01279     the first (at most) n characters of s1 and s2.
01280 
01281     \returns The strncmp_P() function returns an integer less than, equal to,
01282     or greater than zero if s1 (or the first n bytes thereof) is found,
01283     respectively, to be less than, to match, or be greater than s2.  */
01284 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01285 
01286 /** \ingroup avr_pgmspace
01287     \fn int strncasecmp_P(const char *s1, const char *s2, size_t n)
01288     \brief Compare two strings ignoring case.
01289 
01290     The strncasecmp_P() function is similar to strcasecmp_P(), except it
01291     only compares the first \p n characters of \p s1.
01292 
01293     \param s1 A pointer to a string in the devices SRAM.
01294     \param s2 A pointer to a string in the devices Flash.
01295     \param n The maximum number of bytes to compare.
01296 
01297     \returns The strncasecmp_P() function returns an integer less than,
01298     equal to, or greater than zero if \p s1 (or the first \p n bytes
01299     thereof) is found, respectively, to be less than, to match, or be
01300     greater than \p s2. A consequence of the ordering used by
01301     strncasecmp_P() is that if \p s1 is an initial substring of \p s2,
01302     then \p s1 is considered to be "less than" \p s2.  */
01303 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01304 
01305 /** \ingroup avr_pgmspace
01306     \fn char *strncat_P(char *dest, const char *src, size_t len)
01307     \brief Concatenate two strings.
01308 
01309     The strncat_P() function is similar to strncat(), except that the \e src
01310     string must be located in program space (flash).
01311 
01312     \returns The strncat_P() function returns a pointer to the resulting string
01313     dest.  */
01314 extern char *strncat_P(char *, const char *, size_t);
01315 
01316 /** \ingroup avr_pgmspace
01317     \fn char *strncpy_P(char *dest, const char *src, size_t n)
01318 
01319     The strncpy_P() function is similar to strcpy_P() except that not more
01320     than n bytes of src are copied.  Thus, if there is no null byte among the
01321     first n bytes of src, the result will not be null-terminated.
01322 
01323     In the case where the length of src is less than that of n, the remainder
01324     of dest will be padded with nulls.
01325 
01326     \returns The strncpy_P() function returns a pointer to the destination
01327     string dest.  */
01328 extern char *strncpy_P(char *, const char *, size_t);
01329 
01330 /** \ingroup avr_pgmspace
01331     \fn char *strpbrk_P(const char *s, const char *accept)
01332 
01333     The strpbrk_P() function locates the first occurrence in the string
01334     \p s of any of the characters in the flash string \p accept. This
01335     function is similar to strpbrk() except that \p accept is a pointer
01336     to a string in program space.
01337 
01338     \return  The strpbrk_P() function returns a pointer to the character
01339     in \p s that matches one of the characters in \p accept, or \c NULL
01340     if no such character is found. The terminating zero is not considered
01341     as a part of string: if one or both args are empty, the result will
01342     \c NULL. */
01343 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
01344 
01345 /** \ingroup avr_pgmspace
01346     \fn const char *strrchr_P(const char *s, int val)
01347     \brief Locate character in string.
01348 
01349     The strrchr_P() function returns a pointer to the last occurrence of
01350     the character \p val in the flash string \p s.
01351 
01352     \return The strrchr_P() function returns a pointer to the matched
01353     character or \c NULL if the character is not found. */
01354 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
01355 
01356 /** \ingroup avr_pgmspace
01357     \fn char *strsep_P(char **sp, const char *delim)
01358     \brief Parse a string into tokens.
01359 
01360     The strsep_P() function locates, in the string referenced by \p *sp,
01361     the first occurrence of any character in the string \p delim (or the
01362     terminating '\\0' character) and replaces it with a '\\0'.  The
01363     location of the next character after the delimiter character (or \c
01364     NULL, if the end of the string was reached) is stored in \p *sp. An
01365     ``empty'' field, i.e. one caused by two adjacent delimiter
01366     characters, can be detected by comparing the location referenced by
01367     the pointer returned in \p *sp to '\\0'. This function is similar to
01368     strsep() except that \p delim is a pointer to a string in program
01369     space.
01370 
01371     \return The strsep_P() function returns a pointer to the original
01372     value of \p *sp. If \p *sp is initially \c NULL, strsep_P() returns
01373     \c NULL. */
01374 extern char *strsep_P(char **__sp, const char * __delim);
01375 
01376 /** \ingroup avr_pgmspace
01377     \fn size_t strspn_P(const char *s, const char *accept)
01378 
01379     The strspn_P() function calculates the length of the initial segment
01380     of \p s which consists entirely of characters in \p accept. This
01381     function is similar to strspn() except that \p accept is a pointer
01382     to a string in program space.
01383 
01384     \return  The strspn_P() function returns the number of characters in
01385     the initial segment of \p s which consist only of characters from \p
01386     accept. The terminating zero is not considered as a part of string. */
01387 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
01388 
01389 /** \ingroup avr_pgmspace
01390     \fn char *strstr_P(const char *s1, const char *s2)
01391     \brief Locate a substring.
01392 
01393     The strstr_P() function finds the first occurrence of the substring
01394     \p s2 in the string \p s1.  The terminating '\\0' characters are not
01395     compared. The strstr_P() function is similar to strstr() except that
01396     \p s2 is pointer to a string in program space.
01397 
01398     \returns The strstr_P() function returns a pointer to the beginning
01399     of the substring, or NULL if the substring is not found. If \p s2
01400     points to a string of zero length, the function returns \p s1. */
01401 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
01402 
01403 /** \ingroup avr_pgmspace
01404     \fn char *strtok_P(char *s, const char * delim)
01405     \brief Parses the string into tokens.
01406 
01407     strtok_P() parses the string \p s into tokens. The first call to
01408     strtok_P() should have \p s as its first argument. Subsequent calls
01409     should have the first argument set to NULL. If a token ends with a
01410     delimiter, this delimiting character is overwritten with a '\\0' and a
01411     pointer to the next character is saved for the next call to strtok_P().
01412     The delimiter string \p delim may be different for each call.
01413 
01414     The strtok_P() function is similar to strtok() except that \p delim
01415     is pointer to a string in program space.
01416 
01417     \returns The strtok_P() function returns a pointer to the next token or
01418     NULL when no more tokens are found.
01419 
01420     \note strtok_P() is NOT reentrant. For a reentrant version of this
01421     function see strtok_rP().
01422  */
01423 extern char *strtok_P(char *__s, const char * __delim);
01424 
01425 /** \ingroup avr_pgmspace
01426     \fn char *strtok_rP (char *string, const char *delim, char **last)
01427     \brief Parses string into tokens.
01428 
01429     The strtok_rP() function parses \p string into tokens. The first call to
01430     strtok_rP() should have string as its first argument. Subsequent calls
01431     should have the first argument set to NULL. If a token ends with a
01432     delimiter, this delimiting character is overwritten with a '\\0' and a
01433     pointer to the next character is saved for the next call to strtok_rP().
01434     The delimiter string \p delim may be different for each call. \p last is
01435     a user allocated char* pointer. It must be the same while parsing the
01436     same string. strtok_rP() is a reentrant version of strtok_P().
01437 
01438     The strtok_rP() function is similar to strtok_r() except that \p delim
01439     is pointer to a string in program space.
01440 
01441     \returns The strtok_rP() function returns a pointer to the next token or
01442     NULL when no more tokens are found. */
01443 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
01444 
01445 /** \ingroup avr_pgmspace
01446     \fn size_t strlen_PF(uint_farptr_t s)
01447     \brief Obtain the length of a string
01448 
01449     The strlen_PF() function is similar to strlen(), except that \e s is a
01450     far pointer to a string in program space.
01451 
01452     \param s A far pointer to the string in flash
01453 
01454     \returns The strlen_PF() function returns the number of characters in
01455     \e s. The contents of RAMPZ SFR are undefined when the function returns. */
01456 extern size_t strlen_PF(uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
01457 
01458 /** \ingroup avr_pgmspace
01459     \fn size_t strnlen_PF(uint_farptr_t s, size_t len)
01460     \brief Determine the length of a fixed-size string
01461 
01462     The strnlen_PF() function is similar to strnlen(), except that \e s is a
01463     far pointer to a string in program space.
01464 
01465     \param s A far pointer to the string in Flash
01466     \param len The maximum number of length to return
01467 
01468     \returns The strnlen_PF function returns strlen_P(\e s), if that is less
01469     than \e len, or \e len if there is no '\\0' character among the first \e
01470     len characters pointed to by \e s. The contents of RAMPZ SFR are
01471     undefined when the function returns. */
01472 extern size_t strnlen_PF(uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
01473 
01474 /** \ingroup avr_pgmspace
01475     \fn void *memcpy_PF(void *dest, uint_farptr_t src, size_t n)
01476     \brief Copy a memory block from flash to SRAM
01477 
01478     The memcpy_PF() function is similar to memcpy(), except the data
01479     is copied from the program space and is addressed using a far pointer.
01480 
01481     \param dest A pointer to the destination buffer
01482     \param src A far pointer to the origin of data in flash memory
01483     \param n The number of bytes to be copied
01484 
01485     \returns The memcpy_PF() function returns a pointer to \e dst. The contents
01486     of RAMPZ SFR are undefined when the function returns. */
01487 extern void *memcpy_PF(void *dest, uint_farptr_t src, size_t len);
01488 
01489 /** \ingroup avr_pgmspace
01490     \fn char *strcpy_PF(char *dst, uint_farptr_t src)
01491     \brief Duplicate a string
01492 
01493     The strcpy_PF() function is similar to strcpy() except that \e src is a far
01494     pointer to a string in program space.
01495 
01496     \param dst A pointer to the destination string in SRAM
01497     \param src A far pointer to the source string in Flash
01498 
01499     \returns The strcpy_PF() function returns a pointer to the destination
01500     string \e dst. The contents of RAMPZ SFR are undefined when the funcion
01501     returns. */
01502 extern char *strcpy_PF(char *dest, uint_farptr_t src);
01503 
01504 /** \ingroup avr_pgmspace
01505     \fn char *strncpy_PF(char *dst, uint_farptr_t src, size_t n)
01506     \brief Duplicate a string until a limited length
01507 
01508     The strncpy_PF() function is similar to strcpy_PF() except that not more
01509     than \e n bytes of \e src are copied.  Thus, if there is no null byte among
01510     the first \e n bytes of \e src, the result will not be null-terminated.
01511 
01512     In the case where the length of \e src is less than that of \e n, the
01513     remainder of \e dst will be padded with nulls.
01514 
01515     \param dst A pointer to the destination string in SRAM
01516     \param src A far pointer to the source string in Flash
01517     \param n The maximum number of bytes to copy
01518 
01519     \returns The strncpy_PF() function returns a pointer to the destination
01520     string \e dst. The contents of RAMPZ SFR are undefined when the function
01521     returns. */
01522 extern char *strncpy_PF(char *dest, uint_farptr_t src, size_t len);
01523 
01524 /** \ingroup avr_pgmspace
01525     \fn char *strcat_PF(char *dst, uint_farptr_t src)
01526     \brief Concatenates two strings
01527 
01528     The strcat_PF() function is similar to strcat() except that the \e src
01529     string must be located in program space (flash) and is addressed using
01530     a far pointer
01531 
01532     \param dst A pointer to the destination string in SRAM
01533     \param src A far pointer to the string to be appended in Flash
01534 
01535     \returns The strcat_PF() function returns a pointer to the resulting
01536     string \e dst. The contents of RAMPZ SFR are undefined when the function
01537     returns */
01538 extern char *strcat_PF(char *dest, uint_farptr_t src);
01539 
01540 /** \ingroup avr_pgmspace
01541     \fn size_t strlcat_PF(char *dst, uint_farptr_t src, size_t n)
01542     \brief Concatenate two strings
01543 
01544     The strlcat_PF() function is similar to strlcat(), except that the \e src
01545     string must be located in program space (flash) and is addressed using
01546     a far pointer.
01547 
01548     Appends src to string dst of size \e n (unlike strncat(), \e n is the
01549     full size of \e dst, not space left).  At most \e n-1 characters
01550     will be copied.  Always NULL terminates (unless \e n <= strlen(\e dst)).
01551 
01552     \param dst A pointer to the destination string in SRAM
01553     \param src A far pointer to the source string in Flash
01554     \param n The total number of bytes allocated to the destination string
01555 
01556     \returns The strlcat_PF() function returns strlen(\e src) + MIN(\e n,
01557     strlen(initial \e dst)).  If retval >= \e n, truncation occurred. The
01558     contents of RAMPZ SFR are undefined when the funcion returns. */
01559 extern size_t strlcat_PF(char *dst, uint_farptr_t src, size_t siz);
01560 
01561 /** \ingroup avr_pgmspace
01562     \fn char *strncat_PF(char *dst, uint_farptr_t src, size_t n)
01563     \brief Concatenate two strings
01564 
01565     The strncat_PF() function is similar to strncat(), except that the \e src
01566     string must be located in program space (flash) and is addressed using a
01567     far pointer.
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     \param n The maximum number of bytes to append
01572 
01573     \returns The strncat_PF() function returns a pointer to the resulting
01574     string \e dst. The contents of RAMPZ SFR are undefined when the function
01575     returns. */
01576 extern char *strncat_PF(char *dest, uint_farptr_t src, size_t len);
01577 
01578 /** \ingroup avr_pgmspace
01579     \fn int strcmp_PF(const char *s1, uint_farptr_t s2)
01580     \brief Compares two strings
01581 
01582     The strcmp_PF() function is similar to strcmp() except that \e s2 is a far
01583     pointer to a string in program space.
01584 
01585     \param s1 A pointer to the first string in SRAM
01586     \param s2 A far pointer to the second string in Flash
01587 
01588     \returns The strcmp_PF() function returns an integer less than, equal to,
01589     or greater than zero if \e s1 is found, respectively, to be less than, to
01590     match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
01591     when the function returns. */
01592 extern int strcmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01593 
01594 /** \ingroup avr_pgmspace
01595     \fn int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n)
01596     \brief Compare two strings with limited length
01597 
01598     The strncmp_PF() function is similar to strcmp_PF() except it only
01599     compares the first (at most) \e n characters of \e s1 and \e s2.
01600 
01601     \param s1 A pointer to the first string in SRAM
01602     \param s2 A far pointer to the second string in Flash
01603     \param n The maximum number of bytes to compare
01604 
01605     \returns The strncmp_PF() function returns an integer less than, equal
01606     to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
01607     respectively, to be less than, to match, or be greater than \e s2. The
01608     contents of RAMPZ SFR are undefined when the function returns. */
01609 extern int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01610 
01611 /** \ingroup avr_pgmspace
01612     \fn int strcasecmp_PF(const char *s1, uint_farptr_t s2)
01613     \brief Compare two strings ignoring case
01614 
01615     The strcasecmp_PF() function compares the two strings \e s1 and \e s2, ignoring
01616     the case of the characters.
01617 
01618     \param s1 A pointer to the first string in SRAM
01619     \param s2 A far pointer to the second string in Flash
01620 
01621     \returns The strcasecmp_PF() function returns an integer less than, equal
01622     to, or greater than zero if \e s1 is found, respectively, to be less than, to
01623     match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
01624     when the function returns. */
01625 extern int strcasecmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01626 
01627 /** \ingroup avr_pgmspace
01628     \fn int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n)
01629     \brief Compare two strings ignoring case
01630 
01631     The strncasecmp_PF() function is similar to strcasecmp_PF(), except it
01632     only compares the first \e n characters of \e s1 and the string in flash is
01633     addressed using a far pointer.
01634 
01635     \param s1 A pointer to a string in SRAM
01636     \param s2 A far pointer to a string in Flash
01637     \param n The maximum number of bytes to compare
01638 
01639     \returns The strncasecmp_PF() function returns an integer less than, equal
01640     to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
01641     respectively, to be less than, to match, or be greater than \e s2. The
01642     contents of RAMPZ SFR are undefined when the function returns.  */
01643 extern int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01644 
01645 /** \ingroup avr_pgmspace
01646     \fn char *strstr_PF(const char *s1, uint_farptr_t s2)
01647     \brief Locate a substring.
01648 
01649     The strstr_PF() function finds the first occurrence of the substring \c s2
01650     in the string \c s1.  The terminating '\\0' characters are not
01651     compared.
01652     The strstr_PF() function is similar to strstr() except that \c s2 is a
01653     far pointer to a string in program space.
01654 
01655     \returns The strstr_PF() function returns a pointer to the beginning of the
01656     substring, or NULL if the substring is not found.
01657     If \c s2 points to a string of zero length, the function returns \c s1. The
01658     contents of RAMPZ SFR are undefined when the function returns. */
01659 extern char *strstr_PF(const char *s1, uint_farptr_t s2);
01660 
01661 /** \ingroup avr_pgmspace
01662     \fn size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz)
01663     \brief Copy a string from progmem to RAM.
01664 
01665     Copy src to string dst of size siz.  At most siz-1 characters will be
01666     copied. Always NULL terminates (unless siz == 0).
01667 
01668     \returns The strlcpy_PF() function returns strlen(src). If retval >= siz,
01669     truncation occurred.  The contents of RAMPZ SFR are undefined when the
01670     function returns. */
01671 extern size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz);
01672 
01673 /** \ingroup avr_pgmspace
01674     \fn int memcmp_PF(const void *s1, uint_farptr_t s2, size_t len)
01675     \brief Compare memory areas
01676 
01677     The memcmp_PF() function compares the first \p len bytes of the memory
01678     areas \p s1 and flash \p s2. The comparision is performed using unsigned
01679     char operations. It is an equivalent of memcmp_P() function, except
01680     that it is capable working on all FLASH including the exteded area
01681     above 64kB.
01682 
01683     \returns The memcmp_PF() function returns an integer less than, equal
01684     to, or greater than zero if the first \p len bytes of \p s1 is found,
01685     respectively, to be less than, to match, or be greater than the first
01686     \p len bytes of \p s2.  */
01687 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
01688 
01689 #ifdef __DOXYGEN__
01690 /** \ingroup avr_pgmspace
01691     \fn size_t strlen_P(const char *src)
01692 
01693     The strlen_P() function is similar to strlen(), except that src is a
01694     pointer to a string in program space.
01695 
01696     \returns The strlen_P() function returns the number of characters in src.
01697 
01698     \note strlen_P() is implemented as an inline function in the avr/pgmspace.h
01699     header file, which will check if the length of the string is a constant
01700     and known at compile time. If it is not known at compile time, the macro
01701     will issue a call to __strlen_P() which will then calculate the length
01702     of the string as normal.
01703 */
01704 static inline size_t strlen_P(const char * s);
01705 #else
01706 extern size_t __strlen_P(const char *) __ATTR_CONST__;  /* internal helper function */
01707 __attribute__((__always_inline__)) static __inline__ size_t strlen_P(const char * s);
01708 static __inline__ size_t strlen_P(const char *s) {
01709   return __builtin_constant_p(__builtin_strlen(s))
01710      ? __builtin_strlen(s) : __strlen_P(s);
01711 }
01712 #endif
01713 
01714 #ifdef __cplusplus
01715 }
01716 #endif
01717 
01718 #endif /* __PGMSPACE_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Defines