Reduire taille core libs

Bonjour, je suis à la recherche d'un moyen de réduire la taille des libs intégrés par défaut dans un sketch.

Je dois écrire un prog pour un Attiny10 et vu le peu de place dispo je cherche un moyen simple pour réduire la taille du sketch.

Basiquement j'ai besoin juste de ces fonctions:

  • AnalogRead
  • DigitalWrite
  • Millis
  • PinMode

Je sais qu'on peut le faire en C pur mais j'ai un peu de mal encore avec les registres et leur utilisations et pas trop le temps de m'y pencher dessus.

Donc l'idée serai d'avoir un "core" arduino réduit avec juste les fonctions dont j'ai besoin

Si quelqu'un à une idée...

Merci !!

Donc l'idée serai d'avoir un "core" arduino réduit avec juste les fonctions dont j'ai besoin

Lorsque l'on utilise une librairie seules les fonctions réellement utilisées sont liées à l'exécutable en plus de ton propre code.

L'optimisation sans utiliser les registres va être difficile.
L'optimisation sans lire la datasheet d'un atmega 10 pour en connaitre ses possibilités exactes va être difficile.

Les fonctions arduino sont destinées aux non professionnel de la programation et comportent de nombreuses lignes de code destinées à détecter et à corriger des "conneries". Elles ne sont absolument pas optimisée.
Une grosse source de "pertes", au moins en temps d'exécution, est la corespondance entre les dénominations des sorties "Atmel", qui est la seule que le micro comprend, et la dénomination introduite par Wiring/arduino.

Registres.
Les fonction digitalWrite et pinMode sont triviales à remplacer.
Registre DDRx pour sens entrée ou sortie
Registre PORTx pour écrire dans une sortie

analogRead() est un peu moins simple mais cela reste relativement facile.
Quand je dis "moins simple" c'est parce que les possibilités pour la lecture analogique sont limitées volontairement par Arduino et que de nombreux réglages sont ignorés alors qu'ils peuvent être intéressants.

millis()
As tu des besoins précis en terme de pas de mesure et de valeurs maximale ?
Parce que le coeur de millis c'est de lire un registre d'un timer. Tout le reste du code ne sert qu'à obtenir une valeur de débordement (passage à 0) de 49 jours.

La lecture directe d'un timer dont le diviseur d'horloge aura été adapté à tes besoins peut largement suffire à condition de connaitre ses besoins.

tu peux aussi supprimer les libs : tu y pompes les fonctions qu'il te faut et tu les intègres à ton .ino
(c'est ce que je fais quand je veux réécrire une fonction pour + d'efficacité)

toutefois, là, tu rames à contre courant : les efforts principaux sont faits pour développer et généraliser les bibliothèques afin de faciliter l'accès des choses au + grand nombre
ce n'est pas en enlevant quelques lignes ça et là dans des fichiers que tu feras un progrès quelconque pour toi ou pour la planète

ce n'est pas en enlevant quelques lignes ça et là dans des fichiers que tu feras un progrès quelconque pour toi ou pour la planète

Oh là , il a un problème particulier avec un atmega10 , il n'est pas interdit de le traiter sur le forum.
L'universalité est une gageure, tout le monde un jour ou l'autre aura un problème spécifique qui ne pourra pas être réglé avec les méthodes classiques, il est préférable de s'y préparer.
Le truc qui fait tout est obèse et on va droit sur les méthodes du couple infernal Microsoft/Intel. Bientôt il faudra 1 Mega octets de mémoire pour faire clignoter une Del. Je suis sérieux sur ce coup il suffit de voir la taille minimale du programme Blink sur ESP8266 ou ESP32.

Et je suis certain que quelques esprits curieux seront intéressés

tu peux aussi supprimer les libs : tu y pompes les fonctions qu'il te faut et tu les intègres à ton .ino

