Thanks for all the responses. I now understand that for a Mega2560 (which I use) that the strlcpy_PF needs to be used to be on the safe side with the possibility that the string is located above 64KB. If I use the strlcpy_PF with the PROGMEM string being global or static all is fine.
FURTHER INVESTIGATION
I also put the following into the program:
Serial.print (sizeof (sHeating));
and got back 4 covering off the detail provided by david_2018 - as he stated the address is 4 bytes (32 bits). I presume it does not report the actual string size because of the special nature of PROGMEM arrays.
I then printed the memory address using:
Serial.print ((uint32_t)&sHeating, HEX);
and got:
50C4
which was all good (string located in 16 bit address) as code was < 64KB even though 32 bits allocated for address.
USING FLASH MORE THAN 64KB
I thought that while I was at it I would test the scenario where the code is more than 64KB. Currently it is 57KB approx.
What I did was added a the following to the program:
const uint16_t GJB_Pic1[] PROGMEM = {
0x3394, 0x3374, 0x2b74, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x2b94, 0x3394, 0x3394, 0x3394, 0x3394, 0x3394, 0x3394, 0x3394, 0x3394, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3395, 0x3394, 0x3394, 0x33b5, ... };
which was longer than shown above (for brevity) and I then used it in the program so that the compiler didn't have its optimizer remove the array:
tData = pgm_read_byte_far (&GJB_Pic1[50]);
The compiled size was then around 81KB - all as expected:
Sketch uses 80564 bytes (31%) of program storage space. Maximum is 253952 bytes.
I also then printed the global char array I have declared:
const char sHeating[] PROGMEM = "HEATING";
and the output on serial monitor now shows:
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
so once again broken. I then inserted the following code:
Serial.print ((uint32_t)&sHeating, HEX); Serial.print (F(" "));
Serial.print (sHeating);
FFFFA204 ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
so yes using an address that is above 64KB but it is not correct.
so attempted to search ALL of the PROGRAM SPACE with the following code:
byte tData;
uint32_t t;
Serial.println (F("Searching for string in program space..."));
char search[]="HEATING";
for (t=256; t < 262144UL; t++) {
tData=pgm_read_byte_far(t);
if (tData == (byte)search[0]) {
bool tabort=false;
for (uint32_t p=1; (p < strlen(search)) && !tabort; p++) {
tData=pgm_read_byte_far (t+p);
if ((char)tData == search[p]) {
tabort=false;
} else {
tabort=true;
}
}
if (!tabort) {
//We found it.
Serial.print (F("String located at address: ")); Serial.println (t, HEX);
}
}
}
Serial.println();
Serial.println (F("Search complete."));
and low and behold found the string at the following locations (serial monitor output):
Searching for string in program space...
String located at address: A200
String located at address: 13A56
Search complete.
The address 13A56 is above 64KB so is the actual address. I believe the A200 location will be the value assigned to the search char array (address of text in program space to initialize the string in data space).
There is however a new problem with dealing with code above 64KB - the actual address of the string in PROGMEM space is wrong when accessing the &sHeating const char.
Why is this happening ?
Geoffrey