Timer hardware ou les 55 cycles manquant...

Je ne sais pas pour vous mais c’est plus fort que moi: Quand quelque chose ne se passe pas comme prévu j’ai besoin de comprendre le « pourquoi? ». Lors de l’écriture de la librairie RunLoop pour Arduino, j’avais constaté à l’époque un décalage sur les timers hardware entre la période demandée par le programme et la périodicité réellement constatée en sortie avec l’analyseur logique.

RunLoop

Le problème c’est que toutes les librairies testées avaient le même décalage que moi: un peu plus de 3us!!! Cela peut paraitre ridicule vu de loin mais pour des fréquences dépassant le KHz, l’erreur est de plus en plus problématique si l’on a besoin de précision. Hors en astronomie, pour le pilotage des moteurs pas à pas, la précision est de rigueur. A l’époque, j’avais donc intégré ce décalage dans RunLoop en l’estimant de manière empirique autour des 3,3us.

Et voilà qu’aujourd’hui, je viens de tomber sur l’excellentissime blog de Bill Grundmann! Si vous lisez l’anglais, c’est par ici que cela se passe:
The overhead of Arduino Interrupts

Pour résumer: il a étudié le phénomène à l’oscilloscope et décortiqué le code assembleur de la librairie Arduino. Et effectivement, la levée d’interruption entraine un surcout de 55 cycles! Soit 55*0,0625 = 3,4375us précisément!!! Hors faute de le savoir, les librairies qu’on trouve sur le net n’en tiennent pas compte. Et bim!

J’ai donc le plaisir de vous annoncer que je viens d’en profiter pour affiner encore un peu plus le code de RunLoop et de le publier sur mon github. Un test à 20Khz, montre maintenant une périodicité quasi parfaite à +-40ns près d’après l’analyseur logique (hors avec ses 12MS/s max on est dans la limite de précision d’échantillonnage donc même pas sûr que la variation résiduelle soit réelle).

50us-20khz


Note: en toute logique, le phénomène constaté n’est présent que pour des timers hardware levant une interruption au niveau logiciel. Je ne pense pas qu’un usage en PWM soit concerné.

Veni, vidi, vici et big up à Bill! :)