Message passing advice wanted

Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application satisfying
these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

“No One” <no.one@home.yet> wrote in message news:e8b9mm$j4g$1@inn.qnx.com

Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application satisfying
these requirements:


-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.

Under most RTOS you actuall want processes/threads to stop and wait for
something to do otherwise its called busy wait (consumes alls CPU) which in general, isnt good.

In a case of a control task, typicaly the control is time based, hence you
setup a timer at fixed intervaled that wakes up you process.

As for handling externel messages, the command can be done in between timer
event if that`s possible otherwise a low priority thread can be create (or
the control thread is high priority).

As for IPC there a multiple choices, in your case I would use the resources
manager frame work. When possible I like to setup the path space to allow
interfacing with an application from the shell. For example

cp configfile /dev/myapp/config : would configure the application based on
an ascii file
echo start >/dev/myapp/ctrl : would tell the application to start doing its
thing
echo stop >/dev/myapp/ctrl : would tell the application to stop doing its
thing

You get the idea :wink: Very nice because you can start debugging/using the
control task without the GUI.

  • If for example the user interface task dies, the control task must
    detect this and close down the machine in an orderly fashion.

Why ? If the control is critical why stop it if the GUI dies. Why not just
restart the GUI.

That being said the resources manager framework does provide hooks that
indicates a process connected to it as close it`s connection. If you want
more then that, the GUI could send a heart beart like message

There are several interprocess communication options in Neutrino. be the
best in this situation?

Several, hum not really check out IPC under Windows for fun :wink: Under QNX6
the IPC of choice is messaging, and most other IPC are based on top of
messages.

  • Mario

Hi Jorri,



You’d be surprised at how much control tasks actually have left over when
controlling hardware (depending on how fast your control loop has to run).
Blocking is only undesirable if there is a chance that a deadline will be
missed. If your control loop is a server and the GUI is a client to this
server, then it won’t happen. Servers should never MsgSend to clients, only
MsgReply or send them a pulse.



I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t continue
processing when it needs to so they develop some kind of asynchronous
communication scheme or use a queue. Some folks consider it easier (I would
disagree). Sometimes it imay actually be necessary, although I haven’t
(yet) come across a reason why it has to be. I think many folks’ point of
reference QNX IPC is like that of a socket TCP/IP connection. I wouldn’t
want to learn the subtleties of a connection oriented socket in a critical
system either, so w/o QNX IPC, async would be preferable.



Asynchronous may be required where things are architected in such a way that
Synchronous communication is impossible. But if your application is
architected well, QNX IPC is really fast with almost no overhead and it
doesn’t pose any problems. It actually makes things very workable and
easier to debug, troubleshoot, verify, etc.



We have an application that uses IPC sending commands to high voltage
induction motor controllers. This happens at 100 times and our experience
is that the CPU hardly notices the IPC. We have also run these applications
over the Ethernet, same rate, and it works great.



I would study the Neutrino architecture manual very well and do some sample
programs to convince yourself of how well it will actually work (do some
simple timing benchmarks, play with different architectures, etc) before
making any hard conclusions. There are many here who would love to help
you with architectural questions (me included).



I think you will be delighted in the responsiveness of QNX’s IPC when you
start using it. It just works. Don’t confuse microkernel and IPC with
extensive overhead. Try it, you’ll like it.



BTW: Mario’s solution of having the GUI restart is a good one.




Good Luck,



Kevin





“No One” <no.one@home.yet> wrote in message news:e8b9mm$j4g$1@inn.qnx.com

Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application satisfying
these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

BTW: Mario’s solution of having the GUI restart is a good one.

I left the some detailed out obviously. Like one as to consider/handle the
GUI sigsegv’ing on startup :wink:

\

  • Mario

Details, details, who cares about details anymore? :wink:

Kevin

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:e8bpr1$t5f$1@inn.qnx.com

BTW: Mario’s solution of having the GUI restart is a good one.

I left the some detailed out obviously. Like one as to consider/handle
the GUI sigsegv’ing on startup > :wink:

\

  • Mario

Hi Kevin,

Thank you for your answer. I wrote that I’m new to Neutrino, but I’ve done
some programming in QNX4. So I’m familiar with the Send/Receive/Reply
scheme. It’s not time consumption that worries me with this scheme, but that
it is a blocking affair.

A little more background: The machinery to be controlled are some large
wavemakers in our ocean basin laboratory. Twenty times a second a new
position of the wavemaker must be read from a time sequence file and this
new position must be sent the wavemakers. A test run in the lab lasts
typically 1/2 hour. Prior to a test the operator will use the GUI to input
the name of the time sequence file, the startup ramp, etc., and then issue a
start command when the test run starts. When the test is finished he will
issue a stop command.

Like you, I regard the control task to be a server and the GUI to be a
client. During setup (prior to the test run) the control task can afford to
do blocking MsgReceive calls and wait for setup info and the start command.
When the start command is received I plan to use a counter on a digital I/O
card on the PCI bus to create interrupts with precisely determined time
intervals in order to control the temporal output of wavemaker positions. If
the control task should do a blocking MsgReceive after all wavemaker
position have been output, the GUI task must be required to i) do a MsgSend
at the same rate as the control task in order not to delay the control task
or to queue messages, and ii) always MsgSend even if there’s no new
information from the GUI. The second point is of small concern, but the
first point requires that the GUI task is syncronized to the counter
interrupts.

Also I would like to avoid threads in the control task, since I feel that
threads make programs harder to read and maintain. I feel there should be a
simple and elegant solution to this. Maybe a common memory area to store
information, and a flag byte to tell which task is in command of the memory
at any time. The two tasks could then access this memory area asynchronously
and with no blocking. Could that be something?

Regards,
Jorn Jensen

“Kevin Stallard” <kevin@a.com> wrote in message
news:e8bncc$rdb$1@inn.qnx.com

Hi Jorri,



You’d be surprised at how much control tasks actually have left over when
controlling hardware (depending on how fast your control loop has to run).
Blocking is only undesirable if there is a chance that a deadline will be
missed. If your control loop is a server and the GUI is a client to this
server, then it won’t happen. Servers should never MsgSend to clients,
only MsgReply or send them a pulse.



I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t
continue processing when it needs to so they develop some kind of
asynchronous communication scheme or use a queue. Some folks consider it
easier (I would disagree). Sometimes it imay actually be necessary,
although I haven’t (yet) come across a reason why it has to be. I think
many folks’ point of reference QNX IPC is like that of a socket TCP/IP
connection. I wouldn’t want to learn the subtleties of a connection
oriented socket in a critical system either, so w/o QNX IPC, async would
be preferable.



Asynchronous may be required where things are architected in such a way
that Synchronous communication is impossible. But if your application is
architected well, QNX IPC is really fast with almost no overhead and it
doesn’t pose any problems. It actually makes things very workable and
easier to debug, troubleshoot, verify, etc.



We have an application that uses IPC sending commands to high voltage
induction motor controllers. This happens at 100 times and our experience
is that the CPU hardly notices the IPC. We have also run these
applications over the Ethernet, same rate, and it works great.



I would study the Neutrino architecture manual very well and do some
sample programs to convince yourself of how well it will actually work (do
some simple timing benchmarks, play with different architectures, etc)
before making any hard conclusions. There are many here who would love
to help you with architectural questions (me included).



I think you will be delighted in the responsiveness of QNX’s IPC when you
start using it. It just works. Don’t confuse microkernel and IPC with
extensive overhead. Try it, you’ll like it.



BTW: Mario’s solution of having the GUI restart is a good one.




Good Luck,



Kevin





“No One” <> no.one@home.yet> > wrote in message
news:e8b9mm$j4g$> 1@inn.qnx.com> …
Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application
satisfying these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

Mario,

I sent a reply where I thanked Kevin for his answer. My thanks goes to you
also, of course. Sorry for forgetting your name in the first reply.

Jorn

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:e8bpr1$t5f$1@inn.qnx.com

BTW: Mario’s solution of having the GUI restart is a good one.

