ver usuario una todos tiene recursivo propietario permisos para los log dar comando carpeta cambiar archivos archivo c linux serial-port

c - usuario - permisos linux 777



La lectura en serie de Linux arroja un error (3)

Estoy intentando leer desde mi puerto serie usando el siguiente código C. Puedo escribir con éxito en una computadora que escucha (¡pero!) Pero el error de lectura arroja un error (Código 11 - Recurso temporalmente no disponible). También he notado que mis mensajes / registros de dmesg no tienen información sobre fallas, etc. Así que eso es bueno.

//A bunch of INCLUDES exist here....the the code int fd=0; int status=0; int running=1; char buffer[100]; char message[7]; void main(){ fd = 1; fd=open("/dev/ttyM0",O_RDWR | O_NOCTTY); if(fd == -1) { perror("open_port: Unable to open /dev/ttys0"); } else { while(running<20) { sprintf(message,"Test%d/r",running); status=write(fd,message,6); if(status<0) { printf("Error Writing. Status=%d/n %s/n",errno, strerror(errno)); } status=read(fd,buffer,8); //This throws an error(11). My connected device is writing "Testing/r" if(status<0) { printf("Error Reading. Status=%d /n%s/n",errno, strerror(errno)); //close(fd); running=running+1; } else { printf("%s/n/r",buffer); } sleep(2); } close(fd); } } //END MAIN

Estas son mis configuraciones de serie para mi puerto. Estoy intentando leer / escribir a 9600 8bit, sin paridad, 1 bit de parada. Creo que mi configuración es correcta.

sudo stty -a -F /dev/ttyM0 speed 9600 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^/; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Cualquier ayuda sería muy apreciada. ¡Gracias!


Con O_NDELAY desaparecido, el programa se queda ahí esperando la entrada

Parece que termios está configurado para entrada canónica (basado en el icanon en la salida stty ). En el modo canónico (también conocido como cocinado), los caracteres recibidos desde el puerto serie se procesan antes de estar disponibles para el programa de usuario utilizando read () .

Según la página man de Linux:

En modo canónico:

  • La entrada está disponible línea por línea. Una línea de entrada está disponible cuando se escribe uno de los delimitadores de línea (NL, EOL, EOL2 o EOF al comienzo de la línea). Excepto en el caso de EOF, el delimitador de línea se incluye en el almacenamiento intermedio devuelto por read (2).

Su termios también tiene icrnl set, lo que significa que un retorno de carro se traduce a nueva línea en la entrada (a menos que se establezca igncr , que no es así porque tiene un guión precedente). Tanto eol como eol2 no están definidos (que son los valores predeterminados).

Por lo tanto, para su configuración, un final de línea se define como una línea nueva o un retorno de carro (o cntl-D al inicio de la línea). Verifique que su dispositivo remoto realmente está enviando un carácter de control CR o LF para terminar la línea. Su comentario en el código indica que no lo está (es decir, "/ r" no es un retorno de carro).

Para utilizar correctamente el texto devuelto por read () como una cadena, establezca la solicitud para uno menor que el tamaño de búfer asignado (para garantizar el espacio para agregar un terminador nulo). Luego, después de una buena devolución, use el recuento de bytes devueltos como índice para almacenar el terminador de cadena.

status = read(fd, buffer, sizeof(buffer) - 1); if (status < 0) { /* handle error condition */ } else { buffer[status] = ''/0''; printf("%s/n/r", buffer); }


Está utilizando la opción O_NDELAY en su llamada open . Esto hace que el descriptor de archivo no sea bloqueante . Esto significa que si haces una read y no hay datos disponibles, la llamada de read devolverá EAGAIN que es el error que estás viendo.

Por el momento, puedes eliminar el O_NDELAY de open . En el futuro, probablemente debas volver a bloquearlo y usar select o poll para determinar cuándo puedes leer.


Usted tiene un desbordamiento de búfer aquí:

sprintf(message,"Test%d/r",running);

ya que el message se declara como:

char message[6];

message debe tener al menos 7 caracteres de tamaño si va a contener una cadena de 6 caracteres, debido a la necesidad de un terminador ''/0'' .

También puede haber otros problemas, pero debe arreglar esto y ver si hace alguna diferencia.