blocking read is not blocking

This commit is contained in:
tth 2018-12-20 11:57:23 +01:00
parent 8a34fed6af
commit bb10042aae
6 changed files with 115 additions and 26 deletions

View File

@ -12,6 +12,11 @@ Pour en savoir plus sur ce passionnant projet, il y a le canal IRC
`#tetalab` sur le réseau Freenode et/ou les rencontres du mercredi `#tetalab` sur le réseau Freenode et/ou les rencontres du mercredi
soir au DD2, à Mixart-Myrys. soir au DD2, à Mixart-Myrys.
# WTF status
Le `read` bloquant ne bloque pas. Ça craint grave.

View File

@ -22,6 +22,12 @@ par le professeur Cispeo.
Un petit exemple ? Un petit exemple ?
Oui, voilà. À ce jour (20 déc. 2018), on va dire que ça ne marche pas.
Il faut dire que les `serial devices` ont toujours étés un peu le
domaine de la magie noire. Mais quand même, coincer sur un `read` qui
ne bloque pas, c'est un peu ironique.

View File

@ -1,7 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <sys/select.h> #include <sys/select.h>
#include <string.h>
#include <unistd.h> //Used for UART #include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART #include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART #include <termios.h> //Used for UART
@ -60,13 +62,15 @@ fprintf(stderr, "%s ( %s %d )\n", __func__, port, baudrate);
// shall not cause the terminal device to become the controlling terminal // shall not cause the terminal device to become the controlling terminal
// for the process. // for the process.
uart0 = open(port, O_RDWR | O_NOCTTY); uart0 = open(port, O_RDONLY | O_NOCTTY);
if (uart0== -1) if (uart0 < 0)
{ {
perror("unable to open uart "); perror("unable to open uart ");
return -1; return -1;
} }
return uart0; /* WTF ??? */
// CONFIGURE THE UART // CONFIGURE THE UART
// The flags defined in /usr/include/termios.h - // The flags defined in /usr/include/termios.h -
// see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html // see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html
@ -87,6 +91,9 @@ baudbits = baudrate2const(baudrate);
#if DEBUG_LEVEL #if DEBUG_LEVEL
fprintf(stderr, "%d -> 0x%04x\n", baudrate, baudbits); fprintf(stderr, "%d -> 0x%04x\n", baudrate, baudbits);
#endif #endif
memset(&options, 0, sizeof(options));
tcgetattr(uart0, &options); tcgetattr(uart0, &options);
options.c_cflag = baudbits | CS8 | CLOCAL | CREAD; //<Set baud rate options.c_cflag = baudbits | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag = IGNPAR; options.c_iflag = IGNPAR;
@ -100,16 +107,20 @@ return uart0;
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* /*
* this function have NO timeout ! * this function have NO timeout !
* blocking read is not blocking, wtf ?
*/ */
int getbyte(int fd) int getbyte(int fd)
{ {
unsigned char byte; unsigned char byte;
int foo; int foo;
byte = 0;
foo = read(fd, &byte, 1); foo = read(fd, &byte, 1);
if (1 != foo) if (1 != foo)
{ {
perror("read a byte"); fprintf(stderr, "byte %d rd %d errno %d\n",
byte, foo, errno);
return -1; return -1;
} }
return (int)byte; return (int)byte;
@ -126,9 +137,8 @@ int retval;
timeout.tv_sec = to_ms / 1000; timeout.tv_sec = to_ms / 1000;
timeout.tv_usec = (to_ms % 1000) * 1000; timeout.tv_usec = (to_ms % 1000) * 1000;
#if DEBUG_LEVEL #if DEBUG_LEVEL
fprintf(stderr, "timeout %6d is %4ld %6ld\n", to_ms, fprintf(stderr, "timeout %6d is %4ld.%6ld\n", to_ms,
timeout.tv_sec, timeout.tv_usec); timeout.tv_sec, timeout.tv_usec);
#endif #endif
@ -136,38 +146,37 @@ FD_ZERO (&rfds);
FD_SET (fd, &rfds); FD_SET (fd, &rfds);
retval = select(1, &rfds, NULL, NULL, &timeout); retval = select(1, &rfds, NULL, NULL, &timeout);
#if DEBUG_LEVEL #if DEBUG_LEVEL
fprintf(stderr, "%s : select -> %d\n", __func__, retval); fprintf(stderr, "%s : select -> %d\n", __func__, retval);
#endif #endif
retval = retval < 0 ? -1 : retval;
switch (retval) { switch (retval) {
case -1: case -1:
fprintf(stderr, "omg ?\n"); fprintf(stderr, "omg ?\n");
byte = -1; retval = -1;
break; break;
case 0: case 0:
fprintf(stderr, "timeout\n"); fprintf(stderr, "timeout\n");
byte = -99; retval = -99;
break; break;
default: default:
fprintf(stderr, "%s default -> %d\n", __func__, retval);
if (retval==fd) { if (retval==fd) {
read(fd, &byte, 1); read(fd, &byte, 1);
fprintf(stderr, "got 0x%02x\n", byte); fprintf(stderr, "got 0x%02x\n", byte);
retval = byte;
} }
else { else {
fprintf(stderr, "%d bad fd ?\n", retval); fprintf(stderr, "%d bad fd ?\n", retval);
byte = -3; retval = -3;
} }
break; break;
} }
return byte; return retval;
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* timeout is in milliseconds */ /* timeout is in milliseconds */
@ -195,15 +204,21 @@ for(;;) {
retval = curpos; retval = curpos;
} }
if (curpos < szm) { /* ya de la place */
where[curpos] = byte;
curpos++;
}
else { /* oups overflow */
retval = -6;
break;
}
} }
fprintf(stderr, "%s -> '%s'\n", __func__, where); fprintf(stderr, "%s -> '%s'\n", __func__, where);
return -666; return retval;
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */

View File

@ -6,7 +6,7 @@
int prepare_UART(char *port, int bauds); int prepare_UART(char *port, int bauds);
int getbyte(int fd); int getbyte(int fd); /* really brotched func */
/* timeout is exprimed in milliseconds. */ /* timeout is exprimed in milliseconds. */

View File

@ -1,28 +1,36 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <time.h> #include <time.h>
#include "serial.h" #include "serial.h"
int verbosity;
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int serial_in; int serial_in;
int byte, foo, to; int byte;
serial_in = prepare_UART("/dev/ttyS0", 9600); serial_in = prepare_UART("/dev/ttyACM0", 9600);
fprintf(stderr, "prepare uart -> %d\n", serial_in); fprintf(stderr, "prepare uart -> %d\n", serial_in);
for (foo=0; foo<20; foo++) { if (serial_in < 0) {
to = (foo+1) * 666; exit(1);
byte = getbyte_to(serial_in, to); }
for (;;) {
byte = getbyte(serial_in);
if (byte < 0) { if (byte < 0) {
fprintf(stderr, "get byte : err is %d\n", byte); fprintf(stderr, "get byte : err is %d\n", byte);
} }
// XXX else { else {
printf("%9ld %6d %6d %02x\n", printf("%9ld %02x/%d\n",
time(NULL), foo, to, byte); time(NULL), byte, byte);
// XXX } }
} }
return 0; return 0;

View File

@ -0,0 +1,55 @@
/*
* simulateur de telemesure automate
*/
/* -------------------------------------------------- */
#define NBVAL 4
int values[NBVAL];
/* -------------------------------------------------- */
void setup() {
int foo;
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
for (foo=0; foo<NBVAL; foo++) {
values[foo] = 0;
}
}
/* -------------------------------------------------- */
void updatevalues(void)
{
int foo;
for (foo=0; foo<NBVAL; foo++) {
if (rand()%100<33) {
values[foo] += (foo + 1);
}
if (values[foo] > 1023) {
values[foo] = rand()%15;
}
}
}
/* -------------------------------------------------- */
void sendvalues(void)
{
int foo;
Serial.print("X ");
for (foo=0; foo<NBVAL; foo++) {
Serial.print(" ");
Serial.print(values[foo]);
}
Serial.print("\n");
}
/* -------------------------------------------------- */
void loop() {
updatevalues();
sendvalues();
delay(5000);
}
/* -------------------------------------------------- */