puddletag picard musicbrainz mp3tag kid3 linux serial-port blocking nonblocking

picard - Bloqueo de Linux vs. Lectura serial no bloqueada



musicbrainz picard (1)

El código que mencionas está IMO mal codificado y comentado. Ese código no cumple con las prácticas POSIX para la portabilidad, como se describe en Configuración de los modos de terminal correctamente y Guía de programación en serie para sistemas operativos POSIX . Ese código no menciona que usa el modo no canónico (también conocido como sin formato ) y reutiliza la terminología de "bloqueo" y "no bloqueo" para describir los atributos de VMIN y VTIME .

La definición convencional de una lectura de "bloqueo" frente a "no bloqueo" se basa en "cuándo" la llamada de lectura volverá a su programa (y reanudará la ejecución con la siguiente declaración) y si habrá datos almacenados en el búfer de lectura de su programa. Una lectura de bloqueo es el modo predeterminado, a menos que se solicite el no bloqueo abriendo el puerto serie con la opción O_NONBLOCK o O_NDELAY.

Modo canónico
Para una llamada de lectura canónica de bloqueo de un puerto serie, siempre se devolverá una línea (también conocida como registro) en el búfer proporcionado (a menos que se produzca un error). La llamada de lectura bloqueará (es decir, suspenderá la ejecución de su programa) durante el tiempo en que se reciba y procese un carácter de terminación de línea.

Una llamada de lectura canónica sin bloqueo de un puerto serie siempre devolverá "inmediatamente". La lectura puede o no devolver cualquier dato.
Si (desde la llamada de lectura anterior) al menos una línea de texto se ha recibido y almacenado en el búfer del sistema, la línea más antigua se eliminará del búfer del sistema y se copiará al búfer del programa. El código de retorno indicará la longitud de los datos.
Si (desde la llamada de lectura anterior) un carácter de terminación de línea no se ha recibido y procesado, entonces no hay una línea de texto (completa) disponible. La lectura () devolverá un error EAGAIN (es decir, un código de retorno -1 y errno establecido en EAGAIN). Su programa puede realizar algún cálculo o solicitar E / S de otro dispositivo, o demora / suspende. Después de una demora arbitraria o mediante notificación por sondeo () o select () , su programa puede volver a intentar leer () .

Modo no canónico
Cuando el puerto serie está configurado para el modo no canónico, los elementos de la matriz termios c_cc VMIN y VTIME deben usarse para controlar el "bloqueo", pero esto requiere que el puerto esté abierto en el modo de bloqueo predeterminado, es decir, no especifique el O_NONBLOCK abierto opción. De lo contrario, O_NONBLOCK tendrá prioridad sobre la especificación VMIN y VTIME, y read () establecerá errno en EAGAIN e inmediatamente devolverá -1 en lugar de 0 cuando no haya datos disponibles. (Este es el comportamiento observado en los últimos kernels 3.x de Linux; los kernels 2.6.x más antiguos pueden comportarse de manera diferente).

La página del manual de termios describe ( c_cc array index) VMIN como el "número mínimo de caracteres para la lectura no canónica" , y ( c_cc array index) VTIME como el "tiempo de espera en deciseconds para la lectura no canónica" .
El programa debe ajustar VMIN para adaptarse a la longitud típica del mensaje o datagrama que se espera y / o el tamaño mínimo para que los datos se recuperen y procesen por lectura () .
El programa VTIME debe ser ajustado por su programa para acomodar la ráfaga típica o la tasa de llegada de los datos en serie que se espera y / o el tiempo máximo para esperar los datos o un dato.

Los valores de VMIN y VTIME interactúan para determinar el criterio de cuándo debe leer la lectura; sus significados precisos dependen de cuál de ellos es distinto de cero. Hay cuatro casos posibles.
Esta página web lo explica como:

  • VMIN = 0 y VTIME = 0

    Esta es una lectura completamente sin bloqueo: la llamada se satisface inmediatamente directamente desde la cola de entrada del controlador. Si los datos están disponibles, se transfieren al búfer de la persona que llama hasta nbytes y se devuelven. De lo contrario, se devuelve inmediatamente cero para indicar "sin datos". Notaremos que esto es "sondeo" del puerto serial, y casi siempre es una mala idea. Si se hace repetidamente, puede consumir enormes cantidades de tiempo de procesador y es altamente ineficiente. No use este modo a menos que realmente sepa lo que está haciendo.

  • VMIN = 0 y VTIME> 0

    Esta es una lectura de tiempo puro. Si los datos están disponibles en la cola de entrada, se transfieren al búfer de la persona que llama hasta un máximo de nbytes y se devuelven inmediatamente a la persona que llama. De lo contrario, el controlador se bloquea hasta que llegan los datos, o cuando las décimas de VTIME caducan desde el inicio de la llamada. Si el temporizador caduca sin datos, se devuelve cero. Un solo byte es suficiente para satisfacer esta llamada de lectura, pero si hay más disponible en la cola de entrada, se devuelve al llamante. Tenga en cuenta que este es un temporizador general, no un interchacter.

  • VMIN> 0 y VTIME> 0

    Una lectura () se cumple cuando los caracteres VMIN se han transferido al búfer de la persona que llama, o cuando las décimas VTIME caducan entre los caracteres. Dado que este temporizador no se inicia hasta que llega el primer carácter, esta llamada puede bloquearse indefinidamente si la línea serie está inactiva. Este es el modo de operación más común, y consideramos que VTIME es un tiempo de espera entre caracteres, no uno general. Esta llamada nunca debe devolver cero bytes leídos.

(En mi experiencia, el modo VMIN>0 and VTIME>0 no funciona como se anuncia. El temporizador parece ser un intervalo muy corto, mucho menos que un 1/10 de segundo. No lo he visto funcionar en ARM con 2.6 y Linux 3.13 en x86. A una velocidad rápida (115200), con VMIN = 1 y VTIME = 1, un read () a veces devuelve 10 o más bytes. Pero más a menudo es solo una lectura parcial de unos pocos bytes, independientemente del valor VTIME. ¿Tal vez se prefiera / se desee este quebrantamiento? Una separación mínima de mensajes de 0,1 segundos es simplemente demasiado larga (y no práctica) en baudrates rápidos modernos).

  • VMIN> 0 y VTIME = 0

    Esta es una lectura contada que se cumple solo cuando al menos los caracteres VMIN se han transferido al búfer de la persona que llama, no hay ningún componente de tiempo involucrado. Esta lectura puede satisfacerse desde la cola de entrada del conductor (donde la llamada podría retornar de inmediato), o esperando que lleguen nuevos datos: a este respecto, la llamada podría bloquearse indefinidamente. Creemos que es un comportamiento indefinido si nbytes es menor que VMIN.

Ese código que usted menciona configura el modo "sin bloqueo" como VMIN = 0 y VTIME = 5. Esto no hará que el read () regrese inmediatamente como lo haría una lectura canónica sin bloqueo; con ese código, un read () siempre debe esperar al menos medio segundo antes de regresar. La definición convencional de "no bloqueo" es que su programa de llamada no se anula durante el syscall y obtiene el control (casi) de inmediato. Para obtener una devolución inmediata (incondicional y) (para una lectura no canónica), configure VMIN = 0 y VTIME = 0.

Tengo este código para leer desde Serial en Linux, pero no sé cuál es la diferencia entre bloquear y no bloquear en la lectura de Puerto Serial y cuál es mejor en qué situación.