I'm having one of those mental-block moments in trying to implement what should be a fairly simple routine, for serial IO.
The situation is that we have an embedded linux board (think Pi / Beagle) which communicates with another device on the UART using the standard Linux termios code.
The problem is we have two clashing requirements:
In the transmit direction, we want to block on the Linux messaging queue msgrcv() function until a message arrives for us to send.
In the receive direction, we need to wait/block for an incoming message (which can have a termination character for canonical mode operation).
Tx and Rx are asynchronous and not related to each other - either could want to happen at any time.
Polling would be a pain as it introduces an overhead in CPU cycles and delay in response.
One approach would be to split this into two threads, one handling the Tx and blocking on msgrcv(), and the other on the Rx and blocking on UART read() in canonical mode - but that would introduce the pain of setting up semaphores between the Tx & Rx processes and both having to repeatedly open & close the serial port, and the Rx thread would presumably end up having to poll the semaphore in case the Tx wanted control, putting us back to polling.
I would stress that I'm relatively new to all this Linux stuff, so am entirely ready to be shown the bleeding obvious solution/method/call/operation that I'm missing here.
Is there some way to be blocking on the UART Rx but still able to transmit on demand?
In the end I followed Martin James' suggestion, doing something like this:
fd = open(serial_port);
pthread_create(TxThread, fd);
pthread_create(RxThread, fd);
Linux seems entirely happy with this, both threads do their jobs with no problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With