#1 Le 30/09/2008, à 08:20
- Efhache84
communication sérielle, en ansi C ??
Bien le bonjour à tous,
dans le cadre d'un projet "scolaire" il m'est demandé de réaliser une communication entre deux plate-forme linux (système embarqué). Cette communication doit se passer par le port série. Quelque chose dans le genre client-serveur. Soit envoit d'un message d'interrogation à un ordinateur A pour connaitre l'état de quelques I/O, réponses de l'état des I/O par ce dernier et si possible avec de l'acquittement à chaque fois (en soit ce n'est pas compliquer pour l'acquitement, puisqu'il suffit de "voir" si on recoit qqch et de dire "j'ai eu qqch")
Y a bien l'idée un peu "sale" d'ouvrir /dev/tty0 et d'écrire dedans mais peut-être pas le plus malin?
Quelqu'un aurait une idée??? j'ai beau chercher sur le net, je ne trouve pas. (je ne cherche sans doute pas convenablement)
Aspire 5633 WLMi - Lucid Lynx 10.04 en 64 bits
Hors ligne
#2 Le 30/09/2008, à 10:23
- claudius01
Re : communication sérielle, en ansi C ??
Bonjour,
cf. http://www.cppfrance.com/codes/LIAISON-SERIE-RS-232_47035.aspx
Quant au /dev/tty0 cf. http://doc.ubuntu-fr.org/console_serie
Cordialement, A+
--
Claudius
Hors ligne
#3 Le 30/09/2008, à 10:43
- Efhache84
Re : communication sérielle, en ansi C ??
entre temps j'ai pu me dépatouiller avec ça... (pour l'instant je tente juste de retrouver un message qe je m'envoit)
int OpenSerialPort (char* PortNumber);
int WriteSerialPort(char* SerialPOut);
int ReadSerialPort(char* SerialPReponse, int Chmax);
void CloseSerialPort();
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include "serialport.h"
static int spfd = 0;
// Ouverture port série : si spfd >0 le port est ouvert, -1 signale une erreur
int OpenSerialPort(char* PortNumber)
{
char PortName[64];
sprintf(PortName, "/dev/ttyUSB0"); // %s", PortNumber);
printf("Open Port=%s\n", PortName);
// S'assurer que le port était précédement clos
CloseSerialPort(spfd);
spfd = open(PortName, O_RDWR | O_NOCTTY | O_NDELAY);
if (spfd < 0)
{
printf("erreur à l'ouverture %d %s\n", errno, strerror(errno));
}
else
{
printf("tout ok"); //ok jusqu'ici
}
return spfd; //renvoit résultat tentative ouverture
}
// Ecriture sur port série : iout renvoit le nombre de caractère écrit, si -1 alors erreur
int WriteSerialPort(char* SerialPOut)
{
int iOut;
if (spfd < 1)
{
printf(" Port série non ouvert\n");
return -1;
}
iOut = write(spfd, SerialPOut, strlen(SerialPOut));
if (iOut < 0)
{
printf("Erreur écriture %d %s\n", errno, strerror(errno));
}
else
{
printf("%d caractères ont été écrit: %s\n", iOut, SerialPOut);
}
return iOut; //renvoit le résultat de l'écriture
}
//Lecture Port série : si -1 lecture échouée, sinon nombre de caractère lu
int ReadSerialPort(char* SerialPReponse, int Chmax)
{
int iIn;
//printf("in ReadAdrPort Chmax=%d\n", Chmax);
if (spfd < 1)
{
printf(" Port série non ouvert\n");
return -1;
}
strncpy (SerialPReponse, "N/A", Chmax<4?Chmax:4);
iIn = read(spfd, SerialPReponse, Chmax-1);
if (iIn < 0)
{
if (errno == EAGAIN)
{
return 0; // assume that command generated no response
}
else
{
printf("Erreur de lecture %d %s\n", errno, strerror(errno));
}
}
else
{
SerialPReponse[iIn<Chmax?iIn:Chmax] = '\0';
printf("%d carcatères ont été lu: %s\n", iIn, SerialPReponse);
}
return iIn;
}
// Fermeture port série
void CloseSerialPort()
{
// Eventuellement on pourrait remettre l'état initial du port série
if (spfd > 0)
{
close(spfd);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "serialport.h"
int main(int argc, char *argv[])
{
argc=2;
char sCmd[254];
char sResult[254];
// int i;
if (argc < 2 || argc > 2)
{
printf("serialport necessite en argument le numéro de port\n");
printf(" par exemplle, tappez 0 pour utiliser /dev/tty0\n");
return 0;
}
printf("Tappez Q pour quitter.\n\n");
if (OpenSerialPort(argv[1]) < 0) return 0;
while (1)
{
int iSpot;
printf("message?:");
gets(sCmd);
if (sCmd[0] == 'q' || sCmd[0] == 'Q') return 0; //on vérifie si on quitte
iSpot = strlen(sCmd);
sCmd[iSpot] = 0x0d; // retour chariot après la commande
sCmd[iSpot+1] = 0x00; // envoit d'un fin de chaine
if (WriteSerialPort(sCmd) < 0) return 0;
sleep(1); // temps d'attente pour une réponse
if (ReadSerialPort(sResult,254) > 0)
{
printf("La reponse fut: %s\n", sResult);
}
}
CloseSerialPort();
}
Surement plus propre, sûrement moyen de faire mieux mais bon...
Mais reste un soucis, le message que j'ai en retour (avec un loopback) est celui que j'ai envoyé il y a une plombe... même un sleep de 10 sec n'est pas suffisant.
Dois-je faire un flush? ou alors modifier la vitesse de transmission de mon port série dans ma buntu??
Aspire 5633 WLMi - Lucid Lynx 10.04 en 64 bits
Hors ligne
#4 Le 30/09/2008, à 17:46
- qqun
Re : communication sérielle, en ansi C ??
salut ,
regardes ici tu trouveras peut etre qqchose .
http://tldp.org/HOWTO/Serial-Programming-HOWTO/index.html
http://www.easysw.com/~mike/serial/serial.html