Il faut gerer les time-out sur les lectures et ecritures, mais sinon lecture et ecriture sont en gras dans le texte,
ceci n'est pas un exemple mais une appli fonctionnelle
quelque chose comme çà pour l'ecriture
/***********************************
envoi de la question a l'API
retourne -1 si defaut
************************************/
int comm_send_mbus(int port ,char *question, int size_q )
{
int i = 0 ;
fd_set wfds;
struct timeval tv;
int retval;
/* Set the non-blocking write */
fcntl(port, F_SETFL, fcntl(port,F_GETFL)|O_NONBLOCK); */
i = write(port,question,size_q);
tv.tv_sec = timeout_s;
tv.tv_usec = timeout_usec;
/* check write end */
FD_SET(port, &wfds);
retval = select(port+1, NULL, &wfds, NULL, &tv);
if (retval <= 0) {
if DEBUG2 fprintf(stderr,"SOCK_SEND_MBUSerious Time-out en ecriture d'écriture, comm non-disponible\n");
tcflush(port, TCIOFLUSH );
return retval;
}
/* Set the blocking write */
fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK);
return i;
}
et pour la lecture
/***********************************
lecture de la reponse de l'API
retourne le nombre de caractere lus
************************************/
int comm_recv_mbus(int port, char *reponse, int size_r)
{
int i=0;
int j=0;
long k=0;
int on = 1;
int off = 0;
int car;
fd_set rfds;
struct timeval tv;
int retval;
if (size_r >= 261 ) {
if DEBUG1 fprintf(stderr,"SRV_API:comm_recv_mbuserious Panique trop d'éléménts à lire\n");
return -3;
}
/* Set the non-blocking read */
fcntl(port, F_SETFL, fcntl(port,F_GETFL)|O_NONBLOCK);
/* Wait up to few seconds. */
tv.tv_sec = timeout_s;
tv.tv_usec = timeout_usec;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(port, &rfds);
while ( i < size_r ) {
retval = select(port+1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if ( retval > 0 )
{
/* FD_ISSET(0, &rfds) will be true. */
if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info données disponibles depuis API%d .\n",retval);
j = read(port,reponse+i,size_r-i);
if ( j > 0 ) {
if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info nb caractere a lire 0x%02x lu 0x%02x total 0x%02x\n",size_r-i,j,i+j);
if DEBUG2 {
for ( k = 0; k<j;k++)
fprintf(stderr,"SRV-API:comm_recv_mbus:Info i=%02x caractere %02x\n",i+k,reponse[i+k]);
}
tv.tv_sec = timeout_s;
tv.tv_usec = timeout_usec;
i += j;
} else {
fprintf(stderr,"errno %d\n",errno);
perror("read");
if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info nb caractere a lire 0x%02x lu 0x%02x total 0x%02x\n",size_r-i,j,i+j);
}
} else {
if DEBUG1 fprintf(stderr,"SRV-API:comm_recv_mbuserious Pas de reponse de l'esclave MODBUS\n");
/* Set the blocking read */
fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK);
return -2;
}
}
/* Set the blocking read */
fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK);
return i;
}
les fonctions seront appelées comme suit
/* ouverture du port*/
if( !(port_serie=comm_init(port_serie)) )
{
fprintf(stderr,"SRV-APIanique: ouverture port impossible\n");
return (-1);
}
/* envoi de la demande à l'API*/
if ( comm_send_mbus(port_serie ,question, psize_q ) == -1 )
{
fprintf(stderr,"SRV-APIanique: erreur d'ecriture vers l'API\n");
comm_close(port_serie);
return (-1);
}
/* lecture normale du port API */
if ( comm_recv_mbus(port_serie ,reponse, psize_r ) <= 0 ) {
fprintf(stderr,"SRV-APIanique: pas de reponse de l'API\n");
comm_close(port_serie);
return (-1);
}
/* fermeture port et liberation verrou */
comm_close(port_serie);