Question sur PROGMEM, es-ce qu'il y a de mieux?

Bonjour,
Je suis un peu embeter car il me reste peut de SRAM alors que j’ai encore du code à mettre.
En cherchant, j’ai appris à utiliser PROGMEM et je me pose maintenant si

#define ATFTPSER "AT+FTPSER"

ne pouvait pas être mieux.

Je m’explique.

J’ai ce code afin d’utiliser PROGMEM

#define OK_RESPONSE "OK"

const char AT[]             PROGMEM = "";                 //0
const char GPS_POWER[]		  PROGMEM = "+CGPSPWR";			    //1
const char GPS_RESET[]		  PROGMEM = "+CGPSRST";			    //2
const char GPS_INFO[]		    PROGMEM = "+CGPSINF";			    //3
const char GPS_STATUS[]	    PROGMEM = "+CGPSSTATUS?";		  //4
const char GPS_UNKNOW[]			PROGMEM = "Location Unknown";	//5
const char GPS_NOT_FIX[]		PROGMEM = "Location Not Fix";	//6
const char GPS_FIX_2D[]			PROGMEM = "Location 2D Fix";	//7
const char GPS_FIX_3D[]			PROGMEM = "Location 3D Fix";	//8

const char CREG[]           PROGMEM = "+CREG";            //9
const char SMS_STORAGE[]    PROGMEM = "+CPMS";            //10
const char DIR_STORAGE[]    PROGMEM = "+CPBS";            //11
const char GET_TIME[]       PROGMEM = "+CCLK";            //12
const char GET_IMEI[]       PROGMEM = "+GSN";             //13
const char GET_ICCID[]      PROGMEM = "+CCID";            //14
const char GET_OPERATOR[]   PROGMEM = "+COPS";            //15
const char GET_BATT[]       PROGMEM = "+CBC";             //16

const char FTP_SERVER[]     PROGMEM = "+FTPSERV";        //17
const char FTP_PORT[]       PROGMEM = "+FTPPORT";        //18
const char FTP_MODE[]       PROGMEM = "+FTPMODE";        //19
const char FTP_TYPE[]       PROGMEM = "+FTPTYPE";        //20
const char FTP_UN[]         PROGMEM = "+FTPUN";          //21
const char FTP_PW[]         PROGMEM = "+FTPPW";          //22
const char SAPBR[]          PROGMEM = "+SAPBR";           //23
const char CONTYPE[]        PROGMEM = "CONTYPE";          //24
const char GPRS[]           PROGMEM = "GPRS";             //25
const char FTP_CID[]        PROGMEM = "+FTPCID";           //26
const char FTP_PUTNAME[]    PROGMEM = "+FTPPUTNAME";      //27
const char FTP_PUTPATH[]    PROGMEM = "+FTPPUTPATH";      //28
const char FTP_PUT[]        PROGMEM = "+FTPPUT";          //29





/*
const char POWER_FULL[]     PROGMEM = "+CFUN=1";          //23
const char POWER_RF_OFF[]   PROGMEM = "+CFUN=4";          //24
const char POWER_MIN[]      PROGMEM = "+CFUN=0";          //25
const char POWER_OFF[]      PROGMEM = "+CPOF";            //26
const char SET_TIME[]       PROGMEM = "+CCLK=";           //27

const char AT_3G_CHECK[]    PROGMEM = "+CGATT?";          //28
const char AT_3G_CHECK_ON[] PROGMEM = "+CGATT: 1";        //29
const char AT_3G_CHECK_OFF[]  PROGMEM = "+CGATT: 0";      //30
const char AT_3G_ATT_ON[]   PROGMEM = "+CGATT=1";         //31
const char AT_3G_ATT_OFF[]  PROGMEM = "+CGATT=0";         //32


const char _3G_AUTH[]       PROGMEM = "+CSOCKAUTH=1,";    //34
*/




