IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

sizeof() PROGMEM en mettant la valeur de l'adresse dans sizeof()


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 986
    Par défaut sizeof() PROGMEM en mettant la valeur de l'adresse dans sizeof()
    Bonjour,

    J'ai un problème tout bête mais que je n'arrive pas à résoudre.

    Dans mon code j'ai plusieurs tableaux en progmem

    Attention, ce ne sont pas des chaines de caractères "normales"
    Ce sont des tableaux unsigned char pouvant contenir des octets nulls, ces octets nulls font partie des données et ne doivent surtout pas être interprétés comme des marqueurs de fin de chaine.
    (sinon, ça serait trop facile )

    J'arrive à passer ces tableaux dans une variable qui contient leur adresse (un pointer en fait) pour les utiliser
    MAIS je n'arrive pas à calculer leur taille (sizeof()) à partir de leur adresse

    Voici le code de départ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    				switch (menu_index) {
    				case Menu_3_DemoShapes:
    					len = sizeof(Buffer_HTTP_DemoShapes);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoShapes+j);}
    					break;
    				case Menu_4_DemoBitmpas:
    					len = sizeof(Buffer_HTTP_Bitmap);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_Bitmap+j);}
    					break;
    				case Menu_5_DemoButtons:
    					len = sizeof(Buffer_HTTP_DemoButtons);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoButtons+j);}
    					break;
    				case Menu_6_DemoRainbows:
    					len = sizeof(Buffer_HTTP_DemoRainbows);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoRainbows+j);}
    					break;
    				case Menu_7_DemoSetup:
    					len = sizeof(Buffer_HTTP_DemoSetup);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoSetup+j);}
    					break;
    				case Menu_8_DemoBig1:
    					len = sizeof(Buffer_HTTP_DemoBig1);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoBig1+j);}
    					break;
    				case Menu_9_DemoBig2:
    					len = sizeof(Buffer_HTTP_DemoBig2);
    					for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(Buffer_HTTP_DemoBig2+j);}
    					break; 
    				}
    C'est très con, on ne respecte pas le principe DRY (don't repeat yourself)

    Voici le code que je n'arrive pas à faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    				uint16_t p; // valeur de l'adresse PROGMEM
    				switch (menu_index) {
    				case Menu_3_DemoShapes:
    					p = Buffer_HTTP_DemoShapes;
    					break;
    				case Menu_4_DemoBitmpas:
    					p = Buffer_HTTP_Bitmap;
    					break;
    				case Menu_5_DemoButtons:
    					p = Buffer_HTTP_DemoButtons;
    					break;
    				case Menu_6_DemoRainbows:
    					p = Buffer_HTTP_DemoRainbows;
    					break;
    				case Menu_7_DemoSetup:
    					p = Buffer_HTTP_DemoSetup;
    					break;
    				case Menu_8_DemoBig1:
    					p = Buffer_HTTP_DemoBig1;
    					break;
    				case Menu_9_DemoBig2:
    					p = Buffer_HTTP_DemoBig2;
    					break; 
    				}
    				len = sizeof(p); // Evidemment ça ne fonctionne pas mais vous comprenez que je j'aimerais faire 
    				for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(p+j);} // cette partie là fonctionne
    Le problème vient de sizeof(), car si je fait cela ça fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    				uint16_t p; // valeur de l'adresse PROGMEM
    				switch (menu_index) {
    				case Menu_3_DemoShapes:
    					len = sizeof(Buffer_HTTP_DemoShapes);
    					p = Buffer_HTTP_DemoShapes;
    					break;
    				case Menu_4_DemoBitmpas:
    					len = sizeof(Buffer_HTTP_Bitmap);
    					p = Buffer_HTTP_Bitmap;
    					break;
    				case Menu_5_DemoButtons:
    					len = sizeof(Buffer_HTTP_DemoButtons);
    					p = Buffer_HTTP_DemoButtons;
    					break;
    				case Menu_6_DemoRainbows:
    					len = sizeof(Buffer_HTTP_DemoRainbows);
    					p = Buffer_HTTP_DemoRainbows;
    					break;
    				case Menu_7_DemoSetup:
    					len = sizeof(Buffer_HTTP_DemoSetup);
    					p = Buffer_HTTP_DemoSetup;
    					break;
    				case Menu_8_DemoBig1:
    					len = sizeof(Buffer_HTTP_DemoBig1);
    					p = Buffer_HTTP_DemoBig1;
    					break;
    				case Menu_9_DemoBig2:
    					len = sizeof(Buffer_HTTP_DemoBig2);
    					p = Buffer_HTTP_DemoBig2;
    					break; 
    				}
    				for (j=0;j<len;j++) {Buffer_HTTP[j+1] = pgm_read_byte(p+j);}
    J'ai regardé le code de pgmspace.h pour savoir comment pgm_read_byte() fonctionne.

    pgm_read_byte(addr) va lire le contenu de la ROM à l'adresse 'addr', sur un Arduino UNO (qui a moins de 64ko de ROM) 'addr' est un entier non signé sur 16 bits.

    Ce n'est pas très "propre" mais cette façon de lire la flash ROM correspond à ce qu'on fait en assembleur.

    Il faudrait que je trouve comment fonctionne sizeof() quand on l'appelle avec en paramètre le nom d'une variable PROGMEM...

    Il y a sûrement des choses se passent au moment de la compilation, et pas seulement au niveau de l'execution...
    Ca se trouve, ce que je veux faire ne sera pas possible, il faudra peut être que je construise au démarrage de mon programme un petit tableau avec les tailles, et faire quelques #defines pour éviter d'avoir des nombres magiques.

    A bientôt

  2. #2
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 884
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    sizeof est un opérateur du langage qui fonctionne très bien...
    C’est quelque chose qui est effectué à la compilation.

    Quand vous demandez vous demandez la taille d’un pointeur.

    Alors que quand vous demandez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     len = sizeof Buffer_HTTP_DemoRainbows;
    vous demandez bien la taille du tableau.

    Tout cela vient du fait que tant que vous utilisez le nom du tableau, le compilateur connaît sa taille, mais dès que vous utilisez le nom du tableau pour l’affecter au pointeur on dit qu’il y a un "decay", un pointeur est typé mais n’embarque pas la taille et donc vous perdez cette information.

    Bref - pas de raccourci, il faut mémoriser la taille au moment où vous affectez le pointeur.

  3. #3
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 986
    Par défaut
    Citation Envoyé par Jay M Voir le message
    C’est quelque chose qui est effectué à la compilation.
    Merci, je me doutait que ça fonctionnait de cette façon - En gros, sizeof() fonctionne comme les macros #define.

    Juste avant la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const unsigned char XXX[] PROGMEM = {1,2,3,4,5};
    ...
    lenXXX = sizeof(XXX);
    est remplacé par :

    et on ne trouve donc aucune trace de la fonction sizeof() dans le code final en assembleur.

    A bientôt

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Déterminer la Valeur la plus grande dans une table
    Par arnaud_verlaine dans le forum Langage SQL
    Réponses: 9
    Dernier message: 22/08/2014, 23h35
  2. Recherchev mettant plusieurs valeur dans une cellule
    Par michaeldms dans le forum Excel
    Réponses: 5
    Dernier message: 06/09/2011, 10h32
  3. récupérer la valeur du 2ème champ dans un DBLookUpListBox
    Par jakouz dans le forum Bases de données
    Réponses: 3
    Dernier message: 20/07/2004, 16h45
  4. [XSL] Tester si la valeur est un entier dans un xml
    Par MrMaze dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 23/07/2003, 04h35
  5. Valeur par defaut 'True' dans un champ de type bit
    Par Mouse dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 24/03/2003, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo