Skip to content
Snippets Groups Projects
Commit 30398b65 authored by benjamin.franksen's avatar benjamin.franksen
Browse files

docs: re-write of the Using chapter

parent 3e556b0b
No related branches found
No related tags found
No related merge requests found
...@@ -1735,6 +1735,7 @@ macValueGet ...@@ -1735,6 +1735,7 @@ macValueGet
Returns a pointer to the value of the specified program parameter, if Returns a pointer to the value of the specified program parameter, if
it exists, else ``NULL``. See `Program Name and Parameters`_. it exists, else ``NULL``. See `Program Name and Parameters`_.
.. _Shell Commands:
Shell Commands Shell Commands
-------------- --------------
......
Using the Run Time Sequencer Running SNL Programs
============================ ====================
.. todo:: This chapter should be completely re-worked. This chapter is about how to run and customize a program, once it has been
compiled. It also explains how to get information about a running program
instance and how to stop a program.
.. warning:: Much of the information here is out-dated, some is Our running example is the "demo" program which you find under the path
missing, and some is plainly wrong. I badly need to re-write ``examples/demo`` in the source tree.
this chapter.
In the previous chapter you learned how to create and compile some
simple programs. In this chapter you will be introduced to
the run-time sequencer so that you can execute your program.
VxWorks-specific instructions Command Syntax
----------------------------- --------------
Loading the sequencer The commands discussed in this chapter can be invoked in different ways. One
^^^^^^^^^^^^^^^^^^^^^ way is to call them directly from C code. Prototypes for the corresponding C
functions can be found in the header file "seqCom.h" which a successful
build installs into the "include" directory.
The sequencer is unbundled from EPICS base and so must be loaded More typical, however, is to call them from some kind of command shell, such
separately. The sequencer is loaded into an IOC by the VxWorks as the EPICS IOC shell, or the VxWorks C shell, or the RTEMS cexp shell. In
loader from object files on the UNIX file system. Assuming the each case the syntax is slightly different, but this is not the place to
IOC's working directory is set properly, the following command will discuss all these (sometimes subtle) differences. Thus, for simplicity, I
load the sequencer object code:: will mostly use the IOC shell syntax, indicated by a leading "epics> "
shell prompt (so this does not belong to the command itself).
ld < pvLibrary Details about the commands can also be found in
ld < seqLibrary section :ref:`Shell Commands` of the SNL language reference.
Loading a State Program Starting a Program
^^^^^^^^^^^^^^^^^^^^^^^ ------------------
State programs are loaded into an IOC by the VxWorks loader from To start an SNL program, the :c:func:`seq` function is called with three
object files on the UNIX file system. Assuming the IOC's working parameters:
directory is set properly, the following command will load the
object file "example.o"::
ld < example.o #. The address of the ``seqProgram`` structure. This is a value that is
generated by the SNL compiler; it has the same name as the identifier
after the :token:`program` keyword.
This can be typed in from the console or put into a script file, #. Optionally a string containing parameter definitions, see next section.
such as the VxWorks start-up file.
Executing the State Program #. Optionally a stack size. If ``0`` (zero), a reasonable default for the
^^^^^^^^^^^^^^^^^^^^^^^^^^^ target platform is used (``epicsThreadStackSmall``).
Let's assume that the program name (from the ``program`` statement) For instance, the following command starts the demo program with no
is "level\_check". Then to execute the program parameters and teh default stack size::
under VxWorks you would use the following command::
seq &level_check epics> seq demo
This will create one task for each state set in the program. The Note that the IOC shell defaults missing arguments to zero. Also note that
task ID of the first state set task will be displayed. You can find the program gets passed as a string when using the IOC shell, whereas in C
out which tasks are running by using the VxWorks ``i`` command. you would have to call it like::
Examining the State Program seq(&demo,0,0);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. warning:: The following works only if you are using the EPICS If parameters are to be specified (see next section), this would instead
IOC shell, not if you use the VxWorks C shell. On the VxWorks shell look like ::
you must supply the thread ID, giving the program name (even in
double quotes) will not work.
You can find the thread ID belonging to the program by executing
``seqShow`` without arguments.
You can examine the program by typing:: epics> seq demo "debug=0,prefix=demo"
seqShow level_check The sequencer responds with the following output::
This will display information about each state set (e.g. state Sequencer release 2.1.14, compiled Wed Sep 25 12:18:24 2013
set names, current state, previous state). You can display Spawning sequencer program "demo", thread 0x98fe120: "demo"
information about the process variables associated with this
program by typing either of::
seqChanShow level_check The most useful information here is the (EPICS) thread ID ``0x98fe120``,
seqChanShow level_check, "DTL_6:CM_2:ai1" since this can be used later on to identify the running program.
seqChanShow level_check, "-"
You can display information about monitor queues by typing:: BTW, all shell commands write their output to ``stdout``.
seqQueueShow level_check
The first parameter to ``seqShow`` , ``seqChanShow`` and ``seqQueueShow`` .. _run time parameters:
is either the task identifier (tid) or the *unquoted* task name of
the program task. If the program has more than one tid
or name, then any one of these can be used. The second parameter is
a valid channel name, or ``-`` to show only those channels which
are disconnected, or ``+`` to show only those channels which are
connected. The ``seqChanShow`` and ``seqQueueShow`` utilities will
prompt for input after showing the first or the specified channel;
enter *<Enter>* or a signed number to view more channels or queues;
enter ``q`` to quit.
If you wish to see the task names, state set names, and task
identifiers for all programs type::
seqShow
.. _Stopping the State Program Tasks:
Stopping the State Program Tasks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You should not directly delete program tasks. Instead, use
the ``seqStop`` command::
seqStop level_check
The parameter to ``seqStop`` is either the task identifier (tid) or
the task name of the program task.
A program can also terminate itself, see :ref:`Transitions`.
Unix-specific instructions
--------------------------
Executing the State Program
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Under Unix, you execute the program directly. You might type
the following::
level_check Program Parameters
------------------
Once the state set threads have been created, the console remains Parameters are a way to customize an SNL program. A program parameter
active and you can type commands as described below. has a name (a string) and a value (also a string). The parameter name
should be a valid SNL identifier, while the value can be anything.
Examining the program Parameters are specified (or defined) in two places: when invoking a
^^^^^^^^^^^^^^^^^^^^^^^^^^^ program for execution, using the :c:func:`seq` procedure, or from inside
a program after the initial :token:`program` clause. Parameters specified
on invocation override those specified in the program. In both cases, the
syntax of the actual specification is, roughly::
The following commands can be issued under Unix (hit ``?`` to "name1=value1,name2=value2,..."
obtain the list):
commands (abbreviable): Note that the whole specification is embedded in a single string. A single
definition consists of the parameter name, followed by an equal sign,
followed by the value. Multiple parameter definitions are separated by comma.
i The value is not allowed to contain a comma, or spaces; leading or
show all threads trailing spaces around the value are ignored. Normal C/SNL string character
escaping is admissable, e.g. to embed double quotes or line breaks,
but cannot be used to circumvent these limitations.
all
show all sequencers
channels Special Parameters
show all channels ^^^^^^^^^^^^^^^^^^
+ The following built-in parameters have special meaning to the sequencer.
show conn. channels
- ::
show disc. channels
queues debug = <level>
show queues
statesets This is currently only used by the PV subsystem.
show state-sets A level of 1 or greater turns on debug messages.
<EOF> ::
exit
As you see, all commands can be abbreviated to a single character. name = <thread_name>
Stopping the State Program Tasks Normally the thread names are derived from the program name. This
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ parameter specifies an alternative base name for the state
set threads.
A program may be killed by sending it a ``SIGTERM`` (*Ctrl-C*) ::
signal (this is an untidy exit, but who cares?) or by entering an
*<EOF>* (*Ctrl-D*) character. The latter calls ``seqStop`` and is a
tidy exit.
.. _run time parameters: priority = <task_priority>
Specifying Run-Time Parameters This parameter specifies initial thread priorities. The value should
------------------------------ be an integer between 0 (lowest) and 99 (highest) and will be passed
epicsThreadCreate when teh state set threads are created.
You can specify run-time parameters to the sequencer. Parameters ::
serve three purposes:
#. macro substitution in process variable names, stack = <stack_size>
#. providing arguments to your program, and
#. as special parameters to the sequencer.
You can pass parameters to your program at run time by This parameter specifies the stack size in bytes. The default is
including them in a string with the following format:: whatever ``epicsThreadGetStackSize(epicsThreadStackSmall)`` returns.
"<param1>=<value1>, <param2>=<value2>, ..."
This same format can be used in the ``program`` statement's parameter Using Parameters
list (see :ref:`StateProgram`). Parameters ^^^^^^^^^^^^^^^^
specified on the command-line override those specified in the
``program`` statement.
Parameter values are available inside the program via the built-in Parameter values are available inside the program via the built-in
procedure :c:func:`macValueGet`. They are also (automatically) procedure :c:func:`macValueGet`. They are also (automatically)
available for parameter expansion when specifying PV names in available for parameter expansion when specifying PV names in
:token:`assign` clauses and the built-in procedure :c:func:`pvAssign`. :token:`assign` clauses.
VxWorks
^^^^^^^
For example, if we wish to specify the value of the "unit" parameter in
the example in the last chapter, we would execute the program with
the following command::
seq &level_check, "unit=DTL_6:CM_2"
Unix
^^^^
This works just the same under Unix. The above example becomes:: Examining a Program
-------------------
level_check "unit=DTL_6:CM_2" You can get information about your program at runtime by calling one of
several shell commands. They all take a thread ID as first argument to
uniquely identify the a running program instance. If this argument is
zero (i.e. omitted in the IOC shell), they default to displaying
a table that lists the thread IDs of all state
sets of all running program instances.
Access within program Here is what you might get for the demo program::
^^^^^^^^^^^^^^^^^^^^^
Parameters can be accessed by your program with the function epics> seqShow
:c:func:`macValueGet`. The following built-in Program Name Thread ID Thread Name SS Name
parameters have special meaning to the sequencer:: ------------ --------- ----------- -------
demo 0x88c1da8 demo light
0xb6a1e160 demo_1 ramp
0xb6a1e2b8 demo_2 limit
debug = <level> When the :c:func:`seqShow` command is called with one of the thread IDs
listed in the table it will give you more detailed information about the
running program.
Sets a logging level. *level-1* is passed on to the PV API. Can be You can get detailed information about the process variables associated
used in user code:: with a program by calling :c:func:`seqChanShow` with a valid thread ID
as the first argument. Similarly, :c:func:`seqChanShow` displays
information about monitor queues. Here are some example invocations::
logfile = <filename> epics> seqChanShow 0x88c1da8 demo:lightOn
epics> seqChanShow 0x88c1da8 -
epics> seqChanShow 0x88c1da8 +
epics> seqQueueShow 0x88c1da8
This parameter specifies the name of the logging file for the The optional second parameter to seqChanShow or seqQueueShow is
run-time tasks associated with the program. If none is a channel name, or ``-`` to show only those channels which
specified then all log messages are written to ``stdout``:: are disconnected, or ``+`` to show only those channels which are
connected. Both will prompt for input after showing the first
(or the specified) channel: hit Enter or a signed number to view
more channels or queues; enter ``q`` to quit.
name = <thread_name>
Normally the thread names are derived from the program name. This .. _Stopping the State Program Tasks:
parameter specifies an alternative base name for the run-time
threads::
priority = <task_priority> Stopping a Program
^^^^^^^^^^^^^^^^^^
This parameter specifies the initial task priority when the tasks In order to cleanly shut down a running program, use the ``seqStop``
are created. The value ``task_priority`` must be an integer between command::
0 and 99 (it's ignored under Unix)::
stack = <stack_size> epics> seqStop 0x88c1da8
This parameter specifies the stack size in bytes (its use is A program can also terminate itself, see :ref:`Transitions`.
deprecated, and it is in any case ignored under Unix).
Sequencer Logging
-----------------
The sequencer logs various information that could help a user
determine the health of a program. Logging uses the
``errlogPrintf`` function and will be directed to the IOC log file if
the IOC log facility has been initialized. Under VxWorks this is
done automatically but under Unix it must be done by the
programmer. This can be done in the main program (if you are
writing it yourself) or in the entry handler, which is executed in
the context of the first state set before the remaining state sets
have been created. For example::
entry {
#ifdef UNIX
%%#include "logClient.h"
iocLogInit();
#endif
}
The programmer may log information using ``errlogPrintf`` directly or
else by using the ``seqLog`` function. By default, ``seqLog`` output
goes to ``stdout`` , but it may be directed to any file by specifying
the ``logfile`` parameter as described above.
What Triggers an Event?
-----------------------
There are five types of sequencer event:
- a process variable monitor is posted
- an asynchronous ``pvGet`` or ``pvPut`` completes
- a time delay elapses
- an event flag is set or cleared
- a process variable connects or disconnects
When one of these events occur, the sequencer executes the
appropriate ``when`` statements based on the current states and the
particular event or events. Whenever a new state is entered, the
corresponding ``when`` statements for that state are executed
immediately, regardless of the occurrence of any of the above
events.
Prior to Version 1.8 of the sequencer, event flags were cleared
after a ``when`` statement executed. Currently, event flags must be
cleared with either ``efTestAndClear`` or ``efClear`` , unless
the :option:`-e` compiler option was chosen.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment