Keyboard firmwares for Atmel AVR and Cortex-M
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. """
  2. mbed SDK
  3. Copyright (c) 2011-2013 ARM Limited
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. """
  14. # Check if 'serial' module is installed
  15. try:
  16. from serial import Serial
  17. except ImportError, e:
  18. print "Error: Can't import 'serial' module: %s"% e
  19. exit(-1)
  20. import os
  21. import re
  22. import types
  23. from sys import stdout
  24. from time import sleep, time
  25. from optparse import OptionParser
  26. import host_tests_plugins
  27. # This is a little tricky. We need to add upper directory to path so
  28. # we can find packages we want from the same level as other files do
  29. import sys
  30. sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
  31. class Mbed:
  32. """ Base class for a host driven test
  33. """
  34. def __init__(self):
  35. parser = OptionParser()
  36. parser.add_option("-m", "--micro",
  37. dest="micro",
  38. help="The target microcontroller",
  39. metavar="MICRO")
  40. parser.add_option("-p", "--port",
  41. dest="port",
  42. help="The serial port of the target mbed",
  43. metavar="PORT")
  44. parser.add_option("-d", "--disk",
  45. dest="disk",
  46. help="The target disk path",
  47. metavar="DISK_PATH")
  48. parser.add_option("-f", "--image-path",
  49. dest="image_path",
  50. help="Path with target's image",
  51. metavar="IMAGE_PATH")
  52. parser.add_option("-c", "--copy",
  53. dest="copy_method",
  54. help="Copy method selector",
  55. metavar="COPY_METHOD")
  56. parser.add_option("-C", "--program_cycle_s",
  57. dest="program_cycle_s",
  58. help="Program cycle sleep. Define how many seconds you want wait after copying bianry onto target",
  59. type="float",
  60. metavar="COPY_METHOD")
  61. parser.add_option("-t", "--timeout",
  62. dest="timeout",
  63. help="Timeout",
  64. metavar="TIMEOUT")
  65. parser.add_option("-r", "--reset",
  66. dest="forced_reset_type",
  67. help="Forces different type of reset")
  68. parser.add_option("-R", "--reset-timeout",
  69. dest="forced_reset_timeout",
  70. metavar="NUMBER",
  71. type="int",
  72. help="When forcing a reset using option -r you can set up after reset timeout in seconds")
  73. (self.options, _) = parser.parse_args()
  74. self.DEFAULT_RESET_TOUT = 0
  75. self.DEFAULT_TOUT = 10
  76. if self.options.port is None:
  77. raise Exception("The serial port of the target mbed have to be provided as command line arguments")
  78. # Options related to copy / reset mbed device
  79. self.port = self.options.port
  80. self.disk = self.options.disk
  81. self.image_path = self.options.image_path.strip('"')
  82. self.copy_method = self.options.copy_method
  83. self.program_cycle_s = float(self.options.program_cycle_s)
  84. self.serial = None
  85. self.serial_baud = 9600
  86. self.serial_timeout = 1
  87. self.timeout = self.DEFAULT_TOUT if self.options.timeout is None else self.options.timeout
  88. print 'MBED: Instrumentation: "%s" and disk: "%s"' % (self.port, self.disk)
  89. def init_serial_params(self, serial_baud=9600, serial_timeout=1):
  90. """ Initialize port parameters.
  91. This parameters will be used by self.init_serial() function to open serial port
  92. """
  93. self.serial_baud = serial_baud
  94. self.serial_timeout = serial_timeout
  95. def init_serial(self, serial_baud=None, serial_timeout=None):
  96. """ Initialize serial port.
  97. Function will return error is port can't be opened or initialized
  98. """
  99. # Overload serial port configuration from default to parameters' values if they are specified
  100. serial_baud = serial_baud if serial_baud is not None else self.serial_baud
  101. serial_timeout = serial_timeout if serial_timeout is not None else self.serial_timeout
  102. # Clear serial port
  103. if self.serial:
  104. self.serial.close()
  105. self.serial = None
  106. # We will pool for serial to be re-mounted if it was unmounted after device reset
  107. result = self.pool_for_serial_init(serial_baud, serial_timeout) # Blocking
  108. # Port can be opened
  109. if result:
  110. self.flush()
  111. return result
  112. def pool_for_serial_init(self, serial_baud, serial_timeout, pooling_loops=40, init_delay=0.5, loop_delay=0.25):
  113. """ Functions pools for serial port readiness
  114. """
  115. result = True
  116. last_error = None
  117. # This loop is used to check for serial port availability due to
  118. # some delays and remounting when devices are being flashed with new software.
  119. for i in range(pooling_loops):
  120. sleep(loop_delay if i else init_delay)
  121. try:
  122. self.serial = Serial(self.port, baudrate=serial_baud, timeout=serial_timeout)
  123. except Exception as e:
  124. result = False
  125. last_error = "MBED: %s"% str(e)
  126. stdout.write('.')
  127. stdout.flush()
  128. else:
  129. print "...port ready!"
  130. result = True
  131. break
  132. if not result and last_error:
  133. print last_error
  134. return result
  135. def set_serial_timeout(self, timeout):
  136. """ Wraps self.mbed.serial object timeout property
  137. """
  138. result = None
  139. if self.serial:
  140. self.serial.timeout = timeout
  141. result = True
  142. return result
  143. def serial_read(self, count=1):
  144. """ Wraps self.mbed.serial object read method
  145. """
  146. result = None
  147. if self.serial:
  148. try:
  149. result = self.serial.read(count)
  150. except:
  151. result = None
  152. return result
  153. def serial_readline(self, timeout=5):
  154. """ Wraps self.mbed.serial object read method to read one line from serial port
  155. """
  156. result = ''
  157. start = time()
  158. while (time() - start) < timeout:
  159. if self.serial:
  160. try:
  161. c = self.serial.read(1)
  162. result += c
  163. except Exception as e:
  164. print "MBED: %s"% str(e)
  165. result = None
  166. break
  167. if c == '\n':
  168. break
  169. return result
  170. def serial_write(self, write_buffer):
  171. """ Wraps self.mbed.serial object write method
  172. """
  173. result = None
  174. if self.serial:
  175. try:
  176. result = self.serial.write(write_buffer)
  177. except:
  178. result = None
  179. return result
  180. def reset_timeout(self, timeout):
  181. """ Timeout executed just after reset command is issued
  182. """
  183. for n in range(0, timeout):
  184. sleep(1)
  185. def reset(self):
  186. """ Calls proper reset plugin to do the job.
  187. Please refer to host_test_plugins functionality
  188. """
  189. # Flush serials to get only input after reset
  190. self.flush()
  191. if self.options.forced_reset_type:
  192. result = host_tests_plugins.call_plugin('ResetMethod', self.options.forced_reset_type, disk=self.disk)
  193. else:
  194. result = host_tests_plugins.call_plugin('ResetMethod', 'default', serial=self.serial)
  195. # Give time to wait for the image loading
  196. reset_tout_s = self.options.forced_reset_timeout if self.options.forced_reset_timeout is not None else self.DEFAULT_RESET_TOUT
  197. self.reset_timeout(reset_tout_s)
  198. return result
  199. def copy_image(self, image_path=None, disk=None, copy_method=None):
  200. """ Closure for copy_image_raw() method.
  201. Method which is actually copying image to mbed
  202. """
  203. # Set closure environment
  204. image_path = image_path if image_path is not None else self.image_path
  205. disk = disk if disk is not None else self.disk
  206. copy_method = copy_method if copy_method is not None else self.copy_method
  207. # Call proper copy method
  208. result = self.copy_image_raw(image_path, disk, copy_method)
  209. sleep(self.program_cycle_s)
  210. return result
  211. def copy_image_raw(self, image_path=None, disk=None, copy_method=None):
  212. """ Copy file depending on method you want to use. Handles exception
  213. and return code from shell copy commands.
  214. """
  215. if copy_method is not None:
  216. # image_path - Where is binary with target's firmware
  217. result = host_tests_plugins.call_plugin('CopyMethod', copy_method, image_path=image_path, destination_disk=disk)
  218. else:
  219. copy_method = 'default'
  220. result = host_tests_plugins.call_plugin('CopyMethod', copy_method, image_path=image_path, destination_disk=disk)
  221. return result;
  222. def flush(self):
  223. """ Flush serial ports
  224. """
  225. result = False
  226. if self.serial:
  227. self.serial.flushInput()
  228. self.serial.flushOutput()
  229. result = True
  230. return result
  231. class HostTestResults:
  232. """ Test results set by host tests
  233. """
  234. def __init__(self):
  235. self.RESULT_SUCCESS = 'success'
  236. self.RESULT_FAILURE = 'failure'
  237. self.RESULT_ERROR = 'error'
  238. self.RESULT_IO_SERIAL = 'ioerr_serial'
  239. self.RESULT_NO_IMAGE = 'no_image'
  240. self.RESULT_IOERR_COPY = "ioerr_copy"
  241. self.RESULT_PASSIVE = "passive"
  242. self.RESULT_NOT_DETECTED = "not_detected"
  243. self.RESULT_MBED_ASSERT = "mbed_assert"
  244. import workspace_tools.host_tests as host_tests
  245. class Test(HostTestResults):
  246. """ Base class for host test's test runner
  247. """
  248. # Select default host_test supervision (replaced after autodetection)
  249. test_supervisor = host_tests.get_host_test("default")
  250. def __init__(self):
  251. self.mbed = Mbed()
  252. def detect_test_config(self, verbose=False):
  253. """ Detects test case configuration
  254. """
  255. result = {}
  256. while True:
  257. line = self.mbed.serial_readline()
  258. if "{start}" in line:
  259. self.notify("HOST: Start test...")
  260. break
  261. else:
  262. # Detect if this is property from TEST_ENV print
  263. m = re.search('{([\w_]+);([\w\d\+ ]+)}}', line[:-1])
  264. if m and len(m.groups()) == 2:
  265. # This is most likely auto-detection property
  266. result[m.group(1)] = m.group(2)
  267. if verbose:
  268. self.notify("HOST: Property '%s' = '%s'"% (m.group(1), m.group(2)))
  269. else:
  270. # We can check if this is TArget Id in mbed specific format
  271. m2 = re.search('^([\$]+)([a-fA-F0-9]+)', line[:-1])
  272. if m2 and len(m2.groups()) == 2:
  273. if verbose:
  274. target_id = m2.group(1) + m2.group(2)
  275. self.notify("HOST: TargetID '%s'"% target_id)
  276. self.notify(line[len(target_id):-1])
  277. else:
  278. self.notify("HOST: Unknown property: %s"% line.strip())
  279. return result
  280. def run(self):
  281. """ Test runner for host test. This function will start executing
  282. test and forward test result via serial port to test suite
  283. """
  284. # Copy image to device
  285. self.notify("HOST: Copy image onto target...")
  286. result = self.mbed.copy_image()
  287. if not result:
  288. self.print_result(self.RESULT_IOERR_COPY)
  289. # Initialize and open target's serial port (console)
  290. self.notify("HOST: Initialize serial port...")
  291. result = self.mbed.init_serial()
  292. if not result:
  293. self.print_result(self.RESULT_IO_SERIAL)
  294. # Reset device
  295. self.notify("HOST: Reset target...")
  296. result = self.mbed.reset()
  297. if not result:
  298. self.print_result(self.RESULT_IO_SERIAL)
  299. # Run test
  300. try:
  301. CONFIG = self.detect_test_config(verbose=True) # print CONFIG
  302. if "host_test_name" in CONFIG:
  303. if host_tests.is_host_test(CONFIG["host_test_name"]):
  304. self.test_supervisor = host_tests.get_host_test(CONFIG["host_test_name"])
  305. result = self.test_supervisor.test(self) #result = self.test()
  306. if result is not None:
  307. self.print_result(result)
  308. else:
  309. self.notify("HOST: Passive mode...")
  310. except Exception, e:
  311. print str(e)
  312. self.print_result(self.RESULT_ERROR)
  313. def setup(self):
  314. """ Setup and check if configuration for test is
  315. correct. E.g. if serial port can be opened.
  316. """
  317. result = True
  318. if not self.mbed.serial:
  319. result = False
  320. self.print_result(self.RESULT_IO_SERIAL)
  321. return result
  322. def notify(self, message):
  323. """ On screen notification function
  324. """
  325. print message
  326. stdout.flush()
  327. def print_result(self, result):
  328. """ Test result unified printing function
  329. """
  330. self.notify("\r\n{{%s}}\r\n{{end}}" % result)
  331. class DefaultTestSelector(Test):
  332. """ Test class with serial port initialization
  333. """
  334. def __init__(self):
  335. HostTestResults.__init__(self)
  336. Test.__init__(self)
  337. if __name__ == '__main__':
  338. DefaultTestSelector().run()