Le gain ne sera pas énorme, voir ce qu'à dit hbachetti et que Skywood m'avait expliqué il y a quelques temps : dans bibliothèque statique ( crée par l'IDE dans le répertoire provisoire : core.a ) seul ce qui est utilisé est conservé.

La question que je me pose : est-ce que les interminables #define truc qui ne servent jamais (voir PI; PI/2; la litanie de B0000000x alors que la notation 0b0000000x existe, etc....) occupent de la place en mémoire ? Il semblerait que non mais une confirmation serait la bienvenue.

#define truc est traité par le préprocesseur, avant la phase de compilation. Ils ne prennent donc pas de place spécifique en soit dans un exécutable.

Merci pour les précisions.

Voilà le montage prévu pour aider à comprendre ce que je cherche :

  • 1 bouton poussoir
  • 1 mosfet N-Channel qui coupe un circuit de puissance
  • 2 led

Ce que je veux faire :

  • 3 clics sur le bouton = blocage / déblocage de la commande du mosfet et blink de la led (millis)
  • ensuite en fonction de la tension batterie 1 appui sur le bouton ferme le mosfet si la batterie est suffisante et si c'est pas désactiver par les 3 clics (analogread et digital write) + allumage des leds
  • si la batterie est trop faible pas de fermeture du mosfet et blink rapide des LEDs.

Je cherche pas le code pour faire tout ça juste les fonctions pour les entrées/sorties. Pour la précision de millis c'est pas une grosse précision vu qu'il va servir juste pour le blink des LEDs et le debounce du bouton.

Voilà ! Merci !

Tu as maintenant un aperçu de ce qu’il est possible de faire :

  • rester avec les fonctions arduino
  • simplifier les fonctions arduino
  • utiliser les registres.

Première question : est-ce que cela passe avec la solution 1 ?
Si oui ce n’est pas la peine de se prendre la tête avec les solutions 2 et 3.

Si cela ne passe pas de peu voir si avec la solution 2 cela ne suffirait pas.
Par exemple il existe une fonction (chercher sur internet) digitalFastRead ou Write. Ces fonctions simplifiées suppriment des contrôles anti conneries et s’exécutent deux fois plus vite et donc “pourraient” prendre deux fois moins de place.

Sinon c’est clair que la solution 3 va demander un investissement faisable mais non négligeable.

Remarque préalable :
Pour le debouncing l’anti rebonds il n’est pas utile de le faire de façon logicielle. Cela fonctionne très bien avec un condensateur de 100 nF soudé en parallèle sur le contact et cela prend 0 lignes de code
L’électronique c’est génial ! :grin: .

Il reste le cas des leds dels :
Je découvre la datasheet de l’attyny 10.
J’y vois que la fréquence horloge est 12 MHz, le préscaler max est 1024 et le timer est sur 16 bits.
Ce qui donne un temps max avant débordement de 5,6 secondes.
Fréquence du timer 12MHz/1024 soit 11,7 kHz
Temps max = (216) / (11,7 103) = 5,59
S’il est possible de baisser la fréquence horloge le temps max de 5,6 secondes augmentera dans les mêmes proportions.

Pour gérer dans une fonction une Entrée/Sortie par les registres voir ce lien :
https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_port_pass.html

AT Tiny10 sans le core Arduino ?

Avec sa mémoire Flash de 1ko et ses 32 octets de RAM la question se pose, naturellement !
Le recours à l'assembleur vient à l'esprit.

Et sous IDE Aduino en C/C++ ?
Voir içi l'utilisation d'un "At Tiny Core' et des exemples d'accès aux registres pour pallier l'absence de PinMode, DIgitalWrite/Read, AnalogRead......
Ce core particulier est une coquille presque vide, il faut écrire ses fonctions en fonction des besoins en vue d'avoir l'occupement mémoire minimal.
http://www.technoblogy.com/show?1YQY

içi un thermometre avec un DS18B20 et une fonction DelayMicros()
http://www.technoblogy.com/show?2G8A

Içi un pendentif avec une led RGB (interruptions par Timer 16 bits)
http://www.technoblogy.com/show?201J

Avec la page de présentation + les deux exempelles on déjà quelques fonctions permettant de gérer un BP, le temps, des leds et un DS12B20.. les autres il faut les écrire avec la Data Sheet di Tiny10
On est la dans l'esprit des réponses #2 et #3

Le recours à l'assembleur vient à l'esprit.

J'osais par le dire vu que je ne connais rien à l'assembleur si ce n'est que c'est le plus efficace.

" ses 32 octets de RAM "
Est ce qu'il a assez de RAM pour pouvoir invoquer une fonction (je ne parle même pas de variables internes)?

Il suffit normalement de 2 octets sur la pile (adresse de retour) pour faire un appel de fonction.

je pense que les 32 octets de RAM sont la contrainte la plus forte
ça impose sans doute un soin extrème au niveau du codage (appels de fonctions imbriqués ? pile pendant les interruptions? ) , ca me fait penser à un travail d'équilibriste...

(pas facile avec un IDE qui ne donne pas accès à une simulation ou une exécution pas à pas avec suivi de la RAM et la pile en particulier)

"Il suffit normalement de 2 octets sur la pile (adresse de retour) pour faire un appel de fonction."
IIRC, il s'agit alors d'un appel de fonction
sans arguments
sans variables internes
....
Bonne nouvelle: il faut effectivement 2 octets pour l'adresse de retour (s'il n'avait que 256 octets de flash, un octet suffirait)....

au temps pour moi, j'avais zappé l’extrême tinysité de la chose :blush:

en effet, programmer en assembleur permet de garder la main sur l'utilisation de la ram + les 16 registres -> ~ 50% de la ram ...

mais rien n'empêche de tenter le coup en arduino
et de jeter un œil sur ce qui a été compilé

Bonjour ,

Avec la page de présentation + les deux exempelles on déjà quelques fonctions permettant de gérer un BP, le temps, des leds et un DS12B20.. les autres il faut les écrire avec la Data Sheet di Tiny10
On est la dans l'esprit des réponses #2 et #3

Effectivement je pense que ça devrais suffire pour écrire mon soft. Je vais commencer avec ça et je reviendrais vous dire et cloturer le sujet dés que c'est ok !

Merci @ tous