I left the some detailed out obviously. Like one as to consider/handle
the GUI sigsegv’ing on startup > :wink:

\

  • Mario

Jorn Jensen wrote:

Hi Kevin,

Thank you for your answer. I wrote that I’m new to Neutrino, but I’ve done
some programming in QNX4. So I’m familiar with the Send/Receive/Reply
scheme. It’s not time consumption that worries me with this scheme, but that
it is a blocking affair.

A little more background: The machinery to be controlled are some large
wavemakers in our ocean basin laboratory. Twenty times a second a new
position of the wavemaker must be read from a time sequence file and this
new position must be sent the wavemakers. A test run in the lab lasts
typically 1/2 hour. Prior to a test the operator will use the GUI to input
the name of the time sequence file, the startup ramp, etc., and then issue a
start command when the test run starts. When the test is finished he will
issue a stop command.

Like you, I regard the control task to be a server and the GUI to be a
client. During setup (prior to the test run) the control task can afford to
do blocking MsgReceive calls and wait for setup info and the start command.
When the start command is received I plan to use a counter on a digital I/O
card on the PCI bus to create interrupts with precisely determined time
intervals in order to control the temporal output of wavemaker positions. If
the control task should do a blocking MsgReceive after all wavemaker
position have been output, the GUI task must be required to i) do a MsgSend
at the same rate as the control task in order not to delay the control task
or to queue messages, and ii) always MsgSend even if there’s no new
information from the GUI. The second point is of small concern, but the
first point requires that the GUI task is syncronized to the counter
interrupts.

Also I would like to avoid threads in the control task, since I feel that
threads make programs harder to read and maintain. I feel there should be a
simple and elegant solution to this. Maybe a common memory area to store
information, and a flag byte to tell which task is in command of the memory
at any time. The two tasks could then access this memory area asynchronously
and with no blocking. Could that be something?

IMHO … the access to the shared memory must also be synchronized.

If you are using blocking message passing primitives, you can use
‘kernel timeouts’ in order to limit the time of blocking.

Best Regards

Armin Steinhoff



Regards,
Jorn Jensen

“Kevin Stallard” <> kevin@a.com> > wrote in message
news:e8bncc$rdb$> 1@inn.qnx.com> …

Hi Jorri,



You’d be surprised at how much control tasks actually have left over when
controlling hardware (depending on how fast your control loop has to run).
Blocking is only undesirable if there is a chance that a deadline will be
missed. If your control loop is a server and the GUI is a client to this
server, then it won’t happen. Servers should never MsgSend to clients,
only MsgReply or send them a pulse.



I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t
continue processing when it needs to so they develop some kind of
asynchronous communication scheme or use a queue. Some folks consider it
easier (I would disagree). Sometimes it imay actually be necessary,
although I haven’t (yet) come across a reason why it has to be. I think
many folks’ point of reference QNX IPC is like that of a socket TCP/IP
connection. I wouldn’t want to learn the subtleties of a connection
oriented socket in a critical system either, so w/o QNX IPC, async would
be preferable.



Asynchronous may be required where things are architected in such a way
that Synchronous communication is impossible. But if your application is
architected well, QNX IPC is really fast with almost no overhead and it
doesn’t pose any problems. It actually makes things very workable and
easier to debug, troubleshoot, verify, etc.



We have an application that uses IPC sending commands to high voltage
induction motor controllers. This happens at 100 times and our experience
is that the CPU hardly notices the IPC. We have also run these
applications over the Ethernet, same rate, and it works great.



I would study the Neutrino architecture manual very well and do some
sample programs to convince yourself of how well it will actually work (do
some simple timing benchmarks, play with different architectures, etc)
before making any hard conclusions. There are many here who would love
to help you with architectural questions (me included).



I think you will be delighted in the responsiveness of QNX’s IPC when you
start using it. It just works. Don’t confuse microkernel and IPC with
extensive overhead. Try it, you’ll like it.



BTW: Mario’s solution of having the GUI restart is a good one.




Good Luck,



Kevin





“No One” <> no.one@home.yet> > wrote in message
news:e8b9mm$j4g$> 1@inn.qnx.com> …

Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application
satisfying these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

\

“Armin Steinhoff” <a-steinhoff@web.de> wrote in message
news:e8dj8b$6jq$1@inn.qnx.com

Jorn Jensen wrote:
Hi Kevin,

Thank you for your answer. I wrote that I’m new to Neutrino, but I’ve
done some programming in QNX4. So I’m familiar with the
Send/Receive/Reply scheme. It’s not time consumption that worries me with
this scheme, but that it is a blocking affair.

A little more background: The machinery to be controlled are some large
wavemakers in our ocean basin laboratory. Twenty times a second a new
position of the wavemaker must be read from a time sequence file and this
new position must be sent the wavemakers. A test run in the lab lasts
typically 1/2 hour. Prior to a test the operator will use the GUI to
input the name of the time sequence file, the startup ramp, etc., and
then issue a start command when the test run starts. When the test is
finished he will issue a stop command.

Like you, I regard the control task to be a server and the GUI to be a
client. During setup (prior to the test run) the control task can afford
to do blocking MsgReceive calls and wait for setup info and the start
command. When the start command is received I plan to use a counter on a
digital I/O card on the PCI bus to create interrupts with precisely
determined time intervals in order to control the temporal output of
wavemaker positions. If the control task should do a blocking MsgReceive
after all wavemaker position have been output, the GUI task must be
required to i) do a MsgSend at the same rate as the control task in order
not to delay the control task or to queue messages, and ii) always
MsgSend even if there’s no new information from the GUI. The second point
is of small concern, but the first point requires that the GUI task is
syncronized to the counter interrupts.

If work has to be done 50 times a seconds I wouldn’t worry about using
interrupts I would use timers. Of course it depends on the jitters you are
willing to live with. If that’s a problem write a high priority thread to
handle that timer. You mention you don’t want to use threads, but I’ll take
a thread over an interrupt routine any day :wink:

I think you absolutely need to NOT have the GUI synchronised in any way with
the controle task, otherwise what would be the point in having two separte
entities. The GUI could send certain commands (start/stop) as pulses.

Jorn Jensen wrote:

Hi Kevin,

Thank you for your answer. I wrote that I’m new to Neutrino, but I’ve done
some programming in QNX4. So I’m familiar with the Send/Receive/Reply
scheme. It’s not time consumption that worries me with this scheme, but that
it is a blocking affair.

A little more background: The machinery to be controlled are some large
wavemakers in our ocean basin laboratory. Twenty times a second a new
position of the wavemaker must be read from a time sequence file and this
new position must be sent the wavemakers. A test run in the lab lasts
typically 1/2 hour. Prior to a test the operator will use the GUI to input
the name of the time sequence file, the startup ramp, etc., and then issue a
start command when the test run starts. When the test is finished he will
issue a stop command.

Like you, I regard the control task to be a server and the GUI to be a
client. During setup (prior to the test run) the control task can afford to
do blocking MsgReceive calls and wait for setup info and the start command.
When the start command is received I plan to use a counter on a digital I/O
card on the PCI bus to create interrupts with precisely determined time
intervals in order to control the temporal output of wavemaker positions.

You can also use the IRQ8 (real-time clock) of your PC :slight_smile: It costs
‘nothing’ and is very precisely.

If
the control task should do a blocking MsgReceive after all wavemaker
position have been output,

That server functionality could be handled be a ‘server thread’, which
avoids the blocking of the whole control application.

If it is acceptable that the whole control application is ‘receive
blocked’ … use 'kernel timeouts’in order to limit the time of blocking.

the GUI task must be required to i) do a MsgSend

at the same rate as the control task in order not to delay the control task
or to queue messages, and ii) always MsgSend even if there’s no new
information from the GUI. The second point is of small concern, but the
first point requires that the GUI task is syncronized to the counter
interrupts.

Also I would like to avoid threads in the control task, since I feel that
threads make programs harder to read and maintain.

I’m not convienced that this makes always sense …

However it makes sense to separate a (multithreaded) control task from
the GUI part of your application, because the Photon API isn’t thread safe.

