[MAT logo][Prev][Up][Next]

Appendix: linuxplc.conf

#
# sample linuxplc.conf configuration file
#


######################################################
#                                                    #
#     C O N F I G U R A T I O N     S Y N T A X      #
#     =========================================      #
#                                                    #
######################################################



#   G E N E R A L   S Y N T A X
#   ===========================
#
# (name,value) pairs:
# name = <value>
#
# tables:
# table_name <value_1_1> <value_1_2> <value_1_3> ...
# table_name <value_2_1> <value_2_2> <value_2_3> ...
# ...
#
#
# tables and names are divided into sections.
# (Jiri, do you think you can come up with some good sentences
#  explainig how sections work, and how modules look for parameters
#  in sections named after their module_name ??)
# Should also explain how #includes are supported, and that it is protected
# against circular includes.
#
#
# NOTES:
#  (1)  when value is an integer, it may usually be written in
#       hexadecimal (0xF45A), octal (0172132) or decimal (62554) formats.
#
#  (2)  when value or a name is a string with white space characters, it
#       must be enclosed within "  ("this is a single value")



[PLC]
#
#   T h e   P L C   s e c t i o n
#   =============================
#
#
# The PLC section is used to configure parameters related to the PLC, and
# are used by all modules. Some other parameters related to the PLC, but
# module specific, must be specified under those modules' sections.
#
#
# Note that the synchronisation system uses a petri net to synchronise the
# module execution. This petri net may be configured by _one_ of two methods.
# The first, the simplified method, is merely the definition of the sequence
# by which the modules should execute. This method is configured with the
# synch and synch_start tables.
# The second, more complete and complicated method, requires the complete
# definition of the petri net. Although more complex, this method is also
# more powerfull, and supports some synchronisation sequences that can not be
# configured by the simple method. This complex method is configured by the
# place, transition, arc, and synchpt tables, and the synchpt_beg/end values.
#
#
#
# name = value pairs:
# ------------------
# confmap_key   = <x> : The key to use for the confmap shared memory. This is
#                       actually the same parameter configured through
#                       --PLCplc_id=xxx. The command line argument takes
#                       precedence over the value configured in this file.
#                       If this parameter is not specified either way, the
#                       default value DEF_CONFMAP_KEY (currenty = 23) is used.
#                       Valid values go from 0..INT_MAX. If 0 is specified,
#                       then a random key is chosen.
#
# confsem_key   = <x> : The id of the sempahore set used by the CMM.
#                       If no value is specified, then the default
#                       GMM_DEF_SEM_KEY is used (currently = 0). Valid values
#                       go from 0..INT_MAX. If 0 is specified, then a random
#                       key is chosen.
#
# confmap_pg    = <x> : The size of the confmap given in number of memory pages.
#                       If this value is left unspecified, the default value
#                       DEF_CONFMAP_PG (currently = 2) is used.
#                       The size of each memory page is given by PAGE_SIZE
#                       defined in asm/page.h or sys/user.h (which is the
#                       correct include?) (for linux on intel (?) PAGE_SIZE
#                       is 4 kBytes).
#
# globalmap_key = <x> : The key to use for the globalmap shared memory segment.
#                       If no value is specified, then the default
#                       DEF_GLOBALMAP_KEY is used (currently = 0). Valid values
#                       go from 0..INT_MAX. If 0 is specified, then a random
#                       key is chosen.
#
# globalsem_key = <x> : The key to use for the globalmap semaphore set used by
#                       the GMM. If no value is specified, then the default
#                       DEF_SEM_KEY is used (currently = 0). Valid values
#                       go from 0..INT_MAX. If 0 is specified, then a random
#                       key is chosen.
#
# globalmap_pg  = <x> : The size of the globalmap given in number of memory
#                       pages. If this value is left unspecified, the default
#                       value DEF_CONFMAP_PG (currently = 2) is used.
#
# synchsem_key  = <x> : The id of the sempahore set used by the SYNCH sub-system.
#                       If no value is specified, then the default
#                       DEF_SYNCH_SEM_KEY is used (currently = 0). Valid values
#                       go from 0..INT_MAX. If 0 is specified, then a random
#                       key is chosen.
#
#
# tables:
# ------
# module     : defines which modules should be started by the plc setup program.
# point      : defines the named points in the plc. See further down for syntax.
# point_alias: defines aliases to the named points in the plc. See further
#              down for syntax.
# synch      : used by the simple method of configuring module synchronisation.
#              It specifies the module depencies and how they should synchronise
#              between themselves.
# synch_start: used by the simple method of configuring module synchronisation.
#              It specifies which modules should be allowed to execute the first scan
#              as soon as the plc is started.
# place      : used by the complex method of configuring module synchronisation.
#              It specifies the places in the synchronisation Petri net.
# transition : used by the complex method of configuring module synchronisation.
#              It specifies the transitions in the synchronisation Petri net.
# arc        : used by the complex method of configuring module synchronisation.
#              It specifies the arcs in the synchronisation Petri net.
# synchpt    : used by the complex method of configuring module synchronisation.
#              It specifies the synchpts in the synchronisation Petri net.
#
#
#
# the MODULE table
# ----------------
# syntax:
# module <name> <file> [<options> ...]
#
# where:
# name      = the name of the module. This name will be used in sections, module
#             synchronisation, etc...
# file      = the program that will be executed.
# options   = other command line options that need to pe passed to the program.
#
#
#
# The POINT table
# ---------------
# syntax:
# point <name> <full name> <owner> [at <offset>[.<bit>]] [[i|u|f]<length>] [init <init_val>]
#
# where:
# point     = 'point' identifier
# name      = Name used to search for point in plc_pt_by_name()
# full name = More extensive description of the point
#             This information is not loaded into the confmap of the plc
# owner     = Name of the module with write permission on the point
# at        = 'at' identifier
#             This, along with the <offset>.<bit> is optional. When not
#             explicitly specified, the plc will try to find an empty slot
#             for the point.
# offset    = location of word in the globalmap that holds the point's state.
# bit       = the bit, in the word, that holds the point's state. This is
#             optional, defaulting to 0.
# i | u | f = the 'i', 'u' or 'f' identifiers.
#             These are used to specify the format of the data in the plc point.
#             At the moment this is only used by the plc code to figure out
#             how to interpret the initial value of the point when parsing
#             the init_val parameter.
# length    = the size in bits of the point. The point must not overflow
#             onto the next offset position (i.e. (bit + length) <
#             (8*sizeof (u32)).
#             The length is optional, defaulting to:
#                1 if the {at <offset>.<bit>} is not explicitly specified.
#               32 if {at <offset>} is specified without explicitly
#                  specifying the <bit>
#                1 if both {at <offset>.<bit>} are explicitly specified.
# init      = 'init' identifier
# init_val  = the initial value of the plc point. Defaults to 0.
#             If it is not specifically specified how to interpret the init_val
#             using the [i|u|f] identifiers before the length of the point,
#             then it will be interpreted as a 32 bit float (f32)
#             if it contains a floating point (e.g. 1.1) or an exponent (e.g. 1e9)
#             If the above is not true, then the init_val will be interpreted
#             as an xx bit signed integer if it has a leading '+' or '-' character.
#             If none of the above apply, then the value will be interpreted as
#             an xx bit unsigned integer.
#             The xx is the length of the plc point. Only 32 bit floats, integers
#             or unsigned integers are currently supported.
#
#
#
# the POINT_ALIAS table
# ---------------------
# syntax:
# point_alias <name> <full name> <org_name> [<bit> [<length>]]
#
# where:
# point_alias = 'point_alias' identifier
# name        = Name used to search for point in plc_pt_by_name()
# full name = More extensive description of the point
#             This information is not loaded into the confmap of the plc
# bit       = The first bit, of the original point, that this alias will
#             reference. This is optional, defaulting to 0.
# length    = the size in bits of the point. The point must not overflow
#             outside the original point (i.e. (bit + length) <
#             (length of org_name point). The length is optional, defaulting
#             to the length of the org_name point if no bit is explicitly
#             specified, and 1 otherwise.
#
#
#
# the SYNCH table
# ---------------
# syntax:
# synch <module_1> arrow <module_2>
#
# where:
# module_X = The name of a module. Whenever module_1 finishes executing it's scan,
#            then module_2 will start executing a new scan.
# arrow    = is an arrow with the same syntax as the one specified for the arrow
#            in the arc table, but with the additional constraint that only weights
#            with a value of 1 are valid for this table.
#
#
#
# the SYNCH_START table
# ---------------------
# syntax:
# synch_start <module_1> [<module_2> ...]
#
# where:
# module_X = The name of a module. Identifies which modules should be allowed to start
#            executing their first scan without any synchronisations. In other words,
#            which modules should start executing imediately once the PLC is started.
#
#
#
# the PLACE table
# ---------------
# syntax:
# place <name> [<init_tokens>]
#
# where:
# name        = The name of the place. The names specified on this table will later be
#               used in the arc table.
# init_tokens = The number of tokens the place should have when the PLC is started. If
#               not specified, it defaults to 0.
#
#
#
# the TRANSITION table
# --------------------
# syntax:
# transition <name>
#
# where:
# name        = The name of the transition. The names specified on this table will
#               later be used in the arc and synchpt tables.
#
#
#
# the ARC table
# -------------
# syntax:
# arc <place> arrow <transition>
#   or
# arc <transition> arrow <place>
#
# where:
# place      = The name of a place specified in the place table.
# transition = The name of a transition specified in the transition table.
# arrow      = is an arrow with the following syntax:
#                [-][(][<weight>][)][-]>
#              where weight is a positive integer.
#              Possible correct examples are:
#                ->         # weight = 1
#                ----->     # weight = 1
#                >          # weight = 1
#                -()->      # weight = 1
#                ()>        # weight = 1
#                (>         # weight = 1
#                )>         # weight = 1
#                -7->       # weight = 7
#                8>         # weight = 8
#                (9)>       # weight = 9
#                (9>        # weight = 9
#                9)>        # weight = 9
#                etc...
#              Even though all above examples are correct, we sugest using:
#                ->         : for arrows with weight = 1
#                -X->       : for arrows with weight = X
#
#
# the SYNCHPT table
# -----------------
# syntax:
# synchpt <name> <type> <parameter>
#
# where:
# name        = The name of the synchpt. This name will be used as a value for the
#               synchpt_beg and synchpt_end, and in the plc_synchpt_by_name(...)
#               function call.
# parameter   = A parameter that will depend on the transition type.
# type        = {transition | transition.beg | transition.end}
#               Identifies the synchpt type.
#               transition: Requires that <parameter> identifies a transition.
#                           Synching to a synchpt of this type will block until the
#                           transition can be fired. Before continuing the transition
#                           will be fully fired, i.e. the required number of tokens
#                           will be removed from the places with arcs pointing to
#                           this transition, and tokens will be inserted into the
#                           places pointed to by the arcs emanating from this
#                           transition.
#               transition.beg: Requires that <parameter> identifies a transition.
#                               Synching to a synchpt of this type will block until
#                               the transition can be fired. Before continuing the
#                               transition will be partially fired, i.e. the required
#                               number of tokens will be removed from the places with
#                               arcs pointing to this transition, but *no* token will
#                               be inserted into the places pointed to by the arcs
#                               emanating from this transition.
#               transition.end: Requires that <parameter> identifies a transition.
#                               Synching to a synchpt of this type will never block.
#                               Before continuing the transition will be partially
#                               fired, i.e. *no* token will be removed from the places
#                               with arcs pointing to this transition, but tokens will
#                               be inserted into the places pointed to by the arcs
#                               emanating from this transition.
#
# NOTE: The synchpt name "NULL" is reserved for the null synchpt.
#       Wherever a name = value pair requires the name of a synchpt for the
#       value, the name "NULL" may be used to specify the null synchpt.





