Skip to content

Commit 0e77f67

Browse files
committed
htrun: serial: Use provided serial port when given
In order to work well with boards via the pyocd copy method, we should not attempt to list Mbed style boards to see if the serial port changed names. We should instead use the serial port as provided on the command line. If we attempt to list Mbed style boards, we will run into an error when the board is not Mbed-style, even if the command-line provided serial port is correct. To add insult to injury, the error message given in such cases gives advice that is impossible to follow; the output from htrun recommends you provide the -u option, but you cannot; the -u option is for mbed-ls, not htrun. $ mbedhtrun -f build/test.elf -p /dev/ttyUSB1:115200 -r pyocd -c pyocd --target-id 0240 [1627903348.60][mbedls.lstools_base]MBED with target id '0240000034544e45001e00048e3800515a91000097969900' is connected, but not mounted. Use the '-u' flag to include it in the list. The reason we are not simply overriding the pyocd plugin's check_serial_port_ready() method is because we don't want to attempt auto-detection of the serial port for any type of device, not just those we'd use pyocd with. We always want to use the provided serial port when passed in. If users want auto-detection of the serial port to use, they can avoid providing the port on the command line to get the previous behavior. Fixes #267
1 parent ac6c00b commit 0e77f67

File tree

2 files changed

+105
-7
lines changed

2 files changed

+105
-7
lines changed

src/mbed_os_tools/test/host_tests_conn_proxy/conn_primitive_serial.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,25 @@ def __init__(self, name, port, baudrate, config):
3737
self.skip_reset = config.get('skip_reset', False)
3838
self.serial = None
3939

40-
# Check if serial port for given target_id changed
41-
# If it does we will use new port to open connections and make sure reset plugin
42-
# later can reuse opened already serial port
43-
#
44-
# Note: This listener opens serial port and keeps connection so reset plugin uses
45-
# serial port object not serial port name!
46-
serial_port = HostTestPluginBase().check_serial_port_ready(self.port, target_id=self.target_id, timeout=self.polling_timeout)
40+
# Assume the provided serial port is good. Don't attempt to use the
41+
# target_id to re-discover the serial port, as the board may not be a
42+
# fully valid DAPLink-compatable or Mbed Enabled board (it may be
43+
# missing a mount point). Do not attempt to check if the serial port
44+
# for given target_id changed. We will attempt to open the port and
45+
# pass the already opened port object (not name) to the reset plugin.
46+
serial_port = None
47+
if self.port is not None:
48+
# A serial port was provided.
49+
# Don't pass in the target_id, so that no change in serial port via
50+
# auto-discovery happens.
51+
self.logger.prn_inf("using specified port '%s'" % (self.port))
52+
serial_port = HostTestPluginBase().check_serial_port_ready(self.port, target_id=None, timeout=self.polling_timeout)
53+
else:
54+
# No serial port was provided.
55+
# Fallback to auto-discovery via target_id.
56+
self.logger.prn_inf("getting serial port via mbedls)")
57+
serial_port = HostTestPluginBase().check_serial_port_ready(self.port, target_id=self.target_id, timeout=self.polling_timeout)
58+
4759
if serial_port is None:
4860
raise ConnectorPrimitiveException("Serial port not ready!")
4961

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (c) 2018-2021, Arm Limited and affiliates.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
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+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import unittest
17+
import mock
18+
19+
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive_serial import SerialConnectorPrimitive
20+
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive import ConnectorPrimitiveException
21+
22+
@mock.patch("mbed_os_tools.test.host_tests_conn_proxy.conn_primitive_serial.Serial")
23+
@mock.patch("mbed_os_tools.test.host_tests_plugins.host_test_plugins.detect")
24+
class ConnPrimitiveSerialTestCase(unittest.TestCase):
25+
def test_provided_serial_port_used_with_target_id(self, mock_detect, mock_serial):
26+
platform_name = "irrelevant"
27+
target_id = "1234"
28+
port = "COM256"
29+
baudrate = "9600"
30+
31+
# The mock list_mbeds() call needs to return a list of dictionaries,
32+
# and each dictionary must have a "serial_port", or else the
33+
# check_serial_port_ready() function we are testing will sleep waiting
34+
# for the serial port to become ready.
35+
mock_detect.create().list_mbeds.return_value = [
36+
{"target_id": target_id,
37+
"serial_port": port,
38+
"platform_name": platform_name},
39+
]
40+
41+
# Set skip_reset to avoid the use of a physical serial port.
42+
config = {
43+
"port": port,
44+
"baudrate": baudrate,
45+
"image_path": "test.bin",
46+
"platform_name": "kaysixtyfoureff",
47+
"target_id": "9900",
48+
"skip_reset": True,
49+
}
50+
connector = SerialConnectorPrimitive("SERI", port, baudrate, config=config)
51+
52+
mock_detect.create().list_mbeds.assert_not_called()
53+
54+
def test_discovers_serial_port_with_target_id(self, mock_detect, mock_serial):
55+
platform_name = "kaysixtyfoureff"
56+
target_id = "9900"
57+
port = "COM256"
58+
baudrate = "9600"
59+
60+
mock_detect.create().list_mbeds.return_value = [
61+
{"target_id": target_id,
62+
"serial_port": port,
63+
"platform_name": platform_name},
64+
]
65+
66+
# Set skip_reset to avoid the use of a physical serial port. Don't pass
67+
# in a port, so that auto-detection based on target_id will find the
68+
# port for us (using our mock list_mbeds data).
69+
config = {
70+
"port": None,
71+
"baudrate": baudrate,
72+
"image_path": "test.bin",
73+
"platform_name": platform_name,
74+
"target_id": target_id,
75+
"skip_reset": True,
76+
}
77+
try:
78+
connector = SerialConnectorPrimitive("SERI", None, baudrate, config=config)
79+
except ConnectorPrimitiveException:
80+
# lol bad
81+
pass
82+
83+
mock_detect.create().list_mbeds.assert_called_once()
84+
85+
if __name__ == '__main__':
86+
unittest.main()

0 commit comments

Comments
 (0)