No One wrote:
-The application shall run under Neutrino 6.3 with a Photon GUI.
-The application shall control some machinery.
- I’ve planned to split the application in two: A user interface task and a
task controlling the machine.
- The user interface task shall send setup information and start/stop
commands to the control task.
- When running the machine, the control task can’t afford to stop and wait
for information from the user interface task, i.e. blocking is undesirable.
- If for example the user interface task dies, the control task must detect
this and close down the machine in an orderly fashion.
There are several interprocess communication options in Neutrino. Which will
be the best in this situation?
We had exactly this problem for our DARPA Grand Challenge vehicle,
and message passing solved the problem nicely.
You want to cycle the control loop with a 20ms cycle, which is
no problem.
I’d suggest something like this:
Machine control task
Create a message channel with name_attach and attach to it.
loop
TimerTimeout for time of next scheduled hardware action
(use CLOCK_MONOTONIC, so if somebody sets the clock,
the timing won’t be messed up, and TIMER_ABSTIME, so
it’s 20ms from the last cycle, not 20ms of waiting)
MsgReceive to get info from GUI program
if (timeout)
do hardware interaction
add 20ms to time for next hardware action
else
handle request from GUI program
do MsgReply to reply. (note that this does not block)
end loop
User interface task
Connect to the channel with connect_attach.
Whenever you need to talk to the machine control task, use
MsgSend, and don’t worry about the timing.
Notes:
The machine control task should run at a reasonable real-time
priority, like 14 or so. Note that if it goes into a compute
loop, the machine will hang. Also note that if you take
more than 20ms to process a cycle in the machine control
task, the next cycle will start immediately, with no
delay. So check for time overruns.
This should consistently service the hardware every 20ms,
regardless of what’s going on at lower priorities.
The GUI task doesn’t need to run at a high priority.
Note that if the GUI program isn’t running, the machine
control task will happily go on doing whatever it is doing.
If your emergency stop function is via the GUI, you need
something where you send a message from the GUI to the
machine control task periodically, and the interface task
checks for this watchdog message.
QNX is beautiful for this sort of thing, but the lack of good
third-party documentation makes it hard for new users to use
it effectively.
John Nagle