[module_name]
#
#  P L C   r e l a t e d   v a l u e s
#  ===================================
#
#  PLC related values, specific to each module.
#
# name = value pairs:
# ------------------
# location = <x> : defines how the module should access the shared plc
#                  resources. Possible values are "local" for direct access,
#                  and "isolate" for access through proxy process.
#                  This is the same as the command line --PLClocal and
#                  --PLCisolate arguments. The command line arguments take
#                  precedence over whatever is defined in the config file.
#                  If no value is specified by either method, the default
#                  DEF_PLC_LOCATION (currently = local) is used.
#
# privatemap_key = <x>: defines the key to use for the local map shared memory.
#                       Valid values go from 0..INT_MAX. A value of 0 has
#                       diferent meanings, depending on the location value.
#                       For local access, a value of 0 implies the use of malloc
#                       to allocate memry for the local map. For isolate access,
#                       a random key is used for the local map shared memory.
#                       The default value for every access method is
#                       DEF_LOCALMAP_KEY (currently = 0)
#                       NOTE: in the source code the localmap is also sometimes
#                       refered to as the private map. This is something that
#                       must be corrected...
#
# scan_period = <x> : defines the scan period, in seconds, of the module. The PLC
#                     interprets values down to 1 ns, but the precision is limited
#                     to the resolution of the clock of the hardware on which it is
#                     running. On plain vanilla linux on x86 hardware the resolution
#                     is normally 10 ms.
#                     Note that the effective scan period of a module
#                     also depends on how it synchronises with every other
#                     module of the PLC. When a module finishes executing it's scan,
#                     it will first wait until it's scan period has elapsed, and then
#                     synchronise with the remaining modules. Only then will it
#                     actually execute the next scan. This means that the effective
#                     scan period may end up being larger than the one specified in
#                     this parameter.
#                     The scan periods are counted on an absolute time frame. Consider
#                     t0 the instant the first scan started. The following scans will
#                     be enabled at t0+T, to+2*T, t0+3*T, etc...
#
# scan_beg = <x> : used by the complex method of specifying the synchronisation
#                  dependencies.
#                  Identifies the synchpt to which the module should synch at the
#                  begining of every scan. If no synchpt is specified, the default
#                  NULL synchpt is used. Note that synchronising to the NULL synchpt
#                  always returns without any delay, so by default the module will not
#                  synchronise to anything.
#
# scan_end = <x> : used by the complex method of specifying the synchronisation
#                  dependencies.
#                  Identifies the synchpt to which the module should synch at the
#                  end of every scan. If no synchpt is specified, the default
#                  NULL synchpt is used. Note that synchronising to the NULL synchpt
#                  always returns without any delay, so by default the module will not
#                  synchronise to anything.
#






