I'm not sure what you mean by "connections" with respect a serial port. A serial port just receives and transmits raw bytes. This is a point to point connection between two machines. The concept of "connections" as in a TCP/IP socket does not exist.
Anyway my work with serial pots also use tokio-serial. I have separate tokio tasks for receiving and sending on a serial port. The magic here is tokio::io::split()
which returns a reader and a writer 'handle' for a single serial port. I can then pass those reader and writer 'handles' to whatever functions/tasks I like.
My serial port handling code then starts out like this:
let mut settings = tokio_serial::SerialPortSettings::default();
settings.baud_rate = 115200;
let port = tokio_serial::Serial::from_path(&tty_path, &settings)?;
// Make separate serial port reader and writer streams.
let (serial_reader, serial_writer) = tokio::io::split(port);
let serial_reader = Arc::new(Mutex::new(serial_reader));
let serial_writer = Arc::new(Mutex::new(serial_writer));
You may or may not need to wrap them in Arc
like that. I do because I am about to pass them to other tokio-tasks.
Then I start a serial listener task passing it the serial reader handle
like so:
// Run the threads!
tokio::select! {
_ = serial_reader_task(serial_reader.clone(), clients.clone(), nc.clone()) => {
Err(Box::new(Ser2NetError::ThreadFailure{code:51}))
}
// Other threads here.
}
The serial writer handle is passed to other tasks that will wait on other things and write to the serial port. I use select! here because all my tasks are expected to run forever. The select! catches any task failure and exits the whole program.
My serial reader task is then an loop that runs forever and looks like this:
fn serial_reader_task(
serial_reader: SerialReader,
// Other params...
) -> tokio::task::JoinHandle<Result<(), MyError>> {
tokio::spawn(async move {
loop {
let buf: &mut [u8] = &mut [0; 1024];
let mut serial_reader = serial_reader.lock().await;
let n = match serial_reader.read(buf).await {
Ok(n) => n,
Err(e) => {
println!("Error reading serial port {:?}", e);
break;
}
};
// println!("Serial got: {:?}", &buf[0..n]);
// Do something with serial bytes.
}
})
}