Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8b1caeb

Browse files
committed
PgmSpace working
PSTR() and F() macros correctly place string into flash memory relying on PROGMEM PROGMEM uses ICACHE_RODATA_ATTR Print and String classes fixed up str* classes fixed up
1 parent 1862e0d commit 8b1caeb

File tree

7 files changed

+296
-30
lines changed

7 files changed

+296
-30
lines changed

hardware/esp8266com/esp8266/cores/esp8266/Print.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
Modified 23 November 2006 by David A. Mellis
2020
Modified December 2014 by Ivan Grokhotkov
21+
Modified May 2015 by Michael C. Miller - esp8266 progmem support
2122
*/
2223

2324
#include <stdlib.h>
@@ -42,6 +43,18 @@ size_t ICACHE_FLASH_ATTR Print::write(const uint8_t *buffer, size_t size) {
4243
return n;
4344
}
4445

46+
size_t ICACHE_FLASH_ATTR Print::print(const __FlashStringHelper *ifsh) {
47+
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
48+
49+
size_t n = 0;
50+
while (1) {
51+
uint8_t c = pgm_read_byte(p++);
52+
if (c == 0) break;
53+
n += write(c);
54+
}
55+
return n;
56+
}
57+
4558
size_t ICACHE_FLASH_ATTR Print::print(const String &s) {
4659
return write(s.c_str(), s.length());
4760
}
@@ -92,6 +105,12 @@ size_t ICACHE_FLASH_ATTR Print::print(double n, int digits) {
92105
return printFloat(n, digits);
93106
}
94107

108+
size_t ICACHE_FLASH_ATTR Print::println(const __FlashStringHelper *ifsh) {
109+
size_t n = print(ifsh);
110+
n += println();
111+
return n;
112+
}
113+
95114
size_t ICACHE_FLASH_ATTR Print::print(const Printable& x) {
96115
return x.printTo(*this);
97116
}

hardware/esp8266com/esp8266/cores/esp8266/Print.h

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class Print {
6363
return write((const uint8_t *) buffer, size);
6464
}
6565

