awlsim-test 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # AWL simulator - Commandline testing interface
  5. #
  6. # Copyright 2012-2016 Michael Buesch <m@bues.ch>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. #
  22. from __future__ import division, absolute_import, print_function, unicode_literals
  23. import sys
  24. import os
  25. import getopt
  26. import traceback
  27. import signal
  28. from awlsim_loader.common import *
  29. from awlsim_loader.core import *
  30. from awlsim_loader.coreclient import *
  31. from awlsim_loader.awlcompiler import *
  32. from awlsim_loader.fupcompiler import *
  33. import awlsim_loader.cython_helper as cython_helper
  34. class TestAwlSimClient(AwlSimClient):
  35. def handle_CPUDUMP(self, dumpText):
  36. emitCpuDump(dumpText)
  37. class ConsoleSSHTunnel(SSHTunnel):
  38. def sshMessage(self, message, isDebug):
  39. if opt_loglevel > Logging.LOG_INFO:
  40. isDebug = False
  41. super(ConsoleSSHTunnel, self).sshMessage(message, isDebug)
  42. def usage():
  43. print("awlsim version %s" % VERSION_STRING)
  44. print("")
  45. print("Usage: awlsim-test [OPTIONS] <AWL-source or awlsim-project file>")
  46. print("")
  47. print("Options:")
  48. print(" -Y|--cycle-limit SEC Cycle time limit, in seconds (default 5.0)")
  49. print(" -M|--max-runtime SEC CPU will be stopped after SEC seconds (default: off)")
  50. print(" -2|--twoaccu Force 2-accu mode")
  51. print(" -4|--fouraccu Force 4-accu mode")
  52. print(" -D|--no-cpu-dump Do not show CPU status while running")
  53. print(" -x|--extended-insns Enable extended instructions")
  54. print(" -t|--obtemp 1/0 Enable/disable writing of OB-temp variables (Default: off)")
  55. print(" -T|--clock-mem ADDR Force clock memory address (Default: off)")
  56. print(" -m|--mnemonics auto Force mnemonics type: en, de, auto")
  57. print(" -O|--optimizers OPT Sets the optimization mode.")
  58. print(" OPT may be one of:")
  59. print(" default: Keep project settings (default)")
  60. print(" all: Enable all optimizers")
  61. print(" off: Disable all optimizers")
  62. print(" -L|--loglevel LVL Set the log level:")
  63. print(" 0: Log nothing")
  64. print(" 1: Log errors")
  65. print(" 2: Log errors and warnings")
  66. print(" 3: Log errors, warnings and info messages (default)")
  67. print(" 4: Verbose logging")
  68. print(" 5: Extremely verbose logging")
  69. print("")
  70. print("Server backend related options:")
  71. print(" -c|--connect Connect to server backend")
  72. print(" -C|--connect-to IP:PORT Connect to server backend")
  73. print(" -b|--spawn-backend Spawn a new backend server and connect to it")
  74. if not isWinStandalone:
  75. print(" -i|--interpreter EXE Set the backend interpreter executable")
  76. print("")
  77. print("Loading hardware modules:")
  78. print(" -H|--hardware NAME:PARAM=VAL:PARAM=VAL...")
  79. print("Print module information:")
  80. print(" -I|--hardware-info NAME")
  81. print("")
  82. print(" Where NAME is the name of the hardware module.")
  83. print(" PARAM=VAL are optional hardware specific parameters.")
  84. print("")
  85. print("Other options:")
  86. print(" --list-sfc Print a list of all supported SFCs")
  87. print(" --list-sfc-verbose Verbose SFC list")
  88. print(" --list-sfb Print a list of all supported SFBs")
  89. print(" --list-sfb-verbose Verbose SFB list")
  90. print("")
  91. print("Environment variables:")
  92. print(" AWLSIM_PROFILE =0 Disable profiling (default)")
  93. print(" =1 Enable core cycle profiling")
  94. print(" =2 Enable full core profiling (including startup)")
  95. print("")
  96. print(" AWLSIM_CYTHON =0 Do not attempt to use Cython core (default)")
  97. print(" =1 Attempt to use Cython core, but fall back to Python")
  98. print(" =2 Enforce Cython core")
  99. print("")
  100. print(" AWLSIM_AFFINITY =0,2,... Comma separated list of host CPU cores")
  101. print(" to run on. Default: all cores.")
  102. def printSysblockInfo(blockTable, prefix, withExtended, withInterface):
  103. for block in sorted(dictValues(blockTable),
  104. key = lambda b: b.name[0]):
  105. if block.broken:
  106. continue
  107. number, name, desc = block.name
  108. if number < 0 and not withExtended:
  109. continue
  110. if desc:
  111. desc = " (%s)" % desc
  112. else:
  113. desc = ""
  114. print(" %s %d \"%s\"%s" % (prefix, number, name, desc))
  115. if withInterface:
  116. for ftype in (BlockInterfaceField.FTYPE_IN,
  117. BlockInterfaceField.FTYPE_OUT,
  118. BlockInterfaceField.FTYPE_INOUT):
  119. try:
  120. fields = block.interfaceFields[ftype]
  121. except KeyError:
  122. continue
  123. for field in fields:
  124. field.fieldType = ftype
  125. print(" %s" % str(field))
  126. def writeStdout(message):
  127. if Logging.loglevel >= Logging.LOG_INFO:
  128. sys.stdout.write(message)
  129. sys.stdout.flush()
  130. nextScreenUpdate = 0.0
  131. lastDump = ""
  132. lastDumpNrLines = 0
  133. emptyLine = " " * 79
  134. def clearConsole():
  135. # Make cursor visible, clear console and
  136. # move cursor to homeposition.
  137. if osIsPosix:
  138. writeStdout("\x1B[?25h\x1B[2J\x1B[H")
  139. elif osIsWindows:
  140. os.system("cls")
  141. def emitCpuDump(dump):
  142. global lastDump
  143. global lastDumpNrLines
  144. # Pad lines
  145. dumpLines = list(line + (78 - len(line)) * ' ' + '|'
  146. for line in dump.splitlines())
  147. dumpNrLines = len(dumpLines)
  148. # Clear lines from previous dump.
  149. if dumpNrLines < lastDumpNrLines:
  150. dumpLines.extend([ emptyLine, ] * (lastDumpNrLines - dumpNrLines))
  151. dump = "\n".join(dumpLines)
  152. lastDumpNrLines = dumpNrLines
  153. lastDump = dump
  154. if osIsPosix:
  155. # Clear console, move home and print dump.
  156. writeStdout("\x1B[2J\x1B[H" + dump)
  157. else:
  158. # Clear console, move home and print dump.
  159. clearConsole()
  160. writeStdout(dump)
  161. def emitSpeedDump(cpu):
  162. dump = "S7 CPU speed: %s stmt/s" % cpu.insnPerSecondHR
  163. dump += " " * (79 - len(dump))
  164. writeStdout("\x1B[2J\x1B[H" + dump + "\n")
  165. def cpuDumpCallback(cpu):
  166. global nextScreenUpdate
  167. if cpu.now >= nextScreenUpdate:
  168. nextScreenUpdate = cpu.now + 0.3
  169. emitCpuDump(str(cpu))
  170. def cpuStatsCallback(cpu):
  171. global nextScreenUpdate
  172. if cpu.now >= nextScreenUpdate:
  173. nextScreenUpdate = cpu.now + 1.0
  174. emitSpeedDump(cpu)
  175. def assignCpuSpecs(cpuSpecs, projectCpuSpecs):
  176. cpuSpecs.assignFrom(projectCpuSpecs)
  177. if opt_nrAccus is not None:
  178. cpuSpecs.setNrAccus(opt_nrAccus)
  179. def assignCpuConf(cpuConf, projectCpuConf):
  180. cpuConf.assignFrom(projectCpuConf)
  181. if opt_mnemonics is not None:
  182. cpuConf.setConfiguredMnemonics(opt_mnemonics)
  183. if opt_clockMem is not None:
  184. cpuConf.setClockMemByte(opt_clockMem)
  185. def run(inputFile):
  186. s = None
  187. try:
  188. if cython_helper.shouldUseCython():
  189. printInfo("*** Using accelerated CYTHON core "
  190. "(AWLSIM_CYTHON environment variable is set)")
  191. project = Project.fromProjectOrRawAwlFile(inputFile)
  192. printInfo("Parsing code...")
  193. generatedAwlSrcs = []
  194. # Get mnemonics type
  195. mnemonics = project.getCpuConf().getConfiguredMnemonics()
  196. if opt_mnemonics is not None:
  197. mnemonics = opt_mnemonics
  198. # Parse FUP sources
  199. optSettCont = None
  200. if opt_optimizers == "off":
  201. optSettCont = AwlOptimizerSettingsContainer(globalEnable=False)
  202. elif opt_optimizers == "all":
  203. optSettCont = AwlOptimizerSettingsContainer(globalEnable=True,
  204. allEnable=True)
  205. for fupSrc in project.getFupSources():
  206. if not fupSrc.enabled:
  207. continue
  208. generatedAwlSrcs.append(FupCompiler().compile(
  209. fupSource=fupSrc,
  210. symTabSources=project.getSymTabSources(),
  211. mnemonics=mnemonics,
  212. optimizerSettingsContainer=optSettCont))
  213. # Parse KOP sources
  214. for kopSrc in project.getKopSources():
  215. if not kopSrc.enabled:
  216. continue
  217. pass#TODO
  218. # Parse AWL sources
  219. parseTrees = []
  220. for awlSrc in itertools.chain(project.getAwlSources(),
  221. generatedAwlSrcs):
  222. if not awlSrc.enabled:
  223. continue
  224. p = AwlParser()
  225. p.parseSource(awlSrc)
  226. parseTrees.append(p.getParseTree())
  227. # Parse symbol tables
  228. symTables = []
  229. for symTabSrc in project.getSymTabSources():
  230. if not symTabSrc.enabled:
  231. continue
  232. tab = SymTabParser.parseSource(symTabSrc,
  233. autodetectFormat = True,
  234. mnemonics = mnemonics)
  235. symTables.append(tab)
  236. printInfo("Initializing core...")
  237. s = AwlSim()
  238. s.reset()
  239. # Load hardware modules
  240. def loadMod(name, parameters):
  241. printInfo("Loading hardware module '%s'..." % name)
  242. hwClass = s.loadHardwareModule(name)
  243. s.registerHardwareClass(hwClass = hwClass,
  244. parameters = parameters)
  245. for modDesc in project.getHwmodSettings().getLoadedModules():
  246. loadMod(modDesc.getModuleName(),
  247. modDesc.getParameters())
  248. for name, parameters in opt_hwmods:
  249. loadMod(name, parameters)
  250. # Configure the CPU
  251. cpu = s.getCPU()
  252. assignCpuSpecs(cpu.getSpecs(), project.getCpuSpecs())
  253. assignCpuConf(cpu.getConf(), project.getCpuConf())
  254. cpu.enableObTempPresets(project.getObTempPresetsEn() or opt_obtemp)
  255. cpu.enableExtendedInsns(project.getExtInsnsEn() or opt_extInsns)
  256. if not opt_noCpuDump:
  257. if opt_speedStats:
  258. cpu.setBlockExitCallback(cpuStatsCallback, cpu)
  259. elif opt_loglevel >= Logging.LOG_INFO:
  260. cpu.setBlockExitCallback(cpuDumpCallback, cpu)
  261. cpu.setCycleTimeLimit(opt_cycletime)
  262. cpu.setRunTimeLimit(opt_maxRuntime)
  263. # Download the program
  264. printInfo("Initializing CPU...")
  265. for symTable in symTables:
  266. s.loadSymbolTable(symTable)
  267. for libSel in project.getLibSelections():
  268. s.loadLibraryBlock(libSel)
  269. for parseTree in parseTrees:
  270. s.load(parseTree)
  271. # Run the program
  272. s.startup()
  273. printInfo("[Initialization finished - CPU is executing user code]")
  274. try:
  275. if not opt_noCpuDump:
  276. clearConsole()
  277. while 1:
  278. s.runCycle()
  279. finally:
  280. if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
  281. clearConsole()
  282. writeStdout(lastDump + '\n')
  283. except (AwlParserError, AwlSimError) as e:
  284. printError(e.getReport())
  285. return ExitCodes.EXIT_ERR_SIM
  286. except KeyboardInterrupt as e:
  287. pass
  288. except MaintenanceRequest as e:
  289. if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
  290. MaintenanceRequest.TYPE_STOP,
  291. MaintenanceRequest.TYPE_RTTIMEOUT):
  292. printInfo("Shutting down, as requested (%s)..." % str(e))
  293. else:
  294. printError("Received unknown maintenance request "
  295. "(%d: %s)..." % (e.requestType, str(e)))
  296. finally:
  297. if s:
  298. s.shutdown()
  299. return ExitCodes.EXIT_OK
  300. def runWithServerBackend(inputFile):
  301. client = None
  302. tunnel = None
  303. try:
  304. project = Project.fromProjectOrRawAwlFile(inputFile)
  305. linkSettings = project.getCoreLinkSettings()
  306. if opt_spawnBackend:
  307. host = AwlSimServer.DEFAULT_HOST
  308. port = range(AwlSimServer.DEFAULT_PORT,
  309. AwlSimServer.DEFAULT_PORT + 4096)
  310. else:
  311. host = linkSettings.getConnectHost()
  312. port = linkSettings.getConnectPort()
  313. if opt_connectTo:
  314. host, port = opt_connectTo
  315. # Establish SSH tunnel, if requested.
  316. if linkSettings.getTunnel() == linkSettings.TUNNEL_SSH and\
  317. not opt_spawnBackend:
  318. printInfo("Establishing SSH tunnel...")
  319. localPort = linkSettings.getTunnelLocalPort()
  320. if localPort == linkSettings.TUNNEL_LOCPORT_AUTO:
  321. localPort = None
  322. tunnel = ConsoleSSHTunnel(
  323. remoteHost = host,
  324. remotePort = port,
  325. localPort = localPort,
  326. sshUser = linkSettings.getSSHUser(),
  327. sshPort = linkSettings.getSSHPort(),
  328. sshExecutable = linkSettings.getSSHExecutable(),
  329. )
  330. host, port = tunnel.connect()
  331. # Connect to the server
  332. client = TestAwlSimClient()
  333. if opt_spawnBackend:
  334. client.spawnServer(interpreter = opt_interpreter,
  335. listenHost = host,
  336. listenPort = port)
  337. port = client.serverProcessPort
  338. printInfo("Connecting to core server...")
  339. client.connectToServer(host=host, port=port, timeout=20.0)
  340. printInfo("Initializing core...")
  341. client.setLoglevel(opt_loglevel)
  342. client.setRunState(False)
  343. client.reset()
  344. # Load hardware modules
  345. client.loadHardwareModules(project.getHwmodSettings().getLoadedModules())
  346. for name, parameters in opt_hwmods:
  347. client.loadHardwareModule(HwmodDescriptor(name, parameters))
  348. # Configure the core
  349. if opt_noCpuDump:
  350. client.setPeriodicDumpInterval(0)
  351. else:
  352. client.setPeriodicDumpInterval(300)
  353. client.enableOBTempPresets(project.getObTempPresetsEn() or opt_obtemp)
  354. client.enableExtendedInsns(project.getExtInsnsEn() or opt_extInsns)
  355. client.setCycleTimeLimit(opt_cycletime)
  356. client.setRunTimeLimit(opt_maxRuntime)
  357. specs = client.getCpuSpecs()
  358. assignCpuSpecs(specs, project.getCpuSpecs())
  359. client.setCpuSpecs(specs)
  360. conf = client.getCpuConf()
  361. assignCpuConf(conf, project.getCpuConf())
  362. client.setCpuConf(conf)
  363. #TODO configure optimizers
  364. # Fire up the core
  365. printInfo("Initializing CPU...")
  366. client.loadProject(project, loadCpuSpecs=False,
  367. loadCpuConf=False,
  368. loadTempPresets=False,
  369. loadExtInsns=False,
  370. loadHwMods=False)
  371. client.setRunState(True)
  372. # Run the client-side event loop
  373. printInfo("[Initialization finished - Remote-CPU is executing user code]")
  374. try:
  375. if not opt_noCpuDump:
  376. clearConsole()
  377. while True:
  378. client.processMessages(None)
  379. finally:
  380. if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
  381. clearConsole()
  382. writeStdout(lastDump + '\n')
  383. except AwlSimError as e:
  384. printError(e.getReport())
  385. return ExitCodes.EXIT_ERR_SIM
  386. except MaintenanceRequest as e:
  387. if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
  388. MaintenanceRequest.TYPE_STOP,
  389. MaintenanceRequest.TYPE_RTTIMEOUT):
  390. printInfo("Shutting down, as requested (%s)..." % str(e))
  391. else:
  392. printError("Received unknown maintenance request "
  393. "(%d: %s)..." % (e.requestType, str(e)))
  394. except KeyboardInterrupt as e:
  395. pass
  396. finally:
  397. if tunnel:
  398. tunnel.shutdown()
  399. if client:
  400. client.shutdown()
  401. return ExitCodes.EXIT_OK
  402. def __signalHandler(sig, frame):
  403. printInfo("Received signal %d" % sig)
  404. if sig == signal.SIGTERM:
  405. # Raise SIGINT. It will shut down everything.
  406. os.kill(os.getpid(), signal.SIGINT)
  407. def main():
  408. global opt_cycletime
  409. global opt_maxRuntime
  410. global opt_noCpuDump
  411. global opt_speedStats
  412. global opt_nrAccus
  413. global opt_extInsns
  414. global opt_obtemp
  415. global opt_clockMem
  416. global opt_mnemonics
  417. global opt_optimizers
  418. global opt_hwmods
  419. global opt_hwinfos
  420. global opt_loglevel
  421. global opt_connect
  422. global opt_connectTo
  423. global opt_spawnBackend
  424. global opt_interpreter
  425. opt_cycletime = 5.0
  426. opt_maxRuntime = -1.0
  427. opt_noCpuDump = False
  428. opt_speedStats = False
  429. opt_nrAccus = None
  430. opt_extInsns = False
  431. opt_obtemp = False
  432. opt_clockMem = None
  433. opt_mnemonics = None
  434. opt_optimizers = "default"
  435. opt_hwmods = []
  436. opt_hwinfos = []
  437. opt_loglevel = Logging.LOG_INFO
  438. opt_connect = None
  439. opt_connectTo = False
  440. opt_spawnBackend = False
  441. opt_interpreter = None
  442. try:
  443. (opts, args) = getopt.getopt(sys.argv[1:],
  444. "hY:M:24qDSxt:T:m:O:H:I:P:L:cC:bi:",
  445. [ "help", "cycle-limit=", "max-runtime=", "twoaccu", "fouraccu",
  446. "quiet", "no-cpu-dump", "speed-stats", "extended-insns",
  447. "obtemp=", "clock-mem=", "mnemonics=", "optimizers=",
  448. "hardware=", "hardware-info=", "profile=",
  449. "loglevel=",
  450. "connect", "connect-to=", "spawn-backend", "interpreter=",
  451. "list-sfc", "list-sfc-verbose",
  452. "list-sfb", "list-sfb-verbose", ])
  453. except getopt.GetoptError as e:
  454. printError(str(e))
  455. usage()
  456. return ExitCodes.EXIT_ERR_CMDLINE
  457. for (o, v) in opts:
  458. if o in ("-h", "--help"):
  459. usage()
  460. return ExitCodes.EXIT_OK
  461. if o in ("-Y", "--cycle-limit"):
  462. try:
  463. opt_cycletime = float(v)
  464. except ValueError:
  465. printError("-Y|--cycle-limit: Invalid time format")
  466. sys.exit(1)
  467. if o in ("-M", "--max-runtime"):
  468. try:
  469. opt_maxRuntime = float(v)
  470. except ValueError:
  471. printError("-M|--max-runtime: Invalid time format")
  472. sys.exit(1)
  473. if o in ("-2", "--twoaccu"):
  474. opt_nrAccus = 2
  475. if o in ("-4", "--fouraccu"):
  476. opt_nrAccus = 4
  477. if o in ("-D", "--no-cpu-dump"):
  478. opt_noCpuDump = True
  479. if o in ("-S", "--speed-stats"):
  480. opt_speedStats = True
  481. if o in ("-x", "--extended-insns"):
  482. opt_extInsns = True
  483. if o in ("-t", "--obtemp"):
  484. opt_obtemp = str2bool(v)
  485. if o in ("-T", "--clock-mem"):
  486. try:
  487. opt_clockMem = int(v)
  488. if opt_clockMem < -1 or opt_clockMem > 0xFFFF:
  489. raise ValueError
  490. except ValueError:
  491. printError("-T|--clock-mem: Invalid byte address")
  492. sys.exit(1)
  493. if o in ("-m", "--mnemonics"):
  494. opt_mnemonics = v.lower()
  495. if opt_mnemonics not in ("en", "de", "auto"):
  496. printError("-m|--mnemonics: Invalid mnemonics type")
  497. sys.exit(1)
  498. if o in ("-O", "--optimizers"):
  499. try:
  500. modes = v.split(",")
  501. for mode in modes:
  502. mode = mode.lower()
  503. if mode in ("off", "all", "default"):
  504. opt_optimizers = mode
  505. else:
  506. printError("-O|--optimizers: Unknown optimizer: %s" % mode)
  507. sys.exit(1)
  508. except (ValueError, IndexError) as e:
  509. printError("-O|--optimizers: Invalid optimization mode")
  510. sys.exit(1)
  511. if o in ("-H", "--hardware"):
  512. try:
  513. v = v.split(':')
  514. if not v:
  515. raise ValueError
  516. name = v[0]
  517. params = {}
  518. for pstr in v[1:]:
  519. if not pstr:
  520. continue
  521. i = pstr.find('=')
  522. if i < 0:
  523. raise ValueError
  524. pname = pstr[:i]
  525. pval = pstr[i+1:]
  526. if not pname or not pval:
  527. raise ValueError
  528. params[pname] = pval
  529. opt_hwmods.append( (name, params) )
  530. except (ValueError, IndexError) as e:
  531. printError("-H|--hardware: Invalid module name or parameters")
  532. sys.exit(1)
  533. if o in ("-I", "--hardware-info"):
  534. opt_hwinfos.append(v.split(':')[0])
  535. if o in ("-L", "--loglevel"):
  536. try:
  537. opt_loglevel = int(v)
  538. except ValueError:
  539. printError("-L|--loglevel: Invalid log level")
  540. sys.exit(1)
  541. if o in ("-c", "--connect"):
  542. opt_connect = True
  543. if o in ("-C", "--connect-to"):
  544. try:
  545. idx = v.rfind(":")
  546. if idx <= 0:
  547. raise ValueError
  548. opt_connectTo = (v[:idx], int(v[idx+1:]))
  549. except ValueError:
  550. printError("-c|--connect: Invalid host/port")
  551. sys.exit(1)
  552. if o in ("-b", "--spawn-backend"):
  553. opt_spawnBackend = True
  554. if o in ("-i", "--interpreter"):
  555. if isWinStandalone:
  556. printError("-i|--interpreter not supported on win-standalone")
  557. sys.exit(1)
  558. opt_interpreter = v
  559. if o in ("--list-sfc", "--list-sfc-verbose"):
  560. print("The supported system functions (SFCs) are:")
  561. from awlsim.core.systemblocks.tables import SFC_table
  562. printSysblockInfo(SFC_table, "SFC", opt_extInsns,
  563. o.endswith("verbose"))
  564. return ExitCodes.EXIT_OK
  565. if o in ("--list-sfb", "--list-sfb-verbose"):
  566. print("The supported system function blocks (SFBs) are:")
  567. from awlsim.core.systemblocks.tables import SFB_table
  568. printSysblockInfo(SFB_table, "SFB", opt_extInsns,
  569. o.endswith("verbose"))
  570. return ExitCodes.EXIT_OK
  571. if len(args) != 1 and not opt_hwinfos:
  572. usage()
  573. return ExitCodes.EXIT_ERR_CMDLINE
  574. if args:
  575. inputFile = args[0]
  576. Logging.setLoglevel(opt_loglevel)
  577. opt_mnemonics = {
  578. None : None,
  579. "en" : S7CPUConfig.MNEMONICS_EN,
  580. "de" : S7CPUConfig.MNEMONICS_DE,
  581. "auto" : S7CPUConfig.MNEMONICS_AUTO,
  582. }[opt_mnemonics]
  583. try:
  584. if opt_hwinfos:
  585. # Just print the hardware-infos and exit.
  586. for name in opt_hwinfos:
  587. cls = AwlSim.loadHardwareModule(name)
  588. print(cls.getModuleInfo())
  589. return ExitCodes.EXIT_OK
  590. except (AwlParserError, AwlSimError) as e:
  591. printError(e.getReport())
  592. return ExitCodes.EXIT_ERR_SIM
  593. signal.signal(signal.SIGTERM, __signalHandler)
  594. if opt_interpreter and not opt_spawnBackend:
  595. printError("Selected an --interpreter, but no "
  596. "--spawn-backend was requested.")
  597. return ExitCodes.EXIT_ERR_CMDLINE
  598. if opt_spawnBackend or opt_connect or opt_connectTo:
  599. return runWithServerBackend(inputFile)
  600. return run(inputFile)
  601. if __name__ == "__main__":
  602. sys.exit(main())