Git Product home page Git Product logo

dott-ng's Introduction

DOTT.NG: Debugger-Based On-Target Testing - New Generation

This file provides a short overview about the scope of the Debugger-Based On Target Testing (DOTT) framework followed by a quick step-by-step guide to get people started. Full documentation is provided online at the GitHub DOTT documentation site.

DOTT is a framework for on-target testing of firmware for Arm Cortex-M microcontrollers. Tests are implemented in Python, and they are executed on a host PC. The host PC is connected to the target (microcontroller) via a debugger, typically using SWD or JTAG. At this time, DOTT relies on Segger J-Link debug probes.

|-----------|                                            |------------|
|  HOST PC  |   USB                          SWD         |   TARGET   |
|           | <----> J-Link Debugger <-----------------> |            |
|   Tests   |                                            | Unmodified |
| in Python | <----> Other Test Equipment <------------> |  Firmware  |
|           |   USB   (e.g., RaspberryPi)  I2C, SPI, ... |            |
|-----------|                                            |------------|

Where it's from & What it does

DOTT was originally developed internally at ams AG (later ams-OSRAM AG) to simplify automated testing of firmware for Arm Cortex-M microcontrollers. In spring 2021 it was decided to release DOTT via GitHub to the public.

In fall 2022, the development of DOTT was discontinued and a fork called DOTT-NG (aka new generation) was created on Github where development continues under the same open source (Apache 2) license. Contributions from industry and the open-source community are welcomed and highly encouraged.

DOTT aims to enable firmware testing ...

  • ... without modifications of the firmware for the sake of testing
  • ... without mocking of, e.g., peripherals
  • ... with support for selective injection of data into the execution
  • ... on the original target device
  • ... using the original compiler

DOTT also comes with the benefit that the test runner and tests are executed on the host PC and do not have to be compiled for the target device or downloaded to it. Executing the tests on a host PC also makes it easy to integrate whatever additional test equipment is available/required (e.g., stimulus generation, interface hardware, logic analyzers, ...).

How it works

DOTT relies on the GNU Debugger (GDB) and its machine interface (MI). DOTT allows you to do a multitude of things such as writing very basic unit tests where you are calling functions implemented in your firmware with parameters of your choice. Suppose your firmware contains a function example_Addition. You can call it from a test in Python as follows:

def test_example_Addition(self, target_load, target_reset):
    res = dott().target.eval('example_Addition(31, 11)')
    assert(42 == res)

You did not only test that your function returns 42 when feeding in 31 and 11 as parameters but along the way, via the target_load and target_reset pytest fixtures coming with DOTT, you also loaded the firmware binary to the target device and performed a target reset. This ensures that the target is in a known state when you execute your test.

A slightly more involved example is the following one. Suppose your firmware has a function called test_example_AdditionSubcalls which in turn calls two other functions, namely example_GetA which returns the value of a local variable a and exammple_GetB which modifies the value of pointer variable b. The following test first calls example_AdditionSubcalls and checks for the expected result. Next, it changes what example_GetA and example_GetB return and then again checks if the new result matches the expected one. This demonstrates how DOTT can be used to inject data into the program execution which is very useful to test corner cases.

def test_example_Simple(self, target_load, target_reset):
    dt = dott().target
    res = dt.eval('example_AdditionSubcalls()')
    assert (63 == res)

    # Now tweak the sub function return values and see if example_AdditionSubcalls delivers the new expected result
    class IpA(InterceptPoint):
        def reached(self):
            self.ret(10)

    class IpB(InterceptPoint):
        def reached(self):
            self.eval('*b = 89')
            self.ret(0)

    ipa = IpA('example_GetA')
    ipb = IpB('example_GetB')

    res = dt.eval('example_AdditionSubcalls()')

    ipa.delete()
    ipb.delete()

    assert(99 == res)

These examples are barely scratching the surface of how you can use DOTT for firmware testing and things really start to get fun when you advance from basic unit/component testing to system testing where you integrate additional test equipment. With DOTT you can then observe, e.g., which (side)effects external test stimuli have on your firmware. System testing examples can be found in the System Testing Section of the DOTT documentation.

Dependencies and Requirements

