serial port - serialport - Restaure los atributos del puerto serie incluso después del control-C?
listar puertos com c# (1)
Después de más investigaciones, creo que he respondido esto a mi satisfacción.
En primer lugar, en la página de manual de señal noté que un manejador de señal está específicamente autorizado a llamar a tcsetattr()
, junto con algunos otros:
La rutina del manejador de señal debe ser muy cuidadosa, ya que el procesamiento en otro lugar fue interrumpido en algún punto arbitrario. POSIX tiene el concepto de "función segura". Si una señal interrumpe una función insegura y el manejador llama a una función insegura, entonces el comportamiento no está definido. Las funciones seguras se enumeran explícitamente en los diversos estándares. La lista POSIX.1-2003 es ... `raise ()` ... `signal ()` ... `tcsetattr ()` [recortado a los relevantes]
Esto sugiere fuertemente que el comité POSIX tenía este tipo exacto de cosas en mente, y conduce a un enfoque directo en el que usted cambia el manejador SIGINT
una vez que ha abierto el serial y guardado sus atributos, luego en su controlador, restaurelos y el viejo Manejador SIGINT
, luego vuelva a subir la señal:
static void (*prev_sigint)( int );
static termios saved_attr;
static int fd;
static void cleanup( int ignored )
{
tcsetattr( fd, TCSANOW, &saved_attr );
signal( SIGINT, prev_sigint );
raise( SIGINT );
}
int main( void )
{
open_serial_and_save_attrs();
prev_sigint = signal( SIGINT, cleanup );
...
}
Cuando se usa un puerto en serie a través de POSIX, se recomienda guardar los atributos originales usando tcgetattr()
antes de cambiarlos con tcsetattr()
, y luego restaurarlos antes de cerrar el puerto. ¿Qué pasa cuando un programa finaliza presionando Control-C o cuando el programa recibe SIGINT
? No he visto esto cubierto en ninguno de los tutoriales en serie.
Aparentemente, una función atexit()
no sería suficiente, porque el gestor de SIGINT
no la llama. Por lo tanto, parece que sería necesaria la instalación de un manejador de señal que restaure los atributos a cualquier puerto serial aún abierto. ¿Es seguro llamar a tcsetattr()
desde un controlador de señal?
Uno podría simplemente descartar este tema como insignificante, pero es común terminar un programa con control C, especialmente uno que puede tomar decenas de segundos para completar las operaciones. Si está bien no conservar las configuraciones del puerto serie en este caso, parece que hay pocas razones para preservarlas. En todo caso, sería mejor no molestarse, en lugar de hacerlo de manera inconsistente.
Encontré algunos ejemplos de código fuente haciendo lo anterior , pero nada bien documentado. Supongo que estoy interesado en una discusión sobre si esta es una buena idea. Gracias.