Paradigm or best practice advice - Devices
My current project in Qt will be to build software to control a custom instrument. Thus far our work has been diagnostic in nature so I've built classes and objects to talk to the various devices that make up the instrument and I've addressed them mainly from a diagnostic UI. This approach has allowed me to debug the I/O and provide diagnostic functionality to the ME and Elec engineers on the project.
My next phase is to begin to transform my work into something that can run the instrument and do what the instrument is designed to do. This will be a run based instrument where a user will load some material, then press start. The software needs to do some preliminary work but then it must setup and schedule some long processing.
I'm not at liberty to reveal exact details so I'm just looking for some general ideas on the best way to proceed.
The instrument has some devices that are communicated with over RS-232. There is also a very large component of the instrument that communicates over a custom USB 2.0 interface.
My problem is this... The instrument has two identical sections that can be doing stuff at the same time or perhaps 1/2 is working while the other is idle then that other 1/2 might be started. I have a great deal of experience with process scheduling so that is the least of my concern. My concern is about what I'm beginning to call "the USB funnel".
A very large amount of my instrument commands must all funnel through this single USB interface. While it is fast, each thing to do be done requires at least one packet to transfer and when reading data it is a two way packet scheme so a request is sent, and a response received.
I'm trying to think about how I want to control/share this primary USB interface.
In general I picture the app in the following blocks:
GUI/UI - Primary event loop
Scheduler thread - This would run to create a list of things to do for processing.
Execution thread - This would take what comes out of scheduler and execute the steps.
Since the instrument has two sort of independent halves it is the execution thread I am thinking about.
Would it be best to have this instead:
Execution thread for first half
Execution thread for second half
Mutex protected IO to instrument
In this scheme the two execution threads could try and execute things at the same time and the USB funnel would be mutex protected to handle that. My concern with this approach is how to minimize the collisions. I know the mutex prevents but I don't want to spend a bunch of time waiting on mutexs.
Execute thread (handles both sides of instrument)
This scheme would pretty much ensure that only one request could be made to the instrument at a time since only one thread would ever be accessing it.
The third approach I've considered is what I might call a priority queue. This would be a thread around the instrument interface itself. To make a call to the instrument you'd create an object that contained your request data and a time you need it executed. You'd submit this object to a queue on the instrument thread. The instrument thread figures out based on the timing provided the best place to insert this task and then it works to execute the tasks in the best order.
This is a scheme I use in a very old program I have and it works quite well but the interactions can be messy in getting things to set their queue objects up correctly.
Anyway I realize that without more detailed info all of you cannot hope to suggest the best alternative. I'm really looking more for ideas and perhaps cases of "I did it this way and it was great or not...".
So in summary, I have an instrument. I have to talk to the various devices on this instrument through RS-232 and mostly over a single USB interface.
I have two roughly identical halves of the instrument both that need to appear to the user as separate things that can start, run, end independently. Both of these need to talk through this single USB interface.
My request is for some ideas on the best way to manage such a thing based on others experience.
Thanks to anyone for taking the time to reply!