ESP8266
pgmspace.h
1 #ifndef __PGMSPACE_H_
2 #define __PGMSPACE_H_
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 #include <stdint.h>
8 #include <stdio.h>
9 #include "ets_sys.h"
10 #include "osapi.h"
11 #ifdef __cplusplus
12 }
13 #endif
14 
15 #define PROGMEM ICACHE_RODATA_ATTR
16 #define PGM_P const char *
17 #define PGM_VOID_P const void *
18 #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
19 
20 
21 #define _SFR_BYTE(n) (n)
22 
23 typedef void prog_void;
24 typedef char prog_char;
25 typedef unsigned char prog_uchar;
26 typedef int8_t prog_int8_t;
27 typedef uint8_t prog_uint8_t;
28 typedef int16_t prog_int16_t;
29 typedef uint16_t prog_uint16_t;
30 typedef int32_t prog_int32_t;
31 typedef uint32_t prog_uint32_t;
32 
33 #define SIZE_IRRELEVANT 0x7fffffff
34 
35 // memchr_P and memrchr_P are not implemented due to danger in its use, and
36 // how uninteresting their use is
37 // since its a flash string, you should already know where the char is within it,
38 // further, it could return a pointer into the flash memory that is not 32bit aligned
39 // which could cause an exception if read
40 // PGM_VOID_P memchr_P(PGM_VOID_P bufP, int c, size_t count);
41 // PGM_VOID_P memrchr_P(PGM_VOID_P bufP, int c, size_t count);
42 
43 int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size);
44 // memccpy_P is only valid when used with pointers to 8bit data, due to size aligned pointers
45 // and endianess of the values greater than 8bit, matching c may return invalid aligned pointers
46 void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count);
47 void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize);
48 void* memcpy_P(void* dest, PGM_VOID_P src, size_t count);
49 
50 char* strncpy_P(char* dest, PGM_P src, size_t size);
51 #define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
52 
53 char* strncat_P(char* dest, PGM_P src, size_t size);
54 #define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
55 
56 int strncmp_P(const char* str1, PGM_P str2P, size_t size);
57 #define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
58 
59 int strncasecmp_P(const char* str1, PGM_P str2P, size_t size);
60 #define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
61 
62 size_t strnlen_P(PGM_P s, size_t size);
63 #define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
64 
65 int printf_P(PGM_P formatP, ...) __attribute__((format(printf, 1, 2)));
66 int sprintf_P(char *str, PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
67 int snprintf_P(char *str, size_t strSize, PGM_P formatP, ...) __attribute__((format(printf, 3, 4)));
68 int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribute__((format(printf, 3, 0)));
69 
70 // flash memory must be read using 32 bit aligned addresses else a processor
71 // exception will be triggered
72 // order within the 32 bit values are
73 // --------------
74 // b3, b2, b1, b0
75 // w1, w0
76 
77 #define pgm_read_byte(addr) \
78 (__extension__({ \
79  PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
80  ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \
81  const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local)-__offset); \
82  uint8_t __result = ((*__addr32) >> (__offset * 8)); \
83  __result; \
84 }))
85 
86 #define pgm_read_word(addr) \
87 (__extension__({ \
88  PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
89  ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \
90  const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local) - __offset); \
91  uint16_t __result = ((*__addr32) >> (__offset * 8)); \
92  __result; \
93 }))
94 
95 #define pgm_read_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
96 #define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
97 
98 #define pgm_read_byte_near(addr) pgm_read_byte(addr)
99 #define pgm_read_word_near(addr) pgm_read_word(addr)
100 #define pgm_read_dword_near(addr) pgm_read_dword(addr)
101 #define pgm_read_float_near(addr) pgm_read_float(addr)
102 #define pgm_read_byte_far(addr) pgm_read_byte(addr)
103 #define pgm_read_word_far(addr) pgm_read_word(addr)
104 #define pgm_read_dword_far(addr) pgm_read_dword(addr)
105 #define pgm_read_float_far(addr) pgm_read_float(addr)
106 
107 #endif //__PGMSPACE_H_