FakePgmSpace.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * FakePgmSpace.h - Support for reading flash memory
8  *
9  ****/
10 
11 #pragma once
12 
13 #include <stdio.h>
14 #include <esp_attr.h>
15 #include <sys/pgmspace.h>
16 
17 #include "m_printf.h"
18 #include <c_types.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
34 #define IS_ALIGNED(_x) (((uint32_t)(_x)&3) == 0)
35 
39 #define ALIGNUP4(n) (((n) + 3) & ~3)
40 
44 #define ALIGNDOWN4(n) ((n) & ~3)
45 
46 #define printf_P_heap(f_P, ...) \
47  (__extension__({ \
48  char* __localF = (char*)malloc(strlen_P(f_P) + 1); \
49  strcpy_P(__localF, f_P); \
50  int __result = os_printf_plus(__localF, ##__VA_ARGS__); \
51  free(__localF); \
52  __result; \
53  }))
54 
55 #define printf_P_stack(f_P, ...) \
56  (__extension__({ \
57  char __localF[256]; \
58  strncpy_P(__localF, f_P, sizeof(__localF)); \
59  __localF[sizeof(__localF) - 1] = '\0'; \
60  m_printf(__localF, ##__VA_ARGS__); \
61  }))
62 
63 #ifdef ARCH_ESP8266
64 // ESP8266 requires byte-aligned flash accesses for format string...
65 #define printf_P(fmt, ...) printf_P_stack(fmt, ##__VA_ARGS__)
66 #else
67 // ... but other architectures do not
68 #define printf_P(fmt, ...) m_printf(fmt, ##__VA_ARGS__)
69 #endif
70 
78 #define PSTR_COUNTED(str) \
79  (__extension__({ \
80  static const char __pstr__[] PROGMEM = str; \
81  &__pstr__[0]; \
82  }))
83 
84 #ifdef ARCH_ESP8266
90 #define _F(str) \
91  (__extension__({ \
92  DEFINE_PSTR_LOCAL(__pstr__, str); \
93  LOAD_PSTR(buf, __pstr__); \
94  buf; \
95  }))
96 #else
97 #define _F(str) (str)
98 #endif
99 
110 void* memcpy_aligned(void* dst, const void* src, unsigned len);
111 
122 int memcmp_aligned(const void* ptr1, const void* ptr2, unsigned len);
123 
128 #define DEFINE_PSTR(name, str) const char name[] PROGMEM_PSTR = str;
129 
134 #define DEFINE_PSTR_LOCAL(name, str) static DEFINE_PSTR(name, str)
135 
140 #define DECLARE_PSTR(name) extern const char name[];
141 
158 #define LOAD_PSTR(name, flash_str) \
159  char name[ALIGNUP4(sizeof(flash_str))] __attribute__((aligned(4))); \
160  memcpy_aligned(name, flash_str, sizeof(flash_str));
161 
162 #define _FLOAD(pstr) \
163  (__extension__({ \
164  LOAD_PSTR(_buf, pstr); \
165  _buf; \
166  }))
167 
186 #define PSTR_ARRAY(name, str) \
187  DEFINE_PSTR_LOCAL(__pstr__##name, str); \
188  LOAD_PSTR(name, __pstr__##name)
189 
192 #ifdef __cplusplus
193 }
194 #endif
int memcmp_aligned(const void *ptr1, const void *ptr2, unsigned len)
compare memory aligned to word boundaries
void * memcpy_aligned(void *dst, const void *src, unsigned len)
copy memory aligned to word boundaries