I feel there should be a

simple and elegant solution to this. Maybe a common memory area to store
information, and a flag byte to tell which task is in command of the memory
at any time. The two tasks could then access this memory area asynchronously
and with no blocking. Could that be something?

Data exchange by shared memory make always sense, but it must also be
synchronized.

–Armin


Regards,
Jorn Jensen

“Kevin Stallard” <> kevin@a.com> > wrote in message
news:e8bncc$rdb$> 1@inn.qnx.com> …

Hi Jorri,



You’d be surprised at how much control tasks actually have left over when
controlling hardware (depending on how fast your control loop has to run).
Blocking is only undesirable if there is a chance that a deadline will be
missed. If your control loop is a server and the GUI is a client to this
server, then it won’t happen. Servers should never MsgSend to clients,
only MsgReply or send them a pulse.



I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t
continue processing when it needs to so they develop some kind of
asynchronous communication scheme or use a queue. Some folks consider it
easier (I would disagree). Sometimes it imay actually be necessary,
although I haven’t (yet) come across a reason why it has to be. I think
many folks’ point of reference QNX IPC is like that of a socket TCP/IP
connection. I wouldn’t want to learn the subtleties of a connection
oriented socket in a critical system either, so w/o QNX IPC, async would
be preferable.



Asynchronous may be required where things are architected in such a way
that Synchronous communication is impossible. But if your application is
architected well, QNX IPC is really fast with almost no overhead and it
doesn’t pose any problems. It actually makes things very workable and
easier to debug, troubleshoot, verify, etc.



We have an application that uses IPC sending commands to high voltage
induction motor controllers. This happens at 100 times and our experience
is that the CPU hardly notices the IPC. We have also run these
applications over the Ethernet, same rate, and it works great.



I would study the Neutrino architecture manual very well and do some
sample programs to convince yourself of how well it will actually work (do
some simple timing benchmarks, play with different architectures, etc)
before making any hard conclusions. There are many here who would love
to help you with architectural questions (me included).



I think you will be delighted in the responsiveness of QNX’s IPC when you
start using it. It just works. Don’t confuse microkernel and IPC with
extensive overhead. Try it, you’ll like it.



BTW: Mario’s solution of having the GUI restart is a good one.




Good Luck,



Kevin





“No One” <> no.one@home.yet> > wrote in message
news:e8b9mm$j4g$> 1@inn.qnx.com> …

Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application
satisfying these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

\

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

“John Nagle” <nagle@downside.com> wrote in message
news:e8e9b4$kh3$1@inn.qnx.com

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.

If handling the request does take more then 20ms that is a problem.

Timeout like this doesn’t work in the case where you need a20ms between each
hardware action. If the timeout is about to expire say 19ms, then a message
is received, handling the message takes 2ms, that means you’d missed the
20ms by 1ms.

That is a problem a thread will nicely solve,

Mario Charest wrote:

“John Nagle” <> nagle@downside.com> > wrote in message
news:e8e9b4$kh3$> 1@inn.qnx.com> …

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.


If handling the request does take more then 20ms that is a problem.

Timeout like this doesn’t work in the case where you need a20ms between each
hardware action. If the timeout is about to expire say 19ms, then a message
is received, handling the message takes 2ms, that means you’d missed the
20ms by 1ms.

That is a problem a thread will nicely solve,

True. But if the processing of an incoming message doesn’t do much (no
blocking and not much compute), this will work. The original poster didn’t
want to use threads.

If you do use threads, you have to be careful about delays at locks.
You’ve just pushed the locking problem back one level. Think of the
MsgReceive/MsgReply path as a time-critical section, just as the
section between any lock and unlock in a thread would be.

There is one change worth making. Check if it’s time for an hardware
before doing the MsgReceive, and take the timeout path if it is. That
way, a huge message overhead can’t starve out the hardware update.

John Nagle

There is one change worth making. Check if it’s time for an hardware
before doing the MsgReceive, and take the timeout path if it is. That
way, a huge message overhead can’t starve out the hardware update.

