Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 31

Fonction ioctl




  1. #1
    DADYCOKE

    Fonction ioctl

    Bonjour j'aurais besoin d'aide
    J'ai besoin de savoir le nombre d'octet présent sur un port serie par lequel je communique.
    j'aimerais pour cela utiliser la fonction ioctl avec le parametre FIONREAD de la maniere suivante :

    Code:
    int nbytes;
    
    int nbreDeBit = ioctl(fd,FIONREAD,&nbytes);
    Or en sortie de la fonction je n'ai que la valeur 0 (pour dire qu'elle s'est bien déroulé) et non le nombre de bit que j'attendais

    Tout aide sera la bienvenu Merci

    -----


  2. Publicité
  3. #2
    PA5CAL

    Re : Fonction ioctl

    Bonjour

    Le résultat attendu doit être lu dans la variable nbytes, et non pas dans la valeur de retour de la fonction que tu mets dans la variable nbreDeBit.

  4. #3
    DADYCOKE

    Re : Fonction ioctl

    Merci au fait je me suis mal exprimé voila ma fonction :

    Code:
    int nbreDeBit = byteDispo(fd);
    
    int byteDipo (fd)
    {
         int nbytes;
         if (ioctl(fd,FIONREAD,&nbytes) == -1);
                   return -1;
         return nbytes;
    
    }
    Dernière modification par DADYCOKE ; 20/02/2013 à 14h33. Motif: eurreur dans la syntaxe


  5. #4
    DADYCOKE

    Re : Fonction ioctl

    Elle retourne toujours pas le nombre de bit

  6. #5
    PA5CAL

    Re : Fonction ioctl

    Il ne s'agit pas du nombre de « bits » mais de « bytes », c'est-à-dire d'octets, actuellement disponibles dans le tampon.

    Si la valeur retournée est 0, c'est qu'il n'y a aucun octet en attente.

  7. A voir en vidéo sur Futura
  8. #6
    DADYCOKE

    Re : Fonction ioctl

    D'accor merci

  9. #7
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par PA5CAL Voir le message
    Si la valeur retournée est 0, c'est qu'il n'y a aucun octet en attente.
    Et là quand j'écris « retournée », il s'agit de l'entier pointé par le troisième paramètre de la fonction.

  10. Publicité
  11. #8
    DADYCOKE

    Re : Fonction ioctl

    oui biensur

  12. #9
    DADYCOKE

    Re : Fonction ioctl

    Bonjour tt le monde
    Bonjour PA5CAL

    voila j'utilise la fonction que j'ai mis un peu plus haut (ioctl) et j'ai remarqué qu'elle fonctionne d la maniere suivante:

    il faut d'abord faire
    Code:
    read(fd,buff,1)
    puis
    Code:
    int nbreDeBit = byteDispo(fd);
    pour savoir le nbre d'octet restant .

    J'aimerais faire l'inverse c-a-d
    Code:
    int nbreDeBit = byteDispo(fd);
    pour savoir le nbre d'octet.
    Puis une boucle

    Code:
    while( i <  nbreDeBit ){
    read(fd,buff,1);
     }
    Le probleme c'est que ca renvois 0 ( dans le 2 ème cas)

    merci

  13. #10
    Dlzlogic

    Re : Fonction ioctl

    Bonjour,
    while( i < nbreDeBit )
    {
    read(fd,buff,1);
    }
    Etant donné que ni i ni nbreDeBit ne sont modifiés dans votre boucle while, cette boucle ne se fera jamais ou indéfiniment.
    Evitez la confusion entre Bit et Byte. Si j'étais vous je choisirais entre nbreDe8bit et nbreDeByte.

  14. #11
    DADYCOKE

    Re : Fonction ioctl

    je veux faire ca au faite.

    Code:
    int i=0;
    nbreDeByte  = byteDispo(fd);       // probleme a ce niveau   ca renvoi 0
    while( i <  nbreDeByte ){
    rx = read(fd,buff,1);
    i++;
     }
    je suis obligé de faire d'abord
    "rx = read(fd,buff,1);" puis "nbreDeByte = byteDispo(fd); " pour avoir un retour de la fonction byteDispo(fd) qui est différent de 0
    Dernière modification par DADYCOKE ; 28/02/2013 à 13h48.

  15. #12
    PA5CAL

    Re : Fonction ioctl

    En principe ça doit marcher. Il y a probablement un problème ailleurs dans ton programme... ou alors ton port série ne reçoit réellement rien.

    Voici un exemple de programme qui fonctionne bien chez moi (il tourne sur Mac/Darwin/gcc) :

    Code:
    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    
    char tty[] = "/dev/tty.SerialPort";
    
    int dispo(int fd)
    {
      int nb = 0;
      if (ioctl(fd, FIONREAD, &nb)<0)
        return -1;
      return nb;
    }
    
    int main()
    {
      int fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd==-1)
        return 1;
    
      int i = 5;
      while (i--) {
    
        int nb = dispo(fd);
        printf("%d ->", nb );
    
        while (nb--) {
          char b = 0;
          read(fd, &b, 1);
          printf(" %d", b);
        }
    
        printf("\n\n");
        sleep(1);
      }
    
      close (fd);
      return 0;
    }
    Dernière modification par PA5CAL ; 28/02/2013 à 14h01.

  16. #13
    Dlzlogic

    Re : Fonction ioctl

    Il serait intéressant de voir le code qui initialise fd, la fonction nbreDeByte.
    Une petite impression du genre
    printf("nbreDeByte = %d\n";
    serait bien utile pour voir ce qui se passe.
    Je crois que je n'ai jamais utilisé open ou read, mais plutôt fopen et fread.
    En fait, je crois qu'il faut avoir une très bonne raison pour utiliser open et read.
    De même pour ioctl, c'est une fonction dont l'utilisation dépend de l'OS, donc casse-cou .

  17. #14
    PA5CAL

    Re : Fonction ioctl

    Oups... dans mon code, il vaut mieux écrit :
    Code:
     while (nb-->0) {

  18. #15
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par Dlzlogic Voir le message
    En fait, je crois qu'il faut avoir une très bonne raison pour utiliser open et read.
    Comme utiliser les fonctions ioctl() et fcntl() pour contrôler l'interface série, par exemple...

    Citation Envoyé par Dlzlogic Voir le message
    De même pour ioctl, c'est une fonction dont l'utilisation dépend de l'OS, donc casse-cou.
    Il serait effectivement intéressant que DADYCOKE précise la plateforme sur laquelle il programme.

  19. #16
    Dlzlogic

    Re : Fonction ioctl

    Oh oui, tout à fait d'accord, voici ce que me répond mon fichier help pour FIONREAD
    FIONREAD = IOC_OUT or ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or (Longint(Byte('f')) shl 8) or 127;

    Description

    The text for this constant has been generated automatically. This means that it is not documented.
    C'est une fonction (ioctl) dont je connaissais le nom, je l'ai peut-être utilisée sous DOS ou sous UNIX, mais je crois pas sous Windows. Peut-être quand j'utilisais mon moniteur pour le graphique et un minitel pour les contrôles (du texte).

  20. #17
    DADYCOKE

    Re : Fonction ioctl

    rebonjour ,

    au fait je travail sur raspberry ( j'essai de communiquer avec arduino via le port usb /dev/ttyACM0)

  21. #18
    DADYCOKE

    Re : Fonction ioctl

    voici le code que j'utilise

    Code:
    #include <iostream>
    #include <stdio.h>
    #include <unistd.h>			//Used for UART
    #include <fcntl.h>			//Used for UART
    #include <termios.h>		        //Used for UART
    #include <sys/time.h>
    #include <inttypes.h>
    #include <sys/ioctl.h>
    
    
    
    static void initialiseEpoche (void);
    unsigned int millis (void);
    int serialDataAvail(int);
    static uint64_t epochMilli;
    int main() {
    
    	initialiseEpoche ();
    	int uart0_filestream = -1;
    	uart0_filestream = open("/dev/ttyACM0", O_RDWR | O_NOCTTY );
    	if (uart0_filestream == -1)
    	{
    		//ERROR - CAN'T OPEN SERIAL PORT
    		printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
    	}
    	struct termios options;
    	tcgetattr(uart0_filestream, &options);
    	cfsetispeed(&options, B9600); //<Set baud rate
    	cfsetospeed(&options, B9600); //<Set baud rate
    	options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; //<Set baud rate
    	options.c_iflag = IGNPAR | ICRNL;
    	options.c_oflag = 0;
    	tcflush(uart0_filestream, TCIFLUSH);
    	tcsetattr(uart0_filestream, TCSANOW, &options);
    
    	//----- TX BYTES -----
    	unsigned char tx_buffer[20];
    	unsigned char *p_tx_buffer;
    	unsigned int nextTime;
    	int a = 65;
    	p_tx_buffer = &tx_buffer[0];
    	*p_tx_buffer++ = 'T';
    	*p_tx_buffer++ = 'O';
    	*p_tx_buffer++ = 'P';
    //	*p_tx_buffer++ = '\0';
    
    	if (uart0_filestream != -1)
    	{
    		int count = 0;
    		nextTime = millis () + 300;
    //		for (count = 0;count <2;) {
    		while(count<1){
    			unsigned int b = millis ();
    			if (b > nextTime){
    				fflush(stdout);
    				int wri = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0]));
    			//	nextTime += 300;
    				++count;
    				if (wri < 0)
    				{
    					printf("UART TX error\n");
    				}
    			}
    		}
    	}
    	//----- CHECK FOR ANY RX BYTES -----
    	fflush(stdin);
    	if (uart0_filestream != -1)
    	{
    		// Read up to 255 characters from the port if they are there
    		unsigned char rx_buffer[256];
    		int rx_length = -1;
    		int nbCharacter = 3;
    		int count = 0;
    		int nbredeBit = -1;
    		int taille = 3;
    
    
    
    		while(count < 3){          // c'est a ce niveau la que je veux utiliser le retour de IOCTL( la fonction serialDataAvail en bas du fichier 
    			rx_length = read(uart0_filestream,&rx_buffer[count],1);
    
    			++count;
    			printf("%d\n", count);
    		}
    
    		rx_buffer[count] = '\0';
    //		}
    		if (rx_length < 0)
    		{
    			//An error occured
    			printf("UART RX error\n");
    		}
    		else if (rx_length == 0)
    		{
    			//No data waiting
    			printf("No DATA ");
    		}
    		else
    		{
    			//Bytes received
    			//rx_buffer[rx_length] = '\0';
    			printf("%i bytes read : %s\n", count, rx_buffer);
    		}
    
    
    }
    return 0;
    }
    
    
    static void initialiseEpoche (void)
    {
    	struct timeval tv;
    	gettimeofday(&tv, NULL);
    	epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec /1000);
    }
    unsigned int millis (void)
    {
      struct timeval tv;
      uint64_t now;
    
      gettimeofday(&tv, NULL);
      now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec /1000);
    
      return (uint32_t)(now - epochMilli);
    
    }
    
    int serialDataAvail(int fd)
    {
    	int result = 0;
    	if(ioctl(fd, FIONREAD, &result)==-1)
    		return -1;
    	return result;
    }

    Le souci j'arrive pas a recevoir toute la reponse de l'arduino ( je recois une partie soit rien)
    Dernière modification par DADYCOKE ; 28/02/2013 à 15h04.

  22. #19
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par DADYCOKE Voir le message
    au fait je travail sur raspberry ( j'essai de communiquer avec arduino via le port usb /dev/ttyACM0)
    Alors, je ne vais pas pouvoir t'aider... pour le moment.

    En ce qui concerne (cette grosse daube de) Raspberry Pi, ça fait une semaine que je tente de le faire fonctionner suffisamment longtemps (dans sa configuration standard Wheezy Raspbian et sans avoir recours au fer à souder) pour pouvoir démarrer des développements. Jusque maintenant je n'y suis pas parvenu, à cause de problèmes récurrents de clavier USB. À la lecture des forums, je constate ne pas être le seul dans ce cas là. L'appareil n'est pas cher, mais il semble souffrir de défauts de conception, certainement matériels, et aussi probablement logiciels.

    D'après ce que tu indiques, la fonction ioctl FIONREAD est prise en charge. Si ton programme est correct et que les octets sont effectivement transmis, un bug du logiciel du RasPi n'est pas non plus à exclure.


    Toutefois, il est parfaitement possible d'écrire des programmes exploitant les octets entrants de l'interface série sans avoir recours à FIONREAD. Jusque maintenant, je m'en suis toujours passé, car dans l'immense majorité des cas, la fonction read() suffit normalement.
    Dernière modification par PA5CAL ; 28/02/2013 à 15h19.

  23. #20
    DADYCOKE

    Re : Fonction ioctl

    En ce qui concerne (cette grosse daube de) Raspberry Pi, ça fait une semaine que je tente de le faire fonctionner suffisamment longtemps (dans sa configuration standard Wheezy Raspbian et sans avoir recours au fer à souder)
    probablement alimentation j'avais un probleme similaire pendant tout le debut utillise un simple chargeur de smatfone ( 1 Amper)

    Toutefois, il est parfaitement possible d'écrire des programmes exploitant les octets entrants de l'interface série sans avoir recours à FIONREAD.
    j'avais deja un bout de code qui recevait correctement de l'arduino sans FIONREAD mais pour une simple envoi reception. La j'essai de faire un programme un peu plus gros et je me retrouve avec des probleme de synchro entre les 2

  24. #21
    PA5CAL

    Re : Fonction ioctl

    Dans ton cas, il devrait suffire d'ouvrir le device avec l'option O_NONBLOCK ou O_NDELAY (non-blocking), et de lire les octets reçus jusqu'à ce que la fonction read() retourne 0 ou bien -1 avec une erreur EAGAIN (= aucun octet restant à lire).

  25. #22
    DADYCOKE

    Re : Fonction ioctl

    J'ai deja essayé avec l'option O_NDELAY le souci c'est que :

    d'abord j'envoi le message 'TOP' a l'arduino et des qu'elle recois ca elle repond en envoyant "TOP'.
    Sauf que mon programme coté raspy est trop rapide par rapport a l'arduino du coup quand il fait le "read" l'arduino n'a encor rien envoyé et avec l'option O_NDELAY le programme continu en retournant -1

  26. #23
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par DADYCOKE Voir le message
    probablement alimentation j'avais un probleme similaire pendant tout le debut utillise un simple chargeur de smatfone ( 1 Amper)
    J'ai éliminé provisoirement cette option (alim trop faible, câble et contacts trop résistif...), car le problème survient quand la tension d'alimentation (entre TP1 et TP2, après le polyfuse) est encore dans les tolérances. Quoi qu'il en soit, je trouve déjà honteux d'avoir conçu une carte qui pose ces problèmes de tension quand on utilise des alimentations répondant aux spécifications prescrites (>700mA sous >4,75V en tension extérieure).

  27. #24
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par DADYCOKE Voir le message
    avec l'option O_NDELAY le programme continu en retournant -1
    Je ne vois pas le problème. Rien ne s'oppose à ce que le RasPi attende patiemment la réponse de l'Arduino. L'un des intérêts du non-blocking, c'est de pouvoir faire tout ce qu'on veut logiciellement au retour de la fonction read()... y compris bloquer, si on le souhaite, en réitérant la lecture.

  28. #25
    DADYCOKE

    Re : Fonction ioctl

    Quand j'ouvre le port avec
    Code:
    uart0_filestream = open("/dev/ttyACM0", O_RDWR | O_NOCTTY |O_NDELAY );
    et que je boucle jusqu'a avoir une réponse de arduino comme ceci

    Code:
    int rx_length = -1;
    while(rx_length == -1){         
    			rx_length = read(uart0_filestream,rx_buffer,255);
    			printf("%d\n", rx_length);
    		}
    j'affiche toujour rx_length = -1;

  29. #26
    PA5CAL

    Re : Fonction ioctl

    Cela me semble parfaitement normal.

    Tu devrais :
    - tester le code d'erreur retourné dans errno pour vérifier que sa valeur est EAGAIN (ou équivalent) afin de quitter en cas d'autres types d'erreur ;
    - attendre un seul caractère (le "T" de "TOP") ;
    - insérer un délai d'attente dans la boucle correspondant au temps d'envoi d'un octet.

    Une fois sorti de la boucle (parce qu'un octet a été reçu), tu continues à lire les octets suivants un à un pour vérifier que tu reçois bien "O" puis "P" (i.e. le reste de "TOP"), et traiter l'erreur de transmission dans le cas contraire. Il faut bien entendu t'attendre à continuer de te voir retourner des -1 avec errno=EAGAIN entre chaque caractères, puisque c'est le fonctionnement normal.
    Dernière modification par PA5CAL ; 28/02/2013 à 16h19.

  30. #27
    DADYCOKE

    Re : Fonction ioctl

    d accord je vais essayé ça MERCI

  31. #28
    DADYCOKE

    Re : Fonction ioctl

    insérer un délai d'attente dans la boucle correspondant au temps d'envoi d'un octet.
    coté arduino vous voulez dire ??


    parceque la j'essai just de recevoir correctement un octet envoyé par arduino.

  32. #29
    DADYCOKE

    Re : Fonction ioctl

    Merci bcp PA5CAL et Dlzlogic...ca MARCHEEE

  33. #30
    PA5CAL

    Re : Fonction ioctl

    Citation Envoyé par DADYCOKE Voir le message
    coté arduino vous voulez dire ??
    Non, dans la boucle de réception d'un octet, côté RasPi. C'est juste pour éviter de faire des milliers de boucles inutiles alors que le système à certainement d'autres choses plus intéressantes à faire en parallèle.
    Dernière modification par PA5CAL ; 28/02/2013 à 16h52.

Sur le même thème :

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. Réponses: 5
    Dernier message: 11/06/2012, 06h56
  2. Détermination d'une fonction exponentielle décroissante en fonction de sa courbe
    Par Julio15 dans le forum Mathématiques du collège et du lycée
    Réponses: 15
    Dernier message: 24/05/2012, 21h59
  3. logiciel R : la fonction acf et le plot d'une fonction alpha stable
    Par rachel.sfez dans le forum Mathématiques du supérieur
    Réponses: 0
    Dernier message: 28/02/2012, 20h07
  4. Proba-stat : fonction de répartition en fonction d'une loi normale
    Par aleexx dans le forum Mathématiques du supérieur
    Réponses: 1
    Dernier message: 16/05/2011, 20h07
  5. Maple, fonction Odeplot comment obtenir une couleur en fonction du temps ?
    Par wdrag dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 28/11/2010, 21h05