125 lines
3.5 KiB
C++
125 lines
3.5 KiB
C++
//
|
|
// PROGMEM keyword tells the compiler "put this information into flash memory",
|
|
// instead of into RAM, where it would normally go.
|
|
//
|
|
// Using PROGMEM is a two-step procedure. After getting the data into Flash
|
|
// memory, it requires special methods (functions) to read the data from
|
|
// program memory back into RAM, so we can do something useful with it.
|
|
//
|
|
|
|
#include <SmingCore.h>
|
|
#include <stdio.h>
|
|
|
|
#include "TestProgmem.h"
|
|
|
|
const uint8_t demoRam[] = {1, 2, 3, 4, 5};
|
|
const PROGMEM uint8_t demoPgm[] = {1, 2, 3, 4, 5};
|
|
|
|
const PROGMEM char demoString[] = "Demo";
|
|
const PROGMEM char demoFormat[] = "Demo %d";
|
|
|
|
const PROGMEM uint8_t bytes[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
const PROGMEM uint16_t words[] = {11, 21, 31, 41, 51, 61, 71, 81};
|
|
const PROGMEM uint32_t dwords[] = {12, 120, 1200, 12000, 120000, 1200000, 12000000, 120000000};
|
|
const PROGMEM float floats[] = {13, 130, 1300, 13000, 130000, 1300000, 13000000, 130000000};
|
|
|
|
void assertEquals8(uint8_t expected, uint8_t actual)
|
|
{
|
|
if(expected != actual) {
|
|
Serial << "assertEquals8: " << expected << " != " << actual << endl;
|
|
}
|
|
}
|
|
|
|
void assertEquals16(uint16_t expected, uint16_t actual)
|
|
{
|
|
if(expected != actual) {
|
|
Serial << "assertEquals16: " << expected << " != " << actual << endl;
|
|
}
|
|
}
|
|
|
|
void assertEquals32(uint32_t expected, uint32_t actual)
|
|
{
|
|
if(expected != actual) {
|
|
Serial << "assertEquals32: " << expected << " != " << actual << endl;
|
|
}
|
|
}
|
|
|
|
void assertEqualsFloat(float expected, float actual)
|
|
{
|
|
if(expected != actual) {
|
|
Serial << "assertEqualsFloat: " << expected << " != " << actual << endl;
|
|
}
|
|
}
|
|
|
|
void assertEqualsString(String expected, String actual)
|
|
{
|
|
if(expected != actual) {
|
|
Serial << "assertEqualsString: " << expected << " != " << actual << endl;
|
|
}
|
|
}
|
|
|
|
void testPgm()
|
|
{
|
|
Serial.println("> Read bytes from PROGMEM:");
|
|
for(uint8_t i = 0, b = 1; i < 8; i++, b++) {
|
|
uint8_t d = pgm_read_byte(bytes + i);
|
|
assertEquals8(b, d);
|
|
Serial << d << ' ';
|
|
}
|
|
Serial.println();
|
|
|
|
for(uint16_t i = 0, w = 11; i < 8; i++, w += 10) {
|
|
assertEquals16(w, pgm_read_word(words + i));
|
|
}
|
|
|
|
for(uint32_t i = 0, dw = 12; i < 8; i++, dw *= 10) {
|
|
assertEquals32(dw, pgm_read_dword(dwords + i));
|
|
}
|
|
|
|
for(uint32_t i = 0, f = 13; i < 8; i++, f *= 10) {
|
|
assertEqualsFloat((float)f, pgm_read_float(floats + i));
|
|
}
|
|
|
|
Serial.println("> Copy a string from PROGMEM:");
|
|
char buf[100];
|
|
strcpy_P(buf, demoString);
|
|
assertEqualsString("Demo", buf);
|
|
assertEquals8(4, strlen_P(demoString));
|
|
Serial.println(buf);
|
|
|
|
strcat_P(buf, demoString);
|
|
assertEqualsString("DemoDemo", buf);
|
|
|
|
assertEquals8(1, strcmp_P(buf, demoString));
|
|
assertEquals8(0, strcmp_P("Demo", demoString));
|
|
|
|
sprintf(buf, "SuperDemo");
|
|
assertEqualsString("Demo", strstr_P(buf, demoString));
|
|
|
|
sprintf_P(buf, demoFormat, 1);
|
|
assertEqualsString("Demo 1", buf);
|
|
|
|
Serial.println("> Copy bytes from PROGMEM:");
|
|
memcpy_P(buf, demoPgm, sizeof(demoPgm));
|
|
for(uint8_t i = 0; i < sizeof(demoPgm); i++) {
|
|
assertEquals8(demoRam[i], buf[i]);
|
|
Serial << (unsigned char)buf[i] << ' ';
|
|
}
|
|
Serial.println();
|
|
}
|
|
|
|
void init()
|
|
{
|
|
Serial.begin(SERIAL_BAUD_RATE); // 115200 or 9600 by default
|
|
|
|
testPgm();
|
|
testProgmem(Serial);
|
|
|
|
Serial.println("> ESP8266EX Memory Layout:");
|
|
Serial.println("> 0x3FFE8000 ~ 0x3FFFBFFF - User data RAM, 80kb. Available to applications.");
|
|
Serial.println("> 0x40200000 ~ ... - SPI Flash.");
|
|
|
|
Serial << "> demoRam array address: 0x" << String(uintptr_t(demoRam), HEX) << " is in the RAM" << endl;
|
|
Serial << "> demoPgm array address: 0x" << String(uintptr_t(demoPgm), HEX) << " is in the Flash" << endl;
|
|
}
|