Différences entre versions de « Arduino Memoire Optimiser SRAM »
Ligne 51 : | Ligne 51 : | ||
== Placer vos données constantes en PROGMEM == | == Placer vos données constantes en PROGMEM == | ||
− | + | Les données déclarées comme PROGMEM ne sont pas copiées en SRAM au démarrage du sketch/croquis. | |
+ | |||
+ | Il est un peu moins facile de travailler avec ces donnée mais cela économise une quantité significative de mémoire SRAM. Vous trouverez les références de PROGMEM [http://arduino.cc/en/Reference/PROGMEM ici sur le site d'Arduino.CCe] (''Anglais, Arduino.CC''). Finalement, vous trouverez plus dans [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003 ce tutoriel détaillé] (''Anglais, AVRFreaks.Net''). | ||
== Réduire la taille des Buffers == | == Réduire la taille des Buffers == |
Version du 5 septembre 2013 à 15:07
Introduction
Cette partie du tutoriel s'attarde sur l'optimisation de la mémoire SRAM.
SRAM est l'une des denrées les plus précieuses sur Arduino. Le manque de mémoire SRAM est probablement le problème de mémoire le plus répandu sur Arduino mais aussi le plus difficile à diagnostiquer.
Si votre programme plante de façon inexplicable, il y a des chances pour que vous soyez face à un crash de la stack (la pile) dut à un manque de mémoire SRAM.
Il y a pas mal de choses qui peuvent être réalisée pour réduire la consommation de SRAM.
Nous en avons repris quelques lignes directrices ci-dessous pour vous aider à démarrer.
Eliminer les variables inutilisées
Si vous ne savez pas si telle ou telle variable est utilisée, mettez la en commentaire.
Si votre sketch/croquis compile encore alors cela signifie qu'elle est inutile et que vous pouvez l'éliminer!
F() ces Strings!
(Stocker les char* dans le PROGMEM de l'architecture Harvard).
PROGMEM signifie "Mémoire Programme", la mémoire Flash allouée au stockage du programme
Le type String permet de stocker une chaine de caractère.
Les chaines de caractères littérales (literal strings) sont des délinquants récidivistes emportant votre précieuse mémoire SRAM. Plus sérieusement ces chaînes de caractères sont de gigantesques consommateurs de SRAM.
Pour commencer, ces chaines de caractères utilise de la place dans la mémoire Flash (l'image du programme) et elle sont ensuite copiée en SRAM lors de l'initialisation des variables statiques. Quel horrible gaspillage de mémooire SRAM étant donné que nous n'allons jamais écrire dedans.
Paul Stoffregen de PJRC et Teensyduino have développé la macro F() qui offre une solution super-simple a ce problème. La macro F() indique au compilateur de garder la chaine de caractère dans la PROGMEM (la mémoire flash qui stocke le programme). Tout ce que vous avez à faire, c'est d'enfermer la chaine littérale dans la macro F().
Par exemple, vous pouvez remplacer le code suivant :
Serial.println("Sram sram sram sram. Lovely sram! Wonderful sram! Sram sra-a-a-a-a-am sram sra-a-a-a-a-am sram. Lovely sram! Lovely sram! Lovely sram! Lovely sram! Lovely sram! Sram sram sram sram!");
avec celui ci:
Serial.println(F("Sram sram sram sram. Lovely sram! Wonderful sram! Sram sra-a-a-a-a-am sram sra-a-a-a-a-am sram. Lovely sram! Lovely sram! Lovely sram! Lovely sram! Lovely sram! Sram sram sram sram!"));
Et vous allez économiser 180 bytes/octets de notre merveilleuse SRAM!
Réservez l'espace des chaines de caractères
Dans la libraire srting Arduino dévolue aux chaines de caractères, il existe la fonction fonction reserve() qui permet de réserver un espace mémoire (buffer en anglais) pour une string.
L'idée en de prévenir la fragmentation de la heap (le tas) en utilisant reserve(num) pour pré-allouer la mémoire d'un chaine de caractère destinée à grandir.
Avec la mémoire déjà allouée, String n'a pas besoin d'appeler realloc() lorsque la longueur de la chaine de caractère augmente.
Dans la plupart des cas d'utilisation, beaucoup de petits objets String sont temporairement utilisés pendant que vous effectuez ce type d'opération (agrandissement de la string). Cela force l'allocation d'une nouvelle chaine de caractères sur la Heap (le tas) laissant ainsi un grand trou à la position ou se trouvait l'ancienne string. C'est ainsi que l'on obtient une mémoire.
Habituellement, tout ce que vous avez besoin de faire, c'est un reserve() sur les objets String ayant une longue durée de vie et dont vous savez pertinent que le longueur va augmenter au fur et à mesure que votre programme effectue ses traitements.
Vous pouvez obtenir de meilleurs résultats avec les 'C strings' mais si vous suivez ces recommandations sur les objets String, vous obtiendrez presque la même efficacité en les utilisant bien plus facilement.
Placer vos données constantes en PROGMEM
Les données déclarées comme PROGMEM ne sont pas copiées en SRAM au démarrage du sketch/croquis.
Il est un peu moins facile de travailler avec ces donnée mais cela économise une quantité significative de mémoire SRAM. Vous trouverez les références de PROGMEM ici sur le site d'Arduino.CCe (Anglais, Arduino.CC). Finalement, vous trouverez plus dans ce tutoriel détaillé (Anglais, AVRFreaks.Net).
Réduire la taille des Buffers
Allocation des Buffers et Array
If you allocate a buffer, make sure it is no bigger than it needs to be.
Buffers dans les librairies
Also be aware that some libraries allocate buffers behind the scenes that may be candidates for trimming as well.
Buffers bystèmes
Another buffer hidden deeply in the system is the 64 byte serial receive buffer. If your sketch is not receiving a lot of high-speed serial data, you can probably cut this buffer size in half - or maybe even less.
The Serial buffer size is defined in HardwareSerial.cpp. This file can be found in your Arduino install directory:
....\Arduino-1.x.x\hardware\arduino\cores\arduino\HardwareSerial.cpp
Look for the line:
#define SERIAL_BUFFER_SIZE 64
And change it to 32 or less.
Réduire les variables surdimensionnées
Don't use a float when an int will do. Don't use an int when a byte will do. Try to use the smallest data type capable of holding the information.
Types de données | Taille en octets/Bytes | Peut contenir: |
boolean | 1 | true (1, pour vrai) ou false (0, pour faux) |
char | 1 | Un caractères ASCII ou une valeur signée entre -128 et 127 |
unsigned char, byte, uint8_t | 1 | Un caractères ASCII ou une valeur non signée entre 0 et 255 |
int, short | 2 | Une valeur signée entre -32.768 et 32767. Int est le diminutif de Ingeter signifiant "Entier". |
unsigned int, word, uint16_t | 2 | Une valeur non signée entre 0 et 65535. |
long | 4 | Une valeur signée entre -2.147.483.648 et 2.147.483.647 |
unsigned long, uint32_t | 4 | Valeur non signée entre 0 et 4.294.967.295 |
float, double | 4 | Une valeur en virgule flottante (floating point value en anglais) dont la valeur est comprise entre -3,4028235E-38 et 3,4028235E+38. Note: Sur cette plateforme, le double est identique au float). |
Pensez globalement. Allouez localement
Let's have another look at how SRAM is used (and abused):
Crédit: AdaFruit Industries www.adafruit.com
Traduction par MCHobby.be
Variables Globales et Statiques
Global and Static variables are the first things loaded into SRAM. They push the start of the heap upward toward the stack and they will occupy this space for all eternity.
Dynamic Allocations
Dynamicaly allocated objects and data cause the heap to grow toward the stack. Unlike Global and Static variables, these variables can be de-allocated to free up space. But this does not necessarily cause the heap to shrink! If there is other dynamic data above it in the heap, the top of the heap will not move. When the heap is full of holes like swiss cheese we call it a "fragmented heap".
Variables Locales
Every function call creates a stack frame that makes the stack grow toward the heap. Each stack frame will contain:
- All parameters passed to the function
- All local variables declared in the function.
This data is usable within the function, but the space is 100% reclaimed when the function exits!
Les bons trucs!
- Avoid dynamic heap allocations - These can quickly fragment the limited heap-space.
- Prefer local to global allocation - Stack variables only exist while they are being used. If you have variables that only are used in a small section of your code, consider making that code into a function and declaring the variables local to the function.
Source: Memories of an Arduino. Crédit AdaFruit Industries.
Créé par Bill Earl pour AdaFruit Industries.
Traduit par Meurisse D. pour MCHobby.be
Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com
Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : « Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.
L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.