Forum Linux.général probleme avec ioctl et rtc

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
12
juil.
2019

Bonjour,

voila je dois créer une alarme de 30 seconde via rtc. J'ai donc autorisé l'alarme puis initialisé l'alarme a 30 secondes. Le probleme et que je reste bloqué dans mon read() comme si l'alarme ne déclenchait aucune interruption. Pourtant dans le man il est bien écrit que l'alarme génere une interruption, et il me semble que j'ai bien respecté la documentation.

Je vous montre mon code :

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <linux/input.h>
    #include <linux/rtc.h>
    #include <string.h>

    int main(int argc, char const *argv[])
    {
        int fd_open;
        struct rtc_time rtc_tm; 

        if( (fd_open = open ("/dev/rtc0", O_RDONLY )) < 0 )
        {
            printf("open : %i\n", errno);
            exit(1);
        }  

        if( ioctl(fd_open, RTC_AIE_ON, NULL) < 0 )
        {
            printf("ioctl : %i\n", errno);
            exit(1);
        }


        memset(&rtc_tm, 0, sizeof(struct rtc_time) );
        rtc_tm.tm_sec = 30;


        if ( ioctl(fd_open, RTC_ALM_SET, &rtc_tm) < 0 )
        {
            printf("ioctl RTC_ALM_SET : %i\n", errno);
            exit(1);
        }

        long int value = 0;
        int ret = read(fd_open, &value, sizeof(long int));
        printf("%li\n", value);

        return 0;
    }

avez vous une idée du probleme?

Merci d'avance

  • # Doc/exemple ?

    Posté par  (site web personnel) . Évalué à 3.

    As-tu regardé Documentation/rtc.txt et tools/testing/selftests/rtc/rtctest.c dans les sources du noyau ? Ça te donnera peut-être des indices ?

    Debian Consultant @ DEBAMAX

    • [^] # Re: Doc/exemple ?

      Posté par  (site web personnel) . Évalué à 2.

      Si j'en crois l'exemple justement :

      • ioctl(RTC_UIE_ON) est inutile (il le désactive ensuite avant le test d'alarme),
      • ioctl(RTC_ALM_SET) met une alarme sur une date absolue, et non à partir du temps d'appel. Le code proposé ici demande une alarme pendant l'an 0, qui a peu de chance d'arriver avant quelques siècles. L'exemple récupère d'abord la date courante avant d'ajouter la période voulue pour demander une alarme à cette date précise.

      Par contre, j'espère que ça n'est utilisé que sur Linux parce que ce truc est tout sauf portable. On peut se demander quel intérêt par rapport à un simple usleep(), je suppose que ça sort de veille si on est en veille quand l'alarme se déclenche ?

      • [^] # Re: Doc/exemple ?

        Posté par  . Évalué à 1.

        Merci pour vos réponses.

        Je n'ai rien trouvé comme documentation sur mon systeme concernant rtc.

        En effet j'initialisais l'alarme pour 00h00 et 30 secondes. Mais ca ne marchait toujours pas apres cette modification. en faite ca marche uniquement si j'initiliaise l'alarme avec RTC_ALM_SET puis je l'autorise avec RTC_AIE_ON. Ca me parait etrange l'obligation de faire dans cette ordre la. Avez vous une idée du pourquoi de cet ordre car sur la documentation rien n'est écrit a ce sujet mais peut etre que ca coule de source.

        j'ai donc modifier ca :
        ```
        memset(&rtc_tm, 0, sizeof(struct rtc_time) );
        rtc_tm.tm_sec = 0;
        rtc_tm.tm_min = 14;
        rtc_tm.tm_hour = 6;

        if ( ioctl(fd_open, RTC_ALM_SET, &rtc_tm) < 0 )
        {
            printf("ioctl RTC_ALM_SET : %i\n", errno);
            exit(1);
        }
        
         if( ioctl(fd_open, RTC_AIE_ON, NULL) < 0 )
        {
            printf("ioctl : %i\n", errno);
            exit(1);
        }
        
        • [^] # Re: Doc/exemple ?

          Posté par  (site web personnel) . Évalué à 2.

          Ah je n'avais pas vu qu'il était réutilisé le AIE_ON dans l'exemple.
          Par contre ça m'étonne que ça fonctionne avec 0 comme année. Ou alors l'alarme ne fonctionne que sur les heures ? Mais c'est bizarre. Autre possibilité le 0 pour l'année indique que c'est relatif (en fait il y a un an 1 mais pas d'année 0)… Mais c'est pas documenté.
          Il reste le code source du pilote mais j'avoue que je ne suis pas motivé pour le lire :D

          • [^] # Re: Doc/exemple ?

            Posté par  (site web personnel) . Évalué à 2.

            Ah par contre la page man indique "Only the tm_sec, tm_min, and tm_hour fields of this structure are used". Mais il ne dit pas si c'est relatif à l'heure actuelle ou pas (et du coup l'exemple serait faux).

        • [^] # Re: Doc/exemple ?

          Posté par  . Évalué à 1.


          marche uniquement si j'initiliaise l'alarme avec RTC_ALM_SET puis je l'autorise avec RTC_AIE_ON.
          Ca me parait etrange l'obligation de faire dans cette ordre la.
          Avez vous une idée du pourquoi de cet ordre car sur la documentation
          rien n'est écrit a ce sujet mais peut etre que ca coule de source.

          Tant qu'une nouvelle date/heure d'alarme n'a pas été programmée,
          l'ancienne date/heure (déjà dépassée) d'alarme reste enregistrée dans la RTC.

          Ça n'a donc aucun sens de demander qu'un signal d'interruption soit déclenché par un évènement passé.

  • # Depuis le bash

    Posté par  . Évalué à 1.

    Bonjour

    Juste pour info,
    car c'est hors sujet

    À partir d'un shell (bash) de debian
    avec les privilèges du compte superutilisateur root
    Je peux programmer la RTC de mon PC
    pour qu'il se mette tout seul sous tension et redémarre
    (par exemple ici dans les 5 minutes qui suivent)
    en lançant la ligne de commandes suivantes :

    echo 0 > /sys/class/rtc/rtc0/wakealarm && date '+%s' -d '+ 5 minutes' > /sys/class/rtc/rtc0/wakealarm

    je vérifie l'état de la RTC
    en lançant la ligne de commande suivante :

    cat /proc/driver/rtc
    • [^] # Re: Depuis le bash

      Posté par  . Évalué à 1. Dernière modification le 13 juillet 2019 à 08:43.

      J'oubliais de parler des particularités de certaines machines :

      La RTC de certaines machines n'acceptera pas
      d'enregistrer une date/heure de demande d'interruption
      avant un certain délai depuis l'heure actuelle.

      Par exemple, pour mon Asus G53SW, ce délai est de 121 minutes

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.