Required

  • host OS (tested): Windows 10 (64bit), Ubuntu Linux 22.04 (64bit)
  • Python 3.10 (64bit) or newer (e.g., [PythonBuilds); See Setup Guide for details on tested versions.
  • Segger J-Link debug probe or STM32 eval board with ST-Link converted to J-Link
  • Segger J-Link Software Pack. Notice: The following version should be avoided since they have known issues related to SRAM download: v6.50, v6.52(a-c)

Recommended

  • STM32F072 Nucleo-64 board which is used as reference platform for the examples coming with DOTT

Optional

  • Arm Compiler 6 to re-build the example firmware images (*)
  • GNU Make + Busybox as build environment to re-build the example firmware images
  • RaspberryPi as test equipment to, e.g., provide stimuli via I2C or SPI to the system under test

(*) GCC support is planned for a future release.

Setup Instructions

  • As a pre-requisite download and install the Segger J-Link software to its default location.

  • If you are using the recommended STM32F072 Nucleo-64 reference board, convert its ST-LINK debugger to a J-Link debugger by the instructions from the DOTT documentation (reference board section).

  • It is assumed that you have a Python interpreter installed. A recommended, self-contained Python distribution for Windows is WinPython. For detailed setup instructions and Linux-specific aspects please check the DOTT Setup Guide.

  • It is recommended (but not required) to create and activate a virtual environment for DOTT:

$ python -m venv dott_venv
$ dott_venv\Scripts\activate.bat
  • DOTT can be installed using pip from the Python package index (PyPi) using pip:
$ pip install dott-ng
  • This installs all the required dependencies including the dott-ng-runtime package. The dott-ng-runtime contains binary dependencies required by DOTT. These are the GNU debug (GDB) client for Arm Cortex-M processors as distributed by Arm in the GNU Arm Embedded Toolchain. Since the Arm's GNU Arm Embedded Toolchain does not yet come with Python 3.x support for GDB-internal scripting also the required Python 2.7 dependencies are included in the dott-ng-runtime (Windows only). Note that only a minor fraction of DOTT uses the 2.7 environment while the majority (including all tests you write) reside in the 3.x environment and interfaces GDB via its machine interface (MI). The 2.7 dependency will vanish as soon as Arm moves the GNU Arm Embedded Toolchain to Python 3.x.

  • Download the zip archive providing documentation and example projects from the DOTT Github releases website and unpack it to your disk.

  • Make sure that the STM32F072 Nucleo-64 board is connected to your PC and that its ST-LINK is already converted to J-Link. Open a shell (and activate the DOTT virtual environment if you are using venv). Next, execute the example tests from the zip file:

$ cd examples\01_component_testing\host
$ pytest
  • This should generate an output similar to the one below. This indicates that you have correctly installed DOTT and successfully executed your first tests. Please consult the DOTT documentation to learn more about basic component testing as in this example as well as about more advanced system testing concepts.
[INFO] dott.py @197: DOTT runtime:          c:\tmp\venv_dott_install_test/dott_data (package-internal)
[INFO] dott.py @198: DOTT runtime version:  package-internal
[INFO] dott.py @201: work directory:        C:\tmp\dott_doc_examples_20191217\examples
[INFO] dott.py @246: BL ELF (load):         None
[INFO] dott.py @254: BL ELF (symbol):       None
[INFO] dott.py @262: BL ADDR (symbol):      0x0
[INFO] dott.py @268: APP ELF (load):        01_component_testing/target/build/dott_example_01/dott_example_01.bin.elf
[INFO] dott.py @275: APP ELF (symbol):      01_component_testing/target/build/dott_example_01/dott_example_01.axf
[INFO] dott.py @279: Device name:           STM32F072RB
[INFO] dott.py @286: Device endianess:      little
[INFO] dott.py @290: J-LINK interface:      SWD
[INFO] dott.py @294: J-LINK speed (set):    15000
[INFO] dott.py @306: GDB client binary:     c:\tmp\venv_dott_install_test/dott_data/apps/gdb/bin/arm-none-eabi-gdb-py
[INFO] dott.py @314: GDB server address:    10.10.171.84
[INFO] dott.py @320: GDB server port:       2331
[INFO] dott.py @344: GDB server assumed to be already running (not started by DOTT).
[INFO] dott.py @390: Std. target mem model for DOTT default fixtures:  TargetMemModel.TESTHOOK
[INFO] fixtures.py @46: Triggering download of APP to FLASH...
PASSED                                                                                                                                                   [  4%]
test_example_functions.py::TestExampleFunctions::test_example_NoArgsStatic PASSED                                                                        [  9%]
test_example_functions.py::TestExampleFunctions::test_example_Addition PASSED                                                                            [ 14%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionPtr PASSED                                                                         [ 19%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionPtr_Alternate PASSED                                                               [ 23%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionPtr_AlternateArray PASSED                                                          [ 28%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionPtrRet PASSED                                                                      [ 33%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionPtrRet_Alternate PASSED                                                            [ 38%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionStruct PASSED                                                                      [ 42%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionStruct_Alternate PASSED                                                            [ 47%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionStruct_ctypes PASSED                                                               [ 52%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionStructPtr PASSED                                                                   [ 57%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionStructPtr_Alternate PASSED                                                         [ 61%]
test_example_functions.py::TestExampleFunctions::test_example_ManyArgs PASSED                                                                            [ 66%]
test_example_functions.py::TestExampleFunctions::test_example_CustomOperation PASSED                                                                     [ 71%]
test_example_functions.py::TestExampleFunctions::test_example_ArgString PASSED                                                                           [ 76%]
test_example_functions.py::TestExampleFunctions::test_example_SumElements PASSED                                                                         [ 80%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionSubcalls PASSED                                                                    [ 85%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionSubcallsBasicIntercept PASSED                                                      [ 90%]
test_example_functions.py::TestExampleFunctions::test_example_AdditionSubcallsExtIntercept PASSED                                                        [ 95%]
test_example_functions.py::TestExampleFunctions::test_global_data_access PASSED                                                                          [100%]

-------------------- generated xml file: C:\tmp\dott_doc_examples_20191217\examples\test_results.xml ---------------------
===================================================================== 21 passed in 10.41s =====================================================================

DOTT-NG Contributors

dott-ng's People

Contributors

tw-ghub avatar twinkler-ams-osram avatar

Stargazers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.