awlsim-test 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # AWL simulator - Commandline testing interface
  5. #
  6. # Copyright 2012-2018 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. def handle_MEMORY(self, memAreas):
  38. for memArea in memAreas:
  39. if memArea.flags & (memArea.FLG_ERR_READ |
  40. memArea.FLG_ERR_WRITE):
  41. raise AwlSimError("awlsim-test: "
  42. "Failed to access memory: %s" % (
  43. str(memArea)))
  44. class ConsoleSSHTunnel(SSHTunnel):
  45. def sshMessage(self, message, isDebug):
  46. if opt_loglevel > Logging.LOG_INFO:
  47. isDebug = False
  48. super(ConsoleSSHTunnel, self).sshMessage(message, isDebug)
  49. def usage():
  50. print("awlsim version %s" % VERSION_STRING)
  51. print("")
  52. print("Usage: awlsim-test [OPTIONS] <AWL-source or awlsim-project file>")
  53. print("")
  54. print("Options:")
  55. print(" -Y|--cycle-limit SEC Cycle time limit, in seconds (default 1.0)")
  56. print(" -M|--max-runtime SEC CPU will be stopped after SEC seconds (default: off)")
  57. print(" -2|--twoaccu Force 2-accu mode")
  58. print(" -4|--fouraccu Force 4-accu mode")
  59. print(" -D|--no-cpu-dump Do not show CPU status while running")
  60. print(" -x|--extended-insns Enable extended instructions")
  61. print(" -t|--obtemp 1/0 Enable/disable writing of OB-temp variables (Default: off)")
  62. print(" -T|--clock-mem ADDR Force clock memory address (Default: off)")
  63. print(" -m|--mnemonics auto Force mnemonics type: en, de, auto")
  64. print(" -O|--optimizers OPT Sets the optimization mode.")
  65. print(" OPT may be one of:")
  66. print(" default: Keep project settings (default)")
  67. print(" all: Enable all optimizers")
  68. print(" off: Disable all optimizers")
  69. print(" -L|--loglevel LVL Set the log level:")
  70. print(" 0: Log nothing")
  71. print(" 1: Log errors")
  72. print(" 2: Log errors and warnings")
  73. print(" 3: Log errors, warnings and info messages (default)")
  74. print(" 4: Verbose logging")
  75. print(" 5: Extremely verbose logging")
  76. print("")
  77. print("Server backend related options:")
  78. print(" -c|--connect Connect to server backend")
  79. print(" -C|--connect-to IP:PORT Connect to server backend")
  80. print(" -b|--spawn-backend Spawn a new backend server and connect to it")
  81. if not isWinStandalone:
  82. print(" -i|--interpreter EXE Set the backend interpreter executable")
  83. print(" -R|--mem-read AREA:OFFS:BITWIDTH Memory read access.")
  84. print(" -W|--mem-write AREA:OFFS:BITWIDTH:VAL Memory write access.")
  85. print("")
  86. print("Loading hardware modules:")
  87. print(" -H|--hardware NAME:PARAM=VAL:PARAM=VAL...")
  88. print("Print module information:")
  89. print(" -I|--hardware-info NAME")
  90. print("")
  91. print(" Where NAME is the name of the hardware module.")
  92. print(" PARAM=VAL are optional hardware specific parameters.")
  93. print("")
  94. print("Environment variables:")
  95. print(" AWLSIM_PROFILE =0 Disable profiling (default)")
  96. print(" =1 Enable core cycle profiling")
  97. print(" =2 Enable full core profiling (including startup)")
  98. print("")
  99. print(" AWLSIM_CYTHON =0 Do not attempt to use Cython core (default)")
  100. print(" =1 Attempt to use Cython core, but fall back to Python")
  101. print(" =2 Enforce Cython core")
  102. print("")
  103. print(" AWLSIM_AFFINITY =0,2,... Comma separated list of host CPU cores")
  104. print(" to run on. Default: all cores.")
  105. print(" AWLSIM_COVERAGE =DATAFILE Enable code coverage tracing.")
  106. def writeStdout(message):
  107. if Logging.loglevel >= Logging.LOG_INFO:
  108. sys.stdout.write(message)
  109. sys.stdout.flush()
  110. nextScreenUpdate = 0.0
  111. lastDump = ""
  112. lastDumpNrLines = 0
  113. emptyLine = " " * 79
  114. def clearConsole():
  115. # Make cursor visible, clear console and
  116. # move cursor to homeposition.
  117. if osIsPosix:
  118. writeStdout("\x1B[?25h\x1B[2J\x1B[H")
  119. elif osIsWindows:
  120. os.system("cls")
  121. def emitCpuDump(dump):
  122. global lastDump
  123. global lastDumpNrLines
  124. # Pad lines
  125. dumpLines = list(line + (78 - len(line)) * ' ' + '|'
  126. for line in dump.splitlines())
  127. dumpNrLines = len(dumpLines)
  128. # Clear lines from previous dump.
  129. if dumpNrLines < lastDumpNrLines:
  130. dumpLines.extend([ emptyLine, ] * (lastDumpNrLines - dumpNrLines))
  131. dump = "\n".join(dumpLines)
  132. lastDumpNrLines = dumpNrLines
  133. lastDump = dump
  134. if osIsPosix:
  135. # Clear console, move home and print dump.
  136. writeStdout("\x1B[2J\x1B[H" + dump)
  137. else:
  138. # Clear console, move home and print dump.
  139. clearConsole()
  140. writeStdout(dump)
  141. def emitSpeedDump(cpu):
  142. dump = "S7 CPU speed: %s stmt/s" % cpu.insnPerSecondHR
  143. dump += " " * (79 - len(dump))
  144. writeStdout("\x1B[2J\x1B[H" + dump + "\n")
  145. def cpuDumpCallback(cpu):
  146. global nextScreenUpdate
  147. if cpu.now >= nextScreenUpdate:
  148. nextScreenUpdate = cpu.now + 0.3
  149. emitCpuDump(str(cpu))
  150. def cpuStatsCallback(cpu):
  151. global nextScreenUpdate
  152. if cpu.now >= nextScreenUpdate:
  153. nextScreenUpdate = cpu.now + 1.0
  154. emitSpeedDump(cpu)
  155. def assignCpuSpecs(cpuSpecs, projectCpuSpecs):
  156. cpuSpecs.assignFrom(projectCpuSpecs)
  157. if opt_nrAccus is not None:
  158. cpuSpecs.setNrAccus(opt_nrAccus)
  159. def assignCpuConf(cpuConf, projectCpuConf):
  160. cpuConf.assignFrom(projectCpuConf)
  161. if opt_mnemonics is not None:
  162. cpuConf.setConfiguredMnemonics(opt_mnemonics)
  163. if opt_clockMem is not None:
  164. cpuConf.setClockMemByte(opt_clockMem)
  165. if opt_cycletime is not None:
  166. cpuConf.setCycleTimeLimitUs(int(round(opt_cycletime * 1000000.0)))
  167. if opt_maxRuntime is not None:
  168. cpuConf.setRunTimeLimitUs(int(round(opt_maxRuntime * 1000000.0)))
  169. if opt_obtemp is not None:
  170. cpuConf.setOBStartinfoEn(opt_obtemp)
  171. if opt_extInsns is not None:
  172. cpuConf.setExtInsnsEn(opt_extInsns)
  173. def readInputFile(inputFile):
  174. if inputFile == "-":
  175. if isPy2Compat:
  176. dataBytes = sys.stdin.read()
  177. else:
  178. dataBytes = sys.stdin.buffer.read()
  179. project = Project.fromProjectOrRawAwlData(dataBytes)
  180. else:
  181. project = Project.fromProjectOrRawAwlFile(inputFile)
  182. return project
  183. def run(inputFile):
  184. s = None
  185. try:
  186. if cython_helper.shouldUseCython():
  187. printInfo("*** Using accelerated CYTHON core "
  188. "(AWLSIM_CYTHON environment variable is set)")
  189. if opt_memReads or opt_memWrites:
  190. raise AwlSimError("awlsim-test --mem-read and --mem-write "
  191. "are not supported in non-server-mode.")
  192. project = readInputFile(inputFile)
  193. printInfo("Parsing code...")
  194. generatedAwlSrcs = []
  195. # Get mnemonics type
  196. mnemonics = project.getCpuConf().getConfiguredMnemonics()
  197. if opt_mnemonics is not None:
  198. mnemonics = opt_mnemonics
  199. # Parse FUP sources
  200. optSettCont = None
  201. if opt_optimizers == "off":
  202. optSettCont = AwlOptimizerSettingsContainer(globalEnable=False)
  203. elif opt_optimizers == "all":
  204. optSettCont = AwlOptimizerSettingsContainer(globalEnable=True,
  205. allEnable=True)
  206. for fupSrc in project.getFupSources():
  207. if not fupSrc.enabled:
  208. continue
  209. generatedAwlSrcs.append(FupCompiler().compile(
  210. fupSource=fupSrc,
  211. symTabSources=project.getSymTabSources(),
  212. mnemonics=mnemonics,
  213. optimizerSettingsContainer=optSettCont))
  214. # Parse KOP sources
  215. for kopSrc in project.getKopSources():
  216. if not kopSrc.enabled:
  217. continue
  218. pass#TODO
  219. # Parse AWL sources
  220. parseTrees = []
  221. for awlSrc in itertools.chain(project.getAwlSources(),
  222. generatedAwlSrcs):
  223. if not awlSrc.enabled:
  224. continue
  225. p = AwlParser()
  226. p.parseSource(awlSrc)
  227. parseTrees.append(p.getParseTree())
  228. # Parse symbol tables
  229. symTables = []
  230. for symTabSrc in project.getSymTabSources():
  231. if not symTabSrc.enabled:
  232. continue
  233. tab = SymTabParser.parseSource(symTabSrc,
  234. autodetectFormat = True,
  235. mnemonics = mnemonics)
  236. symTables.append(tab)
  237. printInfo("Initializing core...")
  238. s = AwlSim()
  239. s.reset()
  240. # Load hardware modules
  241. def loadMod(name, parameters):
  242. printInfo("Loading hardware module '%s'..." % name)
  243. hwClass = s.loadHardwareModule(name)
  244. s.registerHardwareClass(hwClass = hwClass,
  245. parameters = parameters)
  246. for modDesc in project.getHwmodSettings().getLoadedModules():
  247. loadMod(modDesc.getModuleName(),
  248. modDesc.getParameters())
  249. for name, parameters in opt_hwmods:
  250. loadMod(name, parameters)
  251. # Configure the CPU
  252. cpu = s.getCPU()
  253. assignCpuSpecs(cpu.getSpecs(), project.getCpuSpecs())
  254. assignCpuConf(cpu.getConf(), project.getCpuConf())
  255. if not opt_noCpuDump:
  256. if opt_speedStats:
  257. cpu.setBlockExitCallback(cpuStatsCallback, cpu)
  258. elif opt_loglevel >= Logging.LOG_INFO:
  259. cpu.setBlockExitCallback(cpuDumpCallback, cpu)
  260. # Download the program
  261. printInfo("Initializing CPU...")
  262. for symTable in symTables:
  263. s.loadSymbolTable(symTable)
  264. for libSel in project.getLibSelections():
  265. s.loadLibraryBlock(libSel)
  266. for parseTree in parseTrees:
  267. s.load(parseTree)
  268. # Run the program
  269. s.startup()
  270. printInfo("[Initialization finished - CPU is executing user code]")
  271. try:
  272. if not opt_noCpuDump:
  273. clearConsole()
  274. while 1:
  275. s.runCycle()
  276. finally:
  277. if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
  278. clearConsole()
  279. writeStdout(lastDump + '\n')
  280. except (AwlParserError, AwlSimError) as e:
  281. printError(e.getReport())
  282. return ExitCodes.EXIT_ERR_SIM
  283. except KeyboardInterrupt as e:
  284. pass
  285. except MaintenanceRequest as e:
  286. if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
  287. MaintenanceRequest.TYPE_STOP,
  288. MaintenanceRequest.TYPE_RTTIMEOUT):
  289. printInfo("Shutting down, as requested (%s)..." % str(e))
  290. else:
  291. printError("Received unknown maintenance request "
  292. "(%d: %s)..." % (e.requestType, str(e)))
  293. finally:
  294. if s:
  295. s.shutdown()
  296. return ExitCodes.EXIT_OK
  297. def runWithServerBackend(inputFile):
  298. client = None
  299. tunnel = None
  300. try:
  301. project = readInputFile(inputFile)
  302. linkSettings = project.getCoreLinkSettings()
  303. if opt_spawnBackend:
  304. host = AwlSimServer.DEFAULT_HOST
  305. port = range(AwlSimServer.DEFAULT_PORT,
  306. AwlSimServer.DEFAULT_PORT + 4096)
  307. else:
  308. host = linkSettings.getConnectHost()
  309. port = linkSettings.getConnectPort()
  310. if opt_connectTo:
  311. host, port = opt_connectTo
  312. # Establish SSH tunnel, if requested.
  313. if linkSettings.getTunnel() == linkSettings.TUNNEL_SSH and\
  314. not opt_spawnBackend:
  315. printInfo("Establishing SSH tunnel...")
  316. localPort = linkSettings.getTunnelLocalPort()
  317. if localPort == linkSettings.TUNNEL_LOCPORT_AUTO:
  318. localPort = None
  319. tunnel = ConsoleSSHTunnel(
  320. remoteHost = host,
  321. remotePort = port,
  322. localPort = localPort,
  323. sshUser = linkSettings.getSSHUser(),
  324. sshPort = linkSettings.getSSHPort(),
  325. sshExecutable = linkSettings.getSSHExecutable(),
  326. )
  327. host, port = tunnel.connect()
  328. # Connect to the server
  329. client = TestAwlSimClient()
  330. if opt_spawnBackend:
  331. client.spawnServer(interpreter = opt_interpreter,
  332. listenHost = host,
  333. listenPort = port)
  334. port = client.serverProcessPort
  335. printInfo("Connecting to core server...")
  336. client.connectToServer(host=host, port=port, timeout=20.0)
  337. printInfo("Initializing core...")
  338. client.setLoglevel(opt_loglevel)
  339. client.setRunState(False)
  340. client.reset()
  341. # Load hardware modules
  342. client.loadHardwareModules(project.getHwmodSettings().getLoadedModules())
  343. for name, parameters in opt_hwmods:
  344. client.loadHardwareModule(HwmodDescriptor(name, parameters))
  345. # Configure the core
  346. if opt_noCpuDump:
  347. client.setPeriodicDumpInterval(0)
  348. else:
  349. client.setPeriodicDumpInterval(300)
  350. specs = client.getCpuSpecs()
  351. assignCpuSpecs(specs, project.getCpuSpecs())
  352. client.setCpuSpecs(specs)
  353. conf = client.getCpuConf()
  354. assignCpuConf(conf, project.getCpuConf())
  355. client.setCpuConf(conf)
  356. #TODO configure optimizers
  357. # Fire up the core
  358. printInfo("Initializing CPU...")
  359. client.loadProject(project, loadCpuSpecs=False,
  360. loadCpuConf=False,
  361. loadHwMods=False)
  362. client.setRunState(True)
  363. # Run the client-side event loop
  364. printInfo("[Initialization finished - Remote-CPU is executing user code]")
  365. try:
  366. if opt_memReads:
  367. client.setMemoryReadRequests(memAreas=opt_memReads,
  368. repetitionPeriod=0.001,
  369. sync=False)
  370. if not opt_noCpuDump:
  371. clearConsole()
  372. while True:
  373. client.processMessages(timeout=0.05)
  374. if opt_memWrites:
  375. client.writeMemory(memAreas=opt_memWrites,
  376. sync=True)
  377. finally:
  378. if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
  379. clearConsole()
  380. writeStdout(lastDump + '\n')
  381. except AwlSimError as e:
  382. printError(e.getReport())
  383. return ExitCodes.EXIT_ERR_SIM
  384. except MaintenanceRequest as e:
  385. if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
  386. MaintenanceRequest.TYPE_STOP,
  387. MaintenanceRequest.TYPE_RTTIMEOUT):
  388. printInfo("Shutting down, as requested (%s)..." % str(e))
  389. else:
  390. printError("Received unknown maintenance request "
  391. "(%d: %s)..." % (e.requestType, str(e)))
  392. except KeyboardInterrupt as e:
  393. pass
  394. finally:
  395. if client:
  396. client.shutdown()
  397. if tunnel:
  398. tunnel.shutdown()
  399. return ExitCodes.EXIT_OK
  400. def __signalHandler(sig, frame):
  401. printInfo("Received signal %d" % sig)
  402. if sig == signal.SIGTERM:
  403. # Raise SIGINT. It will shut down everything.
  404. os.kill(os.getpid(), signal.SIGINT)
  405. def parseMemoryArea(memAreaStr, withData):
  406. try:
  407. def dataToBytes(value, length):
  408. if not (0 <= value <= ((1 << length) - 1)):
  409. raise ValueError
  410. return WordPacker.toBytes(byteBuffer=bytearray(length // 8),
  411. bitWidth=length,
  412. value=value)
  413. memAreaStr = memAreaStr.split(":")
  414. start = index = length = 0
  415. data = b''
  416. memType = {
  417. "E" : MemoryArea.TYPE_E,
  418. "A" : MemoryArea.TYPE_A,
  419. "M" : MemoryArea.TYPE_M,
  420. "L" : MemoryArea.TYPE_L,
  421. "DB" : MemoryArea.TYPE_DB,
  422. "T" : MemoryArea.TYPE_T,
  423. "Z" : MemoryArea.TYPE_Z,
  424. "STW" : MemoryArea.TYPE_STW,
  425. }[memAreaStr[0].upper().strip()]
  426. if memType in { MemoryArea.TYPE_E,
  427. MemoryArea.TYPE_A,
  428. MemoryArea.TYPE_M,
  429. MemoryArea.TYPE_L, }:
  430. start = int(memAreaStr[1])
  431. length = int(memAreaStr[2])
  432. if (not (0 <= start <= 0xFFFF) or
  433. length not in (8, 16, 32)):
  434. raise ValueError
  435. if withData:
  436. data = dataToBytes(int(memAreaStr[3]), length)
  437. elif memType == MemoryArea.TYPE_DB:
  438. index = int(memAreaStr[1])
  439. start = int(memAreaStr[2])
  440. length = int(memAreaStr[3])
  441. if (not (0 <= start <= 0xFFFF) or
  442. not (0 <= index <= 0xFFFF) or
  443. length not in (8, 16, 32)):
  444. raise ValueError
  445. if withData:
  446. data = dataToBytes(int(memAreaStr[4]), length)
  447. elif memType in { MemoryArea.TYPE_T,
  448. MemoryArea.TYPE_Z, }:
  449. index = int(memAreaStr[1])
  450. length = 16
  451. if not (0 <= index <= 0xFFFF):
  452. raise ValueError
  453. if withData:
  454. data = dataToBytes(int(memAreaStr[2]), 16)
  455. elif memType == MemoryArea.TYPE_STW:
  456. length = 16
  457. if withData:
  458. data = dataToBytes(int(memAreaStr[1]), 16)
  459. else:
  460. assert(0)
  461. return MemoryArea(memType=memType,
  462. flags=0,
  463. index=index,
  464. start=start,
  465. length=length // 8,
  466. data=data)
  467. except (ValueError, IndexError, KeyError, AwlSimError) as e:
  468. pass
  469. return None
  470. def main():
  471. global opt_cycletime
  472. global opt_maxRuntime
  473. global opt_noCpuDump
  474. global opt_speedStats
  475. global opt_nrAccus
  476. global opt_extInsns
  477. global opt_obtemp
  478. global opt_clockMem
  479. global opt_mnemonics
  480. global opt_optimizers
  481. global opt_hwmods
  482. global opt_hwinfos
  483. global opt_loglevel
  484. global opt_connect
  485. global opt_connectTo
  486. global opt_spawnBackend
  487. global opt_interpreter
  488. global opt_memReads
  489. global opt_memWrites
  490. opt_cycletime = None
  491. opt_maxRuntime = None
  492. opt_noCpuDump = False
  493. opt_speedStats = False
  494. opt_nrAccus = None
  495. opt_extInsns = None
  496. opt_obtemp = None
  497. opt_clockMem = None
  498. opt_mnemonics = None
  499. opt_optimizers = "default"
  500. opt_hwmods = []
  501. opt_hwinfos = []
  502. opt_loglevel = Logging.LOG_INFO
  503. opt_connect = None
  504. opt_connectTo = False
  505. opt_spawnBackend = False
  506. opt_interpreter = None
  507. opt_memReads = []
  508. opt_memWrites = []
  509. try:
  510. (opts, args) = getopt.getopt(sys.argv[1:],
  511. "hY:M:24qDSxt:T:m:O:H:I:P:L:cC:bi:R:W:",
  512. [ "help", "cycle-limit=", "max-runtime=", "twoaccu", "fouraccu",
  513. "quiet", "no-cpu-dump", "speed-stats", "extended-insns",
  514. "obtemp=", "clock-mem=", "mnemonics=", "optimizers=",
  515. "hardware=", "hardware-info=", "profile=",
  516. "loglevel=",
  517. "connect", "connect-to=", "spawn-backend", "interpreter=",
  518. "mem-read=", "mem-write=", ])
  519. except getopt.GetoptError as e:
  520. printError(str(e))
  521. usage()
  522. return ExitCodes.EXIT_ERR_CMDLINE
  523. for (o, v) in opts:
  524. if o in ("-h", "--help"):
  525. usage()
  526. return ExitCodes.EXIT_OK
  527. if o in ("-Y", "--cycle-limit"):
  528. try:
  529. opt_cycletime = float(v)
  530. except ValueError:
  531. printError("-Y|--cycle-limit: Invalid time format")
  532. sys.exit(1)
  533. if o in ("-M", "--max-runtime"):
  534. try:
  535. opt_maxRuntime = float(v)
  536. except ValueError:
  537. printError("-M|--max-runtime: Invalid time format")
  538. sys.exit(1)
  539. if o in ("-2", "--twoaccu"):
  540. opt_nrAccus = 2
  541. if o in ("-4", "--fouraccu"):
  542. opt_nrAccus = 4
  543. if o in ("-D", "--no-cpu-dump"):
  544. opt_noCpuDump = True
  545. if o in ("-S", "--speed-stats"):
  546. opt_speedStats = True
  547. if o in ("-x", "--extended-insns"):
  548. opt_extInsns = True
  549. if o in ("-t", "--obtemp"):
  550. opt_obtemp = str2bool(v)
  551. if o in ("-T", "--clock-mem"):
  552. try:
  553. opt_clockMem = int(v)
  554. if opt_clockMem < -1 or opt_clockMem > 0xFFFF:
  555. raise ValueError
  556. except ValueError:
  557. printError("-T|--clock-mem: Invalid byte address")
  558. sys.exit(1)
  559. if o in ("-m", "--mnemonics"):
  560. opt_mnemonics = v.lower()
  561. if opt_mnemonics not in ("en", "de", "auto"):
  562. printError("-m|--mnemonics: Invalid mnemonics type")
  563. sys.exit(1)
  564. if o in ("-O", "--optimizers"):
  565. try:
  566. modes = v.split(",")
  567. for mode in modes:
  568. mode = mode.lower()
  569. if mode in ("off", "all", "default"):
  570. opt_optimizers = mode
  571. else:
  572. printError("-O|--optimizers: Unknown optimizer: %s" % mode)
  573. sys.exit(1)
  574. except (ValueError, IndexError) as e:
  575. printError("-O|--optimizers: Invalid optimization mode")
  576. sys.exit(1)
  577. if o in ("-H", "--hardware"):
  578. try:
  579. v = v.split(':')
  580. if not v:
  581. raise ValueError
  582. name = v[0]
  583. params = {}
  584. for pstr in v[1:]:
  585. if not pstr:
  586. continue
  587. i = pstr.find('=')
  588. if i < 0:
  589. raise ValueError
  590. pname = pstr[:i]
  591. pval = pstr[i+1:]
  592. if not pname or not pval:
  593. raise ValueError
  594. params[pname] = pval
  595. opt_hwmods.append( (name, params) )
  596. except (ValueError, IndexError) as e:
  597. printError("-H|--hardware: Invalid module name or parameters")
  598. sys.exit(1)
  599. if o in ("-I", "--hardware-info"):
  600. opt_hwinfos.append(v.split(':')[0])
  601. if o in ("-L", "--loglevel"):
  602. try:
  603. opt_loglevel = int(v)
  604. except ValueError:
  605. printError("-L|--loglevel: Invalid log level")
  606. sys.exit(1)
  607. if o in ("-c", "--connect"):
  608. opt_connect = True
  609. if o in ("-C", "--connect-to"):
  610. try:
  611. idx = v.rfind(":")
  612. if idx <= 0:
  613. raise ValueError
  614. opt_connectTo = (v[:idx], int(v[idx+1:]))
  615. except ValueError:
  616. printError("-c|--connect: Invalid host/port")
  617. sys.exit(1)
  618. if o in ("-b", "--spawn-backend"):
  619. opt_spawnBackend = True
  620. if o in ("-i", "--interpreter"):
  621. if isWinStandalone:
  622. printError("-i|--interpreter not supported on win-standalone")
  623. sys.exit(1)
  624. opt_interpreter = v
  625. if o in ("-R", "--mem-read"):
  626. memArea = parseMemoryArea(v, withData=False)
  627. if not memArea:
  628. printError("-R|--mem-read invalid arguments.")
  629. sys.exit(1)
  630. opt_memReads.append(memArea)
  631. if o in ("-W", "--mem-write"):
  632. memArea = parseMemoryArea(v, withData=True)
  633. if not memArea:
  634. printError("-W|--mem-write invalid arguments.")
  635. sys.exit(1)
  636. opt_memWrites.append(memArea)
  637. if len(args) != 1 and not opt_hwinfos:
  638. usage()
  639. return ExitCodes.EXIT_ERR_CMDLINE
  640. if args:
  641. inputFile = args[0]
  642. Logging.setLoglevel(opt_loglevel)
  643. opt_mnemonics = {
  644. None : None,
  645. "en" : S7CPUConfig.MNEMONICS_EN,
  646. "de" : S7CPUConfig.MNEMONICS_DE,
  647. "auto" : S7CPUConfig.MNEMONICS_AUTO,
  648. }[opt_mnemonics]
  649. try:
  650. if opt_hwinfos:
  651. # Just print the hardware-infos and exit.
  652. for name in opt_hwinfos:
  653. cls = AwlSim.loadHardwareModule(name)
  654. print(cls.getModuleInfo())
  655. return ExitCodes.EXIT_OK
  656. except (AwlParserError, AwlSimError) as e:
  657. printError(e.getReport())
  658. return ExitCodes.EXIT_ERR_SIM
  659. signal.signal(signal.SIGTERM, __signalHandler)
  660. if opt_interpreter and not opt_spawnBackend:
  661. printError("Selected an --interpreter, but no "
  662. "--spawn-backend was requested.")
  663. return ExitCodes.EXIT_ERR_CMDLINE
  664. if opt_spawnBackend or opt_connect or opt_connectTo:
  665. return runWithServerBackend(inputFile)
  666. return run(inputFile)
  667. if __name__ == "__main__":
  668. sys.exit(main())