Using PROGMEM with Arduino nano 33 IoT

Hi
I'm working with the Nano 33 IoT and I noticed that when I put certain constants in program memory, everything keeps working when I use the ordinary sprintf, strlen, strcmp, ... functions instead of the ..._P equivalents.

Sample declarations / definitions:

In he class header file:

class MyClass {
...
    struct FuncDefs {
        const char* funcname;
        char minArgs;
        char maxArgs;
    };

In the class code file:

PROGMEM const MyClass::FuncDefs MyClass::_functions [] 
{{"t00",0 ,0}, {"t01",0 ,1}, {"t02", 0,2}, {"t11",1 ,1}, {"t12",1 ,2}};

This works (pNext and pch are character pointers):

if ( strlen( _functions [funcIndex].funcname ) != pNext - pch ) { doSomething(); }                                       
if ( strncmp( _functions [funcIndex].funcname, pch, pNext - pch ) != 0 ) { doSomething(); }      

This works as well:

char _minA ,_minB;
_minA = _functions [funcIndex].minArgs;     
_minB = _functions [funcIndex].maxArgs;     

My question: what's the purpose of the ..._P equivalents then ? Or is isn't it safe what I'm doing, even if this works ?
Could not find anything on this topic, so I hope you can help me out here. Thanks !

What you are doing is not guaranteed to work.

Use the correct functions to avoid problems

Compatibility so that code written for an AVR-based Arduino board will compile and work on the SAMD21-based Arduino Nano 33 IoT.

I don't have the core for that processor installed. But, for Adafruit Feather M0 (also a SAMD21 board) from "pgmspace.h":

#define strlen_P(a) strlen((a))

Hello UKHeliBob
I fully realize that. But my question really was "is this a correct function ?" - knowing that Arduino documentation, although great, is not always accurate. But of course your statement is correct.

The ARM CPUs have all the memory (flash and RAM) is the same address space, so:

  1. They don't need special functions like strcpy_P() or pgm_read_byte() to get data from flash.
  2. The compiler will put "const" data like literal strings in the flash memory by default.

The various F(), PROGMEM, and _P() functions are defined in the Arduino headers solely for the sake of portability to other architectures. Both AVR and ESP8266 require "special" handling.

Hello westfw
This is a perfect answer ! I expected something like this, but I wanted to be sure.
Compatibility is a very valuable thing, so it's good it's provided.
As my aim is not to write programs compatible with the whole universe, but programs that target this specific processor family, exploring its possibilities etc., I know what to do now.
Many thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.