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

Appendix: matplc.conf

#
# sample matplc.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:
# ------------------
# max_modules   = <x> : The maximum number of simultaneously active modules
#                       the MatPLC will ever have.
#                       If this parameter is not specified, the
#                       default value STATE_MMC_DEF (currenty = 20) is used.
#                       Valid values go from 0..MMC_MAX. MMC_MAX depends on
#                       the operating system currently being used, and the
#                       number of places in the synchronisation Petri Net.
#                       (For example, on a typical linux the total of
#                       max_modules plus number of places may be 250 max.)
#
#                       Please read on for an explanation on the synchronisation
#                       Petri Net.
#
# 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_size  = <x> : The size of the confmap given in bytes.
#                       If this value is left unspecified, the default value
#                       CMM_DEF_CONFMAP_PG (currently = 8*1024) is used.
#
# 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_size= <x> : The size of the globalmap given in bytes 
#                       If this value is left unspecified, the default
#                       value GMM_DEF_GLOBALMAP_PG (currently = 8*1024) 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 weights
#            with a value of 0 are not 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.
#
# NOTE: The transition name "NULL" is reserved for the null transition.
#       Wherever a name = value pair requires the name of a transition for the
#       value, the name "NULL" may be used to specify the null transition.
#
#
# 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 non negative 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->  or  -(X)->  : for arrows with weight = X
#
# NOTE: arcs with weight 0 are only allowed from <place> --> <transition>







[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 "shared", "local" and
#                  "isolate".
#                  This is the same as the command line --PLClocal,
#                  --PLCisolate and --PLCshared 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.
#                  Detailed explanation:
#                  "shared" provides direct access to the shared plc
#                  resources, while both "local" and "isolate" use a local
#                  copy which is synchronised once every scan cycle.
#                  The "local" version acesses the shared resources directly
#                  when synchronising to the shared resources, while
#                  "isolate" asks a proxy process to do the synchronisation.
#                  The "shared" version has the advantage of not requiring
#                  to synchronise the local copy to the shared resources,
#                  which may be somewhat time comsuming. Unfortunately,
#                  and precisely because it does not use any synchronisation
#                  mechanisms, it may produce incorrect results if more
#                  than one module tries to access the shared resources
#                  simultaneously. This method should only be used if the
#                  modules are guaranteed not to run simultaneously, for
#                  example, by correctly configuring the inter-module
#                  synchronisation mechanism ("synch" table, etc...)
#                  The "local" and "isolate" methods do not have the above
#                  limitations since they keeps a local copy of the shared
#                  resources, which may be safely accessed any time by the
#                  module. The local copy is then typically synchronised with
#                  the shared resources once every scan cycle. Since the
#                  synchronisation is protected by synchronisation mechanisms
#                  to gurantee that only one module may access the shared
#                  resources at a time, these methods may be used safely,
#                  whatever the execution sequence of the modules may be.
#                  The "isolate" and "local" methods merely differ on who
#                  does the actual synchronisation between the local copy and
#                  the shared resources. In the "local" method the module
#                  itself accesses the shared resources while doing the
#                  the synchronisation. In the "isolate" method, the
#                  module asks a proxy process to do the synchronisation.
#                  Note that the proxy process is launched automagically.
#                  The "local" method, although faster, has the drawback that
#                  a bug in the module code may result in the shared
#                  resources being changed involuntarily (e.g. by a stray
#                  pointer). For this reason, we recomend that the "isolate"
#                  method be used when a module is being tested, and the "local"
#                  method be used during normal runs.
#
# 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 transition to which the module should synch at the
#                  begining of every scan. If no transition is specified, the default
#                  NULL transition is used. Note that synchronising to NULL transition
#                  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 transition to which the module should synch at the
#                  end of every scan. If no transition is specified, the default
#                  NULL transition is used. Note that synchronising to NULL transition
#                  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 /matplc.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 /matplc.logic/...
module module2 /matplc.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 /matplc.logic/...
module module2 /matplc.logic/...


[PLC]
#
#  The synchronisation config
#  --------------------------
# Each module will use one place (P_module1, P_module2),
# and two transitions (T_module1_beg, T_module1_end, etc...).
#
# The number of tokens in P_module1 indicates the number of times
# module1 must run its scan loop. Likewise for module 2.
# 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,
# and let the module start executing.
# At the end of the scan module1 will wait on the T_module1_end
# transition. This transition will place a token in P_module2,
# therfore allowing module2 to run.
#
# Module2 works in exactly the same way as module1.

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

transition  T_module1_beg
transition  T_module1_end
transition  T_module2_beg
transition  T_module2_end

arc P_module1     -> T_module1_beg
arc T_module1_end -> P_module2

arc P_module2     -> T_module2_beg
arc T_module2_end -> P_module1

# The only thing left is to tell each module what transitions to use for the beg
# and end of the scan.
module1: scan_beg = T_module1_beg
module1: scan_end = T_module1_end
module2: scan_beg = T_module2_beg
module2: scan_end = T_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]