#######################################################
#                                                     #
#     S A M P L E     C O N F I G U R A T I O N S     #
#     ===========================================     #
#                                                     #
#######################################################


#
#  C O N F I G   (1) : Absolute Minimum Configuration
#  ==================================================
#

[PLC]
# we need some points, otherwise this is a useless exercise...
point P0.0  "full name 0.0" module1 at  0.0      # 1 bit point at 0.0
point P0.1  "full name 0.1" module1 at  0.1  5   # 5 bit point from 0.1 to 0.5
point P1    "full name 1.0" module2 at  1        # 32 bit point from 1.0 to 1.31

[PLC]
# We also need some module to execute...
module module1 /linuxplc/logic/...

[module1]
# Here we would insert module specific configurations



#
#  C O N F I G   (2) : Configuration with Simple Synchronisation
#  =============================================================
#

[PLC]
# we need some points, otherwise this is a useless exercise...
point P0.0  "full name 0.0" module1 at  0.0      # 1 bit point at 0.0
point P0.1  "full name 0.1" module1 at  0.1  5   # 5 bit point from 0.1 to 0.5
point P1    "full name 1.0" module2 at  1        # 32 bit point from 1.0 to 1.31

[PLC]
# We also need some module to execute...
module module1 /linuxplc/logic/...
module module2 /linuxplc/logic/...

