serial port - Lectura del puerto serie con Boost Asio
serial-port boost-asio (2)
Encontré este artículo realmente útil para comprender mejor cómo ASIO se puede usar de manera asincrónica con los puertos seriales: http://www.webalice.it/fede.tft/serial_port/serial_port.html
Quiero verificar los paquetes de datos entrantes en el puerto serial, usando boost.asio
. Cada paquete de datos comenzará con un encabezado de un byte largo y especificará qué tipo de mensaje se envió. Cada tipo diferente de mensaje tiene su propia longitud. La función que quiero escribir debe escuchar continuamente nuevos mensajes entrantes, y cuando encuentra uno debe leerlo y llamar a alguna otra función para analizarlo. Mi código actual es el siguiente:
void check_for_incoming_messages()
{
boost::asio::streambuf response;
boost::system::error_code error;
std::string s1, s2;
if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
s1 = streambuf_to_string(response);
int msg_code = s1[0];
if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
// Handle error, invalid message header
}
if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
s2 = streambuf_to_string(response);
// Handle the content of s1 and s2
}
else if (error != boost::asio::error::eof) {
throw boost::system::system_error(error);
}
}
else if (error != boost::asio::error::eof) {
throw boost::system::system_error(error);
}
}
¿ boost::asio::streambuf
la herramienta adecuada para usar? ¿Y cómo extraigo los datos para poder analizar el mensaje? También quiero saber si necesito tener un hilo separado que solo llame a esta función, para que se llame más a menudo. ¿Debo preocuparme por la pérdida de datos entre dos llamadas a la función debido al alto tráfico y al agotamiento del búfer del puerto serie? Estoy usando las bibliotecas de Qt para la GUI y realmente no sé cuánto tiempo lleva procesar todos los eventos.
Editar: La pregunta interesante es: ¿cómo puedo verificar si hay datos entrantes en el puerto serie? Si no hay datos entrantes, no quiero que la función bloquee ...
Jason,
Si es adecuado para su aplicación, le recomiendo implementar un RX serial asíncrono basado en devolución de llamada. ¿Cómo realizo una lectura sin bloqueo usando asio? tiene un gran pequeño ejemplo de cómo implementar serial asynch con un tiempo de espera. Como reconoció, se requerirá una implementación de subprocesos múltiples para obtener las ventajas de rendimiento, por lo que deberá reflexionar sobre dónde almacenará temporalmente los datos recibidos para asegurarse de que no está realizando una gran cantidad de copias.
En cuanto a las cosas de boost::streambuff
, personalmente prefiero simplemente bloquear algo de memoria como una matriz de caracteres: char m_RXBuffer[m_RXBuffSize]
y uso boost::asio::buffer(m_RXBuffer, m_RXBuffSize)
para pasar el buffer de destino a async_read_some
. En particular, para RS232, siempre he encontrado que el hecho de que los datos subyacentes sean una secuencia de bytes, naturalmente, se mapea mucho mejor en una matriz de caracteres simple que cualquiera de las estructuras de datos más complejas.
¡Buena suerte!