If that happends then it already too late that means the processing the
message
took too much time.

A more ugly way maybe if thread must be avoided at all cost: Have the timer
setup a pulse to firer every 20ms, them do a MsgReceivePulse. That means
the program is ignoring synchronous messages. Once a pulse is receive, the
code dealing with the hardware is run and then right after that MsgReceive
is call along a timeout of 0 to effectively poll for messages.

Hence if processing the hardware takes ~5 ms, as long as processing messages
takes less then ~15ms, no hardware event should be missed.

Mario Charest wrote:

There is one change worth making. Check if it’s time for an hardware
before doing the MsgReceive, and take the timeout path if it is. That
way, a huge message overhead can’t starve out the hardware update.


If that happends then it already too late that means the processing the
message
took too much time.

True, but the original poster indicated that all they wanted to do
when a request came in from the GUI program was to stop, start, change
some parameters, and get info back. So message processing shouldn’t
use that much time.

20ms is a long time with today’s hardware. Now if he had to update
in, say, 100us, it would be harder.

John Nagle

John,

your algorithm will kill every good real-time behavior, IMHO.

What we realy need is a maximum of concurrency with priortized and event
oriented processing. Threads of multi threaded applications don’t use
always the same soft- or hardware resources … so the use of locks,
critical sections a.s.o. are often not so critical.

–Armin


John Nagle wrote:

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

“John Nagle” <nagle@downside.com> wrote in message
news:e8fgcn$fm0$1@inn.qnx.com

Mario Charest wrote:
There is one change worth making. Check if it’s time for an hardware
before doing the MsgReceive, and take the timeout path if it is. That
way, a huge message overhead can’t starve out the hardware update.


If that happends then it already too late that means the processing the
message
took too much time.

True, but the original poster indicated that all they wanted to do
when a request came in from the GUI program was to stop, start, change
some parameters, and get info back. So message processing shouldn’t
use that much time.

The words shouldn’t is what I would be worried about.

20ms is a long time with today’s hardware.

It’s not the time in between events that seems to be important but how
precise that 20ms is.
Is 20ms ± 19ms ok or does the requirement says 20ms ± 100us

Blocking is a good thing. Just make sure that you get interrupted for every
change in your state machine.


“Kevin Stallard” <kevin@a.com> wrote in message
news:e8bncc$rdb$1@inn.qnx.com

Hi Jorri,



You’d be surprised at how much control tasks actually have left over when
controlling hardware (depending on how fast your control loop has to run).
Blocking is only undesirable if there is a chance that a deadline will be
missed. If your control loop is a server and the GUI is a client to this
server, then it won’t happen. Servers should never MsgSend to clients,
only MsgReply or send them a pulse.



I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t
continue processing when it needs to so they develop some kind of
asynchronous communication scheme or use a queue. Some folks consider it
easier (I would disagree). Sometimes it imay actually be necessary,
although I haven’t (yet) come across a reason why it has to be. I think
many folks’ point of reference QNX IPC is like that of a socket TCP/IP
connection. I wouldn’t want to learn the subtleties of a connection
oriented socket in a critical system either, so w/o QNX IPC, async would
be preferable.



Asynchronous may be required where things are architected in such a way
that Synchronous communication is impossible. But if your application is
architected well, QNX IPC is really fast with almost no overhead and it
doesn’t pose any problems. It actually makes things very workable and
easier to debug, troubleshoot, verify, etc.



We have an application that uses IPC sending commands to high voltage
induction motor controllers. This happens at 100 times and our experience
is that the CPU hardly notices the IPC. We have also run these
applications over the Ethernet, same rate, and it works great.



I would study the Neutrino architecture manual very well and do some
sample programs to convince yourself of how well it will actually work (do
some simple timing benchmarks, play with different architectures, etc)
before making any hard conclusions. There are many here who would love
to help you with architectural questions (me included).



I think you will be delighted in the responsiveness of QNX’s IPC when you
start using it. It just works. Don’t confuse microkernel and IPC with
extensive overhead. Try it, you’ll like it.