[PLC]
# We specify that the modules must run synchronously, one after the other
#
# After module1, run module2, and vice-versa
synch module1 -> module2
synch module2 -> module1

# start off by running module1
synch_start module1

# In addition, if we wanted the scans to execute only every 0.1 seconds, we can
# specify the scan period of one of the modules.
# Since both modules run in lock-step, we must only specify the scan period of *one*
# of the modules...
module1: scan_period = 0.1


[module1]
# Here we would insert module specific configurations

[module2]
# Here we would insert module specific configurations



#
#  C O N F I G   (3) : Configuration with Complex Synchronisation
#  ==============================================================
#

[PLC]
# we need some points, otherwise this is a useless exercise...
point P0.0  "full name 0.0" module1 at  0.0      # 1 bit point at 0.0
point P0.1  "full name 0.1" module1 at  0.1  5   # 5 bit point from 0.1 to 0.5
point P1    "full name 1.0" module2 at  1        # 32 bit point from 1.0 to 1.31

[PLC]
# We also need some module to execute...
module module1 /linuxplc/logic/...
module module2 /linuxplc/logic/...


[PLC]
#
#  The synchronisation config
#  --------------------------
# For demonstartion purposes, we shall use two methods to synchronise each of
# the two modules.
#
# The first module will use two places (P_module1_run, P_module1_running),
# and two transitions (T_module1_beg, T_module1_end).
# The number of tokens in P_module1_run indicates the number of times
# module1 must run its scan loop.
# The P_module1_running will contain one token whenever the chaser module is busy
# running its scan loop.
# At the beginning of the module1 scan this module waits on the T_module1_beg
# transition. This transition will remove one token from P_module1_run,
# put one token in P_module1_running, and let the module start executing.
# At the end of the scan module1 will wait on the T_module1_end
# transition. This transition removes the token from P_module1_running, which
# will therefore become empty.
#

