|
|
|
@ -40,7 +40,6 @@ import ply.yacc as yacc
|
|
|
|
|
global Verbose
|
|
|
|
|
global DriverDump
|
|
|
|
|
global CodeDump
|
|
|
|
|
global UsingCreateNode
|
|
|
|
|
global FunctionTypes
|
|
|
|
|
global DriveableFunctionTypes
|
|
|
|
|
global NumberOfLinesIn
|
|
|
|
@ -60,7 +59,6 @@ DriveableFunctionTypes = [
|
|
|
|
|
'checklimits_function',
|
|
|
|
|
'checkstatus_function',
|
|
|
|
|
]
|
|
|
|
|
UsingCreateNode = False
|
|
|
|
|
|
|
|
|
|
Verbose = False
|
|
|
|
|
DriverDump = False
|
|
|
|
@ -88,7 +86,6 @@ reserved = {
|
|
|
|
|
'ADD_ARGS' : 'ADD_ARGS',
|
|
|
|
|
'MAKE_ARGS' : 'MAKE_ARGS',
|
|
|
|
|
'PROTOCOL_ARGS' : 'PROTOCOL_ARGS',
|
|
|
|
|
'USECREATENODE' : 'USECREATENODE',
|
|
|
|
|
# Group keywords
|
|
|
|
|
'GROUP' : 'GROUP',
|
|
|
|
|
'GROUP_PROPERTY' : 'GROUP_PROPERTY',
|
|
|
|
@ -273,7 +270,6 @@ def p_driver_assignment(p):
|
|
|
|
|
| PROTOCOL EQUALS id_or_str
|
|
|
|
|
| CLASS EQUALS id_or_str
|
|
|
|
|
| SIMULATION_GROUP EQUALS id_or_str
|
|
|
|
|
| USECREATENODE EQUALS true_false
|
|
|
|
|
| ADD_ARGS EQUALS TEXT_STRING
|
|
|
|
|
| MAKE_ARGS EQUALS TEXT_STRING
|
|
|
|
|
| PROTOCOL_ARGS EQUALS TEXT_STRING
|
|
|
|
@ -981,110 +977,6 @@ def put_pid_function(MyDriver, func):
|
|
|
|
|
txt += ['}']
|
|
|
|
|
emit(txt)
|
|
|
|
|
|
|
|
|
|
def put_create_node(MyDriver):
|
|
|
|
|
txt = ['']
|
|
|
|
|
txt += ['##']
|
|
|
|
|
txt += ['# @brief createNode() creates a node for the given nodename with the properties given']
|
|
|
|
|
txt += ['#']
|
|
|
|
|
txt += ['# @param scobj_hpath string variable holding the path to the object\'s base node in sics (/sample/tc1)']
|
|
|
|
|
txt += ['# @param sct_controller name of the scriptcontext object (typically sct_xxx_yyy)']
|
|
|
|
|
txt += ['# @param cmdGroup subdirectory (below /sample/tc*/) in which the node is to be created']
|
|
|
|
|
txt += ['# @param varName name of the actual node typically representing one device command']
|
|
|
|
|
txt += ['# @param readable set to 1 if the node represents a query command, 0 if it is not']
|
|
|
|
|
txt += ['# @param writable set to 1 if the node represents a request for a change in settings sent to the device']
|
|
|
|
|
txt += ['# @param drivable if set to 1 it prepares the node to provide a drivable interface']
|
|
|
|
|
txt += ['# @param dataType data type of the node, must be one of none, int, float, text']
|
|
|
|
|
txt += ['# @param permission defines what user group may read/write to this node (is one of spy, user, manager)']
|
|
|
|
|
txt += ['# @param rdCmd actual device query command to be sent to the device']
|
|
|
|
|
txt += ['# @param rdFunc nextState Function to be called after the getValue function, typically rdValue()']
|
|
|
|
|
txt += ['# @param wrCmd actual device write command to be sent to the device']
|
|
|
|
|
txt += ['# @param wrFunc Function to be called to send the wrCmd to the device, typically setValue()']
|
|
|
|
|
txt += ['# @param allowedValues allowed values for the node data - does not permit other']
|
|
|
|
|
txt += ['# @param klass Nexus class name (?)']
|
|
|
|
|
txt += ['# @return OK']
|
|
|
|
|
txt += ['proc %s::createNode {scobj_hpath sct_controller\\' %MyDriver['namespace']]
|
|
|
|
|
txt += [' cmdGroup varName\\']
|
|
|
|
|
txt += [' readable writable drivable\\']
|
|
|
|
|
txt += [' dataType permission\\']
|
|
|
|
|
txt += [' rdCmd rdFunc\\']
|
|
|
|
|
txt += [' wrCmd wrFunc\\']
|
|
|
|
|
txt += [' allowedValues klass} {']
|
|
|
|
|
txt += ['']
|
|
|
|
|
txt += [' set catch_status [ catch {']
|
|
|
|
|
txt += [' set ns "[namespace current]"']
|
|
|
|
|
txt += [' set nodeName "${scobj_hpath}/${cmdGroup}/${varName}"']
|
|
|
|
|
txt += [' if {1 > [string length ${cmdGroup}]} {']
|
|
|
|
|
txt += [' set nodeName "${scobj_hpath}/${varName}"']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' debug_log 1 "Creating node ${nodeName}"']
|
|
|
|
|
txt += [' hfactory ${nodeName} plain ${permission} ${dataType}']
|
|
|
|
|
txt += [' if {${readable} > 0} {']
|
|
|
|
|
txt += [' # the node is readable so set it up to be polled using the rdFunc']
|
|
|
|
|
txt += [' # rdFunc is getValueFunc.rdValueFunc with both explicit functions']
|
|
|
|
|
txt += [' # or rdValueFunc where "getValue" is the implied getValueFunc']
|
|
|
|
|
txt += [' set parts [split "${rdFunc}" "."]']
|
|
|
|
|
txt += [' if { [llength ${parts}] == 2 } {']
|
|
|
|
|
txt += [' set func_name [lindex ${parts} 0]']
|
|
|
|
|
txt += [' set next_state [lindex ${parts} 1]']
|
|
|
|
|
txt += [' } else {']
|
|
|
|
|
txt += [' set func_name "getValue"']
|
|
|
|
|
txt += [' set next_state [lindex ${parts} 0]']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' hsetprop ${nodeName} read ${ns}::${func_name} ${scobj_hpath} ${next_state} ${rdCmd}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} ${next_state} ${ns}::${next_state} ${scobj_hpath}']
|
|
|
|
|
txt += [' # set the poll rate as a period in seconds']
|
|
|
|
|
txt += [' # TODO allow directly settable value in seconds']
|
|
|
|
|
txt += [' set poll_period 5']
|
|
|
|
|
txt += [' if { ${readable} >= 0 && ${readable} <= 300 } {']
|
|
|
|
|
txt += [' set poll_period [expr {int(${readable})}]']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' debug_log 1 "Registering node ${nodeName} for poll at ${poll_period} seconds"']
|
|
|
|
|
txt += [' ${sct_controller} poll ${nodeName} ${poll_period}']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' if {${writable} > 0} {']
|
|
|
|
|
txt += [' # the node is writable so set it up to invoke a callback when written']
|
|
|
|
|
txt += [' # rdFunc is putValueFunc.chkWriteFunc with both explicit functions']
|
|
|
|
|
txt += [' # or putValueFunc where "noResponse" is the implied chkWriteFunc']
|
|
|
|
|
txt += [' set parts [split "${wrFunc}" "."]']
|
|
|
|
|
txt += [' if { [llength ${parts}] == 2 } {']
|
|
|
|
|
txt += [' set func_name [lindex ${parts} 0]']
|
|
|
|
|
txt += [' set next_state [lindex ${parts} 1]']
|
|
|
|
|
txt += [' } else {']
|
|
|
|
|
txt += [' set func_name [lindex ${parts} 0]']
|
|
|
|
|
txt += [' set next_state "noResponse"']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' hsetprop ${nodeName} write ${ns}::${func_name} ${scobj_hpath} ${next_state} ${wrCmd}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} ${next_state} ${ns}::${next_state} ${scobj_hpath}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} writestatus UNKNOWN']
|
|
|
|
|
txt += [' debug_log 1 "Registering node ${nodeName} for write callback"']
|
|
|
|
|
txt += [' ${sct_controller} write ${nodeName}']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' # Initialise the previous value to test against']
|
|
|
|
|
txt += [' switch -exact ${dataType} {']
|
|
|
|
|
txt += [' "none" { }']
|
|
|
|
|
txt += [' "int" { hsetprop ${nodeName} oldval -1 }']
|
|
|
|
|
txt += [' "float" { hsetprop ${nodeName} oldval -1.0 }']
|
|
|
|
|
txt += [' default { hsetprop ${nodeName} oldval UNKNOWN }']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' # Set the allowed values property']
|
|
|
|
|
txt += [' if {1 < [string length ${allowedValues}]} {']
|
|
|
|
|
txt += [' hsetprop ${nodeName} values ${allowedValues}']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' # Drive adapter interface']
|
|
|
|
|
txt += [' # TODO make it a separate function and pass in all this stuff']
|
|
|
|
|
txt += [' if {${drivable} > 0} {']
|
|
|
|
|
txt += [' hsetprop ${nodeName} check ${ns}::check ${scobj_hpath}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} driving 0']
|
|
|
|
|
txt += [' hsetprop ${nodeName} checklimits ${ns}::checklimits ${scobj_hpath}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} checkstatus ${ns}::checkstatus ${scobj_hpath}']
|
|
|
|
|
txt += [' hsetprop ${nodeName} halt ${ns}::halt ${scobj_hpath}']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' } catch_message ]']
|
|
|
|
|
txt += [' handle_exception ${catch_status} ${catch_message} "in [namespace current]::createNode"']
|
|
|
|
|
txt += [' return OK']
|
|
|
|
|
txt += ['}']
|
|
|
|
|
emit(txt)
|
|
|
|
|
|
|
|
|
|
def get_one_var(group_name, MyVar):
|
|
|
|
|
lst = [ group_name ]
|
|
|
|
|
lst.append(MyVar['name'])
|
|
|
|
@ -1283,51 +1175,9 @@ def put_mk_sct_driver(MyDriver):
|
|
|
|
|
txt += [' sicslist setatt ${name} %s "%s"' % (key, MyDriver['DriverProperty'][key])]
|
|
|
|
|
txt += ['']
|
|
|
|
|
txt += [' set scobj_hpath /sics/${name}']
|
|
|
|
|
if UsingCreateNode:
|
|
|
|
|
groups = MyDriver['Groups']
|
|
|
|
|
if len(groups) > 0:
|
|
|
|
|
for group in groups:
|
|
|
|
|
if group:
|
|
|
|
|
txt += [' hfactory ${scobj_hpath}/%s plain spy none' % group]
|
|
|
|
|
txt += ['']
|
|
|
|
|
device_commands = []
|
|
|
|
|
txt += [' set deviceCommand {']
|
|
|
|
|
for grp in sorted(MyDriver['Groups']):
|
|
|
|
|
if grp:
|
|
|
|
|
group_name = grp
|
|
|
|
|
else:
|
|
|
|
|
group_name = '{}'
|
|
|
|
|
for var in sorted(MyDriver['Groups'][grp]['Vars']):
|
|
|
|
|
device_commands.append(get_one_var(group_name, MyDriver['Groups'][grp]['Vars'][var]))
|
|
|
|
|
lens = {}
|
|
|
|
|
for cmd in device_commands:
|
|
|
|
|
for idx, val in enumerate(cmd):
|
|
|
|
|
if not idx in lens:
|
|
|
|
|
lens[idx] = 0
|
|
|
|
|
if len(val) > lens[idx]:
|
|
|
|
|
lens[idx] = len(val)
|
|
|
|
|
|
|
|
|
|
for cmd in device_commands:
|
|
|
|
|
line = ' '
|
|
|
|
|
for idx, val in enumerate(cmd):
|
|
|
|
|
line += " %-*s" % (lens[idx], val)
|
|
|
|
|
txt += [line + '\\']
|
|
|
|
|
txt += [' }']
|
|
|
|
|
txt += [' foreach { grpName varName\\']
|
|
|
|
|
txt += [' readable writeable driveable\\']
|
|
|
|
|
txt += [' dataType permission\\']
|
|
|
|
|
txt += [' rdCmd rdFunc wrCmd wrFunc allowedvalues} ${deviceCommand} {']
|
|
|
|
|
txt += [' createNode ${scobj_hpath} ${sct_controller}\\']
|
|
|
|
|
txt += [' ${cmdGroup} ${varName}\\']
|
|
|
|
|
txt += [' ${readable} ${writable} ${drivable}\\']
|
|
|
|
|
txt += [' ${dataType} ${permission}\\']
|
|
|
|
|
txt += [' ${rdCmd} ${rdFunc}\\']
|
|
|
|
|
txt += [' ${wrCmd} ${wrFunc}\\']
|
|
|
|
|
txt += [' ${allowedValues} %s' % MyDriver['class']]
|
|
|
|
|
txt += [' }']
|
|
|
|
|
else:
|
|
|
|
|
for group in sorted(MyDriver['Groups']):
|
|
|
|
|
txt += put_group(MyDriver, MyDriver['Groups'][group])
|
|
|
|
|
for group in sorted(MyDriver['Groups']):
|
|
|
|
|
txt += put_group(MyDriver, MyDriver['Groups'][group])
|
|
|
|
|
|
|
|
|
|
txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']]
|
|
|
|
|
if 'mkDriver' in MyDriver['Funcs']:
|
|
|
|
@ -1424,8 +1274,6 @@ def generate_driver(MyDriver):
|
|
|
|
|
fdo = open(full_filename, 'w')
|
|
|
|
|
put_preamble(MyDriver)
|
|
|
|
|
put_standard_code(MyDriver)
|
|
|
|
|
if UsingCreateNode:
|
|
|
|
|
put_create_node(MyDriver)
|
|
|
|
|
put_mk_sct_driver(MyDriver)
|
|
|
|
|
put_postamble(MyDriver)
|
|
|
|
|
fdo.close()
|
|
|
|
@ -1438,7 +1286,6 @@ def generate_driver(MyDriver):
|
|
|
|
|
print "Produced file %s with %d lines." % (filename, NumberOfLinesOut)
|
|
|
|
|
|
|
|
|
|
def process_drivers(TheDrivers):
|
|
|
|
|
global UsingCreateNode
|
|
|
|
|
if Verbose:
|
|
|
|
|
print "TheDrivers:", TheDrivers
|
|
|
|
|
for driver in TheDrivers:
|
|
|
|
@ -1449,11 +1296,6 @@ def process_drivers(TheDrivers):
|
|
|
|
|
build_driver(MyDriver, TheDrivers[driver])
|
|
|
|
|
if Verbose:
|
|
|
|
|
print "MyDriver:", MyDriver['name'], '=', MyDriver
|
|
|
|
|
if 'usecreatenode' in MyDriver:
|
|
|
|
|
if MyDriver['usecreatenode'] == 'true':
|
|
|
|
|
UsingCreateNode = True
|
|
|
|
|
else:
|
|
|
|
|
UsingCreateNode = False
|
|
|
|
|
generate_driver(MyDriver)
|
|
|
|
|
if DriverDump or Verbose:
|
|
|
|
|
dump_driver(MyDriver)
|
|
|
|
|