mirror of https://github.com/ARMmbed/mbed-os.git
Bring python packages into the mbed-os source (#192)
* Initial import of python packages * Move tests to subfolder, use tests in generate_configuration.cmake * Bring python packages into the source tree instead of needing to be installed separately * Use python3 * Just use distro default python * Install all the requirements with apt-get * unittests is part of Python now * Add appdirs, set python version * Add some missing dependencies * Add more packages * Add requirements.apt.txt files, fix relative paths with scancode_evaluate.py * Fix return code handling for license scan errors * ok let's try that again, also improve error output from scancode evaluate * Add missing license headerspull/15494/head
parent
e1a1542310
commit
3af1c75ca8
|
|
@ -25,8 +25,11 @@ jobs:
|
|||
-
|
||||
name: install dependencies
|
||||
shell: bash
|
||||
# TODO scancode 32.0 introduced significant breaking changes to the license
|
||||
# detection output format: https://github.com/nexB/scancode-toolkit/releases/tag/v32.0.0
|
||||
# Need to update Mbed's scripts for the new format.
|
||||
run: |
|
||||
pip install -U scancode-toolkit "click>=7,<8"
|
||||
pip install -U "scancode-toolkit<32.0" "click>=7,<8"
|
||||
|
||||
-
|
||||
name: license check
|
||||
|
|
@ -43,10 +46,14 @@ jobs:
|
|||
| while read file; do cp --parents "${file}" SCANCODE; done
|
||||
ls SCANCODE
|
||||
scancode -l --json-pp scancode.json SCANCODE
|
||||
python ./tools/test/ci/scancode-evaluate.py scancode.json || true
|
||||
cat scancode-evaluate.log
|
||||
COUNT=$(cat scancode-evaluate.log | grep 'File:' | grep -v 'SPDX' | wc -l) || true
|
||||
if [ $COUNT = 0 ]; then
|
||||
cd tools/python
|
||||
|
||||
# Run the evaluation script, which may fail, and save its exit code.
|
||||
EVALUATE_EXITCODE=0
|
||||
python -m scancode_evaluate.scancode_evaluate ../../scancode.json || EVALUATE_EXITCODE=$?
|
||||
|
||||
cat scancode_evaluate.log
|
||||
if [ "$EVALUATE_EXITCODE" = 0 ]; then
|
||||
echo "License check OK";
|
||||
true;
|
||||
else
|
||||
|
|
@ -158,25 +165,18 @@ jobs:
|
|||
name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
|
||||
-
|
||||
name: install dependencies
|
||||
run: |
|
||||
pip install -r tools/requirements.txt
|
||||
pip install -r tools/test/requirements.txt
|
||||
xargs sudo apt-get install -y < tools/requirements.apt.txt
|
||||
xargs sudo apt-get install -y < tools/python/python_tests/requirements.apt.txt
|
||||
|
||||
-
|
||||
name: pytest
|
||||
name: Python Tests
|
||||
run: |
|
||||
set -x
|
||||
coverage run -a -m pytest tools/test
|
||||
python tools/test/pylint.py
|
||||
coverage run -a tools/project.py -S | sed -n '/^Total/p'
|
||||
coverage html
|
||||
cd tools/python
|
||||
./run_python_tests.sh
|
||||
|
||||
|
||||
pin-validation:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ venv/
|
|||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
/build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
|||
include(CheckPythonPackage)
|
||||
|
||||
# Check python packages
|
||||
set(PYTHON_PACKAGES_TO_CHECK intelhex prettytable future jinja2 mbed_tools)
|
||||
set(PYTHON_PACKAGES_TO_CHECK intelhex prettytable future jinja2)
|
||||
foreach(PACKAGE_NAME ${PYTHON_PACKAGES_TO_CHECK})
|
||||
string(TOUPPER ${PACKAGE_NAME} PACKAGE_NAME_UCASE) # Ucase name needed for CMake variable
|
||||
string(TOLOWER ${PACKAGE_NAME} PACKAGE_NAME_LCASE) # Lcase name needed for import statement
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ message("Executing: mbedhtrun ${MBEDHTRUN_ARGS_FOR_DISPLAY}")
|
|||
|
||||
# Note: For this command, we need to survive mbedhtrun not being on the PATH, so we import the package and call the main function using "python -c"
|
||||
execute_process(
|
||||
COMMAND @Python3_EXECUTABLE@ -c "import mbed_host_tests.mbedhtrun; exit(mbed_host_tests.mbedhtrun.main())" ${MBEDHTRUN_ARGS}
|
||||
WORKING_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
|
||||
COMMAND @Python3_EXECUTABLE@ -m mbed_host_tests.mbedhtrun ${MBEDHTRUN_ARGS}
|
||||
WORKING_DIRECTORY "@mbed-os_SOURCE_DIR@/tools/python"
|
||||
COMMAND_ERROR_IS_FATAL ANY)
|
||||
|
|
@ -103,7 +103,7 @@ if(MBED_NEED_TO_RECONFIGURE)
|
|||
|
||||
execute_process(
|
||||
COMMAND ${MBEDTOOLS_CONFIGURE_COMMAND}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../python
|
||||
RESULT_VARIABLE MBEDTOOLS_CONFIGURE_RESULT
|
||||
OUTPUT_VARIABLE MBEDTOOLS_CONFIGURE_OUTPUT
|
||||
ERROR_VARIABLE MBEDTOOLS_CONFIGURE_ERROR_OUTPUT
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ function(mbed_generate_map_file target)
|
|||
TARGET
|
||||
${target}
|
||||
POST_BUILD
|
||||
COMMAND ${Python3_EXECUTABLE} ${mbed-os_SOURCE_DIR}/tools/memap.py
|
||||
COMMAND ${Python3_EXECUTABLE} -m memap.memap
|
||||
-t ${MBED_TOOLCHAIN} ${CMAKE_CURRENT_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.map
|
||||
--depth ${MBED_MEMAP_DEPTH}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${mbed-os_SOURCE_DIR}/tools/python
|
||||
)
|
||||
|
||||
# generate json file
|
||||
|
|
@ -66,13 +66,13 @@ function(mbed_generate_map_file target)
|
|||
TARGET
|
||||
${target}
|
||||
POST_BUILD
|
||||
COMMAND ${Python3_EXECUTABLE} ${mbed-os_SOURCE_DIR}/tools/memap.py
|
||||
COMMAND ${Python3_EXECUTABLE} -m memap.memap
|
||||
-t ${MBED_TOOLCHAIN} ${CMAKE_CURRENT_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.map
|
||||
--depth ${MBED_MEMAP_DEPTH}
|
||||
-e json
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.memmap.json
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${mbed-os_SOURCE_DIR}/tools/python
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
@ -82,13 +82,13 @@ function(mbed_generate_map_file target)
|
|||
TARGET
|
||||
${target}
|
||||
POST_BUILD
|
||||
COMMAND ${Python3_EXECUTABLE} ${mbed-os_SOURCE_DIR}/tools/memap.py
|
||||
COMMAND ${Python3_EXECUTABLE} -m memap.memap
|
||||
-t ${MBED_TOOLCHAIN} ${CMAKE_CURRENT_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.map
|
||||
--depth ${MBED_MEMAP_DEPTH}
|
||||
-e html
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.memmap.html
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${mbed-os_SOURCE_DIR}/tools/python
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
set(UPLOAD_SUPPORTS_DEBUG FALSE)
|
||||
|
||||
### Check if upload method can be enabled on this machine
|
||||
check_python_package(mbed_os_tools HAVE_MBED_OS_TOOLS)
|
||||
set(UPLOAD_MBED_FOUND ${HAVE_MBED_OS_TOOLS})
|
||||
set(UPLOAD_MBED_FOUND ${Python3_FOUND})
|
||||
|
||||
if(NOT DEFINED MBED_RESET_BAUDRATE)
|
||||
set(MBED_RESET_BAUDRATE 9600)
|
||||
|
|
@ -20,11 +19,14 @@ set(MBED_TARGET_UID "" CACHE STRING "UID of mbed target to upload to if there ar
|
|||
function(gen_upload_target TARGET_NAME BIN_FILE)
|
||||
|
||||
add_custom_target(flash-${TARGET_NAME}
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/install_bin_file.py
|
||||
COMMAND ${Python3_EXECUTABLE} -m install_bin_file
|
||||
${BIN_FILE}
|
||||
${MBED_TARGET}
|
||||
${MBED_RESET_BAUDRATE}
|
||||
${MBED_TARGET_UID})
|
||||
${MBED_TARGET_UID}
|
||||
WORKING_DIRECTORY
|
||||
${mbed-os_SOURCE_DIR}/tools/python
|
||||
VERBATIM)
|
||||
|
||||
add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME})
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
# Python coverage database
|
||||
.coverage
|
||||
|
||||
# Coverage report
|
||||
htmlcov/
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# Copyright (c) 2020-2023 Arm Limited and Contributors. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
|
@ -42,7 +42,7 @@ def error(lines, code=-1):
|
|||
sys.exit(code)
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Error: Usage: python " + sys.argv[0] + " <path to bin file> <Mbed OS target name> <serial baudrate for sending break> [Target UID for distinguishing multiple targets]")
|
||||
print("Error: Usage: " + sys.argv[0] + " <path to bin file> <Mbed OS target name> <serial baudrate for sending break> [Target UID for distinguishing multiple targets]")
|
||||
sys.exit(1)
|
||||
|
||||
bin_file = sys.argv[1]
|
||||
|
|
@ -81,7 +81,7 @@ elif len(all_connected) > 1:
|
|||
error_lines = ["There are multiple of the targeted board connected to the system. Which do you wish to flash?"]
|
||||
for target in all_connected:
|
||||
error_lines.append("Board: %s, Mount Point: %s, UID: %s" % (target['name'], target['mount'], target['uid']))
|
||||
error_lines.append("Please set MBED_TARGET_UID to the UID of the board you wish to flash.")
|
||||
error_lines.append("Please set the CMake variable MBED_TARGET_UID to the UID of the board you wish to flash.")
|
||||
error(error_lines, 5)
|
||||
|
||||
connected = all_connected[0]
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
# Development moved
|
||||
|
||||
The development of Greentea has been moved into the [mbed-os-tools](../../src/mbed_os_tools) package. You can continue to use this module for legacy reasons, however all further development should be continued in the new package.
|
||||
|
||||
-------------
|
||||
|
||||
[](https://badge.fury.io/py/mbed-greentea)
|
||||
|
||||
# Greentea - test automation for mbed
|
||||
_**G**eneric **re**gression **en**vironment for **te**st **a**utomation_
|
||||
|
||||
## Introduction
|
||||
|
||||
Greentea is the automated testing tool for mbed OS development. It automates the process of flashing mbed boards, driving the test and accumulating test results into test reports. Developers use it for local development as well as for automation in a Continuous Integration environment.
|
||||
|
||||
This document should help you start using Greentea. Please see the [htrun documentation](https://github.com/ARMmbed/htrun), the tool Greentea uses to drive tests, for the technical details of the interactions between the platform and the host machine.
|
||||
|
||||
Because Greentea is an open source project, we accept contributions! Please see our [contributing document](CONTRIBUTING.md) for more information.
|
||||
|
||||
### Prerequistes
|
||||
|
||||
Greentea requires [Python version 2.7](https://www.python.org/downloads/). It supports the following OSes:
|
||||
|
||||
- Windows
|
||||
- Linux (Ubuntu preferred)
|
||||
- OS X (experimental)
|
||||
|
||||
### Installing
|
||||
|
||||
Tools that depend on Greentea usually install it. Determine if Greentea is already installed by running:
|
||||
```
|
||||
$ mbedgt --version
|
||||
1.2.5
|
||||
```
|
||||
|
||||
You can also install it manually via pip.
|
||||
|
||||
```
|
||||
pip install mbed-greentea
|
||||
```
|
||||
|
||||
## Test specification JSON format
|
||||
|
||||
The Greentea test specification format decouples the tool from your build system. It provides important data, such as test names, paths to test binaries and the platform on which the binaries should run.
|
||||
|
||||
Greentea automatically looks for files called `test_spec.json` in your working directory. You can also use the `--test-spec` argument to direct Greentea to a specific test specification file.
|
||||
|
||||
When you use the `-t` / `--target` argument with the `--test-spec` argument, you can select which "build" should be used. In the example below, you could provide the arguments `--test-spec test_spec.json -t K64F-ARM` to only run that build's tests.
|
||||
|
||||
### Example of test specification file
|
||||
|
||||
In the below example, there are two defined builds:
|
||||
* Build `K64F-ARM` for NXP `K64F` platform compiled with `ARMCC` compiler.
|
||||
* Build `K64F-GCC` for NXP `K64F` platform compiled with `GCC ARM` compiler.
|
||||
|
||||
```json
|
||||
{
|
||||
"builds": {
|
||||
"K64F-ARM": {
|
||||
"platform": "K64F",
|
||||
"toolchain": "ARM",
|
||||
"base_path": "./BUILD/K64F/ARM",
|
||||
"baud_rate": 9600,
|
||||
"tests": {
|
||||
"tests-mbedmicro-rtos-mbed-mail": {
|
||||
"binaries": [
|
||||
{
|
||||
"binary_type": "bootable",
|
||||
"path": "./BUILD/K64F/ARM/tests-mbedmicro-rtos-mbed-mail.bin"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests-mbed_drivers-c_strings": {
|
||||
"binaries": [
|
||||
{
|
||||
"binary_type": "bootable",
|
||||
"path": "./BUILD/K64F/ARM/tests-mbed_drivers-c_strings.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"K64F-GCC": {
|
||||
"platform": "K64F",
|
||||
"toolchain": "GCC_ARM",
|
||||
"base_path": "./BUILD/K64F/GCC_ARM",
|
||||
"baud_rate": 9600,
|
||||
"tests": {
|
||||
"tests-mbedmicro-rtos-mbed-mail": {
|
||||
"binaries": [
|
||||
{
|
||||
"binary_type": "bootable",
|
||||
"path": "./BUILD/K64F/GCC_ARM/tests-mbedmicro-rtos-mbed-mail.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The examples below use the above test specification file.
|
||||
|
||||
## Command-line usage
|
||||
This section highlights a few of the capabilities of the Greentea command-line interface. For a full list of the available options, please run `mbedgt --help`.
|
||||
|
||||
Assume for the examples below that the above `test_spec.json` file is in the current directory.
|
||||
|
||||
### Listing all tests
|
||||
You can use the `-l` argument to list all available tests:
|
||||
|
||||
```
|
||||
$ mbedgt -l
|
||||
mbedgt: greentea test automation tool ver. 1.2.5
|
||||
mbedgt: using multiple test specifications from current directory!
|
||||
using 'BUILD\tests\K64F\ARM\test_spec.json'
|
||||
using 'BUILD\tests\K64F\GCC_ARM\test_spec.json'
|
||||
mbedgt: available tests for built 'K64F-GCC_ARM', location 'BUILD/tests/K64F/GCC_ARM'
|
||||
test 'tests-mbedmicro-rtos-mbed-mail'
|
||||
mbedgt: available tests for built 'K64F-ARM', location 'BUILD/tests/K64F/ARM'
|
||||
test 'tests-mbed_drivers-c_strings'
|
||||
test 'tests-mbedmicro-rtos-mbed-mail'
|
||||
```
|
||||
|
||||
### Executing all tests
|
||||
The default action of Greentea using `mbedgt` is to execute all tests that are found in `test_spec.json` files. You can also add `-V` to make the output more verbose.
|
||||
|
||||
|
||||
### Limiting tests
|
||||
You can select test cases by name using the `-n` argument. This command executes all tests named `tests-mbedmicro-rtos-mbed-mail` from all builds in the test specification:
|
||||
```
|
||||
$ mbedgt -n tests-mbedmicro-rtos-mbed-mail
|
||||
```
|
||||
|
||||
When using the `-n` argument, you can use the `*` character at the end of a test name to match all tests that share a prefix. This command executes all tests that start with `tests*`:
|
||||
|
||||
```
|
||||
$ mbedgt -n tests*
|
||||
```
|
||||
|
||||
You can use the `-t` argument to select which build to use when finding tests. This command executes the test `tests-mbedmicro-rtos-mbed-mail` for the `K64F-ARM` build in the test specification:
|
||||
```
|
||||
$ mbedgt -n tests-mbedmicro-rtos-mbed-mail -t K64F-ARM
|
||||
```
|
||||
|
||||
You can use a comma (`,`) to separate test names (argument `-n`) and build names (argument `-t`). This command executes the tests `tests-mbedmicro-rtos-mbed-mail` and `tests-mbed_drivers-c_strings` for the `K64F-ARM` and `K64F-GCC_ARM` builds in the test specification:
|
||||
```
|
||||
$ mbedgt -n tests-mbedmicro-rtos-mbed-mail,tests-mbed_drivers-c_strings -t K64F-ARM,K64F-GCC_ARM
|
||||
```
|
||||
|
||||
### Selecting platforms
|
||||
You can limit which boards Greentea uses for testing by using the `--use-tids` argument.
|
||||
|
||||
```
|
||||
$ mbedgt --use-tids 02400203C3423E603EBEC3D8,024002031E031E6AE3FFE3D2
|
||||
```
|
||||
|
||||
Where ```02400203C3423E603EBEC3D8``` and ```024002031E031E6AE3FFE3D2``` are the target IDs of platforms attached to your system.
|
||||
|
||||
You can view target IDs using the [mbed-ls](https://pypi.org/project/mbed-ls) tool (installed with Greentea).
|
||||
|
||||
```
|
||||
$ mbedls
|
||||
+--------------+---------------------+------------+------------+-------------------------+
|
||||
|platform_name |platform_name_unique |mount_point |serial_port |target_id |
|
||||
+--------------+---------------------+------------+------------+-------------------------+
|
||||
|K64F |K64F[0] |E: |COM160 |024002031E031E6AE3FFE3D2 |
|
||||
|K64F |K64F[1] |F: |COM162 |02400203C3423E603EBEC3D8 |
|
||||
|LPC1768 |LPC1768[0] |G: |COM5 |1010ac87cfc4f23c4c57438d |
|
||||
+--------------+---------------------+------------+------------+-------------------------+
|
||||
```
|
||||
In this case, you won't test one target, the LPC1768.
|
||||
|
||||
### Testing on Fast Model FVPs
|
||||
|
||||
Fast Models FVPs are software models for Arm reference design platfrom
|
||||
|
||||
Greentea supports running test on Fast Models. And [mbed-fastmodel-agent](https://github.com/ARMmbed/mbed-fastmodel-agent) module is required for this purpose.
|
||||
|
||||
The "--fm" option only available when the `mbed-fastmodel-agent` module is installed :
|
||||
|
||||
You can run tests for FVP_MPS2_Cortex-M3 models, by '--fm' option:
|
||||
```
|
||||
$ mbedgt --fm FVP_MPS2_M3:DEFAULT
|
||||
```
|
||||
|
||||
Where ```FVP_MPS2_M3``` is the platfrom name for the ```FVP_MPS2_Cortex-M3``` models in mbed OS.
|
||||
|
||||
And ```DEFAULT``` is the config to the Fast Model, you can find out using ```mbedfm``` command
|
||||
|
||||
### Creating reports
|
||||
Greentea supports a number of report formats.
|
||||
|
||||
#### HTML
|
||||
This creates an interactive HTML page with test results and logs.
|
||||
```
|
||||
mbedgt --report-html html_report.html
|
||||
```
|
||||
|
||||
#### JUnit
|
||||
This creates an XML JUnit report, which you can use with popular Continuous Integration software, such as [Jenkins](https://jenkins.io/index.html).
|
||||
```
|
||||
mbedgt --report-junit junit_report.xml
|
||||
```
|
||||
|
||||
#### JSON
|
||||
This creates a general JSON report.
|
||||
```
|
||||
mbedgt --report-json json_report.json
|
||||
```
|
||||
|
||||
#### Plain text
|
||||
This creates a human-friendly text summary of the test run.
|
||||
```
|
||||
mbedgt --report-text text_report.text
|
||||
```
|
||||
|
||||
## Host test detection
|
||||
When developing with mbed OS, Greentea detects host tests automatically if you place them in the correct location. All tests in mbed OS are placed under a `TESTS` directory. You may place custom host test scripts in a folder named `host_tests` in this folder. For more information about the mbed OS test directory structure, please see the [mbed CLI documentation](https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/cli/#test-directory-structure).
|
||||
|
||||
## Common issues
|
||||
|
||||
### `IOERR_SERIAL` errors
|
||||
Possible causes:
|
||||
- Another program is using the serial port. Be sure all terminals and other instances of Greentea are closed before trying again.
|
||||
- The mbed interface firmware is out of date. Please see the platform's page on [developer.mbed.org](https://developer.mbed.org/) for details about how to update it.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from .mbed_greentea_cli import main
|
||||
|
||||
"""! @package mbed-greentea
|
||||
|
||||
This is a test suite used by mbed project. If you have yotta package with tests you can run them on supported hardware
|
||||
This test suite supports:
|
||||
* mbed-ls - mbed-enabled device auto detection module
|
||||
* mbed-host-test - mbed-enabled device test framework (flash, reset and make host tests)
|
||||
|
||||
"""
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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.
|
||||
"""
|
||||
|
||||
from mbed_greentea.mbed_greentea_cli import main
|
||||
exit(main())
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.cmake_handlers import (
|
||||
load_ctest_testsuite,
|
||||
parse_ctesttestfile_line,
|
||||
list_binaries_for_targets,
|
||||
list_binaries_for_builds,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_common_api import (
|
||||
run_cli_command,
|
||||
run_cli_process,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_coverage_api import (
|
||||
coverage_pack_hex_payload,
|
||||
coverage_dump_file,
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,37 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_greentea_dlm import (
|
||||
HOME_DIR,
|
||||
GREENTEA_HOME_DIR,
|
||||
GREENTEA_GLOBAL_LOCK,
|
||||
GREENTEA_KETTLE,
|
||||
GREENTEA_KETTLE_PATH,
|
||||
greentea_home_dir_init,
|
||||
greentea_get_app_sem,
|
||||
greentea_get_target_lock,
|
||||
greentea_get_global_lock,
|
||||
greentea_update_kettle,
|
||||
greentea_clean_kettle,
|
||||
greentea_acquire_target_id,
|
||||
greentea_acquire_target_id_from_list,
|
||||
greentea_release_target_id,
|
||||
get_json_data_from_file,
|
||||
greentea_kettle_info,
|
||||
)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_greentea_hooks import (
|
||||
GreenteaTestHook,
|
||||
GreenteaCliTestHook,
|
||||
LcovHook,
|
||||
GreenteaHooks,
|
||||
)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_greentea_log import (
|
||||
COLORAMA,
|
||||
GreenTeaSimpleLockLogger,
|
||||
gt_logger,
|
||||
)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_report_api import (
|
||||
export_to_file,
|
||||
exporter_json,
|
||||
exporter_text,
|
||||
exporter_testcase_text,
|
||||
exporter_testcase_junit,
|
||||
html_template,
|
||||
TEST_RESULT_COLOURS,
|
||||
TEST_RESULT_DEFAULT_COLOUR,
|
||||
get_result_colour_class_css,
|
||||
get_result_colour_class,
|
||||
get_dropdown_html,
|
||||
get_result_overlay_testcase_dropdown,
|
||||
get_result_overlay_testcases_dropdown_menu,
|
||||
get_result_overlay_dropdowns,
|
||||
get_result_overlay,
|
||||
exporter_html,
|
||||
exporter_memory_metrics_csv,
|
||||
)
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_target_info import (
|
||||
TARGET_INFO_MAPPING,
|
||||
TARGET_TOOLCAHINS,
|
||||
get_mbed_target_call_yotta_target,
|
||||
parse_yotta_json_for_build_name,
|
||||
get_yotta_target_from_local_config,
|
||||
get_mbed_target_from_current_dir,
|
||||
parse_yotta_target_cmd_output,
|
||||
get_mbed_targets_from_yotta_local_module,
|
||||
parse_mbed_target_from_target_json,
|
||||
get_mbed_targets_from_yotta,
|
||||
parse_yotta_search_cmd_output,
|
||||
add_target_info_mapping,
|
||||
get_mbed_clasic_target_info,
|
||||
get_binary_type_for_platform,
|
||||
get_platform_property,
|
||||
)
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
"""
|
||||
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 os
|
||||
from time import time
|
||||
|
||||
from mbed_os_tools.test.mbed_test_api import (
|
||||
TEST_RESULT_OK,
|
||||
TEST_RESULT_FAIL,
|
||||
TEST_RESULT_ERROR,
|
||||
TEST_RESULT_SKIPPED,
|
||||
TEST_RESULT_UNDEF,
|
||||
TEST_RESULT_IOERR_COPY,
|
||||
TEST_RESULT_IOERR_DISK,
|
||||
TEST_RESULT_IOERR_SERIAL,
|
||||
TEST_RESULT_TIMEOUT,
|
||||
TEST_RESULT_NO_IMAGE,
|
||||
TEST_RESULT_MBED_ASSERT,
|
||||
TEST_RESULT_BUILD_FAILED,
|
||||
TEST_RESULT_SYNC_FAILED,
|
||||
TEST_RESULTS,
|
||||
TEST_RESULT_MAPPING,
|
||||
RUN_HOST_TEST_POPEN_ERROR,
|
||||
get_test_result,
|
||||
run_command,
|
||||
run_htrun,
|
||||
get_testcase_count_and_names,
|
||||
get_testcase_utest,
|
||||
get_coverage_data,
|
||||
get_printable_string,
|
||||
get_testcase_summary,
|
||||
get_testcase_result,
|
||||
get_memory_metrics,
|
||||
get_thread_with_max_stack_size,
|
||||
get_thread_stack_info_summary,
|
||||
log_mbed_devices_in_table,
|
||||
get_test_spec,
|
||||
get_test_build_properties,
|
||||
parse_global_resource_mgr,
|
||||
parse_fast_model_connection,
|
||||
gt_logger,
|
||||
)
|
||||
|
||||
def run_host_test(image_path,
|
||||
disk,
|
||||
port,
|
||||
build_path,
|
||||
target_id,
|
||||
duration=10,
|
||||
micro=None,
|
||||
reset=None,
|
||||
verbose=False,
|
||||
copy_method=None,
|
||||
program_cycle_s=None,
|
||||
forced_reset_timeout=None,
|
||||
digest_source=None,
|
||||
json_test_cfg=None,
|
||||
max_failed_properties=5,
|
||||
enum_host_tests_path=None,
|
||||
global_resource_mgr=None,
|
||||
fast_model_connection=None,
|
||||
compare_log=None,
|
||||
num_sync_packtes=None,
|
||||
polling_timeout=None,
|
||||
retry_count=1,
|
||||
tags=None,
|
||||
run_app=None):
|
||||
"""! This function runs host test supervisor (executes mbedhtrun) and checks output from host test process.
|
||||
@param image_path Path to binary file for flashing
|
||||
@param disk Currently mounted mbed-enabled devices disk (mount point)
|
||||
@param port Currently mounted mbed-enabled devices serial port (console)
|
||||
@param duration Test case timeout
|
||||
@param micro Mbed-enabled device name
|
||||
@param reset Reset type
|
||||
@param forced_reset_timeout Reset timeout (sec)
|
||||
@param verbose Verbose mode flag
|
||||
@param copy_method Copy method type (name)
|
||||
@param program_cycle_s Wait after flashing delay (sec)
|
||||
@param json_test_cfg Additional test configuration file path passed to host tests in JSON format
|
||||
@param max_failed_properties After how many unknown properties we will assume test is not ported
|
||||
@param enum_host_tests_path Directory where locally defined host tests may reside
|
||||
@param num_sync_packtes sync packets to send for host <---> device communication
|
||||
@param polling_timeout Timeout in sec for readiness of mount point and serial port of local or remote device
|
||||
@param tags Filter list of available devices under test to only run on devices with the provided list
|
||||
of tags [tag-filters tag1,tag]
|
||||
@param run_app Run application mode flag (we run application and grab serial port data)
|
||||
@param digest_source if None mbedhtrun will be executed. If 'stdin',
|
||||
stdin will be used via StdInObserver or file (if
|
||||
file name was given as switch option)
|
||||
@return Tuple with test results, test output, test duration times, test case results, and memory metrics.
|
||||
Return int > 0 if running mbedhtrun process failed.
|
||||
Retrun int < 0 if something went wrong during mbedhtrun execution.
|
||||
"""
|
||||
|
||||
def get_binary_host_tests_dir(binary_path, level=2):
|
||||
"""! Checks if in binary test group has host_tests directory
|
||||
@param binary_path Path to binary in test specification
|
||||
@param level How many directories above test host_tests dir exists
|
||||
@return Path to host_tests dir in group binary belongs too, None if not found
|
||||
"""
|
||||
try:
|
||||
binary_path_norm = os.path.normpath(binary_path)
|
||||
current_path_norm = os.path.normpath(os.getcwd())
|
||||
host_tests_path = binary_path_norm.split(os.sep)[:-level] + ['host_tests']
|
||||
build_dir_candidates = ['BUILD', '.build']
|
||||
idx = None
|
||||
|
||||
for build_dir_candidate in build_dir_candidates:
|
||||
if build_dir_candidate in host_tests_path:
|
||||
idx = host_tests_path.index(build_dir_candidate)
|
||||
break
|
||||
|
||||
if idx is None:
|
||||
msg = 'The following directories were not in the path: %s' % (', '.join(build_dir_candidates))
|
||||
raise Exception(msg)
|
||||
|
||||
# Cut /<build dir>/tests/TOOLCHAIN/TARGET
|
||||
host_tests_path = host_tests_path[:idx] + host_tests_path[idx+4:]
|
||||
host_tests_path = os.sep.join(host_tests_path)
|
||||
except Exception as e:
|
||||
gt_logger.gt_log_warn("there was a problem while looking for host_tests directory")
|
||||
gt_logger.gt_log_tab("level %d, path: %s"% (level, binary_path))
|
||||
gt_logger.gt_log_tab(str(e))
|
||||
return None
|
||||
|
||||
if os.path.isdir(host_tests_path):
|
||||
return host_tests_path
|
||||
return None
|
||||
|
||||
if not enum_host_tests_path:
|
||||
# If there is -e specified we will try to find a host_tests path ourselves
|
||||
#
|
||||
# * Path to binary starts from "build" directory, and goes 4 levels
|
||||
# deep: ./build/tests/compiler/toolchain
|
||||
# * Binary is inside test group.
|
||||
# For example: <app>/tests/test_group_name/test_dir/*,cpp.
|
||||
# * We will search for directory called host_tests on the level of test group (level=2)
|
||||
# or on the level of tests directory (level=3).
|
||||
#
|
||||
# If host_tests directory is found above test code will will pass it to mbedhtrun using
|
||||
# switch -e <path_to_host_tests_dir>
|
||||
gt_logger.gt_log("checking for 'host_tests' directory above image directory structure", print_text=verbose)
|
||||
test_group_ht_path = get_binary_host_tests_dir(image_path, level=2)
|
||||
TESTS_dir_ht_path = get_binary_host_tests_dir(image_path, level=3)
|
||||
if test_group_ht_path:
|
||||
enum_host_tests_path = test_group_ht_path
|
||||
elif TESTS_dir_ht_path:
|
||||
enum_host_tests_path = TESTS_dir_ht_path
|
||||
|
||||
if enum_host_tests_path:
|
||||
gt_logger.gt_log_tab("found 'host_tests' directory in: '%s'"% enum_host_tests_path, print_text=verbose)
|
||||
else:
|
||||
gt_logger.gt_log_tab("'host_tests' directory not found: two directory levels above image path checked", print_text=verbose)
|
||||
|
||||
gt_logger.gt_log("selecting test case observer...", print_text=verbose)
|
||||
if digest_source:
|
||||
gt_logger.gt_log_tab("selected digest source: %s"% digest_source, print_text=verbose)
|
||||
|
||||
# Select who will digest test case serial port data
|
||||
if digest_source == 'stdin':
|
||||
# When we want to scan stdin for test results
|
||||
raise NotImplementedError
|
||||
elif digest_source is not None:
|
||||
# When we want to open file to scan for test results
|
||||
raise NotImplementedError
|
||||
|
||||
# Command executing CLI for host test supervisor (in detect-mode)
|
||||
cmd = ["mbedhtrun",
|
||||
'-m', micro,
|
||||
'-p', port,
|
||||
'-f', '"%s"'% image_path,
|
||||
]
|
||||
|
||||
if enum_host_tests_path:
|
||||
cmd += ["-e", '"%s"'% enum_host_tests_path]
|
||||
|
||||
if global_resource_mgr:
|
||||
# Use global resource manager to execute test
|
||||
# Example:
|
||||
# $ mbedhtrun -p :9600 -f "tests-mbed_drivers-generic_tests.bin" -m K64F --grm raas_client:10.2.203.31:8000
|
||||
cmd += ['--grm', global_resource_mgr]
|
||||
else:
|
||||
# Use local resources to execute tests
|
||||
# Add extra parameters to host_test
|
||||
if disk:
|
||||
cmd += ["-d", disk]
|
||||
if copy_method:
|
||||
cmd += ["-c", copy_method]
|
||||
if target_id:
|
||||
cmd += ["-t", target_id]
|
||||
if reset:
|
||||
cmd += ["-r", reset]
|
||||
if run_app:
|
||||
cmd += ["--run"] # -f stores binary name!
|
||||
|
||||
if fast_model_connection:
|
||||
# Use simulator resource manager to execute test
|
||||
# Example:
|
||||
# $ mbedhtrun -f "tests-mbed_drivers-generic_tests.elf" -m FVP_MPS2_M3 --fm DEFAULT
|
||||
cmd += ['--fm', fast_model_connection]
|
||||
if compare_log:
|
||||
cmd += ['--compare-log', compare_log]
|
||||
if program_cycle_s:
|
||||
cmd += ["-C", str(program_cycle_s)]
|
||||
if forced_reset_timeout:
|
||||
cmd += ["-R", str(forced_reset_timeout)]
|
||||
if json_test_cfg:
|
||||
cmd += ["--test-cfg", '"%s"' % str(json_test_cfg)]
|
||||
if num_sync_packtes:
|
||||
cmd += ["--sync",str(num_sync_packtes)]
|
||||
if tags:
|
||||
cmd += ["--tag-filters", tags]
|
||||
if polling_timeout:
|
||||
cmd += ["-P", str(polling_timeout)]
|
||||
|
||||
gt_logger.gt_log_tab("calling mbedhtrun: %s" % " ".join(cmd), print_text=verbose)
|
||||
gt_logger.gt_log("mbed-host-test-runner: started")
|
||||
|
||||
for retry in range(1, 1 + retry_count):
|
||||
start_time = time()
|
||||
returncode, htrun_output = run_htrun(cmd, verbose)
|
||||
end_time = time()
|
||||
if returncode < 0:
|
||||
return returncode
|
||||
elif returncode == 0:
|
||||
break
|
||||
gt_logger.gt_log("retry mbedhtrun {}/{}".format(retry, retry_count))
|
||||
else:
|
||||
gt_logger.gt_log("{} failed after {} count".format(cmd, retry_count))
|
||||
|
||||
testcase_duration = end_time - start_time # Test case duration from reset to {end}
|
||||
htrun_output = get_printable_string(htrun_output)
|
||||
result = get_test_result(htrun_output)
|
||||
result_test_cases = get_testcase_result(htrun_output)
|
||||
test_cases_summary = get_testcase_summary(htrun_output)
|
||||
max_heap, reserved_heap, thread_stack_info = get_memory_metrics(htrun_output)
|
||||
|
||||
thread_stack_summary = []
|
||||
|
||||
if thread_stack_info:
|
||||
thread_stack_summary = get_thread_stack_info_summary(thread_stack_info)
|
||||
|
||||
memory_metrics = {
|
||||
"max_heap": max_heap,
|
||||
"reserved_heap": reserved_heap,
|
||||
"thread_stack_info": thread_stack_info,
|
||||
"thread_stack_summary": thread_stack_summary
|
||||
}
|
||||
get_coverage_data(build_path, htrun_output)
|
||||
|
||||
gt_logger.gt_log("mbed-host-test-runner: stopped and returned '%s'"% result, print_text=verbose)
|
||||
return (result, htrun_output, testcase_duration, duration, result_test_cases, test_cases_summary, memory_metrics)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_yotta_api import (
|
||||
YottaError,
|
||||
build_with_yotta,
|
||||
get_platform_name_from_yotta_target,
|
||||
get_test_spec_from_yt_module,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.mbed_yotta_module_parse import (
|
||||
YottaConfig,
|
||||
YottaModule
|
||||
)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
"""
|
||||
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: Azim Khan <Azim.Khan@arm.com>
|
||||
"""
|
||||
|
||||
"""
|
||||
This module contains classes to represent Test Specification interface that defines the data to be generated by/from
|
||||
a build system to give enough information to Greentea.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.tests_spec import (
|
||||
TestBinary,
|
||||
Test,
|
||||
TestBuild,
|
||||
TestSpec,
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
|
||||
"""! @package mbed-host-tests
|
||||
|
||||
Flash, reset and perform host supervised tests on mbed platforms.
|
||||
Write your own programs (import this package) or use 'mbedhtrun' command line tool instead.
|
||||
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test import (
|
||||
host_tests_plugins,
|
||||
HostRegistry,
|
||||
BaseHostTest,
|
||||
event_callback,
|
||||
DEFAULT_BAUD_RATE,
|
||||
get_plugin_caps,
|
||||
init_host_test_cli_params,
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
# base host test class
|
||||
from .base_host_test import BaseHostTest, event_callback
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.base_host_test import (
|
||||
BaseHostTestAbstract,
|
||||
event_callback,
|
||||
HostTestCallbackBase,
|
||||
BaseHostTest,
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.default_auto import DefaultAuto
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.detect_auto import DetectPlatformTest
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.dev_null_auto import DevNullTest
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.echo import EchoTest
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.hello_auto import HelloTest
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.rtc_auto import RTCTest
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2013 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests.wait_us_auto import WaitusTest
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from .conn_proxy import conn_process
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive import (
|
||||
ConnectorPrimitiveException,
|
||||
ConnectorPrimitive,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive_fastmodel import (
|
||||
FastmodelConnectorPrimitive,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive_remote import (
|
||||
RemoteConnectorPrimitive,
|
||||
)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
from mbed_os_tools.test.host_tests_conn_proxy.conn_primitive_serial import (
|
||||
SerialConnectorPrimitive,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_conn_proxy.conn_proxy import (
|
||||
KiViBufferWalker,
|
||||
conn_primitive_factory,
|
||||
conn_process,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from .ht_logger import HtrunLogger
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_logger.ht_logger import HtrunLogger
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
"""! @package mbed-host-test-plugins
|
||||
|
||||
This package contains plugins used by host test to reset, flash devices etc.
|
||||
This package can be extended with new packages to add more generic functionality
|
||||
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins import (
|
||||
HOST_TEST_PLUGIN_REGISTRY,
|
||||
call_plugin,
|
||||
get_plugin_caps,
|
||||
get_plugin_info,
|
||||
print_plugin_info,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.host_test_plugins import (
|
||||
HostTestPluginBase,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.host_test_registry import (
|
||||
HostTestRegistry,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_jn51xx import (
|
||||
HostTestPluginCopyMethod_JN51xx,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_mbed import (
|
||||
HostTestPluginCopyMethod_Mbed,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_mps2 import (
|
||||
HostTestPluginCopyMethod_MPS2,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2016-2016,2018 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: Russ Butler <russ.butler@arm.com>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_pyocd import (
|
||||
HostTestPluginCopyMethod_pyOCD,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_shell import (
|
||||
HostTestPluginCopyMethod_Shell,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_silabs import (
|
||||
HostTestPluginCopyMethod_Silabs,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_stlink import (
|
||||
HostTestPluginCopyMethod_Stlink,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_copy_ublox import (
|
||||
HostTestPluginCopyMethod_ublox,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_power_cycle_mbed import (
|
||||
HostTestPluginPowerCycleResetMethod,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_jn51xx import (
|
||||
HostTestPluginResetMethod_JN51xx,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_mbed import (
|
||||
HostTestPluginResetMethod_Mbed,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_mps2 import (
|
||||
HostTestPluginResetMethod_MPS2,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2016-2016,2018 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: Russ Butler <russ.butler@arm.com>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_pyocd import (
|
||||
HostTestPluginResetMethod_pyOCD,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_silabs import (
|
||||
HostTestPluginResetMethod_SiLabs,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_stlink import (
|
||||
HostTestPluginResetMethod_Stlink,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_plugins.module_reset_ublox import (
|
||||
HostTestPluginResetMethod_ublox,
|
||||
load_plugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
"""! @package host_registry
|
||||
|
||||
Host registry is used to store all host tests (by id) which can be called from test framework
|
||||
|
||||
"""
|
||||
|
||||
from .host_registry import HostRegistry
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_registry.host_registry import HostRegistry
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2015 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>
|
||||
"""
|
||||
|
||||
"""! @package mbed-host-test-runner
|
||||
|
||||
This package contains basic host test implementation with algorithms to flash and reset device.
|
||||
Functionality can be overridden by set of plugins which can provide specialised flashing and reset implementations.
|
||||
|
||||
"""
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_runner.host_test import (
|
||||
HostTestResults,
|
||||
Test,
|
||||
DefaultTestSelectorBase,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_runner.host_test_default import (
|
||||
DefaultTestSelector,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_runner.mbed_base import Mbed
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from .host_functional import reset_dev
|
||||
from .host_functional import flash_dev
|
||||
from .host_functional import handle_send_break_cmd
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from mbed_os_tools.test.host_tests_toolbox.host_functional import (
|
||||
flash_dev,
|
||||
reset_dev,
|
||||
handle_send_break_cmd,
|
||||
)
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
"""
|
||||
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 sys
|
||||
import optparse
|
||||
|
||||
### Flashing/Reset API provided by mbed--host-tests (mbedhtrun)
|
||||
from mbed_os_tools.test import host_tests_plugins
|
||||
|
||||
|
||||
def cmd_parser_setup():
|
||||
"""! Creates simple command line parser
|
||||
"""
|
||||
parser = optparse.OptionParser()
|
||||
|
||||
parser.add_option('-f', '--file',
|
||||
dest='filename',
|
||||
help='File to flash onto mbed device')
|
||||
|
||||
parser.add_option("-d", "--disk",
|
||||
dest="disk",
|
||||
help="Target disk (mount point) path. Example: F:, /mnt/MBED",
|
||||
metavar="DISK_PATH")
|
||||
|
||||
copy_methods_str = "Plugin support: " + ', '.join(host_tests_plugins.get_plugin_caps('CopyMethod'))
|
||||
|
||||
parser.add_option("-c", "--copy",
|
||||
dest="copy_method",
|
||||
default='shell',
|
||||
help="Copy (flash the target) method selector. " + copy_methods_str,
|
||||
metavar="COPY_METHOD")
|
||||
|
||||
parser.add_option('', '--plugins',
|
||||
dest='list_plugins',
|
||||
default=False,
|
||||
action="store_true",
|
||||
help='Prints registered plugins and exits')
|
||||
|
||||
parser.add_option('', '--version',
|
||||
dest='version',
|
||||
default=False,
|
||||
action="store_true",
|
||||
help='Prints package version and exits')
|
||||
|
||||
parser.description = """Flash mbed devices from command line.""" \
|
||||
"""This module is using build in to mbed-host-tests plugins used for flashing mbed devices"""
|
||||
parser.epilog = """Example: mbedflsh -d E: -f /path/to/file.bin"""
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
return (opts, args)
|
||||
|
||||
|
||||
def main():
|
||||
"""! Function wrapping flashing (copy) plugin
|
||||
@details USers can use mbedflsh command to flash mbeds from command line
|
||||
"""
|
||||
errorlevel_flag = 0
|
||||
(opts, args) = cmd_parser_setup()
|
||||
|
||||
if opts.version:
|
||||
import pkg_resources # part of setuptools
|
||||
version = pkg_resources.require("mbed-host-tests")[0].version
|
||||
print(version)
|
||||
sys.exit(0)
|
||||
elif opts.list_plugins: # --plugins option
|
||||
host_tests_plugins.print_plugin_info()
|
||||
sys.exit(0)
|
||||
else:
|
||||
pass
|
||||
|
||||
if opts.filename:
|
||||
print("mbedflsh: opening file %s..."% opts.filename)
|
||||
result = host_tests_plugins.call_plugin('CopyMethod',
|
||||
opts.copy_method,
|
||||
image_path=opts.filename,
|
||||
destination_disk=opts.disk)
|
||||
errorlevel_flag = result == True
|
||||
|
||||
return errorlevel_flag
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
"""
|
||||
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>
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from multiprocessing import freeze_support
|
||||
from mbed_os_tools.test import init_host_test_cli_params
|
||||
from mbed_os_tools.test.host_tests_runner.host_test_default import DefaultTestSelector
|
||||
from mbed_os_tools.test.host_tests_toolbox.host_functional import handle_send_break_cmd
|
||||
|
||||
|
||||
def main():
|
||||
"""! This function drives command line tool 'mbedhtrun' which is using DefaultTestSelector
|
||||
@details 1. Create DefaultTestSelector object and pass command line parameters
|
||||
2. Call default test execution function run() to start test instrumentation
|
||||
"""
|
||||
freeze_support()
|
||||
result = 0
|
||||
cli_params = init_host_test_cli_params()
|
||||
|
||||
if cli_params.version: # --version
|
||||
import pkg_resources # part of setuptools
|
||||
version = pkg_resources.require("mbed-host-tests")[0].version
|
||||
print(version)
|
||||
elif cli_params.send_break_cmd: # -b with -p PORT (and optional -r RESET_TYPE)
|
||||
handle_send_break_cmd(
|
||||
port=cli_params.port,
|
||||
disk=cli_params.disk,
|
||||
reset_type=cli_params.forced_reset_type,
|
||||
baudrate=cli_params.baud_rate,
|
||||
verbose=cli_params.verbose
|
||||
)
|
||||
else:
|
||||
test_selector = DefaultTestSelector(cli_params)
|
||||
try:
|
||||
result = test_selector.execute()
|
||||
# Ensure we don't return a negative value
|
||||
if result < 0 or result > 255:
|
||||
result = 1
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
test_selector.finish()
|
||||
result = 1
|
||||
raise
|
||||
else:
|
||||
test_selector.finish()
|
||||
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
|
@ -0,0 +1,454 @@
|
|||
# Development moved
|
||||
|
||||
The development of Mbed LS has been moved into the [mbed-os-tools](../../src/mbed_os_tools) package. You can continue to use this module for legacy reasons, however all further development should be continued in the new package.
|
||||
|
||||
-------------
|
||||
|
||||
[](https://badge.fury.io/py/mbed-ls)
|
||||
|
||||
# Mbed LS
|
||||
|
||||
Mbed LS is a Python (2 and 3) module that detects and lists Mbed Enabled devices connected to the host computer. The Mbed OS team publishes Mbed LS on PyPI. It works on all major operating systems (Windows, Linux and Mac OS X).
|
||||
|
||||
It provides the following information for all connected boards in a console (terminal) output:
|
||||
|
||||
- Mbed OS platform name.
|
||||
- Mount point (MSD or disk).
|
||||
- Serial port.
|
||||
|
||||
# Installation
|
||||
|
||||
## Installation from PyPI (Python Package Index)
|
||||
|
||||
To install Mbed LS from [PyPI](https://pypi.python.org/pypi/mbed-ls), run the following command:
|
||||
|
||||
```bash
|
||||
$ pip install mbed-ls --upgrade
|
||||
```
|
||||
|
||||
## Installation from Python sources
|
||||
|
||||
**Prerequisites:** You need to have [Python 2.7.x](https://www.python.org/download/releases/2.7/) or [Python 3.6.x](https://www.python.org/downloads/release/python-362/) installed on your system.
|
||||
|
||||
**Note:** If your OS is Windows, please follow the installation instructions [for the serial port driver](https://os.mbed.com/docs/latest/tutorials/windows-serial-driver.html).
|
||||
|
||||
Install Mbed LS from sources with the following commands:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/ARMmbed/mbed-os-tools.git
|
||||
$ cd mbed-os-tools/packages/mbed-ls
|
||||
$ python setup.py install
|
||||
```
|
||||
|
||||
# Command-line
|
||||
|
||||
The command-line tool is available with the command `mbedls`.
|
||||
|
||||
**Note:** [Mbed CLI](https://github.com/armmbed/mbed-cli) has a similarly-named command `mbed ls`; however, the commands are different. Be sure to omit the space when using the Mbed LS command-line tool.
|
||||
|
||||
```bash
|
||||
$ mbedls
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| platform_name | platform_name_unique | mount_point | serial_port | target_id | daplink_version |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| K64F | K64F[0] | D: | COM18 | 0240000032044e4500257009997b00386781000097969900 | 0244 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
```
|
||||
|
||||
## Result formats
|
||||
|
||||
The Mbed LS command-line accepts a few arguments to change the format of the results. The default format is a table. You may pass `--simple` to simplify this table format, and `--json` to print the table as a json list of the rows.
|
||||
|
||||
### Simple (no table formatting)
|
||||
|
||||
```
|
||||
$ mbedls --simple
|
||||
K64F K64F[0] D: COM18 0240000032044e4500257009997b00386781000097969900 0244
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
```bash
|
||||
$ mbedls --json
|
||||
[
|
||||
{
|
||||
"daplink_auto_reset": "0",
|
||||
"daplink_automation_allowed": "1",
|
||||
"daplink_bootloader_crc": "0xa65218eb",
|
||||
"daplink_bootloader_version": "0242",
|
||||
"daplink_daplink_mode": "Interface",
|
||||
"daplink_git_sha": "67f8727a030bcc585e982d899fb6382db56d673b",
|
||||
"daplink_hic_id": "97969900",
|
||||
"daplink_interface_crc": "0xe4422294",
|
||||
"daplink_interface_version": "0244",
|
||||
"daplink_local_mods": "0",
|
||||
"daplink_overflow_detection": "1",
|
||||
"daplink_remount_count": "0",
|
||||
"daplink_unique_id": "0240000032044e4500257009997b00386781000097969900",
|
||||
"daplink_usb_interfaces": "MSD, CDC, HID",
|
||||
"daplink_version": "0244",
|
||||
"mount_point": "D:",
|
||||
"platform_name": "K64F",
|
||||
"platform_name_unique": "K64F[0]",
|
||||
"product_id": "0204",
|
||||
"serial_port": "COM18",
|
||||
"target_id": "0240000032044e4500257009997b00386781000097969900",
|
||||
"target_id_mbed_htm": "0240000032044e4500257009997b00386781000097969900",
|
||||
"target_id_usb_id": "0240000032044e4500257009997b00386781000097969900",
|
||||
"vendor_id": "0d28"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Mocking (renaming) platforms
|
||||
|
||||
Override a platform's name using the `--mock` parameter:
|
||||
|
||||
```
|
||||
$ mbedls --mock 0240:MY_NEW_PLATFORM
|
||||
$ mbedls
|
||||
+-----------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| platform_name | platform_name_unique | mount_point | serial_port | target_id | daplink_version |
|
||||
+-----------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| MY_NEW_PLATFORM | MY_NEW_PLATFORM[0] | D: | COM18 | 0240000032044e4500257009997b00386781000097969900 | 0244 |
|
||||
+-----------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
```
|
||||
|
||||
The `--mock` parameter accepts a platform ID and a platform name, separated by the `:` character. The platform ID is the first 4 characters of the `target_id`. The platform name is the name you are temporarily assigning to this platform.
|
||||
|
||||
To remove a mocked platform, use the `--mock` parameter again. Continuing from the previous example, use `-<platform id>` as the value:
|
||||
|
||||
```
|
||||
$ mbedls --mock -0240
|
||||
$ mbedls
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| platform_name | platform_name_unique | mount_point | serial_port | target_id | daplink_version |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| K64F | K64F[0] | D: | COM18 | 0240000032044e4500257009997b00386781000097969900 | 0244 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
```
|
||||
|
||||
You can also remove all mocked platforms by supplying `*` as the `target_id`:
|
||||
|
||||
```
|
||||
$ mbedls --mock="-*"
|
||||
```
|
||||
|
||||
**NOTE:** Due to a quirk in the parameter formatting, the command-line can interpret `-*` as another parameter instead of a value. It is necessary to use the complete `--mock="-*"` syntax, so the command-line interprets each part of the command correctly.
|
||||
|
||||
## Retargeting platforms
|
||||
|
||||
It is possible to change the returned results for certain platforms depending on the current directory. This is especially useful when developing new platforms.
|
||||
|
||||
The command-line tool and Python API check the current directory for a file named `mbedls.json`. When it is present, it overrides the returned values. The format of the `mbedls.json` file is:
|
||||
|
||||
```json
|
||||
{
|
||||
"<target_id>": {
|
||||
"<key>": "<value>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For example, to change the `serial_port` of the K64F with a `target_id` of `0240000032044e4500257009997b00386781000097969900`, the `mbedls.json` file contains the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"0240000032044e4500257009997b00386781000097969900": {
|
||||
"serial_port": "COM99"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This results in the following output from the command-line tool:
|
||||
|
||||
```bash
|
||||
$ mbedls
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| platform_name | platform_name_unique | mount_point | serial_port | target_id | daplink_version |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| K64F | K64F[0] | D: | COM99 | 0240000032044e4500257009997b00386781000097969900 | 0244 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
```
|
||||
|
||||
Note how the `serial_port` value changed from `COM18` to `COM99`. Deleting the `mbedls.json` or using the `--skip-retarget` parameter removes these changes.
|
||||
|
||||
# Python API
|
||||
|
||||
The Python API is available through the `mbed_lstools` module.
|
||||
|
||||
## `mbed_lstools.create(...)`
|
||||
|
||||
```python
|
||||
>>> import mbed_lstools
|
||||
>>> mbeds = mbed_lstools.create()
|
||||
>>> mbeds
|
||||
<mbed_lstools.lstools_win7.MbedLsToolsWin7 instance at 0x02F542B0>
|
||||
```
|
||||
|
||||
This returns an instance that provides access to the rest of the API.
|
||||
|
||||
### Arguments
|
||||
|
||||
#### `skip_retarget`
|
||||
|
||||
**Default:** `False`
|
||||
|
||||
When set to `True`, this skips the retargetting step, and the results are unmodified. This enables the same behavior as the `--skip-retarget` command-line flag.
|
||||
|
||||
#### `list_unmounted`
|
||||
|
||||
**Default:** `False`
|
||||
|
||||
When set to `True`, this includes unmounted platforms in the results. This enables the same behavior as the `-u` command-line flag.
|
||||
|
||||
## `mbeds.list_mbeds(...)`
|
||||
|
||||
```python
|
||||
>>> import mbed_lstools
|
||||
>>> mbeds = mbed_lstools.create()
|
||||
>>> mbeds.list_mbeds(fs_interaction=FSInteraction.BeforeFilter,
|
||||
filter_function=None,
|
||||
unique_names=False,
|
||||
read_details_txt=False)
|
||||
[{'target_id_mbed_htm': u'0240000032044e4500257009997b00386781000097969900', 'mount_point': 'D:', 'target_id': u'0240000032044e4500257009997b00386781000097969900', 'serial_port': u'COM18', 'target_id_usb_id': u'0240000032044e4500257009997b00386781000097969900', 'platform_name': u'K64F'}]
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
#### `filter_function`
|
||||
|
||||
**Default:** `None`
|
||||
|
||||
This function allows you to filter results based on platform data. This can hasten the execution of the `list_mbeds` function.
|
||||
|
||||
As a normal function definition:
|
||||
|
||||
```python
|
||||
def filter_func(mbed):
|
||||
return m['platform_name'] == 'K64F'
|
||||
|
||||
mbeds.list_mbeds(filter_function=filter_func)
|
||||
```
|
||||
|
||||
As a lambda function:
|
||||
|
||||
```python
|
||||
platforms = mbeds.list_mbeds(filter_function=lambda m: m['platform_name'] == 'K64F')
|
||||
```
|
||||
|
||||
#### `fs_interaction`
|
||||
|
||||
**Default:** `FSInteraction.BeforeFilter`
|
||||
|
||||
This argument controls the accuracy and speed of this function. There are three choices (in ascending order of accuracy and decreasing order of speed):
|
||||
|
||||
- `FSInteraction.NEVER` - This is the fastest option but also potentially the least accurate. It never touches the file system of the devices. It uses only the information available through the USB descriptors. This is appropriate for use in a highly controlled environment (such as an automated Continuous Integration setup). **This has the potential to provide incorrect names and data. It may also lead to devices not being detected at all.**
|
||||
- `FSInterfaction.AfterFilter` - This accesses the file system but only after application of the `filter_function`. This can lead to speed increases but at the risk of filtering on inaccurate information.
|
||||
- `FSInteraction.BeforeFilter` - This accesses the file system before doing any filtering. It is the most accurate option and is recommended for most uses. This is the default behavior of the command-line tool and the API.
|
||||
|
||||
#### `unique_names`
|
||||
|
||||
**Default:** `False`.
|
||||
|
||||
Mbed LS assigns a unique name to each platform when this is set to `True`. The unique name takes the form of `K64F[0]`, where the number between the brackets is an incrementing value. This name is accessible through the dictionary member `platform_unique_name` in the returned platform data.
|
||||
|
||||
#### `read_details_txt`
|
||||
|
||||
**Default:** `False`
|
||||
|
||||
Mbed LS reads more data from the file system on each device when this is set to `True`. It can provide useful management data but also takes more time to execute.
|
||||
|
||||
## `mbeds.mock_manufacture_id(...)`
|
||||
|
||||
```python
|
||||
>>> import mbed_lstools
|
||||
>>> mbeds = mbed_lstools.create()
|
||||
>>> mbeds.mock_manufacture_id('0240', 'CUSTOM_PLATFORM', oper='+')
|
||||
>>> mbeds.list_mbeds()
|
||||
[{'target_id': u'0240000032044e4500257009997b00386781000097969900', ... 'platform_name': u'CUSTOM_PLATFORM'}]
|
||||
>>> mbeds.mock_manufacture_id('0240', '', oper='-')
|
||||
>>> mbeds.list_mbeds()
|
||||
[{'target_id': u'0240000032044e4500257009997b00386781000097969900', ... 'platform_name': u'K64F'}]
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
#### `mid`
|
||||
|
||||
**Required**
|
||||
|
||||
The first four characters of the `target_id` that you want to mock.
|
||||
|
||||
#### `platform_name`
|
||||
|
||||
**Required**
|
||||
|
||||
Overrides the `platform_name` for any platform with a `target_id` that starts with `mid`.
|
||||
|
||||
#### `oper`
|
||||
|
||||
**Default:** `'+'`
|
||||
|
||||
If set to `'+'`, the mocked platform is enabled. If `'-'`, the mocked platform is disabled.
|
||||
|
||||
|
||||
## `mbeds.get_supported_platforms(...)`
|
||||
|
||||
```python
|
||||
>>> import mbed_lstools
|
||||
>>> mbeds = mbed_lstools.create()
|
||||
>>> mbeds.get_supported_platforms(device_type='daplink')
|
||||
{'0240': 'K64F', '0311': 'K66F'}
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
#### `device_type`
|
||||
|
||||
**Default:** `'daplink'`
|
||||
|
||||
Chooses which device type entries are retrieved from the platform database.
|
||||
|
||||
## Logging
|
||||
|
||||
Mbed LS uses the Python `logging` module for all of its logging needs. Mbed LS uses the logger `"mbedls"` as its root, and all other loggers start with `"mbedls."`. Configuring the Python root logger automatically redirects all of the Mbed LS logs to the configured endpoint. When using the Python API, configure logging, such as by calling `logging.basicConfig()`.
|
||||
|
||||
# Testing
|
||||
|
||||
The `/test` directory contains all tests. You can run the tests with the following command:
|
||||
|
||||
```
|
||||
$ python setup.py test
|
||||
```
|
||||
|
||||
## Code coverage
|
||||
|
||||
The `coverage` Python package measures code coverage. You can install it with following command:
|
||||
|
||||
```
|
||||
$ pip install coverage --upgrade
|
||||
```
|
||||
|
||||
To run the tests while measuring code coverage, use the following command:
|
||||
|
||||
```
|
||||
$ coverage run setup.py test
|
||||
```
|
||||
|
||||
You can then generate a report:
|
||||
|
||||
```
|
||||
$ coverage report
|
||||
Name Stmts Miss Cover
|
||||
-------------------------------------------------------
|
||||
mbed_lstools\__init__.py 2 0 100%
|
||||
mbed_lstools\darwin.py 85 7 92%
|
||||
mbed_lstools\linux.py 45 3 93%
|
||||
mbed_lstools\lstools_base.py 299 124 59%
|
||||
mbed_lstools\main.py 134 44 67%
|
||||
mbed_lstools\platform_database.py 114 4 96%
|
||||
mbed_lstools\windows.py 98 21 79%
|
||||
-------------------------------------------------------
|
||||
TOTAL 777 203 74%
|
||||
```
|
||||
|
||||
# OS-specific behavior
|
||||
|
||||
## Windows
|
||||
|
||||
The Mbed serial port works by default on Mac and Linux, but Windows needs a driver. Check [here](https://os.mbed.com/docs/latest/tutorials/windows-serial-driver.html) for more details.
|
||||
|
||||
## Linux
|
||||
|
||||
Mbed LS requires you to mount a platform before it shows up in the results. Many Linux systems do not automatically mount USB devices. We recommend you use an automounter to manage this for you.
|
||||
|
||||
There are many automounters available, and it is ultimately up to you to determine which is the best one for your use case. However, the `usbmount` package on Ubuntu makes it easy to start. If you need more control over your automounter, you can build and run an open source project called [ldm](https://github.com/LemonBoy/ldm).
|
||||
|
||||
# Mbed Enabled technical requirements overview
|
||||
|
||||
This tool relies on board interfaces conforming to certain standards, so it can detect platforms properly. The [Mbed Enabled](https://www.mbed.com/en/about-mbed/mbed-enabled/) program sets these standards. Please see the [Technical Requirements](https://www.mbed.com/en/about-mbed/mbed-enabled/mbed-enabled-program-requirements/) for more information.
|
||||
|
||||
## Device unique identifier
|
||||
|
||||
Each device must have a unique identifier. This identifier has two parts: a **platform ID** and a **platform unique string**.
|
||||
|
||||
The **platform ID** contains four ASCII characters containing only hexadecimal values (A-F and 0-9). This platform ID is the same for all platforms of the same type. For example, all `K64F` platforms have a platform ID of `0240`. `mbedls` uses this to identify the platform.
|
||||
|
||||
The **platform unique string** can be any length of characters (a-z, A-Z and 0-9) that you can use to uniquely identify platforms of the same type on the same machine. For example, two FRDM-K64F platforms attached to the same machine could have the following attributes:
|
||||
|
||||
```
|
||||
$ mbedls
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| platform_name | platform_name_unique | mount_point | serial_port | target_id | daplink_version |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
| K64F | K64F[0] | D: | COM18 | 0240000032044e4500257009997b00386781000097969900 | 0244 |
|
||||
| K64F | K64F[1] | E: | COM19 | 0240000032044e4500257009997b00386781000097840023 | 0244 |
|
||||
+---------------+----------------------+-------------+-------------+--------------------------------------------------+-----------------+
|
||||
```
|
||||
|
||||
Note how both platforms share the same platform ID (`0240`) but have a unique ending string.
|
||||
|
||||
# Adding platform support
|
||||
|
||||
If a platform meets the Mbed Enabled technical requirements (stated above), it can be added to Mbed LS.
|
||||
|
||||
## Adding a new platform with a supported debugger
|
||||
|
||||
Mbed LS currently supports the following types of debuggers:
|
||||
|
||||
- [DAPLink](https://github.com/ARMmbed/DAPLink)
|
||||
- As well as the related but legacy [CMSIS-DAP](https://github.com/mbedmicro/CMSIS-DAP) firmware
|
||||
- ST-LINK
|
||||
- J-Link
|
||||
|
||||
### Adding support for DAPLink-compatible platforms (DAPLink, ST-LINK, and CMSIS-DAP)
|
||||
|
||||
Add an entry to the `daplink` section of the [`DEFAULT_PLATFORM_DB`](../../src/mbed_os_tools/detect/platform_database.py).
|
||||
|
||||
If your platform's name is `NEW_PLATFORM` and it has platform ID of `9999`, the new entry should be:
|
||||
|
||||
```
|
||||
DEFAULT_PLATFORM_DB = {
|
||||
u'daplink': {
|
||||
...
|
||||
u'9999': u'NEW_PLATFORM',
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please order the entries by the platform ID when adding new platforms.
|
||||
|
||||
### Adding support for J-Link platforms
|
||||
|
||||
J-Link detection works differently due to the information present on the platform's filesystem. All new entries should be added to the `jlink` section of the [`DEFAULT_PLATFORM_DB`](../../src/mbed_os_tools/detect/platform_database.py).
|
||||
|
||||
The following is an example `jlink` platform entry:
|
||||
|
||||
```
|
||||
DEFAULT_PLATFORM_DB = {
|
||||
...
|
||||
u'jlink': {
|
||||
u'X729475D28G': {
|
||||
u'platform_name': u'NRF51_DK',
|
||||
u'jlink_device_name': u'nRF51422_xxAC'
|
||||
},
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Instead of a platform ID, there is a target-unique string (`X729475D28G` in this case). This should correspond with the unique part of the link present in the `Board.html` or `User Guide.html`. This seems to vary among the platforms. In general, try following the links in each file. You want to use the url that links to a product page that references the platform. The J-Link logic in Mbed LS assumes that the url has the target-unique string on the end (after the last `/` character). In the above example, the expected url structure would be `http://www.nordicsemi.com/X729475D28G`.
|
||||
|
||||
If your J-Link platform does not follow this convention, please raise an issue with the following information:
|
||||
|
||||
- The name of the platform
|
||||
- The file **names and contents** present on the platform's filesystem
|
||||
- A link to the J-Link firmware binary if possible
|
||||
|
||||
## Adding a new type of debugger
|
||||
|
||||
The type of debugger present on the platform affects how it is detected. The USB Vendor ID is used to detect which type of debugger is present on the platform.
|
||||
|
||||
If a new type of debugger is being introduced to Mbed LS with the platform, you will need to add the Vendor ID to the [identification map](../../src/mbed_os_tools/detect/lstools_base.py). You will also need to assign the correct "update from the filesystem" logic [here](../../src/mbed_os_tools/detect/lstools_base.py). If the debugger is compatible with the files presented by DAPLink, you may reuse that implementation when updating the device information from the filesystem. If it is not, you may need to write your own update logic. If you need guidance on this, please ask for it when you submit an issue or a pull request.
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
"""! @package mbed-ls
|
||||
|
||||
mbed-ls package is a set of tools inherited from mbed-lmtools used to detect
|
||||
mbed enabled devices on host (Windows, Linux and MacOS).
|
||||
|
||||
mbed-lstools is a Python module that detects and lists mbed-enabled devices
|
||||
connected to the host computer. It will be delivered as a redistributable
|
||||
Python module (package) and command line tool.
|
||||
|
||||
Currently supported operating system:
|
||||
* Windows 7.
|
||||
* Ubuntu.
|
||||
* Mac OS X (Darwin).
|
||||
|
||||
The stand-alone mbed-lstools Python package is still under development,
|
||||
but it's already delivered as part of the mbed SDK's test suite and a command
|
||||
line tool (see below).
|
||||
"""
|
||||
|
||||
from .main import mbedls_main
|
||||
from .main import create
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.detect.darwin import MbedLsToolsDarwin
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.detect.linux import MbedLsToolsLinuxGeneric
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
import logging
|
||||
|
||||
from mbed_os_tools.detect.lstools_base import (
|
||||
FSInteraction,
|
||||
MbedLsToolsBase,
|
||||
)
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
# Make sure that any global generic setup is run
|
||||
from . import lstools_base
|
||||
from mbed_os_tools.detect.main import (
|
||||
create,
|
||||
mbed_os_support,
|
||||
mbed_lstools_os_info,
|
||||
mock_platform
|
||||
)
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger("mbedls.main")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
del logging
|
||||
|
||||
def get_version():
|
||||
"""! Get mbed-ls Python module version string """
|
||||
import mbed_os_tools
|
||||
return mbed_os_tools.VERSION
|
||||
|
||||
def print_version(mbeds, args):
|
||||
print(get_version())
|
||||
|
||||
def print_mbeds(mbeds, args, simple):
|
||||
devices = mbeds.list_mbeds(unique_names=True, read_details_txt=True)
|
||||
if devices:
|
||||
from prettytable import PrettyTable, HEADER
|
||||
columns = ['platform_name', 'platform_name_unique', 'mount_point',
|
||||
'serial_port', 'target_id', 'daplink_version']
|
||||
columns_header = ['platform_name', 'platform_name_unique', 'mount_point',
|
||||
'serial_port', 'target_id', 'interface_version']
|
||||
pt = PrettyTable(columns_header, junction_char="|", hrules=HEADER)
|
||||
pt.align = 'l'
|
||||
for d in devices:
|
||||
pt.add_row([d.get(col, None) or 'unknown' for col in columns])
|
||||
print(pt.get_string(border=not simple, header=not simple,
|
||||
padding_width=1, sortby='platform_name_unique'))
|
||||
|
||||
def print_table(mbeds, args):
|
||||
return print_mbeds(mbeds, args, False)
|
||||
|
||||
def print_simple(mbeds, args):
|
||||
return print_mbeds(mbeds, args, True)
|
||||
|
||||
def list_platforms(mbeds, args):
|
||||
print(mbeds.list_manufacture_ids())
|
||||
|
||||
def mbeds_as_json(mbeds, args):
|
||||
print(json.dumps(mbeds.list_mbeds(unique_names=True,
|
||||
read_details_txt=True),
|
||||
indent=4, sort_keys=True))
|
||||
|
||||
def json_by_target_id(mbeds, args):
|
||||
print(json.dumps({m['target_id']: m for m
|
||||
in mbeds.list_mbeds(unique_names=True,
|
||||
read_details_txt=True)},
|
||||
indent=4, sort_keys=True))
|
||||
|
||||
def json_platforms(mbeds, args):
|
||||
platforms = set()
|
||||
for d in mbeds.list_mbeds():
|
||||
platforms |= set([d['platform_name']])
|
||||
print(json.dumps(list(platforms), indent=4, sort_keys=True))
|
||||
|
||||
def json_platforms_ext(mbeds, args):
|
||||
platforms = defaultdict(lambda: 0)
|
||||
for d in mbeds.list_mbeds():
|
||||
platforms[d['platform_name']] += 1
|
||||
print(json.dumps(platforms, indent=4, sort_keys=True))
|
||||
|
||||
def parse_cli(to_parse):
|
||||
"""! Parse the command line
|
||||
|
||||
@return Retrun a namespace that contains:
|
||||
* command - python function to run
|
||||
* skip_retarget - bool indicting to skip retargeting
|
||||
* list_unmounted - list boards that are not mounted
|
||||
* debug - turn on debug logging
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.set_defaults(command=print_table)
|
||||
|
||||
commands = parser.add_argument_group('sub commands')\
|
||||
.add_mutually_exclusive_group()
|
||||
commands.add_argument(
|
||||
'-s', '--simple', dest='command', action='store_const',
|
||||
const=print_simple,
|
||||
help='list attached targets without column headers and borders')
|
||||
commands.add_argument(
|
||||
'-j', '--json', dest='command', action='store_const',
|
||||
const=mbeds_as_json,
|
||||
help='list attached targets with detailed information in JSON format')
|
||||
commands.add_argument(
|
||||
'-J', '--json-by-target-id', dest='command', action='store_const',
|
||||
const=json_by_target_id,
|
||||
help='map attached targets from their target ID to their detailed '
|
||||
'information in JSON format')
|
||||
commands.add_argument(
|
||||
'-p', '--json-platforms', dest='command', action='store_const',
|
||||
const=json_platforms,
|
||||
help='list attached platform names in JSON format.')
|
||||
commands.add_argument(
|
||||
'-P', '--json-platforms-ext', dest='command', action='store_const',
|
||||
const=json_platforms_ext,
|
||||
help='map attached platform names to the number of attached boards in '
|
||||
'JSON format')
|
||||
commands.add_argument(
|
||||
'-l', '--list', dest='command', action='store_const',
|
||||
const=list_platforms,
|
||||
help='list all target IDs and their corresponding platform names '
|
||||
'understood by mbed-ls')
|
||||
commands.add_argument(
|
||||
'--version', dest='command', action='store_const', const=print_version,
|
||||
help='print package version and exit')
|
||||
commands.add_argument(
|
||||
'-m', '--mock', metavar='ID:NAME',
|
||||
help='substitute or create a target ID to platform name mapping used'
|
||||
'when invoking mbedls in the current directory')
|
||||
|
||||
parser.add_argument(
|
||||
'--skip-retarget', dest='skip_retarget', default=False,
|
||||
action="store_true",
|
||||
help='skip parsing and interpretation of the re-target file,'
|
||||
' `./mbedls.json`')
|
||||
parser.add_argument(
|
||||
'-u', '--list-unmounted', dest='list_unmounted', default=False,
|
||||
action='store_true',
|
||||
help='list mbeds, regardless of whether they are mounted or not')
|
||||
parser.add_argument(
|
||||
'-d', '--debug', dest='debug', default=False, action="store_true",
|
||||
help='outputs extra debug information useful when creating issues!')
|
||||
|
||||
args = parser.parse_args(to_parse)
|
||||
if args.mock:
|
||||
args.command = mock_platform
|
||||
return args
|
||||
|
||||
def start_logging():
|
||||
try:
|
||||
import colorlog
|
||||
colorlog.basicConfig(
|
||||
format='%(log_color)s%(levelname)s%(reset)s:%(name)s:%(message)s')
|
||||
except ImportError:
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
del logging
|
||||
|
||||
def mbedls_main():
|
||||
"""! Function used to drive CLI (command line interface) application
|
||||
@return Function exits with success code
|
||||
"""
|
||||
start_logging()
|
||||
|
||||
args = parse_cli(sys.argv[1:])
|
||||
|
||||
import logging
|
||||
root_logger = logging.getLogger("mbedls")
|
||||
if args.debug:
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
root_logger.setLevel(logging.INFO)
|
||||
del logging
|
||||
logger.debug("mbed-ls ver. %s", get_version())
|
||||
logger.debug("host: %s", str(mbed_lstools_os_info()))
|
||||
|
||||
mbeds = create(skip_retarget=args.skip_retarget,
|
||||
list_unmounted=args.list_unmounted,
|
||||
force_mock=args.command is mock_platform)
|
||||
|
||||
if mbeds is None:
|
||||
logger.critical('This platform is not supported! Pull requests welcome at github.com/ARMmbed/mbed-ls')
|
||||
sys.exit(1)
|
||||
|
||||
ret_code = args.command(mbeds, args)
|
||||
if not ret_code:
|
||||
ret_code = 0
|
||||
|
||||
logger.debug("Return code: %d", ret_code)
|
||||
|
||||
sys.exit(ret_code)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2017-2018 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.
|
||||
"""
|
||||
|
||||
"""Functions that manage a platform database"""
|
||||
|
||||
from mbed_os_tools.detect.platform_database import (
|
||||
LOCAL_PLATFORM_DATABASE,
|
||||
LOCAL_MOCKS_DATABASE,
|
||||
DEFAULT_PLATFORM_DB,
|
||||
PlatformDatabase
|
||||
)
|
||||
|
||||
"""
|
||||
NOTE: The platform database is now in the mbed-os-tools package.
|
||||
You can find it in the following file: mbed_os_tools/detect/platform_database.py
|
||||
Please make all further contributions to the new package.
|
||||
"""
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
mbed SDK
|
||||
Copyright (c) 2011-2018 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.
|
||||
"""
|
||||
|
||||
from mbed_os_tools.detect.windows import (
|
||||
MbedLsToolsWin7,
|
||||
CompatibleIDsNotFoundException
|
||||
)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Mbed CE: added hardcoded version
|
||||
VERSION = "0.0.16"
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""! @package mbed-ls
|
||||
|
||||
mbed-ls package is a set of tools inherited from mbed-lmtools used to detect
|
||||
mbed enabled devices on host (Windows, Linux and MacOS).
|
||||
|
||||
mbed-lstools is a Python module that detects and lists mbed-enabled devices
|
||||
connected to the host computer. It will be delivered as a redistributable
|
||||
Python module (package) and command line tool.
|
||||
|
||||
Currently supported operating system:
|
||||
* Windows 7.
|
||||
* Ubuntu.
|
||||
* Mac OS X (Darwin).
|
||||
|
||||
The stand-alone mbed-lstools Python package is still under development,
|
||||
but it's already delivered as part of the mbed SDK's test suite and a command
|
||||
line tool (see below).
|
||||
"""
|
||||
|
||||
from .main import create
|
||||
|
||||
create = create
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
try:
|
||||
from plistlib import loads
|
||||
except ImportError:
|
||||
from plistlib import readPlistFromString as loads
|
||||
from xml.parsers.expat import ExpatError
|
||||
|
||||
from .lstools_base import MbedLsToolsBase
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("mbedls.lstools_darwin")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
DEBUG = logging.DEBUG
|
||||
del logging
|
||||
|
||||
mbed_volume_name_match = re.compile(r"\b(mbed|SEGGER MSD|ATMEL EDBG Media)\b", re.I)
|
||||
|
||||
|
||||
def _plist_from_popen(popen):
|
||||
out, _ = popen.communicate()
|
||||
if not out:
|
||||
return []
|
||||
try:
|
||||
try:
|
||||
# Try simple and fast first if this fails fall back to the slower but
|
||||
# more robust process.
|
||||
return loads(out)
|
||||
except ExpatError:
|
||||
# Beautiful soup ensures the XML is properly formed after it is parsed
|
||||
# so that it can be used by other less lenient commands without problems
|
||||
xml_representation = BeautifulSoup(out.decode('utf8'), 'xml')
|
||||
|
||||
if not xml_representation.get_text():
|
||||
# The output is not in the XML format
|
||||
return loads(out)
|
||||
return loads(xml_representation.decode().encode('utf8'))
|
||||
except ExpatError:
|
||||
return []
|
||||
|
||||
|
||||
def _find_TTY(obj):
|
||||
""" Find the first tty (AKA IODialinDevice) that we can find in the
|
||||
children of the specified object, or None if no tty is present.
|
||||
"""
|
||||
try:
|
||||
return obj["IODialinDevice"]
|
||||
except KeyError:
|
||||
for child in obj.get("IORegistryEntryChildren", []):
|
||||
found = _find_TTY(child)
|
||||
if found:
|
||||
return found
|
||||
return None
|
||||
|
||||
|
||||
def _prune(current, keys):
|
||||
""" Reduce the amount of data we have to sift through to only
|
||||
include the specified keys, and children that contain the
|
||||
specified keys
|
||||
"""
|
||||
pruned_current = {k: current[k] for k in keys if k in current}
|
||||
pruned_children = list(
|
||||
filter(
|
||||
None, [_prune(c, keys) for c in current.get("IORegistryEntryChildren", [])]
|
||||
)
|
||||
)
|
||||
keep_current = any(k in current for k in keys) or pruned_children
|
||||
if keep_current:
|
||||
if pruned_children:
|
||||
pruned_current["IORegistryEntryChildren"] = pruned_children
|
||||
return pruned_current
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
def _dfs_usb_info(obj, parents):
|
||||
""" Find all of the usb info that we can from this particular IORegistry
|
||||
tree with depth first search (and searching the parent stack....)
|
||||
"""
|
||||
output = {}
|
||||
if (
|
||||
"BSD Name" in obj
|
||||
and obj["BSD Name"].startswith("disk")
|
||||
and mbed_volume_name_match.search(obj["IORegistryEntryName"])
|
||||
):
|
||||
disk_id = obj["BSD Name"]
|
||||
usb_info = {"serial": None, "vendor_id": None, "product_id": None, "tty": None}
|
||||
for parent in [obj] + parents:
|
||||
if "USB Serial Number" in parent:
|
||||
usb_info["serial"] = parent["USB Serial Number"]
|
||||
if "idVendor" in parent and "idProduct" in parent:
|
||||
usb_info["vendor_id"] = format(parent["idVendor"], "04x")
|
||||
usb_info["product_id"] = format(parent["idProduct"], "04x")
|
||||
if usb_info["serial"]:
|
||||
usb_info["tty"] = _find_TTY(parent)
|
||||
if all(usb_info.values()):
|
||||
break
|
||||
logger.debug("found usb info %r", usb_info)
|
||||
output[disk_id] = usb_info
|
||||
for child in obj.get("IORegistryEntryChildren", []):
|
||||
output.update(_dfs_usb_info(child, [obj] + parents))
|
||||
return output
|
||||
|
||||
|
||||
class MbedLsToolsDarwin(MbedLsToolsBase):
|
||||
""" mbed-enabled platform detection on Mac OS X
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
MbedLsToolsBase.__init__(self, **kwargs)
|
||||
self.mac_version = float(".".join(platform.mac_ver()[0].split(".")[:2]))
|
||||
|
||||
def find_candidates(self):
|
||||
# {volume_id: {serial:, vendor_id:, product_id:, tty:}}
|
||||
volumes = self._volumes()
|
||||
|
||||
# {volume_id: mount_point}
|
||||
mounts = self._mount_points()
|
||||
return [
|
||||
{
|
||||
"mount_point": mounts[v],
|
||||
"serial_port": volumes[v]["tty"],
|
||||
"target_id_usb_id": volumes[v].get("serial"),
|
||||
"vendor_id": volumes[v].get("vendor_id"),
|
||||
"product_id": volumes[v].get("product_id"),
|
||||
}
|
||||
for v in set(volumes.keys()) and set(mounts.keys())
|
||||
if v in mounts and v in volumes
|
||||
]
|
||||
|
||||
def _mount_points(self):
|
||||
""" Returns map {volume_id: mount_point} """
|
||||
diskutil_ls = subprocess.Popen(
|
||||
["diskutil", "list", "-plist"], stdout=subprocess.PIPE
|
||||
)
|
||||
disks = _plist_from_popen(diskutil_ls)
|
||||
|
||||
if logger.isEnabledFor(DEBUG):
|
||||
import pprint
|
||||
|
||||
logger.debug(
|
||||
"disks dict \n%s", pprint.PrettyPrinter(indent=2).pformat(disks)
|
||||
)
|
||||
return {
|
||||
disk["DeviceIdentifier"]: disk.get("MountPoint", None)
|
||||
for disk in disks["AllDisksAndPartitions"]
|
||||
}
|
||||
|
||||
def _volumes(self):
|
||||
""" returns a map {volume_id: {serial:, vendor_id:, product_id:, tty:}"""
|
||||
|
||||
# to find all the possible mbed volumes, we look for registry entries
|
||||
# under all possible USB tree which have a "BSD Name" that starts with
|
||||
# "disk" # (i.e. this is a USB disk), and have a IORegistryEntryName that
|
||||
# matches /\cmbed/
|
||||
# Once we've found a disk, we can search up for a parent with a valid
|
||||
# serial number, and then search down again to find a tty that's part
|
||||
# of the same composite device
|
||||
# ioreg -a -r -n <usb_controller_name> -l
|
||||
usb_controllers = [
|
||||
"AppleUSBXHCI",
|
||||
"AppleUSBUHCI",
|
||||
"AppleUSBEHCI",
|
||||
"AppleUSBOHCI",
|
||||
"IOUSBHostDevice",
|
||||
]
|
||||
|
||||
cmp_par = "-n"
|
||||
# For El Captain we need to list all the instances of (-c) rather than
|
||||
# compare names (-n)
|
||||
if self.mac_version >= 10.11:
|
||||
cmp_par = "-c"
|
||||
|
||||
usb_tree = []
|
||||
for usb_controller in usb_controllers:
|
||||
ioreg_usb = subprocess.Popen(
|
||||
["ioreg", "-a", "-r", cmp_par, usb_controller, "-l"],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
usb_tree.extend(_plist_from_popen(ioreg_usb))
|
||||
|
||||
r = {}
|
||||
|
||||
for name, obj in enumerate(usb_tree):
|
||||
pruned_obj = _prune(
|
||||
obj,
|
||||
[
|
||||
"USB Serial Number",
|
||||
"idVendor",
|
||||
"BSD Name",
|
||||
"IORegistryEntryName",
|
||||
"idProduct",
|
||||
"IODialinDevice",
|
||||
],
|
||||
)
|
||||
if logger.isEnabledFor(DEBUG):
|
||||
import pprint
|
||||
|
||||
logger.debug(
|
||||
"finding in \n%s",
|
||||
pprint.PrettyPrinter(indent=2).pformat(pruned_obj),
|
||||
)
|
||||
r.update(_dfs_usb_info(pruned_obj, []))
|
||||
|
||||
logger.debug("_volumes return %r", r)
|
||||
return r
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
from .lstools_base import MbedLsToolsBase
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("mbedls.lstools_linux")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
del logging
|
||||
|
||||
SYSFS_BLOCK_DEVICE_PATH = "/sys/class/block"
|
||||
|
||||
|
||||
def _readlink(link):
|
||||
content = os.readlink(link)
|
||||
if content.startswith(".."):
|
||||
return os.path.abspath(os.path.join(os.path.dirname(link), content))
|
||||
else:
|
||||
return content
|
||||
|
||||
|
||||
class MbedLsToolsLinuxGeneric(MbedLsToolsBase):
|
||||
""" mbed-enabled platform for Linux with udev
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""! ctor
|
||||
"""
|
||||
MbedLsToolsBase.__init__(self, **kwargs)
|
||||
self.nlp = re.compile(r"(pci|usb)-[0-9a-zA-Z:_-]*_(?P<usbid>[0-9a-zA-Z]*)-.*$")
|
||||
self.mmp = re.compile(r"(?P<dev>(/[^/ ]*)+) on (?P<dir>(/[^/ ]*)+) ")
|
||||
self.udp = re.compile(r"^[0-9]+-[0-9]+[^:\s]*$")
|
||||
|
||||
def find_candidates(self):
|
||||
disk_ids = self._dev_by_id("disk")
|
||||
serial_ids = self._dev_by_id("serial")
|
||||
mount_ids = dict(self._fat_mounts())
|
||||
usb_info = self._sysfs_block_devices(disk_ids.values())
|
||||
logger.debug("Mount mapping %r", mount_ids)
|
||||
|
||||
return [
|
||||
{
|
||||
"mount_point": mount_ids.get(disk_dev),
|
||||
"serial_port": serial_ids.get(disk_uuid),
|
||||
"target_id_usb_id": disk_uuid,
|
||||
"vendor_id": usb_info.get(disk_dev, {}).get("vendor_id"),
|
||||
"product_id": usb_info.get(disk_dev, {}).get("product_id"),
|
||||
}
|
||||
for disk_uuid, disk_dev in disk_ids.items()
|
||||
]
|
||||
|
||||
def _dev_by_id(self, device_type):
|
||||
"""! Get a dict, USBID -> device, for a device class
|
||||
@param device_type The type of devices to search. For exmaple, "serial"
|
||||
looks for all serial devices connected to this computer
|
||||
@return A dict: Device USBID -> device file in /dev
|
||||
"""
|
||||
dir = os.path.join("/dev", device_type, "by-id")
|
||||
if os.path.isdir(dir):
|
||||
to_ret = dict(
|
||||
self._hex_ids([os.path.join(dir, f) for f in os.listdir(dir)])
|
||||
)
|
||||
logger.debug("Found %s devices by id %r", device_type, to_ret)
|
||||
return to_ret
|
||||
else:
|
||||
logger.error(
|
||||
"Could not get %s devices by id. "
|
||||
"This could be because your Linux distribution "
|
||||
"does not use udev, or does not create /dev/%s/by-id "
|
||||
"symlinks. Please submit an issue to github.com/"
|
||||
"armmbed/mbed-ls.",
|
||||
device_type,
|
||||
device_type,
|
||||
)
|
||||
return {}
|
||||
|
||||
def _fat_mounts(self):
|
||||
"""! Lists mounted devices with vfat file system (potential mbeds)
|
||||
@result Returns list of all mounted vfat devices
|
||||
@details Uses Linux shell command: 'mount'
|
||||
"""
|
||||
_stdout, _, retval = self._run_cli_process("mount")
|
||||
if not retval:
|
||||
for line in _stdout.splitlines():
|
||||
if b"vfat" in line:
|
||||
match = self.mmp.search(line.decode("utf-8"))
|
||||
if match:
|
||||
yield match.group("dev"), match.group("dir")
|
||||
|
||||
def _hex_ids(self, dev_list):
|
||||
"""! Build a USBID map for a device list
|
||||
@param disk_list List of disks in a system with USBID decoration
|
||||
@return Returns map USBID -> device file in /dev
|
||||
@details Uses regular expressions to get a USBID (TargeTIDs) a "by-id"
|
||||
symbolic link
|
||||
"""
|
||||
logger.debug("Converting device list %r", dev_list)
|
||||
for dl in dev_list:
|
||||
match = self.nlp.search(dl)
|
||||
if match:
|
||||
yield match.group("usbid"), _readlink(dl)
|
||||
|
||||
def _sysfs_block_devices(self, block_devices):
|
||||
device_names = {os.path.basename(d): d for d in block_devices}
|
||||
sysfs_block_devices = set(os.listdir(SYSFS_BLOCK_DEVICE_PATH))
|
||||
common_device_names = sysfs_block_devices.intersection(set(device_names.keys()))
|
||||
result = {}
|
||||
|
||||
for common_device_name in common_device_names:
|
||||
sysfs_path = os.path.join(SYSFS_BLOCK_DEVICE_PATH, common_device_name)
|
||||
full_sysfs_path = os.readlink(sysfs_path)
|
||||
path_parts = full_sysfs_path.split("/")
|
||||
|
||||
end_index = None
|
||||
for index, part in enumerate(path_parts):
|
||||
if self.udp.search(part):
|
||||
end_index = index
|
||||
|
||||
if end_index is None:
|
||||
logger.debug(
|
||||
"Did not find suitable usb folder for usb info: %s", full_sysfs_path
|
||||
)
|
||||
continue
|
||||
|
||||
usb_info_rel_path = path_parts[: end_index + 1]
|
||||
usb_info_path = os.path.join(
|
||||
SYSFS_BLOCK_DEVICE_PATH, os.sep.join(usb_info_rel_path)
|
||||
)
|
||||
|
||||
vendor_id = None
|
||||
product_id = None
|
||||
|
||||
vendor_id_file_paths = os.path.join(usb_info_path, "idVendor")
|
||||
product_id_file_paths = os.path.join(usb_info_path, "idProduct")
|
||||
|
||||
try:
|
||||
with open(vendor_id_file_paths, "r") as vendor_file:
|
||||
vendor_id = vendor_file.read().strip()
|
||||
except OSError as e:
|
||||
logger.debug(
|
||||
"Failed to read vendor id file %s weith error:",
|
||||
vendor_id_file_paths,
|
||||
e,
|
||||
)
|
||||
|
||||
try:
|
||||
with open(product_id_file_paths, "r") as product_file:
|
||||
product_id = product_file.read().strip()
|
||||
except OSError as e:
|
||||
logger.debug(
|
||||
"Failed to read product id file %s weith error:",
|
||||
product_id_file_paths,
|
||||
e,
|
||||
)
|
||||
|
||||
result[device_names[common_device_name]] = {
|
||||
"vendor_id": vendor_id,
|
||||
"product_id": product_id,
|
||||
}
|
||||
|
||||
return result
|
||||
|
|
@ -0,0 +1,805 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from io import open
|
||||
from json import load
|
||||
from os import listdir
|
||||
from os.path import expanduser, isfile, join, exists, isdir
|
||||
import logging
|
||||
import functools
|
||||
import json
|
||||
|
||||
from .platform_database import (
|
||||
PlatformDatabase,
|
||||
LOCAL_PLATFORM_DATABASE,
|
||||
LOCAL_MOCKS_DATABASE,
|
||||
)
|
||||
from future.utils import with_metaclass
|
||||
|
||||
mbedls_root_logger = logging.getLogger("mbedls")
|
||||
mbedls_root_logger.setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger("mbedls.lstools_base")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
def deprecated(reason):
|
||||
"""Deprecate a function/method with a decorator"""
|
||||
|
||||
def actual_decorator(func):
|
||||
@functools.wraps(func)
|
||||
def new_func(*args, **kwargs):
|
||||
logger.warning("Call to deprecated function %s. %s", func.__name__, reason)
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return new_func
|
||||
|
||||
return actual_decorator
|
||||
|
||||
|
||||
class FSInteraction(object):
|
||||
BeforeFilter = 1
|
||||
AfterFilter = 2
|
||||
Never = 3
|
||||
|
||||
|
||||
class MbedLsToolsBase(with_metaclass(ABCMeta, object)):
|
||||
""" Base class for mbed-lstools, defines mbed-ls tools interface for
|
||||
mbed-enabled devices detection for various hosts
|
||||
"""
|
||||
|
||||
# Which OSs are supported by this module
|
||||
# Note: more than one OS can be supported by mbed-lstools_* module
|
||||
os_supported = []
|
||||
|
||||
# Directory where we will store global (OS user specific mocking)
|
||||
HOME_DIR = expanduser("~")
|
||||
MOCK_FILE_NAME = ".mbedls-mock"
|
||||
RETARGET_FILE_NAME = "mbedls.json"
|
||||
DETAILS_TXT_NAME = "DETAILS.TXT"
|
||||
MBED_HTM_NAME = "mbed.htm"
|
||||
|
||||
VENDOR_ID_DEVICE_TYPE_MAP = {
|
||||
"0483": "stlink",
|
||||
"0d28": "daplink",
|
||||
"1366": "jlink",
|
||||
"03eb": "atmel",
|
||||
}
|
||||
|
||||
def __init__(self, list_unmounted=False, **kwargs):
|
||||
""" ctor
|
||||
"""
|
||||
self.retarget_data = {} # Used to retarget mbed-enabled platform properties
|
||||
|
||||
platform_dbs = []
|
||||
if isfile(self.MOCK_FILE_NAME) or (
|
||||
"force_mock" in kwargs and kwargs["force_mock"]
|
||||
):
|
||||
platform_dbs.append(self.MOCK_FILE_NAME)
|
||||
elif isfile(LOCAL_MOCKS_DATABASE):
|
||||
platform_dbs.append(LOCAL_MOCKS_DATABASE)
|
||||
platform_dbs.append(LOCAL_PLATFORM_DATABASE)
|
||||
self.plat_db = PlatformDatabase(platform_dbs, primary_database=platform_dbs[0])
|
||||
self.list_unmounted = list_unmounted
|
||||
|
||||
if "skip_retarget" not in kwargs or not kwargs["skip_retarget"]:
|
||||
self.retarget()
|
||||
|
||||
@abstractmethod
|
||||
def find_candidates(self):
|
||||
"""Find all candidate devices connected to this computer
|
||||
|
||||
Note: Should not open any files
|
||||
|
||||
@return A dict with the keys 'mount_point', 'serial_port' and 'target_id_usb_id'
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def list_mbeds(
|
||||
self,
|
||||
fs_interaction=FSInteraction.BeforeFilter,
|
||||
filter_function=None,
|
||||
unique_names=False,
|
||||
read_details_txt=False,
|
||||
):
|
||||
""" List details of connected devices
|
||||
@return Returns list of structures with detailed info about each mbed
|
||||
@param fs_interaction A member of the FSInteraction class that picks the
|
||||
trade of between quality of service and speed
|
||||
@param filter_function Function that is passed each mbed candidate,
|
||||
should return True if it should be included in the result
|
||||
Ex. mbeds = list_mbeds(filter_function=lambda m: m['platform_name'] == 'K64F')
|
||||
@param unique_names A boolean controlling the presence of the
|
||||
'platform_unique_name' member of the output dict
|
||||
@param read_details_txt A boolean controlling the presense of the
|
||||
output dict attributes read from other files present on the 'mount_point'
|
||||
@details Function returns list of dictionaries with mbed attributes
|
||||
'mount_point', TargetID name etc.
|
||||
Function returns mbed list with platform names if possible
|
||||
"""
|
||||
platform_count = {}
|
||||
candidates = list(self.find_candidates())
|
||||
logger.debug("Candidates for display %r", candidates)
|
||||
result = []
|
||||
for device in candidates:
|
||||
device["device_type"] = self._detect_device_type(device)
|
||||
if (
|
||||
not device["mount_point"]
|
||||
or not self.mount_point_ready(device["mount_point"])
|
||||
) and not self.list_unmounted:
|
||||
if device["target_id_usb_id"] and device["serial_port"]:
|
||||
logger.warning(
|
||||
"MBED with target id '%s' is connected, but not mounted. "
|
||||
"Use the '-u' flag to include it in the list.",
|
||||
device["target_id_usb_id"],
|
||||
)
|
||||
else:
|
||||
platform_data = self.plat_db.get(
|
||||
device["target_id_usb_id"][0:4],
|
||||
device_type=device["device_type"] or "daplink",
|
||||
verbose_data=True,
|
||||
)
|
||||
device.update(platform_data or {"platform_name": None})
|
||||
maybe_device = {
|
||||
FSInteraction.BeforeFilter: self._fs_before_id_check,
|
||||
FSInteraction.AfterFilter: self._fs_after_id_check,
|
||||
FSInteraction.Never: self._fs_never,
|
||||
}[fs_interaction](device, filter_function, read_details_txt)
|
||||
if maybe_device and (
|
||||
maybe_device["mount_point"] or self.list_unmounted
|
||||
):
|
||||
if unique_names:
|
||||
name = device["platform_name"]
|
||||
platform_count.setdefault(name, -1)
|
||||
platform_count[name] += 1
|
||||
device["platform_name_unique"] = "%s[%d]" % (
|
||||
name,
|
||||
platform_count[name],
|
||||
)
|
||||
try:
|
||||
device.update(self.retarget_data[device["target_id"]])
|
||||
logger.debug(
|
||||
"retargeting %s with %r",
|
||||
device["target_id"],
|
||||
self.retarget_data[device["target_id"]],
|
||||
)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# This is done for API compatibility, would prefer for this to
|
||||
# just be None
|
||||
device["device_type"] = (
|
||||
device["device_type"] if device["device_type"] else "unknown"
|
||||
)
|
||||
result.append(maybe_device)
|
||||
|
||||
return result
|
||||
|
||||
def _fs_never(self, device, filter_function, read_details_txt):
|
||||
"""Filter device without touching the file system of the device"""
|
||||
device["target_id"] = device["target_id_usb_id"]
|
||||
device["target_id_mbed_htm"] = None
|
||||
if not filter_function or filter_function(device):
|
||||
return device
|
||||
else:
|
||||
return None
|
||||
|
||||
def _fs_before_id_check(self, device, filter_function, read_details_txt):
|
||||
"""Filter device after touching the file system of the device.
|
||||
Said another way: Touch the file system before filtering
|
||||
"""
|
||||
|
||||
device["target_id"] = device["target_id_usb_id"]
|
||||
self._update_device_from_fs(device, read_details_txt)
|
||||
if not filter_function or filter_function(device):
|
||||
return device
|
||||
else:
|
||||
return None
|
||||
|
||||
def _fs_after_id_check(self, device, filter_function, read_details_txt):
|
||||
"""Filter device before touching the file system of the device.
|
||||
Said another way: Touch the file system after filtering
|
||||
"""
|
||||
device["target_id"] = device["target_id_usb_id"]
|
||||
device["target_id_mbed_htm"] = None
|
||||
if not filter_function or filter_function(device):
|
||||
self._update_device_from_fs(device, read_details_txt)
|
||||
return device
|
||||
else:
|
||||
return None
|
||||
|
||||
def _update_device_from_fs(self, device, read_details_txt):
|
||||
""" Updates the device information based on files from its 'mount_point'
|
||||
@param device Dictionary containing device information
|
||||
@param read_details_txt A boolean controlling the presense of the
|
||||
output dict attributes read from other files present on the 'mount_point'
|
||||
"""
|
||||
if not device.get("mount_point", None):
|
||||
return
|
||||
|
||||
try:
|
||||
directory_entries = listdir(device["mount_point"])
|
||||
device["directory_entries"] = directory_entries
|
||||
device["target_id"] = device["target_id_usb_id"]
|
||||
|
||||
# Always try to update using daplink compatible boards processself.
|
||||
# This is done for backwards compatibility.
|
||||
self._update_device_details_daplink_compatible(device, read_details_txt)
|
||||
|
||||
if device.get("device_type") == "jlink":
|
||||
self._update_device_details_jlink(device, read_details_txt)
|
||||
|
||||
if device.get("device_type") == "atmel":
|
||||
self._update_device_details_atmel(device, read_details_txt)
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
logger.warning(
|
||||
'Marking device with mount point "%s" as unmounted due to the '
|
||||
"following error: %s",
|
||||
device["mount_point"],
|
||||
e,
|
||||
)
|
||||
device["mount_point"] = None
|
||||
|
||||
def _detect_device_type(self, device):
|
||||
""" Returns a string of the device type
|
||||
@param device Dictionary containing device information
|
||||
@return Device type located in VENDOR_ID_DEVICE_TYPE_MAP or None if unknown
|
||||
"""
|
||||
|
||||
return self.VENDOR_ID_DEVICE_TYPE_MAP.get(device.get("vendor_id"))
|
||||
|
||||
def _update_device_details_daplink_compatible(self, device, read_details_txt):
|
||||
""" Updates the daplink-specific device information based on files from its
|
||||
'mount_point'
|
||||
@param device Dictionary containing device information
|
||||
@param read_details_txt A boolean controlling the presense of the
|
||||
output dict attributes read from other files present on the 'mount_point'
|
||||
"""
|
||||
lowercase_directory_entries = [e.lower() for e in device["directory_entries"]]
|
||||
if self.MBED_HTM_NAME.lower() in lowercase_directory_entries:
|
||||
self._update_device_from_htm(device)
|
||||
elif not read_details_txt:
|
||||
logger.debug(
|
||||
"Since mbed.htm is not present, attempting to use "
|
||||
"details.txt for the target id"
|
||||
)
|
||||
read_details_txt = True
|
||||
|
||||
if (
|
||||
read_details_txt
|
||||
and self.DETAILS_TXT_NAME.lower() in lowercase_directory_entries
|
||||
):
|
||||
details_txt = self._details_txt(device["mount_point"]) or {}
|
||||
device.update(
|
||||
{
|
||||
"daplink_%s" % f.lower().replace(" ", "_"): v
|
||||
for f, v in details_txt.items()
|
||||
}
|
||||
)
|
||||
|
||||
# If details.txt contains the target id, this is the most trusted source
|
||||
if device.get("daplink_unique_id", None):
|
||||
device["target_id"] = device["daplink_unique_id"]
|
||||
|
||||
if device["target_id"]:
|
||||
identifier = device["target_id"][0:4]
|
||||
platform_data = self.plat_db.get(
|
||||
identifier, device_type="daplink", verbose_data=True
|
||||
)
|
||||
if not platform_data:
|
||||
logger.warning(
|
||||
'daplink entry: "%s" not found in platform database', identifier
|
||||
)
|
||||
else:
|
||||
device.update(platform_data)
|
||||
else:
|
||||
device["platform_name"] = None
|
||||
|
||||
def _update_device_details_jlink(self, device, _):
|
||||
""" Updates the jlink-specific device information based on files from its 'mount_point'
|
||||
@param device Dictionary containing device information
|
||||
"""
|
||||
lower_case_map = {e.lower(): e for e in device["directory_entries"]}
|
||||
|
||||
if "board.html" in lower_case_map:
|
||||
board_file_key = "board.html"
|
||||
elif "user guide.html" in lower_case_map:
|
||||
board_file_key = "user guide.html"
|
||||
else:
|
||||
logger.warning("No valid file found to update JLink device details")
|
||||
return
|
||||
|
||||
board_file_path = join(device["mount_point"], lower_case_map[board_file_key])
|
||||
with open(board_file_path, "r") as board_file:
|
||||
board_file_lines = board_file.readlines()
|
||||
|
||||
for line in board_file_lines:
|
||||
m = re.search(r"url=([\w\d\:\-/\\\?\.=-_]+)", line)
|
||||
if m:
|
||||
device["url"] = m.group(1).strip()
|
||||
identifier = device["url"].split("/")[-1]
|
||||
platform_data = self.plat_db.get(
|
||||
identifier, device_type="jlink", verbose_data=True
|
||||
)
|
||||
if not platform_data:
|
||||
logger.warning(
|
||||
'jlink entry: "%s", not found in platform database', identifier
|
||||
)
|
||||
else:
|
||||
device.update(platform_data)
|
||||
break
|
||||
|
||||
def _update_device_from_htm(self, device):
|
||||
"""Set the 'target_id', 'target_id_mbed_htm', 'platform_name' and
|
||||
'daplink_*' attributes by reading from mbed.htm on the device
|
||||
"""
|
||||
htm_target_id, daplink_info = self._read_htm_ids(device["mount_point"])
|
||||
if daplink_info:
|
||||
device.update(
|
||||
{
|
||||
"daplink_%s" % f.lower().replace(" ", "_"): v
|
||||
for f, v in daplink_info.items()
|
||||
}
|
||||
)
|
||||
if htm_target_id:
|
||||
logger.debug(
|
||||
"Found htm target id, %s, for usb target id %s",
|
||||
htm_target_id,
|
||||
device["target_id_usb_id"],
|
||||
)
|
||||
device["target_id"] = htm_target_id
|
||||
else:
|
||||
logger.debug(
|
||||
"Could not read htm on from usb id %s. Falling back to usb id",
|
||||
device["target_id_usb_id"],
|
||||
)
|
||||
device["target_id"] = device["target_id_usb_id"]
|
||||
device["target_id_mbed_htm"] = htm_target_id
|
||||
|
||||
def _update_device_details_atmel(self, device, _):
|
||||
""" Updates the Atmel device information based on files from its 'mount_point'
|
||||
@param device Dictionary containing device information
|
||||
@param read_details_txt A boolean controlling the presense of the
|
||||
output dict attributes read from other files present on the 'mount_point'
|
||||
"""
|
||||
|
||||
# Atmel uses a system similar to DAPLink, but there's no details.txt with a
|
||||
# target ID to identify device we can use the serial, which is ATMLXXXXYYYYYYY
|
||||
# where XXXX is the board identifier.
|
||||
# This can be verified by looking at readme.htm, which also uses the board ID
|
||||
# to redirect to platform page
|
||||
|
||||
device["target_id"] = device["target_id_usb_id"][4:8]
|
||||
platform_data = self.plat_db.get(
|
||||
device["target_id"], device_type="atmel", verbose_data=True
|
||||
)
|
||||
|
||||
device.update(platform_data or {"platform_name": None})
|
||||
|
||||
def mock_manufacture_id(self, mid, platform_name, oper="+"):
|
||||
"""! Replace (or add if manufacture id doesn't exist) entry in self.manufacture_ids
|
||||
@param oper '+' add new mock / override existing entry
|
||||
'-' remove mid from mocking entry
|
||||
@return Mocked structure (json format)
|
||||
"""
|
||||
if oper == "+":
|
||||
self.plat_db.add(mid, platform_name, permanent=True)
|
||||
elif oper == "-":
|
||||
self.plat_db.remove(mid, permanent=True)
|
||||
else:
|
||||
raise ValueError("oper can only be [+-]")
|
||||
|
||||
def retarget_read(self):
|
||||
"""! Load retarget data from local file
|
||||
@return Curent retarget configuration (dictionary)
|
||||
"""
|
||||
if isfile(self.RETARGET_FILE_NAME):
|
||||
logger.debug("reading retarget file %s", self.RETARGET_FILE_NAME)
|
||||
try:
|
||||
with open(self.RETARGET_FILE_NAME, "r", encoding="utf-8") as f:
|
||||
return load(f)
|
||||
except IOError as e:
|
||||
logger.exception(e)
|
||||
except ValueError as e:
|
||||
logger.exception(e)
|
||||
return {}
|
||||
|
||||
def retarget(self):
|
||||
"""! Enable retargeting
|
||||
@details Read data from local retarget configuration file
|
||||
@return Retarget data structure read from configuration file
|
||||
"""
|
||||
self.retarget_data = self.retarget_read()
|
||||
return self.retarget_data
|
||||
|
||||
def get_dummy_platform(self, platform_name):
|
||||
"""! Returns simple dummy platform """
|
||||
if not hasattr(self, "dummy_counter"):
|
||||
self.dummy_counter = {} # platform<str>: counter<int>
|
||||
|
||||
if platform_name not in self.dummy_counter:
|
||||
self.dummy_counter[platform_name] = 0
|
||||
|
||||
platform = {
|
||||
"platform_name": platform_name,
|
||||
"platform_name_unique": "%s[%d]"
|
||||
% (platform_name, self.dummy_counter[platform_name]),
|
||||
"mount_point": "DUMMY",
|
||||
"serial_port": "DUMMY",
|
||||
"target_id": "DUMMY",
|
||||
"target_id_mbed_htm": "DUMMY",
|
||||
"target_id_usb_id": "DUMMY",
|
||||
"daplink_version": "DUMMY",
|
||||
}
|
||||
self.dummy_counter[platform_name] += 1
|
||||
return platform
|
||||
|
||||
def get_supported_platforms(self, device_type=None):
|
||||
"""! Return a dictionary of supported target ids and the corresponding platform name
|
||||
@param device_type Filter which device entries are returned from the platform
|
||||
database
|
||||
@return Dictionary of { 'target_id': 'platform_name', ... }
|
||||
"""
|
||||
kwargs = {}
|
||||
if device_type is not None:
|
||||
kwargs["device_type"] = device_type
|
||||
|
||||
items = self.plat_db.items(**kwargs)
|
||||
return {i[0]: i[1] for i in items}
|
||||
|
||||
# Private functions supporting API
|
||||
def _read_htm_ids(self, mount_point):
|
||||
"""! Function scans mbed.htm to get information about TargetID.
|
||||
@param mount_point mbed mount point (disk / drive letter)
|
||||
@return Function returns targetID, in case of failure returns None.
|
||||
@details Note: This function should be improved to scan variety of boards'
|
||||
mbed.htm files
|
||||
"""
|
||||
result = {}
|
||||
target_id = None
|
||||
for line in self._htm_lines(mount_point):
|
||||
target_id = target_id or self._target_id_from_htm(line)
|
||||
ver_bld = self._mbed_htm_comment_section_ver_build(line)
|
||||
if ver_bld:
|
||||
result["version"], result["build"] = ver_bld
|
||||
|
||||
m = re.search(r"url=([\w\d\:/\\\?\.=-_]+)", line)
|
||||
if m:
|
||||
result["url"] = m.group(1).strip()
|
||||
return target_id, result
|
||||
|
||||
def _mbed_htm_comment_section_ver_build(self, line):
|
||||
"""! Check for Version and Build date of interface chip firmware im mbed.htm file
|
||||
@return (version, build) tuple if successful, None if no info found
|
||||
"""
|
||||
# <!-- Version: 0200 Build: Mar 26 2014 13:22:20 -->
|
||||
m = re.search(r"^<!-- Version: (\d+) Build: ([\d\w: ]+) -->", line)
|
||||
if m:
|
||||
version_str, build_str = m.groups()
|
||||
return (version_str.strip(), build_str.strip())
|
||||
|
||||
# <!-- Version: 0219 Build: Feb 2 2016 15:20:54 Git Commit SHA:
|
||||
# 0853ba0cdeae2436c52efcba0ba76a6434c200ff Git local mods:No-->
|
||||
m = re.search(r"^<!-- Version: (\d+) Build: ([\d\w: ]+) Git Commit SHA", line)
|
||||
if m:
|
||||
version_str, build_str = m.groups()
|
||||
return (version_str.strip(), build_str.strip())
|
||||
|
||||
# <!-- Version: 0.14.3. build 471 -->
|
||||
m = re.search(r"^<!-- Version: ([\d+\.]+)\. build (\d+) -->", line)
|
||||
if m:
|
||||
version_str, build_str = m.groups()
|
||||
return (version_str.strip(), build_str.strip())
|
||||
return None
|
||||
|
||||
def _htm_lines(self, mount_point):
|
||||
if mount_point:
|
||||
mbed_htm_path = join(mount_point, self.MBED_HTM_NAME)
|
||||
with open(mbed_htm_path, "r") as f:
|
||||
return f.readlines()
|
||||
|
||||
def _details_txt(self, mount_point):
|
||||
"""! Load DETAILS.TXT to dictionary:
|
||||
DETAILS.TXT example:
|
||||
Version: 0226
|
||||
Build: Aug 24 2015 17:06:30
|
||||
Git Commit SHA: 27a236b9fe39c674a703c5c89655fbd26b8e27e1
|
||||
Git Local mods: Yes
|
||||
|
||||
or:
|
||||
|
||||
# DAPLink Firmware - see https://mbed.com/daplink
|
||||
Unique ID: 0240000029164e45002f0012706e0006f301000097969900
|
||||
HIF ID: 97969900
|
||||
Auto Reset: 0
|
||||
Automation allowed: 0
|
||||
Daplink Mode: Interface
|
||||
Interface Version: 0240
|
||||
Git SHA: c765cbb590f57598756683254ca38b211693ae5e
|
||||
Local Mods: 0
|
||||
USB Interfaces: MSD, CDC, HID
|
||||
Interface CRC: 0x26764ebf
|
||||
"""
|
||||
|
||||
if mount_point:
|
||||
path_to_details_txt = join(mount_point, self.DETAILS_TXT_NAME)
|
||||
with open(path_to_details_txt, "r") as f:
|
||||
return self._parse_details(f.readlines())
|
||||
return None
|
||||
|
||||
def _parse_details(self, lines):
|
||||
result = {}
|
||||
for line in lines:
|
||||
if not line.startswith("#"):
|
||||
key, _, value = line.partition(":")
|
||||
if value:
|
||||
result[key] = value.strip()
|
||||
if "Interface Version" in result:
|
||||
result["Version"] = result["Interface Version"]
|
||||
return result
|
||||
|
||||
def _target_id_from_htm(self, line):
|
||||
"""! Extract Target id from htm line.
|
||||
@return Target id or None
|
||||
"""
|
||||
# Detecting modern mbed.htm file format
|
||||
m = re.search("\\?code=([a-fA-F0-9]+)", line)
|
||||
if m:
|
||||
result = m.groups()[0]
|
||||
logger.debug("Found target id %s in htm line %s", result, line)
|
||||
return result
|
||||
# Last resort, we can try to see if old mbed.htm format is there
|
||||
m = re.search("\\?auth=([a-fA-F0-9]+)", line)
|
||||
if m:
|
||||
result = m.groups()[0]
|
||||
logger.debug("Found target id %s in htm line %s", result, line)
|
||||
return result
|
||||
|
||||
return None
|
||||
|
||||
def mount_point_ready(self, path):
|
||||
"""! Check if a mount point is ready for file operations
|
||||
"""
|
||||
return exists(path) and isdir(path)
|
||||
|
||||
@staticmethod
|
||||
def _run_cli_process(cmd, shell=True):
|
||||
"""! Runs command as a process and return stdout, stderr and ret code
|
||||
@param cmd Command to execute
|
||||
@return Tuple of (stdout, stderr, returncode)
|
||||
"""
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
p = Popen(cmd, shell=shell, stdout=PIPE, stderr=PIPE)
|
||||
_stdout, _stderr = p.communicate()
|
||||
return _stdout, _stderr, p.returncode
|
||||
|
||||
@deprecated(
|
||||
"Functionality has been moved into 'list_mbeds'. "
|
||||
"Please use list_mbeds with 'unique_names=True' and "
|
||||
"'read_details_txt=True'"
|
||||
)
|
||||
def list_mbeds_ext(self):
|
||||
"""! Function adds extra information for each mbed device
|
||||
@return Returns list of mbed devices plus extended data like
|
||||
'platform_name_unique'
|
||||
@details Get information about mbeds with extended parameters/info included
|
||||
"""
|
||||
|
||||
return self.list_mbeds(unique_names=True, read_details_txt=True)
|
||||
|
||||
@deprecated(
|
||||
"List formatting methods are deprecated for a simpler API. "
|
||||
"Please use 'list_mbeds' instead."
|
||||
)
|
||||
def list_manufacture_ids(self):
|
||||
"""! Creates list of all available mappings for target_id -> Platform
|
||||
@return String with table formatted output
|
||||
"""
|
||||
from prettytable import PrettyTable, HEADER
|
||||
|
||||
columns = ["target_id_prefix", "platform_name"]
|
||||
pt = PrettyTable(columns, junction_char="|", hrules=HEADER)
|
||||
for col in columns:
|
||||
pt.align[col] = "l"
|
||||
|
||||
for target_id_prefix, platform_name in sorted(self.plat_db.items()):
|
||||
pt.add_row([target_id_prefix, platform_name])
|
||||
|
||||
return pt.get_string()
|
||||
|
||||
@deprecated(
|
||||
"List formatting methods are deprecated to simplify the API. "
|
||||
"Please use 'list_mbeds' instead."
|
||||
)
|
||||
def list_platforms(self):
|
||||
"""! Useful if you just want to know which platforms are currently
|
||||
available on the system
|
||||
@return List of (unique values) available platforms
|
||||
"""
|
||||
result = []
|
||||
mbeds = self.list_mbeds()
|
||||
for i, val in enumerate(mbeds):
|
||||
platform_name = str(val["platform_name"])
|
||||
if platform_name not in result:
|
||||
result.append(platform_name)
|
||||
return result
|
||||
|
||||
@deprecated(
|
||||
"List formatting methods are deprecated to simplify the API. "
|
||||
"Please use 'list_mbeds' instead."
|
||||
)
|
||||
def list_platforms_ext(self):
|
||||
"""! Useful if you just want to know how many platforms of each type are
|
||||
currently available on the system
|
||||
@return Dict of platform: platform_count
|
||||
"""
|
||||
result = {}
|
||||
mbeds = self.list_mbeds()
|
||||
for i, val in enumerate(mbeds):
|
||||
platform_name = str(val["platform_name"])
|
||||
if platform_name not in result:
|
||||
result[platform_name] = 1
|
||||
else:
|
||||
result[platform_name] += 1
|
||||
return result
|
||||
|
||||
@deprecated(
|
||||
"List formatting methods are deprecated to simplify the API. "
|
||||
"Please use 'list_mbeds' instead."
|
||||
)
|
||||
def list_mbeds_by_targetid(self):
|
||||
"""! Get information about mbeds with extended parameters/info included
|
||||
@return Returns dictionary where keys are TargetIDs and values are mbed
|
||||
structures
|
||||
@details Ordered by target id (key: target_id).
|
||||
"""
|
||||
result = {}
|
||||
mbed_list = self.list_mbeds_ext()
|
||||
for mbed in mbed_list:
|
||||
target_id = mbed["target_id"]
|
||||
result[target_id] = mbed
|
||||
return result
|
||||
|
||||
@deprecated(
|
||||
"List formatting methods are deprecated to simplify the API. "
|
||||
"Please use 'list_mbeds' instead."
|
||||
)
|
||||
def get_string(
|
||||
self, border=False, header=True, padding_width=1, sortby="platform_name"
|
||||
):
|
||||
"""! Printing with some sql table like decorators
|
||||
@param border Table border visibility
|
||||
@param header Table header visibility
|
||||
@param padding_width Table padding
|
||||
@param sortby Column used to sort results
|
||||
@return Returns string which can be printed on console
|
||||
"""
|
||||
from prettytable import PrettyTable, HEADER
|
||||
|
||||
result = ""
|
||||
mbeds = self.list_mbeds(unique_names=True, read_details_txt=True)
|
||||
if mbeds:
|
||||
""" ['platform_name', 'mount_point', 'serial_port', 'target_id'] -
|
||||
columns generated from USB auto-detection
|
||||
['platform_name_unique', ...] -
|
||||
columns generated outside detection subsystem (OS dependent detection)
|
||||
"""
|
||||
columns = [
|
||||
"platform_name",
|
||||
"platform_name_unique",
|
||||
"mount_point",
|
||||
"serial_port",
|
||||
"target_id",
|
||||
"daplink_version",
|
||||
]
|
||||
pt = PrettyTable(columns, junction_char="|", hrules=HEADER)
|
||||
for col in columns:
|
||||
pt.align[col] = "l"
|
||||
|
||||
for mbed in mbeds:
|
||||
row = []
|
||||
for col in columns:
|
||||
row.append(mbed[col] if col in mbed and mbed[col] else "unknown")
|
||||
pt.add_row(row)
|
||||
result = pt.get_string(
|
||||
border=border, header=header, padding_width=padding_width, sortby=sortby
|
||||
)
|
||||
return result
|
||||
|
||||
# Private functions supporting API
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_json_data_from_file(self, json_spec_filename, verbose=False):
|
||||
"""! Loads from file JSON formatted string to data structure
|
||||
@return None if JSON can be loaded
|
||||
"""
|
||||
try:
|
||||
with open(json_spec_filename) as data_file:
|
||||
try:
|
||||
return json.load(data_file)
|
||||
except ValueError as json_error_msg:
|
||||
logger.error(
|
||||
"Parsing file(%s): %s", json_spec_filename, json_error_msg
|
||||
)
|
||||
return None
|
||||
except IOError as fileopen_error_msg:
|
||||
logger.warning(fileopen_error_msg)
|
||||
return None
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_htm_target_id(self, mount_point):
|
||||
target_id, _ = self._read_htm_ids(mount_point)
|
||||
return target_id
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_mbed_htm(self, mount_point):
|
||||
_, build_info = self._read_htm_ids(mount_point)
|
||||
return build_info
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_mbed_htm_comment_section_ver_build(self, line):
|
||||
return self._mbed_htm_comment_section_ver_build(line)
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_mbed_htm_lines(self, mount_point):
|
||||
return self._htm_lines(mount_point)
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def get_details_txt(self, mount_point):
|
||||
return self._details_txt(mount_point)
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def parse_details_txt(self, lines):
|
||||
return self._parse_details(lines)
|
||||
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def scan_html_line_for_target_id(self, line):
|
||||
return self._target_id_from_htm(line)
|
||||
|
||||
@staticmethod
|
||||
@deprecated(
|
||||
"This method will be removed from the public API. "
|
||||
"Please use 'list_mbeds' instead"
|
||||
)
|
||||
def run_cli_process(cmd, shell=True):
|
||||
return MbedLsToolsBase._run_cli_process(cmd, shell)
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
|
||||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
|
||||
# Make sure that any global generic setup is run
|
||||
from . import lstools_base # noqa: F401
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("mbedls.main")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
del logging
|
||||
|
||||
|
||||
def create(**kwargs):
|
||||
"""! Factory used to create host OS specific mbed-lstools object
|
||||
|
||||
:param kwargs: keyword arguments to pass along to the constructors
|
||||
@return Returns MbedLsTools object or None if host OS is not supported
|
||||
|
||||
"""
|
||||
result = None
|
||||
mbed_os = mbed_os_support()
|
||||
if mbed_os is not None:
|
||||
if mbed_os == "Windows7":
|
||||
from .windows import MbedLsToolsWin7
|
||||
|
||||
result = MbedLsToolsWin7(**kwargs)
|
||||
elif mbed_os == "LinuxGeneric":
|
||||
from .linux import MbedLsToolsLinuxGeneric
|
||||
|
||||
result = MbedLsToolsLinuxGeneric(**kwargs)
|
||||
elif mbed_os == "Darwin":
|
||||
from .darwin import MbedLsToolsDarwin
|
||||
|
||||
result = MbedLsToolsDarwin(**kwargs)
|
||||
return result
|
||||
|
||||
|
||||
def mbed_os_support():
|
||||
"""! Function used to determine if host OS is supported by mbed-lstools
|
||||
|
||||
@return Returns None if host OS is not supported else return OS short name
|
||||
|
||||
@details This function should be ported for new OS support
|
||||
"""
|
||||
result = None
|
||||
os_info = mbed_lstools_os_info()
|
||||
if os_info[0] == "nt" and os_info[1] == "Windows":
|
||||
result = "Windows7"
|
||||
elif os_info[0] == "posix" and os_info[1] == "Linux":
|
||||
result = "LinuxGeneric"
|
||||
elif os_info[0] == "posix" and os_info[1] == "Darwin":
|
||||
result = "Darwin"
|
||||
return result
|
||||
|
||||
|
||||
def mbed_lstools_os_info():
|
||||
"""! Returns information about host OS
|
||||
|
||||
@return Returns tuple with information about OS and host platform
|
||||
"""
|
||||
result = (
|
||||
os.name,
|
||||
platform.system(),
|
||||
platform.release(),
|
||||
platform.version(),
|
||||
sys.platform,
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def mock_platform(mbeds, args):
|
||||
for token in args.mock.split(","):
|
||||
if ":" in token:
|
||||
oper = "+" # Default
|
||||
mid, platform_name = token.split(":")
|
||||
if mid and mid[0] in ["+", "-"]:
|
||||
oper = mid[0] # Operation (character)
|
||||
mid = mid[1:] # We remove operation character
|
||||
mbeds.mock_manufacture_id(mid, platform_name, oper=oper)
|
||||
elif token and token[0] in ["-", "!"]:
|
||||
# Operations where do not specify data after colon: --mock=-1234,-7678
|
||||
oper = token[0]
|
||||
mid = token[1:]
|
||||
mbeds.mock_manufacture_id(mid, "dummy", oper=oper)
|
||||
else:
|
||||
logger.error("Could not parse mock from token: '%s'", token)
|
||||
|
|
@ -0,0 +1,571 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Functions that manage a platform database"""
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
from collections import OrderedDict, defaultdict
|
||||
from copy import copy
|
||||
from io import open
|
||||
from os import makedirs
|
||||
from os.path import join, dirname, getmtime
|
||||
from appdirs import user_data_dir
|
||||
from fasteners import InterProcessLock
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("mbedls.platform_database")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
del logging
|
||||
|
||||
try:
|
||||
unicode
|
||||
except NameError:
|
||||
unicode = str
|
||||
|
||||
LOCAL_PLATFORM_DATABASE = join(user_data_dir("mbedls"), "platforms.json")
|
||||
LOCAL_MOCKS_DATABASE = join(user_data_dir("mbedls"), "mock.json")
|
||||
|
||||
DEFAULT_PLATFORM_DB = {
|
||||
u"daplink": {
|
||||
u"0200": u"KL25Z",
|
||||
u"0201": u"KW41Z",
|
||||
u"0210": u"KL05Z",
|
||||
u"0214": u"HEXIWEAR",
|
||||
u"0217": u"K82F",
|
||||
u"0218": u"KL82Z",
|
||||
u"0220": u"KL46Z",
|
||||
u"0227": u"MIMXRT1050_EVK",
|
||||
u"0228": u"RAPIDIOT_K64F",
|
||||
u"0230": u"K20D50M",
|
||||
u"0231": u"K22F",
|
||||
u"0234": u"RAPIDIOT_KW41Z",
|
||||
u"0236": u"LPC55S69",
|
||||
u"0240": u"K64F",
|
||||
u"0245": u"K64F",
|
||||
u"0250": u"KW24D",
|
||||
u"0261": u"KL27Z",
|
||||
u"0262": u"KL43Z",
|
||||
u"0300": u"MTS_GAMBIT",
|
||||
u"0305": u"MTS_MDOT_F405RG",
|
||||
u"0310": u"MTS_DRAGONFLY_F411RE",
|
||||
u"0311": u"K66F",
|
||||
u"0312": u"MTS_DRAGONFLY_L471QG",
|
||||
u"0313": u"MTS_DRAGONFLY_L496VG",
|
||||
u"0315": u"MTS_MDOT_F411RE",
|
||||
u"0316": u"MTS_DRAGONFLY_F413RH",
|
||||
u"0350": u"XDOT_L151CC",
|
||||
u"0360": u"HANI_IOT",
|
||||
u"0400": u"MAXWSNENV",
|
||||
u"0405": u"MAX32600MBED",
|
||||
u"0407": u"MAX32620HSP",
|
||||
u"0408": u"MAX32625NEXPAQ",
|
||||
u"0409": u"MAX32630FTHR",
|
||||
u"0410": u"ETTEPLAN_LORA",
|
||||
u"0415": u"MAX32625MBED",
|
||||
u"0416": u"MAX32625PICO",
|
||||
u"0418": u"MAX32620FTHR",
|
||||
u"0419": u"MAX35103EVKIT2",
|
||||
u"0421": u"MAX32660EVSYS",
|
||||
u"0424": u"MAX32670EVKIT",
|
||||
u"0450": u"MTB_UBLOX_ODIN_W2",
|
||||
u"0451": u"MTB_MXCHIP_EMW3166",
|
||||
u"0452": u"MTB_LAIRD_BL600",
|
||||
u"0453": u"MTB_MTS_XDOT",
|
||||
u"0454": u"MTB_MTS_DRAGONFLY",
|
||||
u"0455": u"MTB_UBLOX_NINA_B1",
|
||||
u"0456": u"MTB_MURATA_ABZ",
|
||||
u"0457": u"MTB_RAK811",
|
||||
u"0458": u"ADV_WISE_1510",
|
||||
u"0459": u"ADV_WISE_1530",
|
||||
u"0460": u"ADV_WISE_1570",
|
||||
u"0461": u"MTB_LAIRD_BL652",
|
||||
u"0462": u"MTB_USI_WM_BN_BM_22",
|
||||
u"0465": u"MTB_LAIRD_BL654",
|
||||
u"0466": u"MTB_MURATA_WSM_BL241",
|
||||
u"0467": u"MTB_STM_S2LP",
|
||||
u"0468": u"MTB_STM_L475",
|
||||
u"0469": u"MTB_STM32_F439",
|
||||
u"0472": u"MTB_ACONNO_ACN52832",
|
||||
u"0602": u"EV_COG_AD3029LZ",
|
||||
u"0603": u"EV_COG_AD4050LZ",
|
||||
u"0604": u"SDP_K1",
|
||||
u"0700": u"NUCLEO_F103RB",
|
||||
u"0705": u"NUCLEO_F302R8",
|
||||
u"0710": u"NUCLEO_L152RE",
|
||||
u"0715": u"NUCLEO_L053R8",
|
||||
u"0720": u"NUCLEO_F401RE",
|
||||
u"0725": u"NUCLEO_F030R8",
|
||||
u"0729": u"NUCLEO_G071RB",
|
||||
u"0730": u"NUCLEO_F072RB",
|
||||
u"0735": u"NUCLEO_F334R8",
|
||||
u"0740": u"NUCLEO_F411RE",
|
||||
u"0742": u"NUCLEO_F413ZH",
|
||||
u"0743": u"DISCO_F413ZH",
|
||||
u"0744": u"NUCLEO_F410RB",
|
||||
u"0745": u"NUCLEO_F303RE",
|
||||
u"0746": u"DISCO_F303VC",
|
||||
u"0747": u"NUCLEO_F303ZE",
|
||||
u"0750": u"NUCLEO_F091RC",
|
||||
u"0755": u"NUCLEO_F070RB",
|
||||
u"0760": u"NUCLEO_L073RZ",
|
||||
u"0764": u"DISCO_L475VG_IOT01A",
|
||||
u"0765": u"NUCLEO_L476RG",
|
||||
u"0766": u"SILICA_SENSOR_NODE",
|
||||
u"0770": u"NUCLEO_L432KC",
|
||||
u"0774": u"DISCO_L4R9I",
|
||||
u"0775": u"NUCLEO_F303K8",
|
||||
u"0776": u"NUCLEO_L4R5ZI",
|
||||
u"0777": u"NUCLEO_F446RE",
|
||||
u"0778": u"NUCLEO_F446ZE",
|
||||
u"0779": u"NUCLEO_L433RC_P",
|
||||
u"0780": u"NUCLEO_L011K4",
|
||||
u"0781": u"NUCLEO_L4R5ZI_P",
|
||||
u"0783": u"NUCLEO_L010RB",
|
||||
u"0785": u"NUCLEO_F042K6",
|
||||
u"0788": u"DISCO_F469NI",
|
||||
u"0790": u"NUCLEO_L031K6",
|
||||
u"0791": u"NUCLEO_F031K6",
|
||||
u"0795": u"DISCO_F429ZI",
|
||||
u"0796": u"NUCLEO_F429ZI",
|
||||
u"0797": u"NUCLEO_F439ZI",
|
||||
u"0805": u"DISCO_L053C8",
|
||||
u"0810": u"DISCO_F334C8",
|
||||
u"0812": u"NUCLEO_F722ZE",
|
||||
u"0813": u"NUCLEO_H743ZI",
|
||||
u"0814": u"DISCO_H747I",
|
||||
u"0815": u"DISCO_F746NG",
|
||||
u"0816": u"NUCLEO_F746ZG",
|
||||
u"0817": u"DISCO_F769NI",
|
||||
u"0818": u"NUCLEO_F767ZI",
|
||||
u"0820": u"DISCO_L476VG",
|
||||
u"0821": u"NUCLEO_L452RE",
|
||||
u"0822": u"DISCO_L496AG",
|
||||
u"0823": u"NUCLEO_L496ZG",
|
||||
u"0824": u"LPC824",
|
||||
u"0825": u"DISCO_F412ZG",
|
||||
u"0826": u"NUCLEO_F412ZG",
|
||||
u"0827": u"NUCLEO_L486RG",
|
||||
u"0828": u"NUCLEO_L496ZG_P",
|
||||
u"0829": u"NUCLEO_L452RE_P",
|
||||
u"0830": u"DISCO_F407VG",
|
||||
u"0833": u"DISCO_L072CZ_LRWAN1",
|
||||
u"0835": u"NUCLEO_F207ZG",
|
||||
u"0836": u"NUCLEO_H743ZI2",
|
||||
u"0839": u"NUCLEO_WB55RG",
|
||||
u"0840": u"B96B_F446VE",
|
||||
u"0841": u"NUCLEO_G474RE",
|
||||
u"0842": u"NUCLEO_H753ZI",
|
||||
u"0843": u"NUCLEO_H745ZI_Q",
|
||||
u"0844": u"NUCLEO_H755ZI_Q",
|
||||
u"0847": u"DISCO_H745I",
|
||||
u"0849": u"NUCLEO_G070RB",
|
||||
u"0850": u"NUCLEO_G431RB",
|
||||
u"0851": u"NUCLEO_G431KB",
|
||||
u"0852": u"NUCLEO_G031K8",
|
||||
u"0853": u"NUCLEO_F301K8",
|
||||
u"0854": u"NUCLEO_L552ZE_Q",
|
||||
u"0855": u"DISCO_L562QE",
|
||||
u"0858": u"DISCO_H750B",
|
||||
u"0859": u"DISCO_H7B3I",
|
||||
u"0860": u"NUCLEO_H7A3ZI_Q",
|
||||
u"0863": u"DISCO_L4P5G",
|
||||
u"0865": u"NUCLEO_L4P5ZG",
|
||||
u"0866": u"NUCLEO_WL55JC",
|
||||
u"0871": u"NUCLEO_H723ZG",
|
||||
u"0872": u"NUCLEO_G0B1RE",
|
||||
u"0875": u"DISCO_H735G",
|
||||
u"0879": u"NUCLEO_F756ZG",
|
||||
u"0882": u"NUCLEO_G491RE",
|
||||
u"0883": u"NUCLEO_WB15CC",
|
||||
u"0884": u"DISCO_WB5MMG",
|
||||
u"0885": u"B_L4S5I_IOT01A",
|
||||
u"0886": u"NUCLEO_U575ZI_Q",
|
||||
u"0887": u"B_U585I_IOT02A",
|
||||
u"0900": u"SAMR21G18A",
|
||||
u"0905": u"SAMD21G18A",
|
||||
u"0910": u"SAML21J18A",
|
||||
u"0915": u"SAMD21J18A",
|
||||
u"1000": u"LPC2368",
|
||||
u"1010": u"LPC1768",
|
||||
u"1017": u"HRM1017",
|
||||
u"1018": u"SSCI824",
|
||||
u"1019": u"TY51822R3",
|
||||
u"1022": u"RO359B",
|
||||
u"1034": u"LPC11U34",
|
||||
u"1040": u"LPC11U24",
|
||||
u"1045": u"LPC11U24",
|
||||
u"1050": u"LPC812",
|
||||
u"1054": u"LPC54114",
|
||||
u"1056": u"LPC546XX",
|
||||
u"1060": u"LPC4088",
|
||||
u"1061": u"LPC11U35_401",
|
||||
u"1062": u"LPC4088_DM",
|
||||
u"1070": u"NRF51822",
|
||||
u"1075": u"NRF51822_OTA",
|
||||
u"1080": u"OC_MBUINO",
|
||||
u"1090": u"RBLAB_NRF51822",
|
||||
u"1093": u"RBLAB_BLENANO2",
|
||||
u"1095": u"RBLAB_BLENANO",
|
||||
u"1100": u"NRF51_DK",
|
||||
u"1101": u"NRF52_DK",
|
||||
u"1102": u"NRF52840_DK",
|
||||
u"1105": u"NRF51_DK_OTA",
|
||||
u"1114": u"LPC1114",
|
||||
u"1120": u"NRF51_DONGLE",
|
||||
u"1130": u"NRF51822_SBK",
|
||||
u"1140": u"WALLBOT_BLE",
|
||||
u"1168": u"LPC11U68",
|
||||
u"1200": u"NCS36510",
|
||||
u"1234": u"UBLOX_C027",
|
||||
u"1236": u"UBLOX_EVK_ODIN_W2",
|
||||
u"1237": u"UBLOX_EVK_NINA_B1",
|
||||
u"1280": u"OKDO_ODIN_W2",
|
||||
u"1300": u"NUC472-NUTINY",
|
||||
u"1301": u"NUMBED",
|
||||
u"1302": u"NUMAKER_PFM_NUC472",
|
||||
u"1303": u"NUMAKER_PFM_M453",
|
||||
u"1304": u"NUMAKER_PFM_M487",
|
||||
u"1305": u"NU_PFM_M2351",
|
||||
u"1306": u"NUMAKER_PFM_NANO130",
|
||||
u"1307": u"NUMAKER_PFM_NUC240",
|
||||
u"1308": u"NUMAKER_IOT_M487",
|
||||
u"1309": u"NUMAKER_IOT_M252",
|
||||
u"1310": u"NUMAKER_IOT_M263A",
|
||||
u"1312": u"NU_M2354",
|
||||
u"1313": u"NUMAKER_IOT_M467",
|
||||
u"1500": u"RHOMBIO_L476DMW1K",
|
||||
u"1549": u"LPC1549",
|
||||
u"1600": u"LPC4330_M4",
|
||||
u"1605": u"LPC4330_M4",
|
||||
u"1701": u"GD32_F307VG",
|
||||
u"1702": u"GD32_F450ZI",
|
||||
u"1703": u"GD32_E103VB",
|
||||
u'1900': u'CY8CKIT_062_WIFI_BT',
|
||||
u'1901': u'CY8CPROTO_062_4343W',
|
||||
u'1902': u'CY8CKIT_062_BLE',
|
||||
u'1903': u'CYW9P62S1_43012EVB_01',
|
||||
u'1904': u'CY8CPROTO_063_BLE',
|
||||
u'1905': u'CY8CKIT_062S2_4343W',
|
||||
u'1906': u'CYW943012P6EVB_01',
|
||||
u'1907': u'CY8CPROTO_064_SB',
|
||||
u'1908': u'CYW9P62S1_43438EVB_01',
|
||||
u'1909': u'CY8CPROTO_062S2_43012',
|
||||
u'190A': u'CY8CKIT_064S2_4343W',
|
||||
u'190B': u'CY8CKIT_062S2_43012',
|
||||
u'190C': u'CY8CPROTO_064B0S3',
|
||||
u'190E': u'CY8CPROTO_062S3_4343W',
|
||||
u'190F': u'CY8CPROTO_064B0S1_BLE',
|
||||
u'1910': u'CY8CKIT064B0S2_4343W',
|
||||
u'1911': u'CY8CKIT064S0S2_4343W',
|
||||
u'1912': u'CYSBSYSKIT_01',
|
||||
u"2000": u"EFM32_G8XX_STK",
|
||||
u"2005": u"EFM32HG_STK3400",
|
||||
u"2010": u"EFM32WG_STK3800",
|
||||
u"2015": u"EFM32GG_STK3700",
|
||||
u"2020": u"EFM32LG_STK3600",
|
||||
u"2025": u"EFM32TG_STK3300",
|
||||
u"2030": u"EFM32ZG_STK3200",
|
||||
u"2035": u"EFM32PG_STK3401",
|
||||
u"2040": u"EFM32PG12_STK3402",
|
||||
u"2041": u"TB_SENSE_12",
|
||||
u"2042": u"EFM32GG11_STK3701",
|
||||
u"2043": u"EFM32TG11_STK3301",
|
||||
u"2045": u"TB_SENSE_1",
|
||||
u"2100": u"XBED_LPC1768",
|
||||
u"2201": u"WIZWIKI_W7500",
|
||||
u"2202": u"WIZWIKI_W7500ECO",
|
||||
u"2203": u"WIZWIKI_W7500P",
|
||||
u"2600": u"EP_AGORA",
|
||||
u"3001": u"LPC11U24",
|
||||
u"3101": u"SDT32620B",
|
||||
u"3102": u"SDT32625B",
|
||||
u"3103": u"SDT51822B",
|
||||
u"3104": u"SDT52832B",
|
||||
u"3105": u"SDT64B",
|
||||
u"3701": u"S5JS100",
|
||||
u"3702": u"S3JT100",
|
||||
u"3703": u"S1SBP6A",
|
||||
u"4000": u"LPC11U35_Y5_MBUG",
|
||||
u"4005": u"NRF51822_Y5_MBUG",
|
||||
u"4100": u"MOTE_L152RC",
|
||||
u"4337": u"LPC4337",
|
||||
u"4500": u"DELTA_DFCM_NNN40",
|
||||
u"4501": u"DELTA_DFBM_NQ620",
|
||||
u"4502": u"DELTA_DFCM_NNN50",
|
||||
u"4600": u"REALTEK_RTL8195AM",
|
||||
u"5000": u"ARM_MPS2",
|
||||
u"5001": u"ARM_IOTSS_BEID",
|
||||
u"5002": u"ARM_BEETLE_SOC",
|
||||
u"5003": u"ARM_MPS2_M0P",
|
||||
u"5004": u"ARM_CM3DS_MPS2",
|
||||
u"5005": u"ARM_MPS2_M0DS",
|
||||
u"5006": u"ARM_MUSCA_A1",
|
||||
u"5007": u"ARM_MUSCA_B1",
|
||||
u"5009": u"ARM_MUSCA_S1",
|
||||
u"5020": u"HOME_GATEWAY_6LOWPAN",
|
||||
u"5500": u"RZ_A1H",
|
||||
u"5501": u"GR_LYCHEE",
|
||||
u"5502": u"GR_MANGO",
|
||||
u"6000": u"FUTURE_SEQUANA",
|
||||
u"6660": u"NZ32_SC151",
|
||||
u"7011": u"TMPM066",
|
||||
u"7012": u"TMPM3H6",
|
||||
u"7013": u"TMPM46B",
|
||||
u"7014": u"TMPM3HQ",
|
||||
u"7015": u"TMPM4G9",
|
||||
u"7020": u"TMPM4KN",
|
||||
u"7402": u"MBED_BR_HAT",
|
||||
u"7778": u"TEENSY3_1",
|
||||
u"8001": u"UNO_91H",
|
||||
u"8012": u"TT_M3HQ",
|
||||
u"8013": u"TT_M4G9",
|
||||
u"8080": u"FF1705_L151CC",
|
||||
u"8081": u"FF_LPC546XX",
|
||||
u"9001": u"LPC1347",
|
||||
u"9002": u"LPC11U24",
|
||||
u"9003": u"LPC1347",
|
||||
u"9004": u"ARCH_PRO",
|
||||
u"9006": u"LPC11U24",
|
||||
u"9007": u"LPC11U35_501",
|
||||
u"9008": u"XADOW_M0",
|
||||
u"9009": u"ARCH_BLE",
|
||||
u"9010": u"ARCH_GPRS",
|
||||
u"9011": u"ARCH_MAX",
|
||||
u"9012": u"SEEED_TINY_BLE",
|
||||
u"9014": u"WIO_3G",
|
||||
u"9015": u"WIO_BG96",
|
||||
u"9017": u"WIO_EMW3166",
|
||||
u"9020": u"UHURU_RAVEN",
|
||||
u"9900": u"NRF51_MICROBIT",
|
||||
u"C002": u"VK_RZ_A1H",
|
||||
u"C005": u"MTM_MTCONNECT04S",
|
||||
u"C006": u"VBLUNO51",
|
||||
u"C008": u"SAKURAIO_EVB_01",
|
||||
u"C030": u"UBLOX_C030_U201",
|
||||
u"C031": u"UBLOX_C030_N211",
|
||||
u"C032": u"UBLOX_C030_R404M",
|
||||
u"C033": u"UBLOX_C030_R410M",
|
||||
u"C034": u"UBLOX_C030_S200",
|
||||
u"C035": u"UBLOX_C030_R3121",
|
||||
u"C036": u"UBLOX_C030_R412M",
|
||||
u"RIOT": u"RIOT",
|
||||
},
|
||||
u"jlink": {
|
||||
u"X729475D28G": {
|
||||
u"platform_name": u"NRF51_DK",
|
||||
u"jlink_device_name": u"nRF51422_xxAC",
|
||||
},
|
||||
u"X349858SLYN": {
|
||||
u"platform_name": u"NRF52_DK",
|
||||
u"jlink_device_name": u"nRF52832_xxaa",
|
||||
},
|
||||
u"FRDM-KL25Z": {
|
||||
u"platform_name": u"KL25Z",
|
||||
u"jlink_device_name": u"MKL25Z128xxx4",
|
||||
},
|
||||
u"FRDM-KL27Z": {
|
||||
u"platform_name": u"KL27Z",
|
||||
u"jlink_device_name": u"MKL27Z64xxx4",
|
||||
},
|
||||
u"FRDM-KL43Z": {
|
||||
u"platform_name": u"KL43Z",
|
||||
u"jlink_device_name": u"MKL43Z256xxx4",
|
||||
},
|
||||
},
|
||||
u"atmel": {u"2241": "SAML21J18A"},
|
||||
}
|
||||
|
||||
|
||||
def _get_modified_time(path):
|
||||
try:
|
||||
mtime = getmtime(path)
|
||||
except OSError:
|
||||
mtime = 0
|
||||
return datetime.datetime.fromtimestamp(mtime)
|
||||
|
||||
|
||||
def _older_than_me(path):
|
||||
return _get_modified_time(path) < _get_modified_time(__file__)
|
||||
|
||||
|
||||
def _modify_data_format(data, verbose_data, simple_data_key="platform_name"):
|
||||
if isinstance(data, dict):
|
||||
if verbose_data:
|
||||
return data
|
||||
|
||||
return data[simple_data_key]
|
||||
else:
|
||||
if verbose_data:
|
||||
return {simple_data_key: data}
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def _overwrite_or_open(db):
|
||||
try:
|
||||
if db is LOCAL_PLATFORM_DATABASE and _older_than_me(db):
|
||||
raise ValueError("Platform Database is out of date")
|
||||
with open(db, encoding="utf-8") as db_in:
|
||||
return json.load(db_in)
|
||||
except (IOError, ValueError) as exc:
|
||||
if db is LOCAL_PLATFORM_DATABASE:
|
||||
logger.warning("Error loading database %s: %s; Recreating", db, str(exc))
|
||||
try:
|
||||
makedirs(dirname(db))
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
with open(db, "w", encoding="utf-8") as out:
|
||||
out.write(unicode(json.dumps(DEFAULT_PLATFORM_DB)))
|
||||
except IOError:
|
||||
pass
|
||||
return copy(DEFAULT_PLATFORM_DB)
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
class PlatformDatabase(object):
|
||||
"""Represents a union of multiple platform database files.
|
||||
Handles inter-process synchronization of database files.
|
||||
"""
|
||||
|
||||
target_id_pattern = re.compile(r"^[a-fA-F0-9]{4}$")
|
||||
|
||||
def __init__(self, database_files, primary_database=None):
|
||||
"""Construct a PlatformDatabase object from a series of platform database
|
||||
files
|
||||
"""
|
||||
self._prim_db = primary_database
|
||||
if not self._prim_db and len(database_files) == 1:
|
||||
self._prim_db = database_files[0]
|
||||
self._dbs = OrderedDict()
|
||||
self._keys = defaultdict(set)
|
||||
for db in database_files:
|
||||
new_db = _overwrite_or_open(db)
|
||||
first_value = None
|
||||
if new_db.values():
|
||||
first_value = next(iter(new_db.values()))
|
||||
if not isinstance(first_value, dict):
|
||||
new_db = {"daplink": new_db}
|
||||
|
||||
if new_db:
|
||||
for device_type in new_db:
|
||||
duplicates = self._keys[device_type].intersection(
|
||||
set(new_db[device_type].keys())
|
||||
)
|
||||
duplicates = set(["%s.%s" % (device_type, k) for k in duplicates])
|
||||
if duplicates:
|
||||
logger.warning(
|
||||
"Duplicate platform ids found: %s,"
|
||||
" ignoring the definitions from %s",
|
||||
" ".join(duplicates),
|
||||
db,
|
||||
)
|
||||
self._dbs[db] = new_db
|
||||
self._keys[device_type] = self._keys[device_type].union(
|
||||
new_db[device_type].keys()
|
||||
)
|
||||
else:
|
||||
self._dbs[db] = new_db
|
||||
|
||||
def items(self, device_type="daplink"):
|
||||
for db in self._dbs.values():
|
||||
for entry in db.get(device_type, {}).items():
|
||||
yield entry
|
||||
|
||||
def all_ids(self, device_type="daplink"):
|
||||
return iter(self._keys[device_type])
|
||||
|
||||
def get(self, index, default=None, device_type="daplink", verbose_data=False):
|
||||
"""Standard lookup function. Works exactly like a dict. If 'verbose_data'
|
||||
is True, all data for the platform is returned as a dict."""
|
||||
for db in self._dbs.values():
|
||||
if device_type in db:
|
||||
maybe_answer = db[device_type].get(index, None)
|
||||
if maybe_answer:
|
||||
return _modify_data_format(maybe_answer, verbose_data)
|
||||
|
||||
return default
|
||||
|
||||
def _update_db(self):
|
||||
if self._prim_db:
|
||||
lock = InterProcessLock("%s.lock" % self._prim_db)
|
||||
acquired = lock.acquire(blocking=False)
|
||||
if not acquired:
|
||||
logger.debug("Waiting 60 seconds for file lock")
|
||||
acquired = lock.acquire(blocking=True, timeout=60)
|
||||
if acquired:
|
||||
try:
|
||||
with open(self._prim_db, "w", encoding="utf-8") as out:
|
||||
out.write(unicode(json.dumps(self._dbs[self._prim_db])))
|
||||
return True
|
||||
finally:
|
||||
lock.release()
|
||||
else:
|
||||
logger.error(
|
||||
"Could not update platform database: "
|
||||
"Lock acquire failed after 60 seconds"
|
||||
)
|
||||
return False
|
||||
else:
|
||||
logger.error(
|
||||
"Can't update platform database: destination database is ambiguous"
|
||||
)
|
||||
return False
|
||||
|
||||
def add(self, id, platform_name, permanent=False, device_type="daplink"):
|
||||
"""Add a platform to this database, optionally updating an origin
|
||||
database
|
||||
"""
|
||||
if self.target_id_pattern.match(id):
|
||||
if self._prim_db:
|
||||
if device_type not in self._dbs[self._prim_db]:
|
||||
self._dbs[self._prim_db][device_type] = {}
|
||||
self._dbs[self._prim_db][device_type][id] = platform_name
|
||||
else:
|
||||
cur_db = next(iter(self._dbs.values()))
|
||||
if device_type not in cur_db:
|
||||
cur_db[device_type] = {}
|
||||
cur_db[device_type][id] = platform_name
|
||||
self._keys[device_type].add(id)
|
||||
if permanent:
|
||||
self._update_db()
|
||||
else:
|
||||
raise ValueError("Invald target id: %s" % id)
|
||||
|
||||
def remove(self, id, permanent=False, device_type="daplink", verbose_data=False):
|
||||
"""Remove a platform from this database, optionally updating an origin
|
||||
database. If 'verbose_data' is True, all data for the platform is returned
|
||||
as a dict.
|
||||
"""
|
||||
logger.debug("Trying remove of %s", id)
|
||||
if id == "*" and device_type in self._dbs[self._prim_db]:
|
||||
self._dbs[self._prim_db][device_type] = {}
|
||||
if permanent:
|
||||
self._update_db()
|
||||
else:
|
||||
for db in self._dbs.values():
|
||||
if device_type in db and id in db[device_type]:
|
||||
logger.debug("Removing id...")
|
||||
removed = db[device_type][id]
|
||||
del db[device_type][id]
|
||||
self._keys[device_type].remove(id)
|
||||
if permanent:
|
||||
self._update_db()
|
||||
|
||||
return _modify_data_format(removed, verbose_data)
|
||||
|
|
@ -0,0 +1,517 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from copy import copy
|
||||
|
||||
from .lstools_base import MbedLsToolsBase
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("mbedls.lstools_win7")
|
||||
logger.addHandler(logging.NullHandler())
|
||||
DEBUG = logging.DEBUG
|
||||
del logging
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
import _winreg as winreg
|
||||
else:
|
||||
import winreg
|
||||
|
||||
|
||||
MAX_COMPOSITE_DEVICE_SUBDEVICES = 8
|
||||
MBED_STORAGE_DEVICE_VENDOR_STRINGS = [
|
||||
"ven_mbed",
|
||||
"ven_segger",
|
||||
"ven_arm_v2m",
|
||||
"ven_nxp",
|
||||
"ven_atmel",
|
||||
]
|
||||
|
||||
|
||||
def _get_values_with_numeric_keys(reg_key):
|
||||
result = []
|
||||
try:
|
||||
for v in _iter_vals(reg_key):
|
||||
try:
|
||||
# The only values we care about are ones that have an integer key.
|
||||
# The other values are metadata for the registry
|
||||
int(v[0])
|
||||
result.append(v[1])
|
||||
except ValueError:
|
||||
continue
|
||||
except OSError:
|
||||
logger.debug("Failed to iterate over all keys")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _is_mbed_volume(volume_string):
|
||||
for vendor_string in MBED_STORAGE_DEVICE_VENDOR_STRINGS:
|
||||
if vendor_string.lower() in volume_string.lower():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _get_cached_mounted_points():
|
||||
"""! Get the volumes present on the system
|
||||
@return List of mount points and their associated volume string
|
||||
Ex. [{ 'mount_point': 'D:', 'volume_string': 'xxxx'}, ...]
|
||||
"""
|
||||
result = []
|
||||
try:
|
||||
# Open the registry key for mounted devices
|
||||
mounted_devices_key = winreg.OpenKey(
|
||||
winreg.HKEY_LOCAL_MACHINE, "SYSTEM\\MountedDevices"
|
||||
)
|
||||
for v in _iter_vals(mounted_devices_key):
|
||||
# Valid entries have the following format: \\DosDevices\\D:
|
||||
if "DosDevices" not in v[0]:
|
||||
continue
|
||||
|
||||
volume_string = v[1].decode("utf-16le", "ignore")
|
||||
if not _is_mbed_volume(volume_string):
|
||||
continue
|
||||
|
||||
mount_point_match = re.match(".*\\\\(.:)$", v[0])
|
||||
|
||||
if not mount_point_match:
|
||||
logger.debug("Invalid disk pattern for entry %s, skipping", v[0])
|
||||
continue
|
||||
|
||||
mount_point = mount_point_match.group(1)
|
||||
logger.debug(
|
||||
"Mount point %s found for volume %s", mount_point, volume_string
|
||||
)
|
||||
|
||||
result.append({"mount_point": mount_point, "volume_string": volume_string})
|
||||
except OSError:
|
||||
logger.error('Failed to open "MountedDevices" in registry')
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _get_disks():
|
||||
logger.debug("Fetching mounted devices from disk service registry entry")
|
||||
try:
|
||||
disks_key = winreg.OpenKey(
|
||||
winreg.HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum"
|
||||
)
|
||||
disk_strings = _get_values_with_numeric_keys(disks_key)
|
||||
return [v for v in disk_strings if _is_mbed_volume(v)]
|
||||
except OSError:
|
||||
logger.debug("No disk service found, no device can be detected")
|
||||
return []
|
||||
|
||||
|
||||
def _get_usb_storage_devices():
|
||||
logger.debug("Fetching usb storage devices from USBSTOR service registry entry")
|
||||
try:
|
||||
usbstor_key = winreg.OpenKey(
|
||||
winreg.HKEY_LOCAL_MACHINE,
|
||||
"SYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum",
|
||||
)
|
||||
return _get_values_with_numeric_keys(usbstor_key)
|
||||
except OSError:
|
||||
logger.debug("No USBSTOR service found, no device can be detected")
|
||||
return []
|
||||
|
||||
|
||||
def _determine_valid_non_composite_devices(devices, target_id_usb_id_mount_point_map):
|
||||
# Some Mbed devices do not expose a composite USB device. This is typical for
|
||||
# DAPLink devices in bootloader mode. Since we only have to check one endpoint
|
||||
# (specifically, the mass storage device), we handle this case separately
|
||||
candidates = {}
|
||||
for device in devices:
|
||||
device_key_string = "SYSTEM\\CurrentControlSet\\Enum\\" + device["full_path"]
|
||||
try:
|
||||
device_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, device_key_string)
|
||||
except OSError:
|
||||
logger.debug('Key "%s" not found', device_key_string)
|
||||
continue
|
||||
|
||||
try:
|
||||
capability = _determine_subdevice_capability(device_key)
|
||||
except CompatibleIDsNotFoundException:
|
||||
logger.debug(
|
||||
'Expected %s to have subkey "CompatibleIDs". Skipping.',
|
||||
device_key_string,
|
||||
)
|
||||
continue
|
||||
|
||||
if capability != "msd":
|
||||
logger.debug(
|
||||
"Expected msd device but got %s, skipping %s",
|
||||
capability,
|
||||
device["full_path"],
|
||||
)
|
||||
continue
|
||||
|
||||
target_id_usb_id = device["entry_key_string"]
|
||||
try:
|
||||
candidates[target_id_usb_id] = {
|
||||
"target_id_usb_id": target_id_usb_id,
|
||||
"mount_point": target_id_usb_id_mount_point_map[target_id_usb_id],
|
||||
}
|
||||
|
||||
candidates[target_id_usb_id].update(
|
||||
_vid_pid_path_to_usb_info(device["vid_pid_path"])
|
||||
)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return candidates
|
||||
|
||||
|
||||
def _determine_subdevice_capability(key):
|
||||
try:
|
||||
vals = winreg.QueryValueEx(key, "CompatibleIDs")
|
||||
compatible_ids = [x.lower() for x in vals[0]]
|
||||
except OSError:
|
||||
raise CompatibleIDsNotFoundException()
|
||||
|
||||
if "usb\\class_00" in compatible_ids or "usb\\devclass_00" in compatible_ids:
|
||||
return "composite"
|
||||
elif "usb\\class_08" in compatible_ids:
|
||||
return "msd"
|
||||
elif "usb\\class_02" in compatible_ids:
|
||||
return "serial"
|
||||
else:
|
||||
logger.debug("Unknown capabilities from the following ids: %s", compatible_ids)
|
||||
return None
|
||||
|
||||
|
||||
def _vid_pid_path_to_usb_info(vid_pid_path):
|
||||
"""! Provide the vendor ID and product ID of a device based on its entry in the registry
|
||||
@return Returns {'vendor_id': '<vendor ID>', 'product': '<product ID>'}
|
||||
@details If the vendor ID or product ID can't be determined, they will be returned
|
||||
as None.
|
||||
"""
|
||||
result = {"vendor_id": None, "product_id": None}
|
||||
|
||||
for component in vid_pid_path.split("&"):
|
||||
component_part = component.lower().split("_")
|
||||
|
||||
if len(component_part) != 2:
|
||||
logger.debug("Unexpected VID/PID string structure %s", component)
|
||||
break
|
||||
|
||||
if component_part[0] == "vid":
|
||||
result["vendor_id"] = component_part[1]
|
||||
elif component_part[0] == "pid":
|
||||
result["product_id"] = component_part[1]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _iter_keys_as_str(key):
|
||||
"""! Iterate over subkeys of a key returning subkey as string
|
||||
"""
|
||||
for i in range(winreg.QueryInfoKey(key)[0]):
|
||||
yield winreg.EnumKey(key, i)
|
||||
|
||||
|
||||
def _iter_keys(key):
|
||||
"""! Iterate over subkeys of a key
|
||||
"""
|
||||
for i in range(winreg.QueryInfoKey(key)[0]):
|
||||
yield winreg.OpenKey(key, winreg.EnumKey(key, i))
|
||||
|
||||
|
||||
def _iter_vals(key):
|
||||
"""! Iterate over values of a key
|
||||
"""
|
||||
logger.debug("_iter_vals %r", key)
|
||||
for i in range(winreg.QueryInfoKey(key)[1]):
|
||||
yield winreg.EnumValue(key, i)
|
||||
|
||||
|
||||
class CompatibleIDsNotFoundException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MbedLsToolsWin7(MbedLsToolsBase):
|
||||
""" mbed-enabled platform detection for Windows
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
MbedLsToolsBase.__init__(self, **kwargs)
|
||||
self.os_supported.append("Windows7")
|
||||
|
||||
def find_candidates(self):
|
||||
cached_mount_points = _get_cached_mounted_points()
|
||||
disks = _get_disks()
|
||||
usb_storage_devices = _get_usb_storage_devices()
|
||||
|
||||
target_id_usb_id_mount_point_map = {}
|
||||
for cached_mount_point_info in cached_mount_points:
|
||||
for index, disk in enumerate(copy(disks)):
|
||||
match_string = disk.split("\\")[-1]
|
||||
if match_string in cached_mount_point_info["volume_string"]:
|
||||
# TargetID is a hex string with 10-48 chars
|
||||
target_id_usb_id_match = re.search(
|
||||
"[&#]([0-9A-Za-z]{10,48})[&#]",
|
||||
cached_mount_point_info["volume_string"],
|
||||
)
|
||||
if not target_id_usb_id_match:
|
||||
logger.debug(
|
||||
"Entry %s has invalid target id pattern %s, skipping",
|
||||
cached_mount_point_info["mount_point"],
|
||||
cached_mount_point_info["volume_string"],
|
||||
)
|
||||
continue
|
||||
|
||||
target_id_usb_id_mount_point_map[
|
||||
target_id_usb_id_match.group(1)
|
||||
] = cached_mount_point_info["mount_point"]
|
||||
disks.pop(index)
|
||||
break
|
||||
|
||||
logger.debug(
|
||||
"target_id_usb_id -> mount_point mapping: %s ",
|
||||
target_id_usb_id_mount_point_map,
|
||||
)
|
||||
non_composite_devices = []
|
||||
composite_devices = []
|
||||
for vid_pid_path in usb_storage_devices:
|
||||
# Split paths like "USB\VID_0483&PID_374B&MI_01\7&25b4dc8e&0&0001" by "\"
|
||||
vid_pid_path_componets = vid_pid_path.split("\\")
|
||||
|
||||
vid_pid_components = vid_pid_path_componets[1].split("&")
|
||||
|
||||
if len(vid_pid_components) != 2 and len(vid_pid_components) != 3:
|
||||
logger.debug(
|
||||
"Skipping USBSTOR device with unusual VID/PID string format '%s'",
|
||||
vid_pid_path,
|
||||
)
|
||||
continue
|
||||
|
||||
device = {
|
||||
"full_path": vid_pid_path,
|
||||
"vid_pid_path": "&".join(vid_pid_components[:2]),
|
||||
"entry_key_string": vid_pid_path_componets[2],
|
||||
}
|
||||
|
||||
# A composite device's vid/pid path always has a third component
|
||||
if len(vid_pid_components) == 3:
|
||||
composite_devices.append(device)
|
||||
else:
|
||||
non_composite_devices.append(device)
|
||||
|
||||
candidates = defaultdict(dict)
|
||||
candidates.update(
|
||||
_determine_valid_non_composite_devices(
|
||||
non_composite_devices, target_id_usb_id_mount_point_map
|
||||
)
|
||||
)
|
||||
# Now we'll find all valid VID/PID and target ID combinations
|
||||
target_id_usb_ids = set(target_id_usb_id_mount_point_map.keys()) - set(
|
||||
candidates.keys()
|
||||
)
|
||||
vid_pid_entry_key_string_map = defaultdict(set)
|
||||
|
||||
for device in composite_devices:
|
||||
vid_pid_entry_key_string_map[device["vid_pid_path"]].add(
|
||||
device["entry_key_string"]
|
||||
)
|
||||
|
||||
vid_pid_target_id_usb_id_map = defaultdict(dict)
|
||||
usb_key_string = "SYSTEM\\CurrentControlSet\\Enum\\USB"
|
||||
for vid_pid_path, entry_key_strings in vid_pid_entry_key_string_map.items():
|
||||
vid_pid_key_string = "%s\\%s" % (usb_key_string, vid_pid_path)
|
||||
try:
|
||||
vid_pid_key = winreg.OpenKey(
|
||||
winreg.HKEY_LOCAL_MACHINE, vid_pid_key_string
|
||||
)
|
||||
target_id_usb_id_sub_keys = set(
|
||||
[k for k in _iter_keys_as_str(vid_pid_key)]
|
||||
)
|
||||
except OSError:
|
||||
logger.debug('VID/PID "%s" not found', vid_pid_key_string)
|
||||
continue
|
||||
|
||||
overlapping_target_id_usb_ids = target_id_usb_id_sub_keys.intersection(
|
||||
set(target_id_usb_ids)
|
||||
)
|
||||
for target_id_usb_id in overlapping_target_id_usb_ids:
|
||||
composite_device_key_string = "%s\\%s" % (
|
||||
vid_pid_key_string,
|
||||
target_id_usb_id,
|
||||
)
|
||||
composite_device_key = winreg.OpenKey(vid_pid_key, target_id_usb_id)
|
||||
|
||||
entry_key_string = target_id_usb_id
|
||||
is_prefix = False
|
||||
|
||||
try:
|
||||
new_entry_key_string, _ = winreg.QueryValueEx(
|
||||
composite_device_key, "ParentIdPrefix"
|
||||
)
|
||||
|
||||
if any(
|
||||
e.startswith(new_entry_key_string) for e in entry_key_strings
|
||||
):
|
||||
logger.debug(
|
||||
"Assigning new entry key string of %s to device %s, "
|
||||
"as found in ParentIdPrefix",
|
||||
new_entry_key_string,
|
||||
target_id_usb_id,
|
||||
)
|
||||
entry_key_string = new_entry_key_string
|
||||
is_prefix = True
|
||||
except OSError:
|
||||
logger.debug(
|
||||
'Device %s did not have a "ParentIdPrefix" key, '
|
||||
"sticking with %s as entry key string",
|
||||
composite_device_key_string,
|
||||
target_id_usb_id,
|
||||
)
|
||||
|
||||
vid_pid_target_id_usb_id_map[vid_pid_path][entry_key_string] = {
|
||||
"target_id_usb_id": target_id_usb_id,
|
||||
"is_prefix": is_prefix,
|
||||
}
|
||||
|
||||
for (
|
||||
vid_pid_path,
|
||||
entry_key_string_target_id_usb_id_map,
|
||||
) in vid_pid_target_id_usb_id_map.items():
|
||||
for composite_device_subdevice_number in range(
|
||||
MAX_COMPOSITE_DEVICE_SUBDEVICES
|
||||
):
|
||||
subdevice_type_key_string = "%s\\%s&MI_0%d" % (
|
||||
usb_key_string,
|
||||
vid_pid_path,
|
||||
composite_device_subdevice_number,
|
||||
)
|
||||
try:
|
||||
subdevice_type_key = winreg.OpenKey(
|
||||
winreg.HKEY_LOCAL_MACHINE, subdevice_type_key_string
|
||||
)
|
||||
except OSError:
|
||||
logger.debug(
|
||||
"Composite device subdevice key %s was not found, skipping",
|
||||
subdevice_type_key_string,
|
||||
)
|
||||
continue
|
||||
|
||||
for (
|
||||
entry_key_string,
|
||||
entry_data,
|
||||
) in entry_key_string_target_id_usb_id_map.items():
|
||||
if entry_data["is_prefix"]:
|
||||
prepared_entry_key_string = "%s&000%d" % (
|
||||
entry_key_string,
|
||||
composite_device_subdevice_number,
|
||||
)
|
||||
else:
|
||||
prepared_entry_key_string = entry_key_string
|
||||
subdevice_key_string = "%s\\%s" % (
|
||||
subdevice_type_key_string,
|
||||
prepared_entry_key_string,
|
||||
)
|
||||
try:
|
||||
subdevice_key = winreg.OpenKey(
|
||||
subdevice_type_key, prepared_entry_key_string
|
||||
)
|
||||
except OSError:
|
||||
logger.debug(
|
||||
"Sub-device %s not found, skipping", subdevice_key_string
|
||||
)
|
||||
continue
|
||||
|
||||
try:
|
||||
capability = _determine_subdevice_capability(subdevice_key)
|
||||
except CompatibleIDsNotFoundException:
|
||||
logger.debug(
|
||||
'Expected %s to have subkey "CompatibleIDs". Skipping.',
|
||||
subdevice_key_string,
|
||||
)
|
||||
continue
|
||||
|
||||
if capability == "msd":
|
||||
candidates[entry_data["target_id_usb_id"]][
|
||||
"mount_point"
|
||||
] = target_id_usb_id_mount_point_map[
|
||||
entry_data["target_id_usb_id"]
|
||||
]
|
||||
candidates[entry_data["target_id_usb_id"]].update(
|
||||
_vid_pid_path_to_usb_info(vid_pid_path)
|
||||
)
|
||||
elif capability == "serial":
|
||||
try:
|
||||
device_parameters_key = winreg.OpenKey(
|
||||
subdevice_key, "Device Parameters"
|
||||
)
|
||||
except OSError:
|
||||
logger.debug(
|
||||
'Key "Device Parameters" not under serial device entry'
|
||||
)
|
||||
continue
|
||||
|
||||
try:
|
||||
candidates[entry_data["target_id_usb_id"]][
|
||||
"serial_port"
|
||||
], _ = winreg.QueryValueEx(
|
||||
device_parameters_key, "PortName"
|
||||
)
|
||||
candidates[entry_data["target_id_usb_id"]].update(
|
||||
_vid_pid_path_to_usb_info(vid_pid_path)
|
||||
)
|
||||
except OSError:
|
||||
logger.debug(
|
||||
'"PortName" value not found under serial device entry'
|
||||
)
|
||||
continue
|
||||
|
||||
final_candidates = []
|
||||
for target_id_usb_id, candidate in candidates.items():
|
||||
candidate["target_id_usb_id"] = target_id_usb_id
|
||||
|
||||
if "serial_port" not in candidate:
|
||||
candidate["serial_port"] = None
|
||||
|
||||
if "mount_point" not in candidate:
|
||||
candidate["mount_point"] = None
|
||||
|
||||
final_candidates.append(candidate)
|
||||
|
||||
return final_candidates
|
||||
|
||||
def mount_point_ready(self, path):
|
||||
"""! Check if a mount point is ready for file operations
|
||||
@return Returns True if the given path exists, False otherwise
|
||||
@details Calling the Windows command `dir` instead of using the python
|
||||
`os.path.exists`. The latter causes a Python error box to appear claiming
|
||||
there is "No Disk" for some devices that are in the ejected state. Calling
|
||||
`dir` prevents this since it uses the Windows API to determine if the
|
||||
device is ready before accessing the file system.
|
||||
"""
|
||||
stdout, stderr, retcode = self._run_cli_process("dir %s" % path)
|
||||
result = True if retcode == 0 else False
|
||||
|
||||
if result:
|
||||
logger.debug("Mount point %s is ready", path)
|
||||
else:
|
||||
logger.debug(
|
||||
"Mount point %s reported not ready with error '%s'",
|
||||
path,
|
||||
stderr.strip(),
|
||||
)
|
||||
|
||||
return result
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
"""! @package mbed-host-tests
|
||||
|
||||
Flash, reset and perform host supervised tests on mbed platforms.
|
||||
Write your own programs (import this package) or use 'mbedhtrun'
|
||||
command line tool instead.
|
||||
|
||||
"""
|
||||
|
||||
import imp
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
from optparse import SUPPRESS_HELP
|
||||
from . import host_tests_plugins
|
||||
from .host_tests_registry import HostRegistry # noqa: F401
|
||||
from .host_tests import BaseHostTest, event_callback # noqa: F401
|
||||
|
||||
# Set the default baud rate
|
||||
DEFAULT_BAUD_RATE = 9600
|
||||
|
||||
###############################################################################
|
||||
# Functional interface for test supervisor registry
|
||||
###############################################################################
|
||||
|
||||
|
||||
def get_plugin_caps(methods=None):
|
||||
if not methods:
|
||||
methods = ["CopyMethod", "ResetMethod"]
|
||||
result = {}
|
||||
for method in methods:
|
||||
result[method] = host_tests_plugins.get_plugin_caps(method)
|
||||
return result
|
||||
|
||||
|
||||
def init_host_test_cli_params():
|
||||
"""! Function creates CLI parser object and returns populated options object.
|
||||
@return Function returns 'options' object returned from OptionParser class
|
||||
@details Options object later can be used to populate host test selector script.
|
||||
"""
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option(
|
||||
"-m",
|
||||
"--micro",
|
||||
dest="micro",
|
||||
help="Target microcontroller name",
|
||||
metavar="MICRO",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-p", "--port", dest="port", help="Serial port of the target", metavar="PORT"
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-d",
|
||||
"--disk",
|
||||
dest="disk",
|
||||
help="Target disk (mount point) path",
|
||||
metavar="DISK_PATH",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-t",
|
||||
"--target-id",
|
||||
dest="target_id",
|
||||
help="Unique Target Id or mbed platform",
|
||||
metavar="TARGET_ID",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--sync",
|
||||
dest="sync_behavior",
|
||||
default=2,
|
||||
type=int,
|
||||
help=(
|
||||
"Define how many times __sync packet will be sent to device: 0: "
|
||||
"none; -1: forever; 1,2,3... - number of times (Default 2 time)"
|
||||
),
|
||||
metavar="SYNC_BEHAVIOR",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--sync-timeout",
|
||||
dest="sync_timeout",
|
||||
default=5,
|
||||
type=int,
|
||||
help="Define delay in seconds between __sync packet (Default is 5 seconds)",
|
||||
metavar="SYNC_TIMEOUT",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-f",
|
||||
"--image-path",
|
||||
dest="image_path",
|
||||
help="Path with target's binary image",
|
||||
metavar="IMAGE_PATH",
|
||||
)
|
||||
|
||||
copy_methods_str = "Plugin support: " + ", ".join(
|
||||
host_tests_plugins.get_plugin_caps("CopyMethod")
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-c",
|
||||
"--copy",
|
||||
dest="copy_method",
|
||||
help="Copy (flash the target) method selector. " + copy_methods_str,
|
||||
metavar="COPY_METHOD",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--retry-copy",
|
||||
dest="retry_copy",
|
||||
default=3,
|
||||
type=int,
|
||||
help="Number of attempts to flash the target",
|
||||
metavar="RETRY_COPY",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--tag-filters",
|
||||
dest="tag_filters",
|
||||
default="",
|
||||
type=str,
|
||||
help=(
|
||||
"Comma seperated list of device tags used when allocating a target "
|
||||
"to specify required hardware or attributes [--tag-filters tag1,tag2]"
|
||||
),
|
||||
metavar="TAG_FILTERS",
|
||||
)
|
||||
|
||||
reset_methods_str = "Plugin support: " + ", ".join(
|
||||
host_tests_plugins.get_plugin_caps("ResetMethod")
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-r",
|
||||
"--reset",
|
||||
dest="forced_reset_type",
|
||||
help="Forces different type of reset. " + reset_methods_str,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-C",
|
||||
"--program_cycle_s",
|
||||
dest="program_cycle_s",
|
||||
default=4,
|
||||
help=(
|
||||
"Program cycle sleep. Define how many seconds you want wait after "
|
||||
"copying binary onto target (Default is 4 second)"
|
||||
),
|
||||
type="float",
|
||||
metavar="PROGRAM_CYCLE_S",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-R",
|
||||
"--reset-timeout",
|
||||
dest="forced_reset_timeout",
|
||||
default=1,
|
||||
metavar="NUMBER",
|
||||
type="float",
|
||||
help=(
|
||||
"When forcing a reset using option -r you can set up after reset "
|
||||
"idle delay in seconds (Default is 1 second)"
|
||||
),
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"--process-start-timeout",
|
||||
dest="process_start_timeout",
|
||||
default=60,
|
||||
metavar="NUMBER",
|
||||
type="float",
|
||||
help=(
|
||||
"This sets the maximum time in seconds to wait for an internal "
|
||||
"process to start. This mostly only affects machines under heavy "
|
||||
"load (Default is 60 seconds)"
|
||||
),
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-e",
|
||||
"--enum-host-tests",
|
||||
dest="enum_host_tests",
|
||||
action="append",
|
||||
default=["./test/host_tests"],
|
||||
help="Define directory with local host tests",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--test-cfg",
|
||||
dest="json_test_configuration",
|
||||
help="Pass to host test class data about host test configuration",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--list",
|
||||
dest="list_reg_hts",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Prints registered host test and exits",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--plugins",
|
||||
dest="list_plugins",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Prints registered plugins and exits",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-g",
|
||||
"--grm",
|
||||
dest="global_resource_mgr",
|
||||
help=(
|
||||
'Global resource manager: "<remote mgr module>:<host url or IP address>'
|
||||
'[:<port>]", Ex. "module_name:10.2.123.43:3334", '
|
||||
'module_name:https://example.com"'
|
||||
),
|
||||
)
|
||||
|
||||
# Show --fm option only if "fm_agent" module installed
|
||||
try:
|
||||
imp.find_module("fm_agent")
|
||||
except ImportError:
|
||||
fm_help = SUPPRESS_HELP
|
||||
else:
|
||||
fm_help = (
|
||||
'Fast Model connection, This option requires mbed-fastmodel-agent '
|
||||
'module installed, list CONFIGs via "mbedfm"'
|
||||
)
|
||||
parser.add_option(
|
||||
"",
|
||||
"--fm",
|
||||
dest="fast_model_connection",
|
||||
metavar="CONFIG",
|
||||
default=None,
|
||||
help=fm_help,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--run",
|
||||
dest="run_binary",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Runs binary image on target (workflow: flash, reset, output console)",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--skip-flashing",
|
||||
dest="skip_flashing",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Skips use of copy/flash plugin. Note: target will not be reflashed",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--skip-reset",
|
||||
dest="skip_reset",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Skips use of reset plugin. Note: target will not be reset",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-P",
|
||||
"--polling-timeout",
|
||||
dest="polling_timeout",
|
||||
default=60,
|
||||
metavar="NUMBER",
|
||||
type="int",
|
||||
help=(
|
||||
"Timeout in sec for readiness of mount point and serial port of "
|
||||
"local or remote device. Default 60 sec"
|
||||
),
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-b",
|
||||
"--send-break",
|
||||
dest="send_break_cmd",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help=(
|
||||
"Send reset signal to board on specified port (-p PORT) and print "
|
||||
"serial output. You can combine this with (-r RESET_TYPE) switch"
|
||||
),
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--baud-rate",
|
||||
dest="baud_rate",
|
||||
help=(
|
||||
"Baud rate of target, overrides values from mbed-ls, disk/mount "
|
||||
"point (-d, --disk-path), and serial port -p <port>:<baud rate>"
|
||||
),
|
||||
metavar="BAUD_RATE",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-v",
|
||||
"--verbose",
|
||||
dest="verbose",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="More verbose mode",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--serial-output-file",
|
||||
dest="serial_output_file",
|
||||
default=None,
|
||||
help="Save target serial output to this file.",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--compare-log",
|
||||
dest="compare_log",
|
||||
default=None,
|
||||
help="Log file to compare with the serial output from target.",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--version",
|
||||
dest="version",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Prints package version and exits",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--format",
|
||||
dest="format",
|
||||
help="Image file format passed to pyocd (elf, bin, hex, axf...).",
|
||||
)
|
||||
|
||||
parser.description = (
|
||||
"""Flash, reset and perform host supervised tests on mbed platforms"""
|
||||
)
|
||||
parser.epilog = (
|
||||
"""Example: mbedhtrun -d E: -p COM5 -f "test.bin" -C 4 -c shell -m K64F"""
|
||||
)
|
||||
|
||||
(options, _) = parser.parse_args()
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
|
||||
return options
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
from .mbed_greentea_cli import main
|
||||
main()
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from .mbed_greentea_log import gt_logger
|
||||
|
||||
|
||||
def load_ctest_testsuite(link_target, binary_type=".bin", verbose=False):
|
||||
"""! Loads CMake.CTest formatted data about tests from test directory
|
||||
@return Dictionary of { test_case : test_case_path } pairs
|
||||
"""
|
||||
result = {}
|
||||
if link_target is not None:
|
||||
ctest_path = os.path.join(link_target, "test", "CTestTestfile.cmake")
|
||||
try:
|
||||
with open(ctest_path) as ctest_file:
|
||||
for line in ctest_file:
|
||||
line_parse = parse_ctesttestfile_line(
|
||||
link_target, binary_type, line, verbose=verbose
|
||||
)
|
||||
if line_parse:
|
||||
test_case, test_case_path = line_parse
|
||||
result[test_case] = test_case_path
|
||||
except: # noqa: E722
|
||||
pass # Return empty list if path is not found
|
||||
return result
|
||||
|
||||
|
||||
def parse_ctesttestfile_line(link_target, binary_type, line, verbose=False):
|
||||
"""! Parse lines of CTestTestFile.cmake file and searches for 'add_test'
|
||||
@return Dictionary of { test_case : test_case_path } pairs or None if
|
||||
failed to parse 'add_test' line
|
||||
@details Example path with CTestTestFile.cmake:
|
||||
c:/temp/xxx/mbed-sdk-private/build/frdm-k64f-gcc/test/
|
||||
|
||||
Example format of CTestTestFile.cmake:
|
||||
# CMake generated Testfile for
|
||||
# Source directory: c:/temp/xxx/mbed-sdk-private/build/frdm-k64f-gcc/test
|
||||
# Build directory: c:/temp/xxx/mbed-sdk-private/build/frdm-k64f-gcc/test
|
||||
#
|
||||
# This file includes the relevant testing commands required for
|
||||
# testing this directory and lists subdirectories to be tested as well.
|
||||
add_test(mbed-test-stdio "mbed-test-stdio")
|
||||
add_test(mbed-test-call_before_main "mbed-test-call_before_main")
|
||||
add_test(mbed-test-dev_null "mbed-test-dev_null")
|
||||
add_test(mbed-test-div "mbed-test-div")
|
||||
add_test(mbed-test-echo "mbed-test-echo")
|
||||
add_test(mbed-test-ticker "mbed-test-ticker")
|
||||
add_test(mbed-test-hello "mbed-test-hello")
|
||||
"""
|
||||
add_test_pattern = r'[adtesADTES_]{8}\([\w\d_-]+ \"([\w\d_-]+)\"'
|
||||
re_ptrn = re.compile(add_test_pattern)
|
||||
if line.lower().startswith("add_test"):
|
||||
m = re_ptrn.search(line)
|
||||
if m and len(m.groups()) > 0:
|
||||
if verbose:
|
||||
print(m.group(1) + binary_type)
|
||||
test_case = m.group(1)
|
||||
test_case_path = os.path.join(link_target, "test", m.group(1) + binary_type)
|
||||
return test_case, test_case_path
|
||||
return None
|
||||
|
||||
|
||||
def list_binaries_for_targets(build_dir="./build", verbose_footer=False):
|
||||
"""! Prints tests in target directories, only if tests exist.
|
||||
@param build_dir Yotta default build directory where tests will be
|
||||
@param verbose_footer Prints additional "how to use" Greentea footer
|
||||
@details Skips empty / no tests for target directories.
|
||||
"""
|
||||
dir = build_dir
|
||||
sub_dirs = (
|
||||
[
|
||||
os.path.join(dir, o)
|
||||
for o in os.listdir(dir)
|
||||
if os.path.isdir(os.path.join(dir, o))
|
||||
]
|
||||
if os.path.exists(dir)
|
||||
else []
|
||||
)
|
||||
|
||||
def count_tests():
|
||||
result = 0
|
||||
for sub_dir in sub_dirs:
|
||||
test_list = load_ctest_testsuite(sub_dir, binary_type="")
|
||||
if len(test_list):
|
||||
for test in test_list:
|
||||
result += 1
|
||||
return result
|
||||
|
||||
if count_tests():
|
||||
for sub_dir in sub_dirs:
|
||||
target_name = sub_dir.split(os.sep)[-1]
|
||||
gt_logger.gt_log(
|
||||
"available tests for target '%s', location '%s'"
|
||||
% (target_name, os.path.abspath(os.path.join(build_dir, sub_dir)))
|
||||
)
|
||||
test_list = load_ctest_testsuite(sub_dir, binary_type="")
|
||||
if len(test_list):
|
||||
for test in sorted(test_list):
|
||||
gt_logger.gt_log_tab("test '%s'" % test)
|
||||
else:
|
||||
gt_logger.gt_log_warn("no tests found in current location")
|
||||
|
||||
if verbose_footer:
|
||||
print(
|
||||
"\nExample: execute 'mbedgt -t TARGET_NAME -n TEST_NAME' to run "
|
||||
"test TEST_NAME for target TARGET_NAME"
|
||||
)
|
||||
|
||||
|
||||
def list_binaries_for_builds(test_spec, verbose_footer=False):
|
||||
"""! Parse test spec and list binaries (BOOTABLE) in lexicographical order
|
||||
@param test_spec Test specification object
|
||||
@param verbose_footer Prints additional "how to use" Greentea footer
|
||||
"""
|
||||
test_builds = test_spec.get_test_builds()
|
||||
for tb in test_builds:
|
||||
gt_logger.gt_log(
|
||||
"available tests for build '%s', location '%s'"
|
||||
% (tb.get_name(), tb.get_path())
|
||||
)
|
||||
for tc in sorted(tb.get_tests().keys()):
|
||||
gt_logger.gt_log_tab("test '%s'" % tc)
|
||||
|
||||
if verbose_footer:
|
||||
print(
|
||||
"\nExample: execute 'mbedgt -t BUILD_NAME -n TEST_NAME' to run test "
|
||||
"TEST_NAME for build TARGET_NAME in current test specification"
|
||||
)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
# base host test class
|
||||
from .base_host_test import BaseHostTest, event_callback
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import inspect
|
||||
import six
|
||||
from time import time
|
||||
from inspect import isfunction, ismethod
|
||||
|
||||
|
||||
class BaseHostTestAbstract(object):
|
||||
""" Base class for each host-test test cases with standard
|
||||
setup, test and teardown set of functions
|
||||
"""
|
||||
|
||||
name = '' # name of the host test (used for local registration)
|
||||
__event_queue = None # To main even loop
|
||||
__dut_event_queue = None # To DUT
|
||||
script_location = None # Path to source file used to load host test
|
||||
__config = {}
|
||||
|
||||
def __notify_prn(self, text):
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(('__notify_prn', text, time()))
|
||||
|
||||
def __notify_conn_lost(self, text):
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(('__notify_conn_lost', text, time()))
|
||||
|
||||
def __notify_sync_failed(self, text):
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(('__notify_sync_failed', text, time()))
|
||||
|
||||
def __notify_dut(self, key, value):
|
||||
"""! Send data over serial to DUT """
|
||||
if self.__dut_event_queue:
|
||||
self.__dut_event_queue.put((key, value, time()))
|
||||
|
||||
def notify_complete(self, result=None):
|
||||
"""! Notify main even loop that host test finished processing
|
||||
@param result True for success, False failure. If None - no action in main even loop
|
||||
"""
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(('__notify_complete', result, time()))
|
||||
|
||||
def reset_dut(self, value):
|
||||
"""
|
||||
Reset device under test
|
||||
:return:
|
||||
"""
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(('__reset_dut', value, time()))
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Reset the device under test and continue running the host test
|
||||
:return:
|
||||
"""
|
||||
if self.__event_queue:
|
||||
self.__event_queue.put(("__reset", "0", time()))
|
||||
|
||||
def notify_conn_lost(self, text):
|
||||
"""! Notify main even loop that there was a DUT-host test connection error
|
||||
@param consume If True htrun will process (consume) all remaining events
|
||||
"""
|
||||
self.__notify_conn_lost(text)
|
||||
|
||||
def log(self, text):
|
||||
"""! Send log message to main event loop """
|
||||
self.__notify_prn(text)
|
||||
|
||||
def send_kv(self, key, value):
|
||||
"""! Send Key-Value data to DUT """
|
||||
self.__notify_dut(key, value)
|
||||
|
||||
def setup_communication(self, event_queue, dut_event_queue, config={}):
|
||||
"""! Setup queues used for IPC """
|
||||
self.__event_queue = event_queue # To main even loop
|
||||
self.__dut_event_queue = dut_event_queue # To DUT
|
||||
self.__config = config
|
||||
|
||||
def get_config_item(self, name):
|
||||
"""
|
||||
Return test config
|
||||
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return self.__config.get(name, None)
|
||||
|
||||
def setup(self):
|
||||
"""! Setup your tests and callbacks """
|
||||
raise NotImplementedError
|
||||
|
||||
def result(self):
|
||||
"""! Returns host test result (True, False or None) """
|
||||
raise NotImplementedError
|
||||
|
||||
def teardown(self):
|
||||
"""! Blocking always guaranteed test teardown """
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def event_callback(key):
|
||||
"""
|
||||
Decorator for defining a event callback method. Adds a property attribute "event_key" with value as the passed key.
|
||||
|
||||
:param key:
|
||||
:return:
|
||||
"""
|
||||
def decorator(func):
|
||||
func.event_key = key
|
||||
return func
|
||||
return decorator
|
||||
|
||||
|
||||
class HostTestCallbackBase(BaseHostTestAbstract):
|
||||
|
||||
def __init__(self):
|
||||
BaseHostTestAbstract.__init__(self)
|
||||
self.__callbacks = {}
|
||||
self.__restricted_callbacks = [
|
||||
'__coverage_start',
|
||||
'__testcase_start',
|
||||
'__testcase_finish',
|
||||
'__testcase_summary',
|
||||
'__exit',
|
||||
'__exit_event_queue'
|
||||
]
|
||||
|
||||
self.__consume_by_default = [
|
||||
'__coverage_start',
|
||||
'__testcase_start',
|
||||
'__testcase_finish',
|
||||
'__testcase_count',
|
||||
'__testcase_name',
|
||||
'__testcase_summary',
|
||||
'__rxd_line',
|
||||
]
|
||||
|
||||
self.__assign_default_callbacks()
|
||||
self.__assign_decorated_callbacks()
|
||||
|
||||
def __callback_default(self, key, value, timestamp):
|
||||
"""! Default callback """
|
||||
#self.log("CALLBACK: key=%s, value=%s, timestamp=%f"% (key, value, timestamp))
|
||||
pass
|
||||
|
||||
def __default_end_callback(self, key, value, timestamp):
|
||||
"""
|
||||
Default handler for event 'end' that gives test result from target.
|
||||
This callback is not decorated as we don't know then in what order this
|
||||
callback would be registered. We want to let users over write this callback.
|
||||
Hence it should be registered before registering user defined callbacks.
|
||||
|
||||
:param key:
|
||||
:param value:
|
||||
:param timestamp:
|
||||
:return:
|
||||
"""
|
||||
self.notify_complete(value == 'success')
|
||||
|
||||
def __assign_default_callbacks(self):
|
||||
"""! Assigns default callback handlers """
|
||||
for key in self.__consume_by_default:
|
||||
self.__callbacks[key] = self.__callback_default
|
||||
# Register default handler for event 'end' before assigning user defined callbacks to let users over write it.
|
||||
self.register_callback('end', self.__default_end_callback)
|
||||
|
||||
def __assign_decorated_callbacks(self):
|
||||
"""
|
||||
It looks for any callback methods decorated with @event_callback
|
||||
|
||||
Example:
|
||||
Define a method with @event_callback decorator like:
|
||||
|
||||
@event_callback('<event key>')
|
||||
def event_handler(self, key, value, timestamp):
|
||||
do something..
|
||||
|
||||
:return:
|
||||
"""
|
||||
for name, method in inspect.getmembers(self, inspect.ismethod):
|
||||
key = getattr(method, 'event_key', None)
|
||||
if key:
|
||||
self.register_callback(key, method)
|
||||
|
||||
def register_callback(self, key, callback, force=False):
|
||||
"""! Register callback for a specific event (key: event name)
|
||||
@param key String with name of the event
|
||||
@param callback Callable which will be registstered for event "key"
|
||||
@param force God mode
|
||||
"""
|
||||
|
||||
# Non-string keys are not allowed
|
||||
if type(key) is not str:
|
||||
raise TypeError("event non-string keys are not allowed")
|
||||
|
||||
# And finally callback should be callable
|
||||
if not callable(callback):
|
||||
raise TypeError("event callback should be callable")
|
||||
|
||||
# Check if callback has all three required parameters (key, value, timestamp)
|
||||
# When callback is class method should have 4 arguments (self, key, value, timestamp)
|
||||
if ismethod(callback):
|
||||
arg_count = six.get_function_code(callback).co_argcount
|
||||
if arg_count != 4:
|
||||
err_msg = "callback 'self.%s('%s', ...)' defined with %d arguments"% (callback.__name__, key, arg_count)
|
||||
err_msg += ", should have 4 arguments: self.%s(self, key, value, timestamp)"% callback.__name__
|
||||
raise TypeError(err_msg)
|
||||
|
||||
# When callback is just a function should have 3 arguments func(key, value, timestamp)
|
||||
if isfunction(callback):
|
||||
arg_count = six.get_function_code(callback).co_argcount
|
||||
if arg_count != 3:
|
||||
err_msg = "callback '%s('%s', ...)' defined with %d arguments"% (callback.__name__, key, arg_count)
|
||||
err_msg += ", should have 3 arguments: %s(key, value, timestamp)"% callback.__name__
|
||||
raise TypeError(err_msg)
|
||||
|
||||
if not force:
|
||||
# Event starting with '__' are reserved
|
||||
if key.startswith('__'):
|
||||
raise ValueError("event key starting with '__' are reserved")
|
||||
|
||||
# We predefined few callbacks you can't use
|
||||
if key in self.__restricted_callbacks:
|
||||
raise ValueError("we predefined few callbacks you can't use e.g. '%s'"% key)
|
||||
|
||||
self.__callbacks[key] = callback
|
||||
|
||||
def get_callbacks(self):
|
||||
return self.__callbacks
|
||||
|
||||
def setup(self):
|
||||
pass
|
||||
|
||||
def result(self):
|
||||
pass
|
||||
|
||||
def teardown(self):
|
||||
pass
|
||||
|
||||
|
||||
class BaseHostTest(HostTestCallbackBase):
|
||||
|
||||
__BaseHostTest_Called = False
|
||||
|
||||
def base_host_test_inited(self):
|
||||
""" This function will check if BaseHostTest ctor was called
|
||||
Call to BaseHostTest is required in order to force required
|
||||
interfaces implementation.
|
||||
@return Returns True if ctor was called (ok behaviour)
|
||||
"""
|
||||
return self.__BaseHostTest_Called
|
||||
|
||||
def __init__(self):
|
||||
HostTestCallbackBase.__init__(self)
|
||||
self.__BaseHostTest_Called = True
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from .. import BaseHostTest
|
||||
|
||||
|
||||
class DefaultAuto(BaseHostTest):
|
||||
""" Simple, basic host test's test runner waiting for serial port
|
||||
output from MUT, no supervision over test running in MUT is executed.
|
||||
"""
|
||||
pass
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import re
|
||||
from .. import BaseHostTest
|
||||
|
||||
class DetectPlatformTest(BaseHostTest):
|
||||
PATTERN_MICRO_NAME = "Target '(\w+)'"
|
||||
re_detect_micro_name = re.compile(PATTERN_MICRO_NAME)
|
||||
|
||||
def result(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def test(self, selftest):
|
||||
result = True
|
||||
|
||||
c = selftest.mbed.serial_readline() # {{start}} preamble
|
||||
if c is None:
|
||||
return selftest.RESULT_IO_SERIAL
|
||||
|
||||
selftest.notify(c.strip())
|
||||
selftest.notify("HOST: Detecting target name...")
|
||||
|
||||
c = selftest.mbed.serial_readline()
|
||||
if c is None:
|
||||
return selftest.RESULT_IO_SERIAL
|
||||
selftest.notify(c.strip())
|
||||
|
||||
# Check for target name
|
||||
m = self.re_detect_micro_name.search(c)
|
||||
if m and len(m.groups()):
|
||||
micro_name = m.groups()[0]
|
||||
micro_cmp = selftest.mbed.options.micro == micro_name
|
||||
result = result and micro_cmp
|
||||
selftest.notify("HOST: MUT Target name '%s', expected '%s'... [%s]"% (micro_name,
|
||||
selftest.mbed.options.micro,
|
||||
"OK" if micro_cmp else "FAIL"))
|
||||
|
||||
for i in range(0, 2):
|
||||
c = selftest.mbed.serial_readline()
|
||||
if c is None:
|
||||
return selftest.RESULT_IO_SERIAL
|
||||
selftest.notify(c.strip())
|
||||
|
||||
return selftest.RESULT_SUCCESS if result else selftest.RESULT_FAILURE
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
from .. import BaseHostTest
|
||||
|
||||
class DevNullTest(BaseHostTest):
|
||||
|
||||
__result = None
|
||||
|
||||
def _callback_result(self, key, value, timestamp):
|
||||
# We should not see result data in this test
|
||||
self.__result = False
|
||||
|
||||
def _callback_to_stdout(self, key, value, timestamp):
|
||||
self.__result = True
|
||||
self.log("_callback_to_stdout !")
|
||||
|
||||
def setup(self):
|
||||
self.register_callback("end", self._callback_result)
|
||||
self.register_callback("to_null", self._callback_result)
|
||||
self.register_callback("to_stdout", self._callback_to_stdout)
|
||||
|
||||
def result(self):
|
||||
return self.__result
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# Copyright (c) 2018, Arm Limited and affiliates.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import uuid
|
||||
from .. import BaseHostTest
|
||||
|
||||
class EchoTest(BaseHostTest):
|
||||
|
||||
__result = None
|
||||
echo_count = 0
|
||||
count = 0
|
||||
uuid_sent = []
|
||||
uuid_recv = []
|
||||
|
||||
def __send_echo_uuid(self):
|
||||
if self.echo_count:
|
||||
str_uuid = str(uuid.uuid4())
|
||||
self.send_kv("echo", str_uuid)
|
||||
self.uuid_sent.append(str_uuid)
|
||||
self.echo_count -= 1
|
||||
|
||||
def _callback_echo(self, key, value, timestamp):
|
||||
self.uuid_recv.append(value)
|
||||
self.__send_echo_uuid()
|
||||
|
||||
def _callback_echo_count(self, key, value, timestamp):
|
||||
# Handshake
|
||||
self.echo_count = int(value)
|
||||
self.send_kv(key, value)
|
||||
# Send first echo to echo server on DUT
|
||||
self.__send_echo_uuid()
|
||||
|
||||
def setup(self):
|
||||
self.register_callback("echo", self._callback_echo)
|
||||
self.register_callback("echo_count", self._callback_echo_count)
|
||||
|
||||
def result(self):
|
||||
self.__result = self.uuid_sent == self.uuid_recv
|
||||
return self.__result
|
||||
|
||||
def teardown(self):
|
||||
pass
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue