firmware-base/vendor/sming/Sming/samples/Basic_ProgMem/app/application.cpp
2026-01-28 16:42:43 +01:00

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;
}