const char* const table_AT[] PROGMEM = 
{
	AT,           //0
  GPS_POWER,		//1
	GPS_RESET,		//2
	GPS_INFO,		  //3
	GPS_STATUS,	  //4
	GPS_UNKNOW,		//5
	GPS_NOT_FIX,	//6
	GPS_FIX_2D,		//7
	GPS_FIX_3D,		//8
  CREG,         //9
  SMS_STORAGE,  //10
  DIR_STORAGE,  //11
  GET_TIME,     //12
  GET_IMEI,     //13
  GET_ICCID,    //14
  GET_OPERATOR, //15
  GET_BATT,     //16
  FTP_SERVER,   //17
  FTP_PORT,     //18
  FTP_MODE,     //19
  FTP_TYPE,     //20
  FTP_UN,       //21
  FTP_PW,       //22
  SAPBR,        //23
  CONTYPE,      //24
  GPRS,         //25
  FTP_CID,    //26
  FTP_PUTNAME,  //27
  FTP_PUTPATH,  //28
  FTP_PUT,      //29
};

Ensuite si je veux definir mon server FTP, je fais ceci

 // SET FTP SERVER ADDRESS: AT+FTPSERV="<ftp_server>"
  strcpy_P(str_aux1, (char*)pgm_read_word(&(table_AT[17])));  //"+FTPSERV"
  snprintf(buffer, sizeof(buffer), "%s=\"%s\"", str_aux1, ftp_server);
  #ifdef DEBUG
    sprint(buffer);
    sprint(F("\t\t"));
  #endif

Maintenant, si j’ajoute toutes les autres commandes, ca va faire encor plus et beaucoup de code

Es-ce que je peux pas faire ceci?

 // SET FTP SERVER ADDRESS: AT+FTPSERV="<ftp_server>"
  snprintf(buffer, sizeof(buffer), "%s=\"%s\"", ATFTPSER, ftp_server);
  #ifdef DEBUG
    sprint(buffer);
    sprint(F("\t\t"));
  #endif

Ceci me permetterai ne plus faire appel à la librairie

#include "avr/pgmspace.h"

ainsi que

const char* const table_AT[] PROGMEM =

et tout le code qui le précède et le suit?

Comment pourriez-vous m’éclairecir, à ce sujet?

Milles mercis

un #define ne définit qu'une substitution de code.
En écrivant ceci

#define ATFTPSER "AT+FTPSER"

tu dis juste au pré-processeur à chaque fois que tu vois ATFTPSER dans le fichier source remplace la chaîne par "AT+FTPSER" et le source modifié est envoyé au compilateur. Donc cela ne fait pas gagner un seul octet de mémoire.

Si tu veux simplifier ton code, fait une routine pour retourner une chaine de caractère à partir d’un élément en mémoire flash. Tu te retrouverais alors avec :

 // SET FTP SERVER ADDRESS: AT+FTPSERV="<ftp_server>"

  snprintf(buffer, sizeof(buffer), "%s=\"%s\"", getStr(table_AT[17]), ftp_server);
  #ifdef DEBUG
    sprint(buffer);
    sprint(F("\t\t"));
  #endif

Il n'y a pas de miracle. Pour gagner de la RAM, il faut:

  • limiter les appels de fonctions (à chaque fois il y a sauvegarde de contexte)
  • faire la chasse aux variables globales inutiles et aux buffers. Le problème c'est que les librairies gèrent chacune dans leur coin des variables sur lesquelles tu n'as pas de contrôle.
  • allouer au plus juste la taille des tableaux

Après s'il n'y a toujours pas assez de mémoire c'est peut être aussi que le processeur est mal adapté au besoin (ou l'inverse).

Je suis un peu embeter car il me reste peut de SRAM alors que j'ai encore du code à mettre.

Ajouter du code ne veut pas nécessairement dire consommer plus de RAM. Si tu utilises au maximum des variables locales.

En parcourant tes autres posts je vois aussi que tu as des tables de 3km de long avec toutes les commandes AT de ton modem. Si tu n'utilises qu'une partie des commandes, il n'est pas nécessaire de toutes les mettre en constantes et ainsi réduire le tableau aux seuls commandes indispensables.
Ceci est vrai aussi pour les messages. Si ce sont des messages de debug les abréger pour qu'ils occupent moins de place.