BTW: Mario’s solution of having the GUI restart is a good one.




Good Luck,



Kevin





“No One” <> no.one@home.yet> > wrote in message
news:e8b9mm$j4g$> 1@inn.qnx.com> …
Since I’m new to Neutrino I’m looking for advise from experienced
programmers in the community. I’m going to write an application
satisfying these requirements:


-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?

Thanks.

Jorn Jensen
Marintek

Kevin Stallard wrote:

Hi Jorri,

I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t continue
processing when it needs to so they develop some kind of asynchronous
communication scheme or use a queue. Some folks consider it easier (I would
disagree). Sometimes it imay actually be necessary, although I haven’t
(yet) come across a reason why it has to be. I think many folks’ point of
reference QNX IPC is like that of a socket TCP/IP connection. I wouldn’t
want to learn the subtleties of a connection oriented socket in a critical
system either, so w/o QNX IPC, async would be preferable.

Me too. The MsgSend/MsgReceive/MsgReply mechanism’s performance is what
makes QNX work. But it’s not well understood by many QNX users.

In almost every other mainstream operating system, message
passing performance is poor. It’s slow, badly integrated with
the scheduler, or doesn’t have proper memory protection.
UNIX(BSD) got it wrong. Linux got it wrong. Mach got it wrong.
Windows got it wrong.

QNX got it right. It’s a very elegant design, and the design
issues behind it need to be thoroughly understood by QNX programmers.
The interaction with scheduling, the non-blocking in MsgReply, and
the ability of TimerTimeout to cleanly break out of a blocked
operation all play together to make it work in hard real time
applications.

I wrote a bit in Wikipedia about this, in the QNX article.

John Nagle

You have to be careful with the word “performance”. Sync message passing
will inherently have lower cost than async, especially when tighty
integrated with the scheduler. But comparing it against async schemes is
unfair and pointless, you’re not comparing equivalent feature sets.

There’s a reason QNX does not use SRR mechanism for communication between
drivers and their respective I/O managers. There’s also a reason why they
bothered to come up with async kernel messages…

Also be careful with trusting the “kernel timeouts”. There is a window for
race condition between you call TimerTimeout() and when your blocking call
starts. You can get preempted and not get CPU back before the timeout
expires. This may not be very likely, but it can happen.

For the purposes of sustained data transfer SRR will be faster on average
than shared memory block controlled by a pair of semaphores (in a classic
producer-consumer arrangement). However if your requirements really do not
permit blocking then shared memory with semaphores will be your best option.

– igor

“John Nagle” <nagle@downside.com> wrote in message
news:e8i0me$876$1@inn.qnx.com

Kevin Stallard wrote:
Hi Jorri,

I’ve noticed that the Send/Receive/Reply mechanism is somewhat feared by
folks. Synchronous communication can be misconstrued as being slow and
troublesome. They fear something holding up the sender so it can’t
continue processing when it needs to so they develop some kind of
asynchronous communication scheme or use a queue. Some folks consider it
easier (I would disagree). Sometimes it imay actually be necessary,
although I haven’t (yet) come across a reason why it has to be. I think
many folks’ point of reference QNX IPC is like that of a socket TCP/IP
connection. I wouldn’t want to learn the subtleties of a connection
oriented socket in a critical system either, so w/o QNX IPC, async would
be preferable.

Me too. The MsgSend/MsgReceive/MsgReply mechanism’s performance is
what
makes QNX work. But it’s not well understood by many QNX users.

In almost every other mainstream operating system, message
passing performance is poor. It’s slow, badly integrated with
the scheduler, or doesn’t have proper memory protection.
UNIX(BSD) got it wrong. Linux got it wrong. Mach got it wrong.
Windows got it wrong.

QNX got it right. It’s a very elegant design, and the design
issues behind it need to be thoroughly understood by QNX programmers.
The interaction with scheduling, the non-blocking in MsgReply, and
the ability of TimerTimeout to cleanly break out of a blocked
operation all play together to make it work in hard real time
applications.

I wrote a bit in Wikipedia about this, in the QNX article.

John Nagle