Bonjour à tous,

J'arrive à faire ce que je veux avec mon Arduino UNO mais la ROM est presque remplie...

Dommage j'avais quelques idées pour des fonctionnalités supplémentaires mais ça risque de ne pas tenir.

Il reste la possibilité d'optimiser le code. (J'utilise le c++ Arduino, les librairies également)

Dans la librairie Ethernet, j'ai pu gagner 600 octets en supprimant le code liée aux puces différentes de celle que j'utilise (la W5500)
De même, il faut optimiser ses algorithmes et nettoyer son code.

La question que je me pose c'est comment optimiser le code en lui même pour sauver de la ROM.

Avant de me mettre aux Arduino j'ai programmé en assembleur 8051 une puce AT89C2051.
Seulement 2Ko de ROM et 128 octets de RAM, mais l'assembleur permet de faire un code très compact :
- utilisation maximale des registres (j'ai du me faire un tableau excel pour noter quels fonctions utilisaient quels registres pour éviter les "collisions")
- que des variables globales (pareil même principe un tableau excel pour noter quels fonctions utilisaient quelles variables en RAM pour éviter les "collisions")
- fonctions "imbriquées" : en assembleur les fonctions c'est un goto avec un return... du coup on peut faire ça (pseudo code) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
EtiquetteFonction1:
...
...
EtiquetteFonction1b:
...
...
EtiquetteFonction1c:
...
...
Return
Cela permet d'éviter :
- de faire trois fonctions avec une partie de code redondant
- de faire une fonction avec un paramètre et un switch...case

Cette astuce m'a permis de gagner beaucoup de place dans mon programme assembleur.

Revenons à l'Arduino...

Refaire tout mon programme en Assembleur n'est pas forcément une bonne idée :
- très complexe, surtout qu'il faut aussi s'attaquer aux librairies
- l'Atmega328 a beaucoup de registres et d'après ce qu'on dit face à un excellent compilateur un être humain n'est pas meilleur
- il est illusoire de vouloir optimiser le code assembleur généré par le compilateur, c'est de la bouillie par rapport à un code assembleur écrit par un humain

Cependant je pense que les "facilités" du C++ doivent consommer beaucoup de ressources. Je pense notamment :
- aux variables locales et paramètres de fonctions
- aux types de données évolués (classes, ...)
- aux multiples appels de fonction
- aux types de données : en assembleur on manipule des octets, en C++ on manipule des types de données et il faut parfois faire des casts

La question que je me pose c'est comment écrire un code C++ qui génère un binaire plus compact, en déterminant des règles à respecter :
- utiliser au maximum des variables globales, si possible très peu ou aucune variable locale, de même, limiter les paramètres passés à une fonction
- éviter l'imbrication de multiples petites fonctions / voir si mon astuce est possible
- éviter l'utilisateur de classe si une seule instance est utilisées (typiquement : Ethernet Server)

Qu'en pensez-vous ?

Il y a aussi la RAM.
Même sans utiliser la classe String, il faut garder assez de RAM disponible pour la pile et les variables locales...
Mais c'est complètement pifométrique : impossible de savoir combien de RAM disponible donc :
- soit on gâche beaucoup de RAM
- soit on prend le risque d'un plantage.
Pour optimiser l'usage de la RAM :
- les variables locales : si on en utilise peut et qu'on épluche tout le code (libairies comprises) on peut savoir ce qu'il faut.
- la pile c'est plus difficile, il faut là aussi voir quelles fonctions utilisent la pile.
C'est mission impossible si il y a des dizaines de fonctions qui s'appellent les unes les autres, et bien sûr si il y a de la récursivité (mais qui ferai des fonctions récursive sur Arduino ?)
En assembleur 8051, je n'utilisait aucune variable locale et très peu la pile, je pouvait donc utiliser ma RAM à l'octet près.

Mon but n'est pas de passer des mois à trouver l'optimisation ultime, mais, plus pragmatiquement, de trouver une façon faisable de réécrire le code pour gagner de la ROM.

A bientôt