66+
size_t print(const __FlashStringHelper *);
6667
size_t print(const String &);
6768
size_t print(const char[]);
6869
size_t print(char);
@@ -74,6 +75,7 @@ class Print {
7475
size_t print(double, int = 2);
7576
size_t print(const Printable&);
7677

78+
size_t println(const __FlashStringHelper *);
7779
size_t println(const String &s);
7880
size_t println(const char[]);
7981
size_t println(char);

hardware/esp8266com/esp8266/cores/esp8266/WString.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
55
Copyright 2011, Paul Stoffregen, [email protected]
66
Modified by Ivan Grokhotkov, 2014 - esp8266 support
7+
Modified by Michael C. Miller, 2015 - esp8266 progmem support
78
89
This library is free software; you can redistribute it and/or
910
modify it under the terms of the GNU Lesser General Public
@@ -44,6 +45,11 @@ ICACHE_FLASH_ATTR String::String(const String &value) {
4445
*this = value;
4546
}
4647

48+
ICACHE_FLASH_ATTR String::String(const __FlashStringHelper *pstr) {
49+
init();
50+
*this = pstr; // see operator =
51+
}
52+
4753
#ifdef __GXX_EXPERIMENTAL_CXX0X__
4854
ICACHE_FLASH_ATTR String::String(String &&rval) {
4955
init();
@@ -167,6 +173,16 @@ String & ICACHE_FLASH_ATTR String::copy(const char *cstr, unsigned int length) {
167173
return *this;
168174
}
169175

176+
String & ICACHE_FLASH_ATTR String::copy(const __FlashStringHelper *pstr, unsigned int length) {
177+
if (!reserve(length)) {
178+
invalidate();
179+
return *this;
180+
}
181+
len = length;
182+
strcpy_P(buffer, (PGM_P)pstr);
183+
return *this;
184+
}
185+
170186
#ifdef __GXX_EXPERIMENTAL_CXX0X__
171187
void ICACHE_FLASH_ATTR String::move(String &rhs) {
172188
if(buffer) {
@@ -223,6 +239,14 @@ String & ICACHE_FLASH_ATTR String::operator =(const char *cstr) {
223239
return *this;
224240
}
225241

242+
String & ICACHE_FLASH_ATTR String::operator = (const __FlashStringHelper *pstr)
243+
{
244+
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
245+
else invalidate();
246+
247+
return *this;
248+
}
249+
226250
// /*********************************************/
227251
// /* concat */
228252
// /*********************************************/
@@ -299,6 +323,17 @@ unsigned char ICACHE_FLASH_ATTR String::concat(double num) {
299323
return concat(string, strlen(string));
300324
}
301325

326+
unsigned char ICACHE_FLASH_ATTR String::concat(const __FlashStringHelper * str) {
327+
if (!str) return 0;
328+
int length = strlen_P((PGM_P)str);
329+
if (length == 0) return 1;
330+
unsigned int newlen = len + length;
331+
if (!reserve(newlen)) return 0;
332+
strcpy_P(buffer + len, (PGM_P)str);
333+
len = newlen;
334+
return 1;
335+
}
336+
302337
/*********************************************/
303338
/* Concatenate */
304339
/*********************************************/
@@ -373,6 +408,13 @@ StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, doubl
373408
return a;
374409
}
375410

411+
StringSumHelper & ICACHE_FLASH_ATTR operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
412+
{
413+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
414+
if (!a.concat(rhs)) a.invalidate();
415+
return a;
416+
}
417+
376418
// /*********************************************/
377419
// /* Comparison */
378420
// /*********************************************/

hardware/esp8266com/esp8266/cores/esp8266/WString.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@
2626
#include <stdlib.h>
2727
#include <string.h>
2828
#include <ctype.h>
29-
#define PROGMEM
29+
#include <pgmspace.h>
3030

3131
// An inherited class for holding the result of a concatenation. These
3232
// result objects are assumed to be writable by subsequent concatenations.
3333
class StringSumHelper;
3434

35-
typedef char* __FlashStringHelper;
36-
//#define F(str) []() -> const char * { static const char tmp[] ICACHE_RODATA_ATTR = str; return &tmp[0]; }()
37-
#define F(str) str
35+
// an abstract class used as a means to proide a unique pointer type
36+
// but really has no body
37+
class __FlashStringHelper;
38+
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
39+
3840

3941
// The string class
4042
class String {
@@ -53,6 +55,7 @@ class String {
5355
// be false).
5456
String(const char *cstr = "");
5557
String(const String &str);
58+
String(const __FlashStringHelper *str);
5659
#ifdef __GXX_EXPERIMENTAL_CXX0X__
5760
String(String &&rval);
5861
String(StringSumHelper &&rval);
@@ -81,6 +84,7 @@ class String {
8184
// marked as invalid ("if (s)" will be false).
8285
String & operator =(const String &rhs);
8386
String & operator =(const char *cstr);
87+
String & operator = (const __FlashStringHelper *str);
8488
#ifdef __GXX_EXPERIMENTAL_CXX0X__
8589
String & operator =(String &&rval);
8690
String & operator =(StringSumHelper &&rval);
@@ -101,6 +105,7 @@ class String {
101105
unsigned char concat(unsigned long num);
102106
unsigned char concat(float num);
103107
unsigned char concat(double num);
108+
unsigned char concat(const __FlashStringHelper * str);
104109

105110
// if there's not enough memory for the concatenated value, the string
106111
// will be left unchanged (but this isn't signalled in any way)
@@ -144,6 +149,10 @@ class String {
144149
concat(num);
145150
return (*this);
146151
}
152+
String & operator += (const __FlashStringHelper *str){
153+
concat(str);
154+
return (*this);
155+
}
147156

148157
friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
149158
friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
@@ -155,6 +164,7 @@ class String {
155164
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
156165
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
157166
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
167+
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
158168

159169
// comparison (only works w/ Strings and "strings")
160170
operator StringIfHelperType() const {
@@ -237,6 +247,7 @@ class String {
237247

238248
// copy and move
239249
String & copy(const char *cstr, unsigned int length);
250+
String & copy(const __FlashStringHelper *pstr, unsigned int length);
240251
#ifdef __GXX_EXPERIMENTAL_CXX0X__
241252
void move(String &rhs);
242253
#endif

hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ char* strncpy(char * dest, const char * src, size_t n) {
116116
return ets_strncpy(dest, src, n);
117117
}
118118

119-
size_t strnlen(const char *s, size_t len) {
119+
size_t ICACHE_FLASH_ATTR strnlen(const char *s, size_t len) {
120120
// there is no ets_strnlen
121121
const char *cp;
122122
for (cp = s; len != 0 && *cp != '\0'; cp++, len--);
@@ -127,7 +127,7 @@ char* strstr(const char *haystack, const char *needle) {
127127
return ets_strstr(haystack, needle);
128128
}
129129

130-
char* strchr(const char * str, int character) {
130+
char* ICACHE_FLASH_ATTR strchr(const char * str, int character) {
131131
while(1) {
132132
if(*str == 0x00) {
133133
return NULL;
@@ -139,7 +139,7 @@ char* strchr(const char * str, int character) {
139139
}
140140
}
141141

142-
char * strrchr(const char * str, int character) {
142+
char * ICACHE_FLASH_ATTR strrchr(const char * str, int character) {
143143
char * ret = NULL;
144144
while(1) {
145145
if(*str == 0x00) {
@@ -223,7 +223,7 @@ char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) {
223223
return ret;
224224
}
225225

226-
int strcasecmp(const char * str1, const char * str2) {
226+
int ICACHE_FLASH_ATTR strcasecmp(const char * str1, const char * str2) {
227227
int d = 0;
228228
while(1) {
229229
int c1 = tolower(*str1++);

0 commit comments

Comments
 (0)