user1275932
user1275932

Reputation: 58

simultanious read/write on the same serial port

I am building an application that intersepts a serial comunication line by recieving the transmition, modifieng the data, and echoing the changed result.

The transmitted data is made of status sentances at high baudrate with alot of data.

I have created two threads, one reads the sentaces and pushes a pointer to each new sentance into a queue, and the Other pops the pointers out of the queue, manipulates them, sends them to the serial port and deletes the pointer.

The queue operstions are in external functions with CririticalSection locks so that works fine.

To make sure the queue doesnt overflow quickly i need to send the messages quickly and not wait for the recieving to end.

To my understanding serial ports can recieve and transmit simultaniously but trying to do so gives error with access resttictions.

The other solution is to split the system into two diffrent ports but I try to avoid it because the hardware changes and the need of another USB and convertor.

I read about Overlapped structures but didnt fully understood what is their usage and, as I got it they manage asinc operation where my issue is parallel operation.

Sorry for my lame english, any help or explanation will help.

I used this class for the serial comunication, setting overlapped to enable when opening the comport to allow wait event timeouts:

http://www.codeproject.com/Articles/992/Serial-library-for-C

Thanks in advance.

Roman.

Clarification: Im not opening the port twice, just once in the main program and pass the handler to both threads (writing it now maximizes the problem in this approach

More details:

The error comes from the Cserial library: "Cserial::read overlapped complete without result." Commenting the send back to serial command in the sending thread will not raise an error and the queue is filled and displays correctly–

Im on a classified system without internet access so i cant upload the sample, writing from my tablet. The error accures after I get the first sentace, which triggers the first send command ss soon as queues size changes, and then the recieving thread exits because recieve failes, so the queue stops to fill and nothing sends out.

Probbly because both use same serial handler but whats the alternative to access the same port simultaniosly without locking one thread or the other

Ignoring error 996, which is the error id of the "read overlapped completed without results" and not exiting the thread when its detected makes both recieve an transmited data wrong (missing bytes)

At the buttom line, after asking alot of questions:

Why a read operation is interrupted by a write operation if these are two seperate comunication lines?can i use two handlers one for each task on the same port?

Is the D+/- in usb is transmit/recieve or both line used for transmit and recieve?

Upvotes: 1

Views: 8924

Answers (2)

ravenspoint
ravenspoint

Reputation: 20492

":read overlapped complete without result"

Are you preventing the read from being interrupted by the OS switching execution to the write thread? You need to protect this from happening by using a mutex or similar.

The real solution is to switch to an asynchronous library, such as bosst::asio.

Why a read operation is interrupted by a write operation if these are two seperate comunication lines?

here is a possible hand-waving visualization of what happens if you use synchronous operations in two threads without locking them against each other. ( I am guessing at the details of how you arranged your software )

  • Your app receives a read request from the port.
  • Your app requests the OS to start the read thread.
  • OS agrees, and your read thread completes the read. -. Your app does its processing.
  • Your app asks the OS to start the write thread.
  • The OS agrees, and your write thread starts a write.
  • A second read request arrives on the port. This does not interrupt anything, it just waits.
  • The write is not yet finished, but the OS decides that the write thread has had enough time. It decides to switch context to the read thread which is waiting.
  • The read thread starts reading
  • Again the OS decides that the running thread ( read ) has had a fair crack at the CPU . It switches context back to the write thread. This crashes the unfinished read. Note that this happens in your software, not in the hardware, or the hardware driver.

This should give you a general insight into the sort of problems that occur, unless you keep the OS from running the reads and writes over the top of each other. It is a matter of opinion wehter it is better to use multithreading with mutexes ( or equivalent ) or asynchronous event-driven designs.

Upvotes: 1

Lukasz
Lukasz

Reputation: 196

Two threads can't operate on single port / file descriptior. Depending on what library you used you should try to do this asynchronous or by checking how many bytes can be read/write without blocking thread. (if it is Linux raw filedescriptor you should look at poll / select)

Upvotes: 0

Related Questions