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 :

Gestion de la mémoire ESP8266 ou autre..


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2003
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 4
    Par défaut Gestion de la mémoire ESP8266 ou autre..
    Bonjour à tous,

    je viens vers vous, car je n'arrive pas à comprendre comment sont stockes les données en mémoire.

    ci dessous petit sketch qui illustre mon incompréhension.
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    //**************************************************
    
    #include <Arduino.h>
    #include <EEPROM.h>
    
    void setup(){
      Serial.begin(115200);
      EEPROM.begin(32);  //EEPROM.begin(Size)
    
      delay(2000);
     Serial.println("  ");
    
     // Carte NodeMCU 1.0(ESP-12E Module)
    
     // declaration d'un integer 32 bit non signé 
     // valeur decimal : 4660,  soit en Hexa 00 00 12 34 
     uint32_t dt =  4660 ; // 0x1234; // 00 00 12 34
    
     Serial.print("val hexa dt : "); Serial.print(dt,DEC);
     Serial.print(" val hexa dt : ");Serial.println(dt,HEX);
    
     //  Resultat moniteur série  val hexa dt : 4660 val hexa dt : 1234
    
    // je récupère la valeur de chaque byte (octet) de l'integer
    // formule magique !! récupérée sur le net, qui marche... mais qui n'est pas claire pour moi
     
     byte byteEeprom1 = * ((byte *) (& dt) + 0); // low byte = 0x34
     Serial.print("val hexa byteEeprom1 : "); Serial.println(byteEeprom1,HEX);
     byte byteEeprom2 = * ((byte *) (& dt) + 1); // high byte = 0x12
     Serial.print("val hexa byteEeprom2 : "); Serial.println(byteEeprom2,HEX);
      byte byteEeprom3 = * ((byte *) (& dt) + 2); // high byte = 0x00
     Serial.print("val hexa byteEeprom3 : "); Serial.println(byteEeprom3,HEX);
      byte byteEeprom4 = * ((byte *) (& dt) + 3); // high byte = 0x00
     Serial.print("val hexa byteEeprom4 : "); Serial.println(byteEeprom4,HEX);
    
     // // je m'attends à 00 00 12 34  et j'obtiens 34 12 00 00
     //  Resultat moniteur série  : val hexa byteEeprom1 : 34
     //  Resultat moniteur série  : val hexa byteEeprom2 : 12
     //  Resultat moniteur série  : val hexa byteEeprom3 : 0
     //  Resultat moniteur série  : val hexa byteEeprom4 : 0
    
     // je copie  l'espace mémoire integer32  : dt vers espace mémoire tableau de 4 bytes : numberByte
     // et j'imprime chaque élément du tableau
     byte numberByte[4];
     memcpy(&numberByte, &dt, 4);
     Serial.print("val hexa numberByte[0] : "); Serial.println(numberByte[0],HEX);
     Serial.print("val hexa numberByte[1] : "); Serial.println(numberByte[1],HEX);
     Serial.print("val hexa numberByte[2] : "); Serial.println(numberByte[2],HEX);
     Serial.print("val hexa numberByte[3] : "); Serial.println(numberByte[3],HEX);
     
     // impression tableau idem formule magique
     // je m'attends à 00 00 12 34  et j'obtiens 34 12 00 00
     //  Resultat moniteur série  : val hexa numberByte[0] : 34
     //  Resultat moniteur série  : val hexa numberByte[1] : 12
     //  Resultat moniteur série  : val hexa numberByte[2] : 0
     //  Resultat moniteur série  : val hexa numberByte[3] : 0
     
    // j'ecris dans l'EEPROM dans l'ordre naturel 00 00 12 34 et je commit
     EEPROM.write(0,numberByte[3]);
     EEPROM.write(1,numberByte[2]);
     EEPROM.write(2,numberByte[1]);
     EEPROM.write(3,numberByte[0]);
     EEPROM.commit();
     
     // je lis le resultat par EEPROM.get dans un integer 32 bit 
     uint32_t intLowHigh = 0;
     EEPROM.get(0,intLowHigh);
     Serial.print("valeur intLowHigh decimal : "); Serial.print(intLowHigh);
     Serial.print("  valeur intLowHigh Hexa : "); Serial.println(intLowHigh,HEX);
     //  Resultat moniteur série  : valeur intLowHigh decimal : 873594880 valeur intLowHigh Hexa : 34120000
     
    // j'ecris de nouveau mais dans l'ordre 34 12 00 00 numberByte [0,1,2,3)
     EEPROM.write(0,numberByte[0]);
     EEPROM.write(1,numberByte[1]);
     EEPROM.write(2,numberByte[2]);
     EEPROM.write(3,numberByte[3]);
     EEPROM.commit();
     
     // je lis le resultat par EEPROM.get dans un integer 32 bit 
     uint32_t intHighLow = 0;
     EEPROM.get(0,intHighLow);
     Serial.print("valeur intHighLow decimal : "); Serial.print(intHighLow);
     Serial.print("  valeur intHighLow Hexa : "); Serial.println(intHighLow,HEX);
     //le resultat correspond au nombre 4660 equivalent à 00 00 12 34
     //  Resultat moniteur série  : valeur intHighLow decimal : 4660valeur intHighLow Hexa : 1234
    
    }
    
    void loop(){
     
    }
    //**************************************************
    ma question est simple , si elle a un sens..., dans quel sens sont donc stockes les bytes??

    Merci pour vos lumières.

  2. #2
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Tout dépend des indiens

    Il y a des architectures dites «*little Indian*» (octets de poids faible en premier en mémoire) Et des architecture dites «*Big Indian*» (octets de points forts en premier mémoire).

    GCC a une architecture Little Indian, donc on met les poids faibles en premier lors de la représentation en mémoire.

    0x00001234 est stocké sous for 34 12 00 00

    En français on dit petit boutiste ou grand boutiste. Cette terminologie a été popularisée dans le domaine informatique par Dany Cohen, en référence aux Voyages de Gulliver, roman satirique de Jonathan Swift datant de 1721, où est décrit des habitants mangeant des œufs à la coque par le gros ou petit bout.

    En pratique on s’en fiche le plus souvent parce qu’on travaille toujours avec des variables qui font ce qu’il faut pour représenter le nombre souhaité. Là où c’est important C’est quand on échange des données entre deux systèmes qui n’ont pas la même représentation.

  3. #3
    Futur Membre du Club
    Inscrit en
    Avril 2003
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 4
    Par défaut
    Merci pour cette info que j’ignorais.
    On apprends à tout âge!!

    Si vous pouvez me développer et m’expliquer le fonctionnement de la formule magique, j’apprécierai
    Cordialement
    Philippe

  4. #4
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Il n’y a pas de formule magique juste une représentation des données qui est choisie en mémoire Par le compilateur par convention arbitraire.

    Dans les architecture petit boutiste, Ce sont Les octets de poids faibles (on commence à droite de la valeur) qui sont mis en premiers à l’écriture comme à la lecture.

  5. #5
    Futur Membre du Club
    Inscrit en
    Avril 2003
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 4
    Par défaut Formule magique
    Merci encore pour votre réponse.
    Quand je parlais de formule magique, je parlais de celle ci:

    byte byteEeprom1 = * ((byte *) (& dt) + 0);

    byte byteEeprom2 = * ((byte *) (& dt) + 1);

    Merci pour votre aide

  6. #6
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Le plus simple c'est de séparer les choses pour avoir de la clarté à la lecture. Si vous prenez ce code
    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
    uint32_t valeur = 0xDEADBEEF;
     
    void setup()
    {
      Serial.begin(115200);
     
      uint8_t * valeurPtr = (uint8_t*) &valeur; // on prend l'adresse de valeur (pointeur vers 4 octets) et on la convertit en pointeur vers un seul octet
     
      uint8_t v0 = *(valeurPtr + 0);  // extraction du premier octet
      uint8_t v1 = *(valeurPtr + 1);  // extraction de l'octet suivant en mémoire (le +1 saute d'un seul octet grâce au type de valeurPtr)
      uint8_t v2 = *(valeurPtr + 2);  // extraction de l'octet suivant en mémoire
      uint8_t v3 = *(valeurPtr + 3);  // extraction du dernier octet
     
      Serial.print(F("v0 = 0x")); Serial.println(v0, HEX);
      Serial.print(F("v1 = 0x")); Serial.println(v1, HEX);
      Serial.print(F("v2 = 0x")); Serial.println(v2, HEX);
      Serial.print(F("v3 = 0x")); Serial.println(v3, HEX);
     
    }
     
    void loop() {}
    la console série vous donnera
    v0 = 0xEF
    v1 = 0xBE
    v2 = 0xAD
    v3 = 0xDE


    on voit donc bien que le premier octet au niveau du pointeur est l'octet de poids faible (le 0xEF de 0xDEADBEEF)

    si vous voulez regrouper sans passer par valeurPtr, il faudra dont faire par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     uint8_t v1 = *(((uint8_t*) &valeur) + 1);
    avec les parenthèses (vaut mieux toujours en mettre même si certaines sont inutiles, ça aide à la lecture) pour bien montrer à quoi s'applique le cast (changement de type)

  7. #7
    Futur Membre du Club
    Inscrit en
    Avril 2003
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 4
    Par défaut
    Ok, merci encore.

    Je vais tester tout ça.

    cordialement.
    Philippe.

Discussions similaires

  1. Réponses: 17
    Dernier message: 02/02/2006, 12h03
  2. gestion de la mémoire
    Par moldavi dans le forum C++
    Réponses: 17
    Dernier message: 04/02/2005, 23h18
  3. Réponses: 11
    Dernier message: 26/12/2004, 22h50
  4. Gestion de la mémoire entre plusieurs DLL
    Par Laurent Gomila dans le forum C++
    Réponses: 7
    Dernier message: 27/07/2004, 15h28
  5. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44

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