place P_module1_run        1    # initialise with 1 token => start off by running this module.
place P_module1_running    0    # 0 is not required, it is the default value.

transition  T_module1_beg
transition  T_module1_end

arc P_module1_run -> T_module1_beg
arc T_module1_beg -> P_module1_running

arc P_module1_running -> T_module1_end


# The modules will wait on synchronisation points (synchpt), and not the
# transitions themselves. We therefore define two synchpts mapped onto the
# relevant transitions.
synchpt module1_beg transition T_module1_beg
synchpt module1_end transition T_module1_end



# The second module, will use only one place and one transition to synchronise.
# The number of tokens in the P_module2_run place will indicate the number
# of times module2 must execute its scan loop.
# The T_module2 transition will remove a token from the P_module2_run place
# and run the vitrine module scan loop synchronously, i.e.:
#   1) remove the token from the places indicated by the arcs terminating at
#      the transition;
#   2) runs the module's scan loop once
#   3) place tokens in the places indicated by the arcs leaving the transition.
#

place P_module2_run
transition T_module2

arc P_module2_run -> T_module2

# once again, the module will actually synchronize on synchpts, and not the
# transition itself. But since it will synchronize synchronously, we
# use two distinct types of mapping between the synchpts and the relevant
# transition.
# One synchpt to remove the tokens indicated by the arcs arriving at
#  the transition. This is the transition.beg type of synchpt.
synchpt module2_beg  transition.beg T_module2

# One synchpt to place the tokens indicated by the arcs leaving
#  the transition. This is the transition.end type of synchpt.
synchpt module2_end  transition.end T_module2



# Now that the synch of each module is established, we define what happens when
# each module finishes executing.
#
# When module1 finishes, we tell module2 to run once
arc T_module1_end -> P_module2_run

# When the vitrine finishes, we tell the chaser to run once
arc T_module2 -> P_module1_run


# The only thing left is to tell each module what synchpts to use for the beg
#  and end of the scan.
module1: scan_beg = module1_beg
module1: scan_end = module1_end
module2: scan_beg = module2_beg
module2: scan_end = module2_end



# In addition, if we wanted the scans to execute only every 0.1 seconds, we can
# specify the scan period of one of the modules.
# Since both modules run in lock-step, we must only specify the scan period of *one*
# of the modules...
module1: scan_period = 0.1
[Prev][Up][Next]