IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Gestion du Port COM


Sujet :

Embarqué

  1. #1
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    928
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 928
    Points : 312
    Points
    312
    Par défaut Gestion du Port COM
    Bonjour à tous,
    Je suis débutant en linux et système embarqué. Et je dois communiqué par le port série.

    Je travail avec un serveur DIGI Connect ME9210 sous linux.
    Mon PC (XP) fait tourner, grâce a VMWare un Package linux Ubuntu modifié par DIGI.
    L'EDI est Eclipse arranger par DIGI. Et les programmes sont en C.

    Je souhaite faire fonctionner le port série de ma carte de développement.

    Je précise qu'aux boot j'ai les instructions qui sont renvoyées par le port série. je visualise donc les étapes du boot jusqu'au pompt linux par un hypertherminal, ou je peux naviguer dans les dossiers du linux embarqué et lancer des commandes. Le linux embarqué se trouve sur mon PC charger par le Serveur en FTP/NFS je peux donc debooger mes programmes.

    Ce que j'ai fait:

    J'arrive à envoyer du texte sur le port COM, je le visualise bien. Par contre il faut que je le lance plusieurs fois car j'ai l'impression qu'il ne prend pas les bons paramètres de COM immédiatement.

    Par contre la réception est plus hasardeuse, car cela ne fonctionne pas. J'ai la doc fourni par DIGI mais ce n'est pas super clair.
    De plus je suis connecté sur le même port COM ou j'ai linux en visu (boot etc...). lorsque je tape donc du texte dans la console je suis sous linux embarqué. Je ne pense pas que se soit correct.

    Voici mon Code:
    Main:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    #include <termios.h> /* POSIX terminal control definitions */
    #include "uart.h"
    
    int main()
    {
    	int n;
    	char Chaine[50];
    	int Fin = 1;
    	int SerialPort; /* File descriptor for the port */
    	uart_conf.baudrate = 38400;
    	uart_conf.bits = 8;
    	uart_conf.stop = 0;
    	uart_conf.flux = 0;
    	uart_conf.parite = 0;
    
    	SerialPort = uart_open_port();
    
    	if (SerialPort == -1 )
    	{
    	}else{
    		usleep(100000);
    		strcpy(Chaine, "Connexion OK : \0");
    		n = strlen(Chaine);
    		n = uart_write(Chaine, n);
    		uart_read();
    	}
    	uart_close();
    	return 0;
    }
    Uart.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    #ifndef UART_H_
    #define UART_H_
    #include <termios.h> /* POSIX terminal control definitions */
    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    
    struct{
    	int baudrate;
    	char bits;
    	char stop;
    	char flux;
    	char parite;
    }uart_conf;
    int SerialPort;
    
    int uart_open_port();
    int uart_write(char* text, int Nbo);
    int uart_rear();
    void uart_close();
    
    #endif /* UART_H_ */
    uart.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    
    #include "uart.h"
    
    int uart_open_port()
    {
    	struct termios options;
    
    
    	SerialPort = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    	if (SerialPort == -1)
    	{
    		/*
    		* Could not open the port.
    		*/
    		perror("open_port: Unable to open /dev/ttyS0 - ");
    		return -1;
    	}
    	else
    		/*
    		 * Get the current options for the port...
    		 */
    
    		tcgetattr(SerialPort, &options);
    
    		/*
    		 * Set the baud rates to 38400...
    		 */
    		switch (uart_conf.baudrate)
    		{
    			case (2400):
    				cfsetispeed(&options, B2400);
    				cfsetospeed(&options, B2400);
    				break;
    			case (9600):
    				cfsetispeed(&options, B9600);
    				cfsetospeed(&options, B9600);
    				break;
    			case (19200):
    				cfsetispeed(&options, B19200);
    				cfsetospeed(&options, B19200);
    				break;
    			case (38400):
    				cfsetispeed(&options, B38400);
    				cfsetospeed(&options, B38400);
    				break;
    			default:
    				cfsetispeed(&options, B19200);
    				cfsetospeed(&options, B19200);
    				break;
    
    		}
    		options.c_cflag |= (CLOCAL | CREAD);
    		//Controle de parité
    		if (uart_conf.parite == 0) {
    			options.c_cflag &= ~PARENB; 			// sans Parité
    		}else{
    			options.c_cflag |= PARENB; 				// avec Parité
    		}
    		//Bit de stop
    		if (uart_conf.stop == 0){
    			options.c_cflag &= ~CSTOPB;				// pas Bit de stop
    		}else{
    			options.c_cflag |= CSTOPB;				// avec Bit de stop
    		}
    
    		options.c_cflag &= ~CSIZE;					//Bit mask for data bits
    		//Controle de flux
    		if (uart_conf.flux == 0){
    			options.c_iflag &= ~(IXON | IXOFF | IXANY);	//sans Control de flux
    		}else{
    			options.c_iflag |= (IXON | IXOFF | IXANY);	//avec Control de flux
    		}
    		switch (uart_conf.bits)
    		{
    			case (5):
    				options.c_cflag |= CS5;	//5 Bits de données
    				break;
    			case (6):
    				options.c_cflag |= CS6;	//7 Bits de données
    				break;
    			case (7):
    				options.c_cflag |= CS7;	//6 Bits de données
    				break;
    			case (8):
    				options.c_cflag |= CS8;	//8 Bits de données
    				break;
    			default:
    				options.c_cflag |= CS8;	//8 Bits de données
    				break;
    		}
    
    		tcsetattr(SerialPort, TCSANOW, &options);
    
    		fcntl(SerialPort, F_SETFL, 0);
    
    	return (SerialPort);
    }
    
    int uart_write(char* text, int Nbo)
    {
    	int n;
    	n = write(SerialPort,text, Nbo);
    	return n;
    }
    void uart_close()
    {
    	close(SerialPort);
    }
    
    int uart_read()
    {
        char buffer[255];  /* Input buffer */
        char *bufptr;      /* Current char in buffer */
        int  nbytes;       /* Number of bytes read */
    
        bufptr = buffer;
    	while ((nbytes = read(SerialPort, buffer, 255)) > 0)
    	{
    	  bufptr += nbytes;
    	  if (bufptr[-1] == '\n' || bufptr[-1] == '\r')
    			break;
    	}
    
    
    	   /* nul terminate the string and see if we got an OK response */
    	*bufptr = '\0';
    	uart_write(buffer,strlen(buffer));
    
    	if (strncmp(buffer, "OK", 2) == 0){
    
    	  return (0);
    	}
    	return (-1);
    }
    Merci de votre aide.

  2. #2
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Points : 356
    Points
    356
    Par défaut
    Connais pas Linux, mais je trouve ton "main" suspect, me semble qu'il devrait comporter une boucle du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    void main(void)
    {
       bool done = true ;
       ComPortInit() ;
       while (!done)
       {
           ComPortWrite("data") ;
           sprintf("%s",ComPortRead() ;
       }
        ComPortDone() ;
    Ton programme test, il fait une seule itération. Donc, si ta fonction ComPortWrite fonctionne en mode non-bloquant, ta fonction de fermeture du port sériel est appelée avant même que le port en ait terminé avec la transmission!

    Aussi, t'as définis 2 variables globales dans le ".h" (uart_conf, SerialPort) qui aurait très bien pu être définies localement dans le "main". C'est pas ça ton problème pour l'instant, mais ça va en devenir un éventuellement.

  3. #3
    Membre chevronné

    Homme Profil pro
    .
    Inscrit en
    Janvier 2006
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Janvier 2006
    Messages : 703
    Points : 1 950
    Points
    1 950
    Par défaut
    Hum sur ta carte, n'as-tu pas d'autres port série de disponibles ?

    Si je comprends bien tu veux faire dialogue ton système Linux avec Windows via "un" port série ? Dans quel but ? Tu veux mettre en place un shell ? ou souhaites-tu faire passer des commandes custom (qui ne sont pas propres au shell ouvert par la console) ?

    Si c'est le second cas, cette façon de procéder n'est pas très propre.

    Le soucis de travailler sur le même "canal" que le port console c'est que tes commandes seront parasitées par la console. Et des commandes "custom" pourraient même être interprétées comme des commandes shell valides.

    Peux-tu nous faire un cat de /etc/inittab ?
    Généralement par défaut le shell ouvert sur ton serial est en respawn, dès que tu le fermes getty va le relancer à nouveau. Tu peux regarder le man de inittab qui explique ça. Maintenant, il y a plusieurs façons de gérer l'init. Si ça se trouve tu as busybox sur ton système et c'est un poil différent. Bref, ce que je veux juste dire c'est que la gestion du serial se fait à ce niveau là dans Linux. Donc si tu n'as qu'un serial, il faut désactiver la console à ce niveau, sinon tu as deux applications qui utilisent le même canal.

    Mais bon je vais pas aller plus loin dans les suppositions, j'attends déjà d'en savoir plus sur le contexte et ce que tu veux faire exactement avec ce serial.

  4. #4
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    928
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 928
    Points : 312
    Points
    312
    Par défaut
    Merci de prendre du temps pour m'aider.

    C'est ce que je pensais aussi avec la console, je pense qu'il faut effectivement la désactiver. D'ailleurs actuellement lors du boot tout est craché sur le port séries et sa c'est pas top pour le but du serveur.

    Explication du but final: En faite le serveur DIGI Connect nous sert à dialoguer avec notre supervision depuis le réseaux Ethernet. Notre supervision communique en RS232. Elle est donc connecter au DIGI par le port COM.

    Depuis Ethernet ont doit pouvoir l'interroger de plusieurs façons. WEB,snmp,Telnet et notre protocole. Pour ce dernier le serveur ne sert que de Transfert de protocole, notre logiciel interrogera directement la supervision par le réseaux Ethernet comme s'il était en local.

    Actuellement j'effectue uniquement des tests.

    J'ai testé le gpio sans souci car j'avais un tuto bien expliqué par le fournisseur. Le but du GPIO et d'avoir 2 entrées, l'une qui fixera un IP pour l'administration, le chargement etc.. L'autre qui servira justement à inhiber le mode console, pour éviter que des paquets incohérent pour notre supervision lui soit envoyé.

    Je test donc actuellement le port série afin de dialoguer avec notre supervision pour au final mettre à jour les serveurs et services utilisés.

    CAT inittab:

    # Early mount proc to be able to parse /proc/cmdline in bootscripts
    ::sysinit:/bin/mount -t proc proc /proc

    # Start any script in init.d
    ::sysinit:/etc/init.d/rcS

    # Start telnet daemon.
    ::sysinit:/bin/sh -l -c '/usr/sbin/telnetd -l /bin/sh'

    # Start busybox console
    ::respawn:/bin/cttyhack /bin/sh -l

    # Stuff to do for the 3-finger salute
    ::ctrlaltdel:/sbin/reboot

    # Start gpio driver
    ::sysinit: modprobe gpio/etc #

    J'ai ajouté justement le driver gpio ici.

    Je pense que c'est dans le programme de l'U-BOOT qu'il faudra vérifier l'entrée et démarrer ou paramétrer linux en fonction d'eux.

    [edit] Bon apparemment il va être difficile de vérifier les entrées lors du Boot puisque le driver gpio ne sera pas chargé. Bon sa c'est pas bien grave. Notre supervision n'est pas trop regardante sur ce qu'il lui arrive elle répondra simplement qu'elle comprend pas la demande.

    Bon j'ai bloquer la console:

    # Start busybox console
    #::respawn:/bin/cttyhack /bin/sh -l

    Je vais continuer les essaies du port COM

  5. #5
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    928
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 928
    Points : 312
    Points
    312
    Par défaut
    Bon cela fonctionne maintenant, par contre j'ai toujours des difficultés pour afficher le 1er texte, le port COM débite pas à la bonne configuration, enfin je suppose vu les ? et autre bizarrerie qu'il envoie avant le OK de "Connexion OK : " ensuite c'est bon et si je redémarre l'appli rapidement j'ai bien le "Connexion OK : " en entier.

    Il va falloir que je vide la file du port COM après ouverture car si non j'ai des traces.

  6. #6
    Membre chevronné

    Homme Profil pro
    .
    Inscrit en
    Janvier 2006
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Janvier 2006
    Messages : 703
    Points : 1 950
    Points
    1 950
    Par défaut
    Question bête ... le baudrate est-il bon ? C'est bien 38400 baud que tu veux ?

  7. #7
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    928
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 928
    Points : 312
    Points
    312
    Par défaut
    Citation Envoyé par Aquanum Voir le message
    Question bête ... le baudrate est-il bon ? C'est bien 38400 baud que tu veux ?
    Oui oui pour le moment c'est bien cela, je ne sais pas si au final on le laissera comme cela mais c'est ce que je souhaite actuellement.

Discussions similaires

  1. [Lazarus] Gestion de port COM !
    Par showza dans le forum Lazarus
    Réponses: 20
    Dernier message: 16/03/2009, 13h15
  2. [IO] PortSerie Gestion des ports COM
    Par maxdwarf dans le forum Windows Forms
    Réponses: 3
    Dernier message: 07/11/2007, 18h45
  3. Gestion du port COM en RS232
    Par bkhbkh dans le forum VB 6 et antérieur
    Réponses: 14
    Dernier message: 08/06/2007, 00h47
  4. Réponses: 4
    Dernier message: 07/04/2006, 18h08
  5. Gestion de deux ports COM
    Par chourmo dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 15/12/2005, 15h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo