2014-06-12 3 views
1

J'expérimente avec quelques tests de synchronisation de la gigue en basculant une ligne GPIO et en observant la forme d'onde sur un oscilloscope. Mon noyau est compilé avec PREEMPT_RT. J'espérais que changer le planificateur pour le processus à SCHED_FIFO permettrait de réduire la gigue, mais cela ne semble pas avoir fait beaucoup de différence. Le code est ci-dessous. Est-ce que je fais quelque chose de mal en essayant d'obtenir des performances en temps réel à partir de ce code?Voyant les performances en temps réel pauvres sur test de bascule GPIO Linux en utilisant SCHED_FIFO

// Program to test Linux timing jitter by driving GPIO output via sysfs interface. 
// In this variant, the scheduler is changed to SCHED_FIFO. 

#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sched.h> 

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) 

int main() { 
    char buf[128]; 
    struct sched_param schedp; 

    const int pin = GPIO_TO_PIN(1, 24); 

    int fd = open("/sys/class/gpio/export", O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open export for writing!\n"); 
     return(-1); 
    } 

    int bytes_written = snprintf(buf, sizeof buf, "%d", pin); 
    write(fd, buf, bytes_written); 
    close(fd); 

    snprintf(buf, sizeof buf, "/sys/class/gpio/gpio%d/direction", pin); 
    fd = open(buf, O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open gpio direction for writing!\n"); 
     return(-1); 
    } 

    if (write(fd, "out", 3) == -1) { 
     fprintf(stderr, "Failed to set direction!\n"); 
     return(-1); 
    } 

    snprintf(buf, sizeof buf, "/sys/class/gpio/gpio%d/value", pin); 
    fd = open(buf, O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open gpio value for writing!\n"); 
     return(-1); 
    } 

    // Change scheduler to SCHED_FIFO. 
    schedp.sched_priority = 99; 
    if (sched_setscheduler(0, SCHED_FIFO, &schedp)) { 
     perror("sched_setscheduler"); 
    } 

    while (1) { 
     if (write(fd, "1", 1) != 1) { 
      fprintf(stderr, "Failed to write value!\n"); 
      return(-1); 
     } 
     usleep(500); 

     if (write(fd, "0", 1) != 1) { 
      fprintf(stderr, "Failed to write value!\n"); 
      return(-1); 
     } 
     usleep(500); 
    } 

    close(fd); 

    return 0; 
} 
+0

D'une manière générale, oui, il est faux d'attendre des performances RT du code en mode utilisateur. Combien de gigue attendez-vous et combien voyez-vous? –

+1

Je vois une gigue de 10% dans le carré lorsque le système est inactif, mais si je cours des commandes alors je peux parfois le voir ne pas basculer pendant quelques ms. Je pensais que le point de l'ajout PREEMPT_RT était de sorte que vous puissiez faire du code temps réel dans l'espace utilisateur? – user43995

+0

@ user43995 Un peu. Linux n'est pas un système d'exploitation en temps réel, donc il n'y a toujours pas de garantie. De plus, par défaut, 5% de seconde peuvent toujours être utilisés par des tâches de priorité inférieure et préempter votre tâche "en temps réel" (voir https://www.kernel.org/doc/Documentation/scheduler/sched-rt-group). SMS). Vous serez également lié par le taux de tick du noyau, mais avec le taux de tick 1000Hz habituel, qui ne pourrait représenter que 1ms. – nos

Répondre

0

Il existe un certain nombre de raisons pour lesquelles vous ne pouvez pas voir une performance décent en temps réel. Tout d'abord, vous devriez vérifier sur le site Web OSADL http://www.osadl.org. La première chose à évaluer est si vous avez un système capable en temps réel en tant que tel.

Vérifiez here pour savoir comment tester les performances en temps réel.

Aussi, je vois que vous écrivez à un GPIO. Je ne suis pas totalement familier avec cela, mais je suppose qu'il y a une sorte de pilote de noyau/thread qui est responsable de l'appareil. Vous devez vous assurer que ce thread récupère aussi RT par quelque chose comme chrt -f -p 99 < pid>

Considérons également nanosleep over usleep.

Bien que assez tard, cela peut vous donner quelques conseils pour commencer.