Arduino Memoire Optimiser SRAM

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche


MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.

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.

Literal strings are repeat memory offenders. First they take up space in the program image in Flash, then they are copied to SRAM at startup as static variables. This is a horrible waste of SRAM since we will never be writing to them.

Paul Stoffregen of PJRC and Teensyduino fame developed the F() macro as a super-simple solution to this problem. The F() macro tells the compiler to keep your strings in PROGMEM. All you have to do is to enclose the literal string in the F() macro.

For example, replacing this:

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!");
with this:
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!"));

Will save you 180 bytes of wonderful SRAM!

Réservez l'espace de vos Strings

The Arduino string library allows you to reserve buffer space for a string with the fonction reserve(). The idea is you can prevent String from fragmenting the heap by using reserve(num) to pre-allocate memory for a String that grows.

With the memory already allocated, String doesn't need to call realloc() if the string grows in length. In most usages, lots of other little String objects are used temporarily as you perform these operations, forcing the new string allocation to a new area of the heap and leaving a big hole where the previous one was (memory fragmentation). Usually all you need to do is use reserve() on any long-lived String objects that you know will be increasing in length as you process text.

You can do better with C strings, but if you just follow these guidelines for String objects, they work nearly as efficiently and using them is so much easier.

Placer vos données constantes en PROGMEM

Data items declared as PROGMEM do not get copied to SRAM at startup. They are a little less convenient to work with, but they can save significant amounts of SRAM. The basic Arduino reference for PROGMEM is here (Anglais, Arduino.CC). And there is a more detailed tutorial on the subject here (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):

Arduino-Memoire-41.jpg
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.