// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// "char*" is a mutable pointer to a mutable character/string.
// ---------------------------------------------------------------------------
// "const char*" is a mutable pointer to an immutable character/string.
// You cannot change the contents of the location(s) this pointer points to.
// Also, compilers are required to give error messages when you try to do so.
// For the same reason, conversion from "const char *"" to "char*"" is deprecated.
// ---------------------------------------------------------------------------
// "char* const" is an immutable pointer (it cannot point to any other location)
// but the contents of location at which it points are mutable.
// ---------------------------------------------------------------------------
// "const char* const" is an immutable pointer to an immutable character/string
// ---------------------------------------------------------------------------
// https://docs.arduino.cc/learn/programming/memory-guide/
// https://www.gammon.com.au/forum/?id=12615
// https://forum.arduino.cc/t/passing-progmem-string-to-a-function/977701/4
// https://stackoverflow.com/questions/37782154/reading-string-from-struct-in-arduino-progmem
// https://github.com/MajicDesigns/MD_MAX72xx
//
// (const) = immutable !!!
//
// string pointer
// | |
// const char* const
//
#include "debug.h"
uint32_t msTimeout;
char ch = '#'; // RAM
char chs[] = "##2.char@@"; //2. PGM->RAM
char* chst = "##3.char*@@"; //3. PGM->RAM
char* const chst_c /*PROGMEM*/= "##4.char* const@@"; //4. PGM->RAM
const char c_ch[] PROGMEM = "##5.const char@@"; //5. PGM
const char* c_chst = "##6.const char*@@"; //6. PGM->RAM
const char* c_chsta[] = {"##7.const char* 1@@","##const char* 12@@"}; //7. PGM->RAM
const char* const c_chsta_c[] /*PROGMEM*/= {"##8.const char* const 2@@","##const char* const 22@@"}; //8. PGM->RAM
// ch @[0x113]=0x23 (1. RAM dir@113 is value '#')
// chs @[0x108]=0x108 (2. RAM ptr@108 hold RAM string@108, ld.text PGM@135A),
// ptr in RAM to a string in RAM initialized from ROM .text
// chst @[0x106]=0x225 (3. RAM ptr@106 hold RAM string@225, ld.text PGM@1477),
// ptr in RAM to a string in RAM initialized from ROM .text
// chst_c @[0x1D6]=0x169 (4. PGM ptr@1D6 hold RAM string@169, ld.text PGM@13BB),
// ptr in ROM to a string in RAM initialized from ROM .text
// c_ch @[0x1B6]=0x1B6 (5. PGM ptr@1B6 hold PGM string@1B6),
// ptr in ROM to a string in ROM
// c_chst @[0x104]=0x213 (6. RAM ptr@104 hold RAM string@213, ld.text PGM@1465),
// ptr in RAM to a string in RAM initialized from ROM .text
// c_chsta @[0x100]=0x100 (7. RAM array ptr@100 hold RAM string@1EC and string@200, ld.text PGM@143E),
// array ptr in RAM to a string in RAM initialized from ROM .text
// c_chsta_c @[0x17B]=0x17B (8. PGM array ptr@17B hold RAM string@1B9 and string@1D3, ld.text PGM@13BB),
// array ptr in ROM to a string in RAM initialized from ROM .text
// ------------------------------------------------------
typedef struct {
char chstr[16];
} tbl_t;
const tbl_t myTABLE[] PROGMEM = { {" "},
{"##Row 00200@@"},
{"##Row 0003@@"},
{"##Row 00004@@"},
{"##Row 000005@@"}, };
const char msg01 [] PROGMEM = " ";
const char msg02 [] PROGMEM = "##Msg 00200@@";
const char msg03 [] PROGMEM = "##Msg 0003@@";
const char msg04 [] PROGMEM = "##Msg 00004@@";
const char msg05 [] PROGMEM = "##Msg 000005@@";
const char * const pgmArray[] PROGMEM = { msg01,
msg02,
msg03,
msg04,
msg05 };
const char txtq1[] PROGMEM = R"=====(##9.This is "text1")====="; // PGM
char* const txtq2 PROGMEM = R"=====(##10.This is "text2")====="; // PGM->RAM
void dumpTable(void)
{
SerialPrintf("\nRuntime at: %d ms>\n---------------------\n" , millis());
//#if 0
SerialPrintf("1. {\'%c\'},\t\t\t[0]:%c, @0x%x[%p]\n", ch, ch, &ch, ch);
SerialPrintf("2. {\"%s\"},\t\t\t[0]:%c, @0x%x[%p]\n", chs, chs[0], &chs, chs);
SerialPrintf("3. {\"%s\"},\t\t\t[0]:%c, @0x%x[%p]\n", chst, chst[0], &chst, chst);
SerialPrintf("4. {\"%s\"},\t\t[0]:%c, @0x%x[%p]\n", chst_c, chst_c[0], &chst_c, chst_c);
SerialPrintf("5. {\"%s\"},\t\t[0]:%c, @0x%x[%p]\n", c_ch, c_ch[0], &c_ch, c_ch);
SerialPrintf("6. {\"%s\"},\t\t[0]:%c, @0x%x[%p]\n", c_chst, c_chst[0], &c_chst, c_chst);
SerialPrintf("7. {\"%s\"},\t\t[0]:%c, @0x%x[%p]\n", c_chsta[0], c_chsta[0][0], &c_chsta, c_chsta);
SerialPrintf("8.1 {\"%s\"},\t[0]:%c, @0x%x[%p]\n", c_chsta_c[0], c_chsta_c[0][0], &c_chsta_c, c_chsta_c);
SerialPrintf("8.2 {\"%s\"},\t[0]:%c, @0x%x[%p]\n", c_chsta_c[0], c_chsta_c[0][0], (char *)pgm_read_word(&(c_chsta_c[0])), c_chsta_c);
SerialPrintf("9. {\"%s\"},\t\t[0]:%c, @0x%x[%p]\n", txtq1, txtq1[0], &txtq1, txtq1);
SerialPrintf("10. {\"%s\"},\t[0]:%c, @0x%x[%p]\n", txtq2, txtq2[0], &txtq2, txtq2);
SerialPrintf("\n");
SerialPrintf("\nmyTABLE[n=%d]\n" , BUFFLEN(myTABLE));
for (uint8_t i=0; i < BUFFLEN(myTABLE); i++) {
SerialPrintf("[%d]={\"%s\"}, [0]:%c, @0x%x[%p]\n", i, (const tbl_t*)(&(myTABLE[i])), myTABLE[i], &myTABLE[i], myTABLE[i]);
//SerialPrintf("[%d]={\"%s\"}, [0]:%c, @0x%x[%p]\n", i, &myTABLE[i], myTABLE[i], &myTABLE[i], myTABLE[i]);
}
SerialPrintf("\n");
//!!!! snprintf_P(s, sizeof(s), PSTR("%s is %i years old"), name, age);
//#endif
#if 0
DPRINTFLN_PTR(ch);
DPRINTFLN_PTR(chs);
DPRINTFLN_PTR(chst);
DPRINTFLN_PTR(chst_c);
DPRINTFLN_PTR(c_ch);
DPRINTFLN_PTR(c_chst);
DPRINTFLN_PTR(c_chsta[0]);
DPRINTFLN_PTR(c_chsta_c[0]);
SerialPrintf("\n");
DPRINTFLN_PTR(myTABLE);
DPRINTFLN_PTR(myTABLE[0]);
DPRINTFLN_PTR(myTABLE[1]);
DPRINTFLN_PTR(myTABLE[2]);
DPRINTFLN_PTR(myTABLE[3]);
DPRINTFLN_PTR(myTABLE[4]);
SerialPrintf("\n");
DPRINTFLN_PTR(pgmArray);
DPRINTFLN_PTR(msg01);
DPRINTFLN_PTR(msg02);
DPRINTFLN_PTR(msg03);
DPRINTFLN_PTR(msg04);
DPRINTFLN_PTR(msg05);
SerialPrintf("\n");
#endif
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
dumpPGM(0x0000UL, 0x1600);
//dumpPGM(0x0000UL, 0x7FFF);
dumpRAM((uint16_t)&__data_start ,dataBssCount());
//dumpRAM(0 ,0x8ff);
dumpTable();
msTimeout = millis();
}
void loop() {
// put your main code here, to run repeatedly:
if (millis() - msTimeout > 2000) {
msTimeout = millis();
//dumpTable();
}
}