123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- #
- # AWL simulator - Commandline testing interface
- #
- # Copyright 2012-2018 Michael Buesch <m@bues.ch>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- #
- from __future__ import division, absolute_import, print_function, unicode_literals
- import sys
- import os
- import getopt
- import traceback
- import signal
- from awlsim_loader.common import *
- from awlsim_loader.core import *
- from awlsim_loader.coreclient import *
- from awlsim_loader.awlcompiler import *
- from awlsim_loader.fupcompiler import *
- import awlsim_loader.cython_helper as cython_helper
- class TestAwlSimClient(AwlSimClient):
- def handle_CPUDUMP(self, dumpText):
- emitCpuDump(dumpText)
- def handle_MEMORY(self, memAreas):
- for memArea in memAreas:
- if memArea.flags & (memArea.FLG_ERR_READ |
- memArea.FLG_ERR_WRITE):
- raise AwlSimError("awlsim-test: "
- "Failed to access memory: %s" % (
- str(memArea)))
- def usage():
- print("awlsim version %s" % VERSION_STRING)
- print("")
- print("Usage: awlsim-test [OPTIONS] <AWL-source or awlsim-project file>")
- print("")
- print("Options:")
- print(" -Y|--cycle-limit SEC Cycle time limit, in seconds (default 1.0)")
- print(" -M|--max-runtime SEC CPU will be stopped after SEC seconds (default: off)")
- print(" -2|--twoaccu Force 2-accu mode")
- print(" -4|--fouraccu Force 4-accu mode")
- print(" -D|--no-cpu-dump Do not show CPU status while running")
- print(" -x|--extended-insns Enable extended instructions")
- print(" -t|--obtemp 1/0 Enable/disable writing of OB-temp variables (Default: off)")
- print(" -T|--clock-mem ADDR Force clock memory address (Default: off)")
- print(" -m|--mnemonics auto Force mnemonics type: en, de, auto")
- print(" -O|--optimizers OPT Sets the optimization mode.")
- print(" OPT may be one of:")
- print(" default: Keep project settings (default)")
- print(" all: Enable all optimizers")
- print(" off: Disable all optimizers")
- print(" --insn-meas OUTFILE Detailed instruction timing measurements")
- print(" -L|--loglevel LVL Set the log level:")
- print(" 0: Log nothing")
- print(" 1: Log errors")
- print(" 2: Log errors and warnings")
- print(" 3: Log errors, warnings and info messages (default)")
- print(" 4: Verbose logging")
- print(" 5: Extremely verbose logging")
- print("")
- print("Server backend related options:")
- print(" -c|--connect Connect to server backend")
- print(" -C|--connect-to IP:PORT Connect to server backend")
- print(" -b|--spawn-backend Spawn a new backend server and connect to it")
- if not isWinStandalone:
- print(" -i|--interpreter EXE Set the backend interpreter executable")
- print(" -R|--mem-read AREA:OFFS:BITWIDTH Memory read access.")
- print(" -W|--mem-write AREA:OFFS:BITWIDTH:VAL Memory write access.")
- print("")
- print("Loading hardware modules:")
- print(" -H|--hardware NAME:PARAM=VAL:PARAM=VAL...")
- print("Print module information:")
- print(" -I|--hardware-info NAME")
- print("")
- print(" Where NAME is the name of the hardware module.")
- print(" PARAM=VAL are optional hardware specific parameters.")
- print("")
- print("Environment variables:")
- print(" AWLSIM_PROFILE =0 Disable profiling (default)")
- print(" =1 Enable core cycle profiling")
- print(" =2 Enable full core profiling (including startup)")
- print("")
- print(" AWLSIM_CYTHON =0 Do not attempt to use Cython core (default)")
- print(" =1 Attempt to use Cython core, but fall back to Python")
- print(" =2 Enforce Cython core")
- print("")
- print(" AWLSIM_AFFINITY =0,2,... Comma separated list of host CPU cores")
- print(" to run on. Default: all cores.")
- print(" AWLSIM_COVERAGE =DATAFILE Enable code coverage tracing.")
- def writeStdout(message):
- if Logging.loglevel >= Logging.LOG_INFO:
- sys.stdout.write(message)
- if not isMicroPython:
- sys.stdout.flush()
- nextScreenUpdate = 0.0
- lastDump = ""
- lastDumpNrLines = 0
- emptyLine = " " * 79
- def clearConsole():
- # Make cursor visible, clear console and
- # move cursor to homeposition.
- if osIsPosix:
- writeStdout("\x1B[?25h\x1B[2J\x1B[H")
- elif osIsWindows:
- os.system("cls")
- def emitCpuDump(dump):
- global lastDump
- global lastDumpNrLines
- # Pad lines
- dumpLines = list(line + (78 - len(line)) * ' ' + '|'
- for line in dump.splitlines())
- dumpNrLines = len(dumpLines)
- # Clear lines from previous dump.
- if dumpNrLines < lastDumpNrLines:
- dumpLines.extend([ emptyLine, ] * (lastDumpNrLines - dumpNrLines))
- dump = "\n".join(dumpLines)
- lastDumpNrLines = dumpNrLines
- lastDump = dump
- if osIsPosix:
- # Clear console, move home and print dump.
- writeStdout("\x1B[2J\x1B[H" + dump)
- else:
- # Clear console, move home and print dump.
- clearConsole()
- writeStdout(dump)
- def cpuBlockExitCallback(cpu):
- global nextScreenUpdate
- if cpu.now >= nextScreenUpdate:
- nextScreenUpdate = cpu.now + 0.3
- emitCpuDump(str(cpu))
- def assignCpuSpecs(cpuSpecs, projectCpuSpecs):
- cpuSpecs.assignFrom(projectCpuSpecs)
- if opt_nrAccus is not None:
- cpuSpecs.setNrAccus(opt_nrAccus)
- def assignCpuConf(cpuConf, projectCpuConf):
- cpuConf.assignFrom(projectCpuConf)
- if opt_mnemonics is not None:
- cpuConf.setConfiguredMnemonics(opt_mnemonics)
- if opt_clockMem is not None:
- cpuConf.setClockMemByte(opt_clockMem)
- if opt_cycletime is not None:
- cpuConf.setCycleTimeLimitUs(int(round(opt_cycletime * 1000000.0)))
- if opt_maxRuntime is not None:
- cpuConf.setRunTimeLimitUs(int(round(opt_maxRuntime * 1000000.0)))
- if opt_obtemp is not None:
- cpuConf.setOBStartinfoEn(opt_obtemp)
- if opt_extInsns is not None:
- cpuConf.setExtInsnsEn(opt_extInsns)
- def readInputFile(inputFile):
- if inputFile == "-":
- if isPy2Compat:
- dataBytes = sys.stdin.read()
- else:
- dataBytes = sys.stdin.buffer.read()
- project = Project.fromProjectOrRawAwlData(dataBytes)
- else:
- project = Project.fromProjectOrRawAwlFile(inputFile)
- return project
- def run(inputFile):
- insnMeas = None
- s = None
- try:
- if cython_helper.shouldUseCython():
- printInfo("*** Using accelerated CYTHON core "
- "(AWLSIM_CYTHON environment variable is set)")
- if opt_memReads or opt_memWrites:
- raise AwlSimError("awlsim-test --mem-read and --mem-write "
- "are not supported in non-server-mode.")
- project = readInputFile(inputFile)
- printInfo("Parsing code...")
- generatedAwlSrcs = []
- # Get mnemonics type
- mnemonics = project.getCpuConf().getConfiguredMnemonics()
- if opt_mnemonics is not None:
- mnemonics = opt_mnemonics
- # Parse FUP sources
- optSettCont = None
- if opt_optimizers == "off":
- optSettCont = AwlOptimizerSettingsContainer(globalEnable=False)
- elif opt_optimizers == "all":
- optSettCont = AwlOptimizerSettingsContainer(globalEnable=True,
- allEnable=True)
- for fupSrc in project.getFupSources():
- if not fupSrc.enabled:
- continue
- generatedAwlSrcs.append(FupCompiler().compile(
- fupSource=fupSrc,
- symTabSources=project.getSymTabSources(),
- mnemonics=mnemonics,
- optimizerSettingsContainer=optSettCont))
- # Parse KOP sources
- for kopSrc in project.getKopSources():
- if not kopSrc.enabled:
- continue
- pass#TODO
- # Parse AWL sources
- parseTrees = []
- for awlSrc in itertools.chain(project.getAwlSources(),
- generatedAwlSrcs):
- if not awlSrc.enabled:
- continue
- p = AwlParser()
- p.parseSource(awlSrc)
- parseTrees.append(p.getParseTree())
- # Parse symbol tables
- symTables = []
- for symTabSrc in project.getSymTabSources():
- if not symTabSrc.enabled:
- continue
- tab = SymTabParser.parseSource(symTabSrc,
- autodetectFormat = True,
- mnemonics = mnemonics)
- symTables.append(tab)
- printInfo("Initializing core...")
- s = AwlSim()
- s.reset()
- # Load hardware modules
- def loadMod(name, parameters):
- printInfo("Loading hardware module '%s'..." % name)
- hwClass = s.loadHardwareModule(name)
- s.registerHardwareClass(hwClass = hwClass,
- parameters = parameters)
- for modDesc in project.getHwmodSettings().getLoadedModules():
- loadMod(modDesc.getModuleName(),
- modDesc.getParameters())
- for name, parameters in opt_hwmods:
- loadMod(name, parameters)
- # Configure the CPU
- cpu = s.getCPU()
- assignCpuSpecs(cpu.getSpecs(), project.getCpuSpecs())
- assignCpuConf(cpu.getConf(), project.getCpuConf())
- if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
- cpu.setBlockExitCallback(cpuBlockExitCallback, cpu)
- # Download the program
- printInfo("Initializing CPU...")
- for symTable in symTables:
- s.loadSymbolTable(symTable)
- for libSel in project.getLibSelections():
- s.loadLibraryBlock(libSel)
- for parseTree in parseTrees:
- s.load(parseTree)
- s.build()
- if opt_insnMeas:
- insnMeas = cpu.setupInsnMeas()
- # Run the program
- s.startup()
- printInfo("[Initialization finished - CPU is executing user code]")
- try:
- if not opt_noCpuDump:
- clearConsole()
- while 1:
- s.runCycle()
- finally:
- if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
- clearConsole()
- writeStdout(lastDump + '\n')
- except (AwlParserError, AwlSimError) as e:
- printError(e.getReport())
- return ExitCodes.EXIT_ERR_SIM
- except KeyboardInterrupt as e:
- if insnMeas:
- if insnMeas.haveAnyMeasurements:
- if opt_insnMeas == "-":
- writeStdout(insnMeas.dump())
- else:
- with open(opt_insnMeas, "wb") as fd:
- fd.write(insnMeas.dumpCSV().encode("UTF-8"))
- else:
- printError("Instruction timing measurement: Not enough samples.")
- return ExitCodes.EXIT_ERR_OTHER
- except MaintenanceRequest as e:
- if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
- MaintenanceRequest.TYPE_STOP,
- MaintenanceRequest.TYPE_RTTIMEOUT):
- printInfo("Shutting down, as requested (%s)..." % str(e))
- else:
- printError("Received unknown maintenance request "
- "(%d: %s)..." % (e.requestType, str(e)))
- finally:
- if s:
- s.shutdown()
- return ExitCodes.EXIT_OK
- def runWithServerBackend(inputFile):
- client = None
- tunnel = None
- try:
- project = readInputFile(inputFile)
- linkSettings = project.getCoreLinkSettings()
- if opt_spawnBackend:
- host = AwlSimServer.DEFAULT_HOST
- port = range(AwlSimServer.DEFAULT_PORT,
- AwlSimServer.DEFAULT_PORT + 4096)
- else:
- host = linkSettings.getConnectHost()
- port = linkSettings.getConnectPort()
- if opt_connectTo:
- host, port = opt_connectTo
- # Establish SSH tunnel, if requested.
- if linkSettings.getTunnel() == linkSettings.TUNNEL_SSH and\
- not opt_spawnBackend:
- printInfo("Establishing SSH tunnel...")
- localPort = linkSettings.getTunnelLocalPort()
- if localPort == linkSettings.TUNNEL_LOCPORT_AUTO:
- localPort = None
- tunnel = SSHTunnel(
- remoteHost=host,
- remotePort=port,
- localPort=localPort,
- sshUser=linkSettings.getSSHUser(),
- sshPort=linkSettings.getSSHPort(),
- sshExecutable=linkSettings.getSSHExecutable(),
- )
- host, port = tunnel.connect()
- # Connect to the server
- client = TestAwlSimClient()
- if opt_spawnBackend:
- client.spawnServer(interpreter = opt_interpreter,
- listenHost = host,
- listenPort = port)
- port = client.serverProcessPort
- printInfo("Connecting to core server...")
- client.connectToServer(host=host, port=port, timeout=20.0)
- printInfo("Initializing core...")
- client.setLoglevel(opt_loglevel)
- client.setRunState(False)
- client.reset()
- # Load hardware modules
- client.loadHardwareModules(project.getHwmodSettings().getLoadedModules())
- for name, parameters in opt_hwmods:
- client.loadHardwareModule(HwmodDescriptor(name, parameters))
- # Configure the core
- if opt_noCpuDump:
- client.setPeriodicDumpInterval(0)
- else:
- client.setPeriodicDumpInterval(300)
- specs = client.getCpuSpecs()
- assignCpuSpecs(specs, project.getCpuSpecs())
- client.setCpuSpecs(specs)
- conf = client.getCpuConf()
- assignCpuConf(conf, project.getCpuConf())
- client.setCpuConf(conf)
- #TODO configure optimizers
- # Fire up the core
- printInfo("Initializing CPU...")
- client.loadProject(project, loadCpuSpecs=False,
- loadCpuConf=False,
- loadHwMods=False)
- client.setRunState(True)
- # Run the client-side event loop
- printInfo("[Initialization finished - Remote-CPU is executing user code]")
- try:
- if opt_memReads:
- client.setMemoryReadRequests(memAreas=opt_memReads,
- repetitionPeriod=0.001,
- sync=False)
- if not opt_noCpuDump:
- clearConsole()
- while True:
- client.processMessages(timeout=0.05)
- if opt_memWrites:
- client.writeMemory(memAreas=opt_memWrites,
- sync=True)
- finally:
- if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
- clearConsole()
- writeStdout(lastDump + '\n')
- except AwlSimError as e:
- printError(e.getReport())
- return ExitCodes.EXIT_ERR_SIM
- except MaintenanceRequest as e:
- if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
- MaintenanceRequest.TYPE_STOP,
- MaintenanceRequest.TYPE_RTTIMEOUT):
- printInfo("Shutting down, as requested (%s)..." % str(e))
- else:
- printError("Received unknown maintenance request "
- "(%d: %s)..." % (e.requestType, str(e)))
- except KeyboardInterrupt as e:
- pass
- finally:
- if client:
- client.shutdown()
- if tunnel:
- tunnel.shutdown()
- return ExitCodes.EXIT_OK
- def __signalHandler(sig, frame):
- printInfo("Received signal %d" % sig)
- if sig == signal.SIGTERM:
- # Raise SIGINT. It will shut down everything.
- os.kill(os.getpid(), signal.SIGINT)
- def parseMemoryArea(memAreaStr, withData):
- try:
- def dataToBytes(value, length):
- if not (0 <= value <= ((1 << length) - 1)):
- raise ValueError
- return WordPacker.toBytes(byteBuffer=bytearray(length // 8),
- bitWidth=length,
- value=value)
- memAreaStr = memAreaStr.split(":")
- start = index = length = 0
- data = b''
- memType = {
- "E" : MemoryArea.TYPE_E,
- "A" : MemoryArea.TYPE_A,
- "M" : MemoryArea.TYPE_M,
- "L" : MemoryArea.TYPE_L,
- "DB" : MemoryArea.TYPE_DB,
- "T" : MemoryArea.TYPE_T,
- "Z" : MemoryArea.TYPE_Z,
- "STW" : MemoryArea.TYPE_STW,
- }[memAreaStr[0].upper().strip()]
- if memType in { MemoryArea.TYPE_E,
- MemoryArea.TYPE_A,
- MemoryArea.TYPE_M,
- MemoryArea.TYPE_L, }:
- start = int(memAreaStr[1])
- length = int(memAreaStr[2])
- if (not (0 <= start <= 0xFFFF) or
- length not in (8, 16, 32)):
- raise ValueError
- if withData:
- data = dataToBytes(int(memAreaStr[3]), length)
- elif memType == MemoryArea.TYPE_DB:
- index = int(memAreaStr[1])
- start = int(memAreaStr[2])
- length = int(memAreaStr[3])
- if (not (0 <= start <= 0xFFFF) or
- not (0 <= index <= 0xFFFF) or
- length not in (8, 16, 32)):
- raise ValueError
- if withData:
- data = dataToBytes(int(memAreaStr[4]), length)
- elif memType in { MemoryArea.TYPE_T,
- MemoryArea.TYPE_Z, }:
- index = int(memAreaStr[1])
- length = 16
- if not (0 <= index <= 0xFFFF):
- raise ValueError
- if withData:
- data = dataToBytes(int(memAreaStr[2]), 16)
- elif memType == MemoryArea.TYPE_STW:
- length = 16
- if withData:
- data = dataToBytes(int(memAreaStr[1]), 16)
- else:
- assert(0)
- return MemoryArea(memType=memType,
- flags=0,
- index=index,
- start=start,
- length=length // 8,
- data=data)
- except (ValueError, IndexError, KeyError, AwlSimError) as e:
- pass
- return None
- def main():
- global opt_cycletime
- global opt_maxRuntime
- global opt_noCpuDump
- global opt_nrAccus
- global opt_extInsns
- global opt_obtemp
- global opt_clockMem
- global opt_mnemonics
- global opt_optimizers
- global opt_insnMeas
- global opt_hwmods
- global opt_hwinfos
- global opt_loglevel
- global opt_connect
- global opt_connectTo
- global opt_spawnBackend
- global opt_interpreter
- global opt_memReads
- global opt_memWrites
- opt_cycletime = None
- opt_maxRuntime = None
- opt_noCpuDump = False
- opt_nrAccus = None
- opt_extInsns = None
- opt_obtemp = None
- opt_clockMem = None
- opt_mnemonics = None
- opt_optimizers = "default"
- opt_insnMeas = None
- opt_hwmods = []
- opt_hwinfos = []
- opt_loglevel = Logging.LOG_INFO
- opt_connect = None
- opt_connectTo = False
- opt_spawnBackend = False
- opt_interpreter = None
- opt_memReads = []
- opt_memWrites = []
- try:
- (opts, args) = getopt.getopt(sys.argv[1:],
- "hY:M:24qDxt:T:m:O:H:I:P:L:cC:bi:R:W:",
- [ "help", "cycle-limit=", "max-runtime=", "twoaccu", "fouraccu",
- "quiet", "no-cpu-dump", "extended-insns",
- "obtemp=", "clock-mem=", "mnemonics=", "optimizers=",
- "hardware=", "hardware-info=", "profile=",
- "loglevel=",
- "connect", "connect-to=", "spawn-backend", "interpreter=",
- "mem-read=", "mem-write=",
- "insn-meas=", ])
- except getopt.GetoptError as e:
- printError(str(e))
- usage()
- return ExitCodes.EXIT_ERR_CMDLINE
- for (o, v) in opts:
- if o in ("-h", "--help"):
- usage()
- return ExitCodes.EXIT_OK
- if o in ("-Y", "--cycle-limit"):
- try:
- opt_cycletime = float(v)
- except ValueError:
- printError("-Y|--cycle-limit: Invalid time format")
- sys.exit(1)
- if o in ("-M", "--max-runtime"):
- try:
- opt_maxRuntime = float(v)
- except ValueError:
- printError("-M|--max-runtime: Invalid time format")
- sys.exit(1)
- if o in ("-2", "--twoaccu"):
- opt_nrAccus = 2
- if o in ("-4", "--fouraccu"):
- opt_nrAccus = 4
- if o in ("-D", "--no-cpu-dump"):
- opt_noCpuDump = True
- if o in ("-x", "--extended-insns"):
- opt_extInsns = True
- if o in ("-t", "--obtemp"):
- opt_obtemp = str2bool(v)
- if o in ("-T", "--clock-mem"):
- try:
- opt_clockMem = int(v)
- if opt_clockMem < -1 or opt_clockMem > 0xFFFF:
- raise ValueError
- except ValueError:
- printError("-T|--clock-mem: Invalid byte address")
- sys.exit(1)
- if o in ("-m", "--mnemonics"):
- opt_mnemonics = v.lower()
- if opt_mnemonics not in ("en", "de", "auto"):
- printError("-m|--mnemonics: Invalid mnemonics type")
- sys.exit(1)
- if o in ("-O", "--optimizers"):
- try:
- modes = v.split(",")
- for mode in modes:
- mode = mode.lower()
- if mode in ("off", "all", "default"):
- opt_optimizers = mode
- else:
- printError("-O|--optimizers: Unknown optimizer: %s" % mode)
- sys.exit(1)
- except (ValueError, IndexError) as e:
- printError("-O|--optimizers: Invalid optimization mode")
- sys.exit(1)
- if o == "--insn-meas":
- opt_insnMeas = v
- if o in ("-H", "--hardware"):
- try:
- v = v.split(':')
- if not v:
- raise ValueError
- name = v[0]
- params = {}
- for pstr in v[1:]:
- if not pstr:
- continue
- i = pstr.find('=')
- if i < 0:
- raise ValueError
- pname = pstr[:i]
- pval = pstr[i+1:]
- if not pname or not pval:
- raise ValueError
- params[pname] = pval
- opt_hwmods.append( (name, params) )
- except (ValueError, IndexError) as e:
- printError("-H|--hardware: Invalid module name or parameters")
- sys.exit(1)
- if o in ("-I", "--hardware-info"):
- opt_hwinfos.append(v.split(':')[0])
- if o in ("-L", "--loglevel"):
- try:
- opt_loglevel = int(v)
- except ValueError:
- printError("-L|--loglevel: Invalid log level")
- sys.exit(1)
- if o in ("-c", "--connect"):
- opt_connect = True
- if o in ("-C", "--connect-to"):
- try:
- idx = v.rfind(":")
- if idx <= 0:
- raise ValueError
- opt_connectTo = (v[:idx], int(v[idx+1:]))
- except ValueError:
- printError("-c|--connect: Invalid host/port")
- sys.exit(1)
- if o in ("-b", "--spawn-backend"):
- opt_spawnBackend = True
- if o in ("-i", "--interpreter"):
- if isWinStandalone:
- printError("-i|--interpreter not supported on win-standalone")
- sys.exit(1)
- opt_interpreter = v
- if o in ("-R", "--mem-read"):
- memArea = parseMemoryArea(v, withData=False)
- if not memArea:
- printError("-R|--mem-read invalid arguments.")
- sys.exit(1)
- opt_memReads.append(memArea)
- if o in ("-W", "--mem-write"):
- memArea = parseMemoryArea(v, withData=True)
- if not memArea:
- printError("-W|--mem-write invalid arguments.")
- sys.exit(1)
- opt_memWrites.append(memArea)
- if len(args) != 1 and not opt_hwinfos:
- usage()
- return ExitCodes.EXIT_ERR_CMDLINE
- if args:
- inputFile = args[0]
- Logging.setLoglevel(opt_loglevel)
- opt_mnemonics = {
- None : None,
- "en" : S7CPUConfig.MNEMONICS_EN,
- "de" : S7CPUConfig.MNEMONICS_DE,
- "auto" : S7CPUConfig.MNEMONICS_AUTO,
- }[opt_mnemonics]
- try:
- if opt_hwinfos:
- # Just print the hardware-infos and exit.
- for name in opt_hwinfos:
- cls = AwlSim.loadHardwareModule(name)
- print(cls.getModuleInfo())
- return ExitCodes.EXIT_OK
- except (AwlParserError, AwlSimError) as e:
- printError(e.getReport())
- return ExitCodes.EXIT_ERR_SIM
- signal.signal(signal.SIGTERM, __signalHandler)
- if opt_interpreter and not opt_spawnBackend:
- printError("Selected an --interpreter, but no "
- "--spawn-backend was requested.")
- return ExitCodes.EXIT_ERR_CMDLINE
- if opt_spawnBackend or opt_connect or opt_connectTo:
- return runWithServerBackend(inputFile)
- return run(inputFile)
- if __name__ == "__main__":
- sys.exit(main())
|