2017-05-27 3 views
0

J'aime échantillonner un signal généré par les pins de mon Raspberry Pi. J'ai fait l'expérience que des taux d'échantillonnage élevés sont difficiles à réaliser.Quelle est la meilleure façon d'échantillonner périodiquement gpio-pins sous Linux?

D'abord j'ai fait une approche rapide avec Python (super lent). Ensuite, j'ai changé pour ANSI C + le bcm2835.h lib. J'ai gagné des gains de performance significatifs.

Maintenant, je me pose la question: Comment faire le meilleur échantillonnage sous Linux?

Mes essais ont été entrepris dans l'espace utilisateur. Mais qu'en est-il de passer à l'espace noyau? Je peux écrire un module de noyau de périphérique de caractères simple. Dans ce module, les broches sont vérifiées périodiquement. Si l'état a changé, certaines informations sont placées dans un tampon. Ce tampon d'E/S est interrogé par un fichier synchrone lu pour une application dans l'espace utilisateur. La meilleure solution pour moi serait, si la vérification des broches peut être faite avec une fréquence fixe (la période d'échantillonnage doit être constante pour le traitement du signal).

La mise en place de ce pourrait être:

@kernel: Module de caractères + thread noyau + dispositif GPIO interface arbre + DSP à l'instant d'échantillonnage constant

espace @user: i/o application de lecture synchrone de module de caractères

Idées/conseils?

+1

Le faire dans le noyau serait un avantage si vous pouviez utiliser une sorte d'interruption quand le GPIO change. Si vous écrivez un thread en mode noyau, vous êtes probablement meilleur avec un thread en temps réel dans l'espace utilisateur. – rodrigo

+1

Si vous souhaitez faire cela dans l'espace utilisateur, vous devez vous assurer que vous avez un noyau récent et que vous avez installé 'libgpiod'. – 0andriy

+0

La libgpiod utilise l'interface du noyau "gpio.h". Le module de caractères lit les broches comme un fichier. ppoll + timeout est utilisé pour valider si un changement s'est produit. La bibliothèque bcm2845 utilise une carte mémoire pour accéder aux registres GPIO. Je pense que c'est le moyen le plus rapide car le mmu ne fait que traduire l'adresse logique en adresse physique. L'utilisation du mmap évite la couche de l'appareil lors de la vérification des broches. Qu'en est-il de la combinaison mmap + thread qui lit cyclique une partie de la mémoire? –

Répondre

1

J'ai une solution pour vous.

J'ai écrit un tel module:

https://github.com/Appyx/gpio-reflect

Vous pouvez lire tout signal synchrone des broches GPIO.

Vous pouvez utiliser la sortie et calculer le signal avec votre fréquence d'échantillonnage. Juste diviser les périodes.

+0

Ce code détecte le changement d'une broche. C'est basé sur l'événement. La question que je posais est sur le point d'échantillonner une ou plusieurs broches sur une base de temps constante (p.ex. lire les broches 1,56 et 96 toutes les 100ms).Bien que la connexion de la broche (fichier souce) avec une interruption semble être une solution à la pointe de la technologie. La solution @Appyx est basée sur http://derekmolloy.ie/kernel-gpio-programming-buttons-and-leds/ –

+1

je sais, mais vous pouvez prendre l'exemple d'envoi et simplement remplacer la fonction gpio. La meilleure solution serait un échantillonnage constant avec hr_timer, puis l'écriture des valeurs dans le tampon de lecture. – Appyx

+0

Quoi de mieux - utiliser un hrtimer au lieu d'un thread noyau pour lire/écrire périodiquement une broche? Un bon exemple de hrtimer peut être trouvé ici: https://gist.github.com/maggocnx/5946907 –