Avec ce sujet, je ferais mieux de discuter des minuteurs HR et du problème de précision réelle. J'ai étudié beaucoup de documentation à leur sujet et je suis sûr qu'ils sont la solution la meilleure et la plus fiable pour retarder l'exécution à l'intérieur des modules noyau Linux, avec un coût moindre pour le CPU et une plus grande précision de synchronisation (par ex. Certains pilotes critiques les utilisent aussi, comme celui-ci: https://dev.openwrt.org/browser/trunk/target/linux/generic/files/drivers/pwm/gpio-pwm.c?rev=35328).Un cas d'étude de précision de minuteurs HR
Est-ce que cela vous convient aussi?
Voici l'un des documents les plus complets et détaillés que j'ai jamais vus sur ce sujet: https://www.landley.net/kdocs/ols/2006/ols2006v1-pages-333-346.pdf. Les minuteurs HR promettent d'aller sous la résolution des jiffies, mais malheureusement sur mon système je n'ai pas obtenu les résultats attendus pour les retards inférieurs à 6 ms (je montrerai plus tard plus de détails).
Mon environnement est:
- de Windows 10 PRO 64 bits/8Gb RAM/CPU Intel 4 Cores
- VMWare Player 12
virtualisé OS Linux Mint 18.1 64 bits
noyau configuration
- Version: 4.10.0-24-ge Neric
- CONFIG_HIGH_RES_TIMERS = y
- CONFIG_POSIX_TIMERS = y
- CONFIG_NO_HZ_COMMON = y
- CONFIG_NO_HZ_IDLE = y
- CONFIG_NO_HZ = y
- CONFIG_HZ_250 = y
CONFIG_HZ = 250
/sys/devices/system/clocksource/clocksource0/available_clocksource => ts c hpet acpi_pm
/sys/devices/system/clocksource/clocksource0/current_clocksource => tsc
Pour faire une référence que j'ai écrit un module du noyau linux que je librement Publiées à la url https://bitbucket.org/DareDevilDev/hr-timers-tester/. Dans le fichier README, il y a les instructions pour le compiler et l'exécuter par vous-même.
il exécute une série de cycles comme suit:
- 10 uS .. 90 uS, par incrément de 10 uS
- 100 uS .. 900 uS, par incrément de 100 uS
- 1 ms. 9 ms, incrément de 1 ms
- 10 ms .. 90 ms, incrément de 10 ms
- 100 ms ..900 ms, l'incrément de 100 ms
- et enfin 1 s
Les timings sont mesurés par la fonction « ktime_get » et stockés dans un tableau pré-alloué, pour des performances plus rapides, et pour éviter les retards non désirés à l'intérieur du hr rappel de la minuterie. Après la collecte des données, le module imprime la table de données des échantillonnages.
Pour mon scénario les données pertinentes sont:
10 uS = 41082 nS
20 uS = 23955 nS
30 uS = 478361 nS
40 uS = 27341 nS
50 uS = 806875 nS
60 uS = 139721 nS
70 uS = 963793 nS
80 uS = 39475 nS
90 uS = 175736 nS
100 uS = 1096272 nS
200 uS = 10099 nS
300 uS = 967644 nS
400 uS = 999006 nS
500 uS = 1025254 nS
600 uS = 1125488 nS
700 uS = 982296 nS
800 uS = 1011911 nS
900 uS = 978652 nS
1000 uS = 1985231 nS
2000 uS = 1984367 nS
3000 uS = 2068547 nS
4000 uS = 5000319 nS
5000 uS = 4144947 nS
6000 uS = 6047991 nS <= First expected delay!
7000 uS = 6835180 nS
8000 uS = 8057504 nS
9000 uS = 9218573 nS
10000 uS = 10435313 nS
... et ainsi de suite ...
Comme vous pouvez le voir dans la sauvegarde du journal du noyau ci-dessus, 6 ms est le premier échantillon de retard prévu . J'ai répété le même test sur mon C.H.I.P. système embarqué (https://getchip.com/pages/chip), une carte basée sur ARM Raspberry like, fonctionnant à 1 GHz, et équipée d'Ubuntu 14.04 (Kernel 4.4.13, HZ = 200).
Dans ce cas, je suis arrivé de meilleurs résultats:
30 = 44666 nS
40 = 24125 nS
50 = 49208 nS
60 = 60208 nS
70 = 70042 nS
80 = 78334 nS
90 = 89708 nS
100 = 126083 nS
200 = 184917 nS
300 = 302917 nS <= First expected delay!
400 = 395000 nS
500 = 515333 nS
600 = 591583 nS
700 = 697458 nS
800 = 800875 nS
900 = 900125 nS
1000 = 1013375 nS
... et ainsi de suite ...
sur cette carte moins cher de bons résultats viennent depuis 300 uS.
Quelle est votre opinion? Existe-t-il un meilleur moyen d'obtenir plus de précision des minuteurs HR indépendamment de la plate-forme? Les temporisateurs HR sont la mauvaise solution pour un timing précis (obligatoire lorsque nous devons écrire des pilotes matériels)?
Chaque contribution serait très appréciée.
Merci!