mbed_base.py
Go to the documentation of this file.
"""
mbed SDK
Copyright (c) 2011-2016 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
"""
import json
import os
import mbed_lstools
from time import sleep
from mbed_host_tests import DEFAULT_BAUD_RATE
import mbed_host_tests.host_tests_plugins as ht_plugins
from mbed_host_tests.host_tests_logger import HtrunLogger
class Mbed:
"""! Base class for a host driven test
@details This class stores information about things like disk, port, serial speed etc.
Class is also responsible for manipulation of serial port between host and mbed device
"""
def __init__(self, options):
""" ctor
"""
# For compatibility with old mbed. We can use command line options for Mbed object
# or we can pass options directly from .
self.optionsoptions = options
self.loggerlogger = HtrunLogger('MBED')
# Options related to copy / reset mbed device
self.portport = self.optionsoptions.port
self.diskdisk = self.optionsoptions.disk
self.target_idtarget_id = self.optionsoptions.target_id
self.image_pathimage_path = self.optionsoptions.image_path.strip('"') if self.optionsoptions.image_path is not None else ''
self.copy_methodcopy_method = self.optionsoptions.copy_method
self.retry_copyretry_copy = self.optionsoptions.retry_copy
self.program_cycle_sprogram_cycle_s = float(self.optionsoptions.program_cycle_s if self.optionsoptions.program_cycle_s is not None else 2.0)
self.polling_timeoutpolling_timeout = self.optionsoptions.polling_timeout
# Serial port settings
self.serial_baudserial_baud = DEFAULT_BAUD_RATE
self.serial_timeoutserial_timeout = 1
# Users can use command to pass port speeds together with port name. E.g. COM4:115200:1
# Format if PORT:SPEED:TIMEOUT
port_config = self.portport.split(':') if self.portport else ''
if len(port_config) == 2:
# -p COM4:115200
self.portport = port_config[0]
self.serial_baudserial_baud = int(port_config[1])
elif len(port_config) == 3:
# -p COM4:115200:0.5
self.portport = port_config[0]
self.serial_baudserial_baud = int(port_config[1])
self.serial_timeoutserial_timeout = float(port_config[2])
# Overriding baud rate value with command line specified value
self.serial_baudserial_baud = self.optionsoptions.baud_rate if self.optionsoptions.baud_rate else self.serial_baudserial_baud
# Test configuration in JSON format
self.test_cfgtest_cfg = None
if self.optionsoptions.json_test_configuration is not None:
# We need to normalize path before we open file
json_test_configuration_path = self.optionsoptions.json_test_configuration.strip("\"'")
try:
self.loggerlogger.prn_inf("Loading test configuration from '%s'..." % json_test_configuration_path)
with open(json_test_configuration_path) as data_file:
self.test_cfgtest_cfg = json.load(data_file)
except IOError as e:
self.loggerlogger.prn_err("Test configuration JSON file '{0}' I/O error({1}): {2}"
.format(json_test_configuration_path, e.errno, e.strerror))
except:
self.loggerlogger.prn_err("Test configuration JSON Unexpected error:", str(e))
raise
def copy_image(self, image_path=None, disk=None, copy_method=None, port=None, retry_copy=5):
"""! Closure for copy_image_raw() method.
@return Returns result from copy plugin
"""
def get_remount_count(disk_path, tries=2):
"""! Get the remount count from 'DETAILS.TXT' file
@return Returns count, None if not-available
"""
for cur_try in range(1, tries + 1):
try:
files_on_disk = [x.upper() for x in os.listdir(disk_path)]
if 'DETAILS.TXT' in files_on_disk:
with open(os.path.join(disk_path, 'DETAILS.TXT'), 'r') as details_txt:
for line in details_txt.readlines():
if 'Remount count:' in line:
return int(line.replace('Remount count: ', ''))
# Remount count not found in file
return None
# 'DETAILS.TXT file not found
else:
return None
except OSError as e:
self.loggerlogger.prn_err("Failed to get remount count due to OSError.", str(e))
self.loggerlogger.prn_inf("Retrying in 1 second (try %s of %s)" % (cur_try, tries))
sleep(1)
# Failed to get remount count
return None
def check_flash_error(target_id, disk, initial_remount_count):
"""! Check for flash errors
@return Returns false if FAIL.TXT present, else true
"""
if not target_id:
self.loggerlogger.prn_wrn("Target ID not found: Skipping flash check and retry")
return True
bad_files = set(['FAIL.TXT'])
# Re-try at max 5 times with 0.5 sec in delay
for i in range(5):
# mbed_lstools.create() should be done inside the loop. Otherwise it will loop on same data.
mbeds = mbed_lstools.create()
mbed_list = mbeds.list_mbeds() #list of mbeds present
# get first item in list with a matching target_id, if present
mbed_target = next((x for x in mbed_list if x['target_id']==target_id), None)
if mbed_target is not None:
if 'mount_point' in mbed_target and mbed_target['mount_point'] is not None:
if not initial_remount_count is None:
new_remount_count = get_remount_count(disk)
if not new_remount_count is None and new_remount_count == initial_remount_count:
sleep(0.5)
continue
common_items = []
try:
items = set([x.upper() for x in os.listdir(mbed_target['mount_point'])])
common_items = bad_files.intersection(items)
except OSError as e:
print("Failed to enumerate disk files, retrying")
continue
for common_item in common_items:
full_path = os.path.join(mbed_target['mount_point'], common_item)
self.loggerlogger.prn_err("Found %s"% (full_path))
bad_file_contents = "[failed to read bad file]"
try:
with open(full_path, "r") as bad_file:
bad_file_contents = bad_file.read()
except IOError as error:
self.loggerlogger.prn_err("Error opening '%s': %s" % (full_path, error))
self.loggerlogger.prn_err("Error file contents:\n%s" % bad_file_contents)
if common_items:
return False
sleep(0.5)
return True
# Set-up closure environment
if not image_path:
image_path = self.image_pathimage_path
if not disk:
disk = self.diskdisk
if not copy_method:
copy_method = self.copy_methodcopy_method
if not port:
port = self.portport
if not retry_copy:
retry_copy = self.retry_copyretry_copy
target_id = self.target_idtarget_id
if not image_path:
self.loggerlogger.prn_err("Error: image path not specified")
return False
if not os.path.isfile(image_path):
self.loggerlogger.prn_err("Error: image file (%s) not found" % image_path)
return False
for count in range(0, retry_copy):
initial_remount_count = get_remount_count(disk)
# Call proper copy method
result = self.copy_image_rawcopy_image_raw(image_path, disk, copy_method, port)
sleep(self.program_cycle_sprogram_cycle_s)
if not result:
continue
result = check_flash_error(target_id, disk, initial_remount_count)
if result:
break
return result
def copy_image_raw(self, image_path=None, disk=None, copy_method=None, port=None):
"""! Copy file depending on method you want to use. Handles exception
and return code from shell copy commands.
@return Returns result from copy plugin
@details Method which is actually copying image to mbed
"""
# image_path - Where is binary with target's firmware
# Select copy_method
# We override 'default' method with 'shell' method
copy_method = {
None : 'shell',
'default' : 'shell',
}.get(copy_method, copy_method)
result = ht_plugins.call_plugin('CopyMethod',
copy_method,
image_path=image_path,
serial=port,
destination_disk=disk,
target_id=self.target_idtarget_id,
pooling_timeout=self.polling_timeoutpolling_timeout)
return result
def hw_reset(self):
"""
Performs hardware reset of target ned device.
:return:
"""
device_info = {}
result = ht_plugins.call_plugin('ResetMethod',
'power_cycle',
target_id=self.target_idtarget_id,
device_info=device_info)
if result:
self.portport = device_info['serial_port']
self.diskdisk = device_info['mount_point']
return result
mbed_host_tests.host_tests_logger.ht_logger.HtrunLogger
Yet another logger flavour.
Definition: ht_logger.py:25
mbed_host_tests.host_tests_runner.mbed_base.Mbed
Base class for a host driven test.
Definition: mbed_base.py:29
mbed_host_tests.host_tests_runner.mbed_base.Mbed.program_cycle_s
program_cycle_s
Definition: mbed_base.py:48
mbed_host_tests.host_tests_runner.mbed_base.Mbed.serial_timeout
serial_timeout
Definition: mbed_base.py:53
mbed_host_tests.host_tests_runner.mbed_base.Mbed.logger
logger
Definition: mbed_base.py:40
mbed_host_tests.host_tests_runner.mbed_base.Mbed.target_id
target_id
Definition: mbed_base.py:44
mbed_host_tests.host_tests_runner.mbed_base.Mbed.copy_method
copy_method
Definition: mbed_base.py:46
mbed_host_tests.host_tests_runner.mbed_base.Mbed.retry_copy
retry_copy
Definition: mbed_base.py:47
mbed_host_tests.host_tests_runner.mbed_base.Mbed.copy_image
def copy_image(self, image_path=None, disk=None, copy_method=None, port=None, retry_copy=5)
Closure for copy_image_raw() method.
Definition: mbed_base.py:87
mbed_host_tests.host_tests_runner.mbed_base.Mbed.port
port
Definition: mbed_base.py:42
mbed_host_tests.host_tests_runner.mbed_base.Mbed.hw_reset
def hw_reset(self)
Definition: mbed_base.py:222
mbed_host_tests.host_tests_runner.mbed_base.Mbed.polling_timeout
polling_timeout
Definition: mbed_base.py:49
mbed_host_tests.host_tests_runner.mbed_base.Mbed.test_cfg
test_cfg
Definition: mbed_base.py:72
mbed_host_tests.host_tests_runner.mbed_base.Mbed.copy_image_raw
def copy_image_raw(self, image_path=None, disk=None, copy_method=None, port=None)
Copy file depending on method you want to use.
Definition: mbed_base.py:198
mbed_host_tests.host_tests_runner.mbed_base.Mbed.options
options
Definition: mbed_base.py:39
mbed_host_tests.host_tests_runner.mbed_base.Mbed.image_path
image_path
Definition: mbed_base.py:45
mbed_host_tests.host_tests_runner.mbed_base.Mbed.__init__
def __init__(self, options)
Definition: mbed_base.py:34
mbed_host_tests.host_tests_runner.mbed_base.Mbed.disk
disk
Definition: mbed_base.py:43
mbed_host_tests.host_tests_runner.mbed_base.Mbed.serial_baud
serial_baud
Definition: mbed_base.py:52
mbed_host_tests.host_tests_logger
Definition: __init__.py:1
mbed_host_tests.host_tests_plugins
Definition: __init__.py:1