Optimisation RAM

Bonjour,

j'avance bien dans mon projet domotique (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231928902/105#105) qui consiste à faire communiquer des arduino (arduino Mega + Ethernet + SDCard) à travers un réseau Ethernet (UDP) via des messages XPL (XPLProject).
Ce protocole étant très verbeux, j'utilise beaucoup de chaine de caractères et de fonctions standard (sscanf, memcmp...) pour décoder et envoyer des messages.
J'en arrive à avoir une saturation de la RAM disponible (8ko sur un atmega1280) qui m'empêche d'aller plus loin pour le moment.

Je cherche donc quelques conseils pour optimiser tout ça.
A noter qu'étant donné que je souhaite pouvoir modifier les chaines de caractères, je ne peux pas trop utiliser PROGMEM et cie.

Merci d'avance de vos idées...

Gromain

Avec ça :

http://www.cutedigi.com/product_info.php?products_id=4514&osCsid=fca6730139b023463808a3b82bb8affc

20Ko de sram et un environnement similaire à l'Arduino aussi pour Mac :smiley:

Merci Jean-François...
mais avant de remettre en question le hardware, je vais essayer d'améliorer le software, je suis sure qu'il y a une marge de progression vu mes lacunes :wink:
d'ailleurs, comment je branche mon shield ethernet là-dessus ?

Je cherche aussi une sorte de tableau récapitulatif du coût mémoire des fonctions standard C pour les AVR.

Gromain

Gromain59:
...
d'ailleurs, comment je branche mon shield ethernet là-dessus ?
...

Pas idiot comme remarque XD ... faudrait faire des adaptateurs.

J'ai une piste pour étendre la RAM:
http://arduino.cc/playground/Main/SpiRAMandEhernetShield

mais bon, si je peux optimiser le code, ce serait mieux...

si tu utilises beaucoup de variables, tu peux essayer de les passer en revue pour vérifier qu'elles ont le bon type,
et aussi, utiliser des trucs du genre uint8_t au lieu de int quand c'est possible.

sinon, comme j'ai été recemment obligé de le faire, passer à la mega 2560 ...

Si les mêmes chaines et/ou mots reviennent souvent, créer un dictionnaire.
Coder les chaines en utilisant le dictionnaire.
Construire les chaines dans un tampon au moment de les utiliser.

Salut,

il me semble que la mega 2560 n'a pas plus de RAM que la mega 1280. Tu dois avoir un programme lourd pour avoir besoin d'autant de place.
Pour ce qui est du format des variables, je vais faire une passe pour grignoter quelques octets.
Ce qui m'étonnes, c'est la place réservé en RAM par chaque fonction dès le démarrage sans même qu'elle soit appelé. Je pensais un peu naïvement que la fonction était stocké en mémoire flash, et qu'une zone de la RAM était ensuite allouée à cette fonction au moment de son appel, puis libéré aussitôt. Et bien visiblement ce n'est pas aussi évident.
Comme j'ai pas mal de buffer à droite à gauche, c'est autant de RAM occupé inutilement. J'ai fait un test en créant un buffer de 200 octets via malloc() au lieu de la méthode traditionnelle, j'ai un gain équivalent en RAM !

Gromain

Salut,

Je pense que, même si tu ne souhaites pas trop l'utiliser, le stockage de chaines dans l'EEPROM est encore ce qui sauve le plus de ram. Essayes d'y mettre toutes les chaines qui ne bougent pas, genre menu, chaines de printf...
C'est ce que j'ai fait sur un atmega168 et ça m'a fait économiser quelques précieux octets.
C'est marrant cette chasse à l'octet de ram me rapelle mes débuts sur zx81 ou chaque octets comptait...

churchill

merci à tous pour vos suggestions.

J’ai réussi à grappiller plus d’1 ko, ce qui me laisse respirer un peu.
Pour cela j’ai:

  • désactivé le maximum de Serial.print qui me servaient à la mise au point → gain assez impressionnant, de toute façon, c’est au point ^^
  • transformé certain integer en byte
  • ajusté au plus juste la taille des différents buffers qui me servent à envoyer des messages XPL en UDP
  • rendre moins systématique l’appel de certaines routines (tous les 100ms au lieu de chaque cycle).
  • abandonné l’idée du malloc(), car soit je ne sais pas m’en servir, soit la mémoire n’est pas correctement libérée avec free()

à faire:

  • passer sur mémoire flash ou Eeprom certaines chaines qui sont fixes.

Gromain

y a t il un tuto sur la façon dont l'arduino utilise les différentes mémoires à sa disposition ??
et pourquoi pas les possibilités d'extension ...

Gromain59, post ton code ici, plusieurs regards externes peuvent trouver des solutions plus facilement avec un code sous les yeux.

Pour ma part, je surveille aussi les appels de fonctions en pagaille (hérité des habitudes de développement sur ordinateur).
Je ne sais pas si ça pose un problème de RAM mais un problème de limite de pile et de temps d'exécution, donc je vais tester. J'utilise l'instruction "inline" pour organiser mon code proprement sans perdre en performances.

y a t il un tuto sur la façon dont l'arduino utilise les différentes mémoires à sa disposition ??
et pourquoi pas les possibilités d'extension ...

pas à ma connaissance, malheureusement. Voir la doc concernant l'utilisation de la mémoire AVR: avr-libc: Memory Areas and Using malloc()

post ton code ici, plusieurs regards externes peuvent trouver des solutions plus facilement avec un code sous les yeux.

mon code est composé d'une multitude de pde et de bibliothèques spécifiques à mon projet, donc ça va être chaud pour le poster ici...
Par contre, je le tiens à dispo par mail.

J'utilise l'instruction "inline" pour organiser mon code proprement sans perdre en performances.

Luj06, j'avais lu cette astuce sur ton site "pobot". Je me la garde sous le coude pour plus tard, quand je me rendrai compte que mon code est trop long à exécuter :wink:

Gromain

à faire:
- passer sur mémoire flash ou Eeprom certaines chaines qui sont fixes.

Après pérégrinations sur le site et recherches sur le web, il y a qq infos intéressantes concernant l'optimisation mémoire.
Attention , un point rarement abordé est la limite en écriture des flash memory et eeprom avec respectivement 10 000 cycles et 100 000 cycles.
ceci implique que ces mémoires, si utilisées pour pallier des pb de taille SRAM, ne doivent pas être trop sollicitées,
ie. faire ses comptes...

forex2:
Attention , un point rarement abordé est la limite en écriture des flash memory et eeprom avec respectivement 10 000 cycles et 100 000 cycles.
ceci implique que ces mémoires, si utilisées pour pallier des pb de taille SRAM, ne doivent pas être trop sollicitées,

Non, effectivement, ces mémoires sont a utiliser pour des chaines qui ne varient (presque) jamais, des paramètres à sauvegarder... Elles ne peuvent supplanter la RAM.
Mais typiquement une chaine sprintf y a sa place ("La température est de %0.2f°") tout comme les réglages qui doivent être sauvegarder en cas de coupure de courant (Relais1="Lumière salon", Duree_allumage=15, ...)

churchill