pyocd-0.13.1/0000755000175000017500000000000013373523011012610 5ustar neilneil00000000000000pyocd-0.13.1/.gitattributes0000644000175000017500000000060213373511253015506 0ustar neilneil00000000000000*.py text *.c text *.cpp text *.h text *.s text *.S text *.ld text *.txt text *.xml text *.yml text *.yaml text *.md text *.rst text *.json text *.ini text Makefile text *.bat text eol=crlf *.map text *.elf binary *.bin binary .git_archival.txt export-subst pyocd-0.13.1/.editorconfig0000644000175000017500000000042113373511253015267 0ustar neilneil00000000000000# top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] end_of_line = lf insert_final_newline = true charset = utf-8 # 4 space indentation for Python [*.py] indent_style = space indent_size = 4 trim_trailing_whitespace = false pyocd-0.13.1/.git_archival.txt0000644000175000017500000000004713373511253016071 0ustar neilneil00000000000000ref-names: tag: v0.13.1, release/v0.13 pyocd-0.13.1/pytest.ini0000644000175000017500000000005513373511253014646 0ustar neilneil00000000000000[pytest] testpaths = pyocd log_level = DEBUG pyocd-0.13.1/dev-requirements.txt0000644000175000017500000000017013373511253016653 0ustar neilneil00000000000000# install pyOCD itself (and dependencies) as editable --editable . pytest>=3.4 pytest-cov coverage elapsedtimer pylint pyocd-0.13.1/PKG-INFO0000644000175000017500000002221113373523011013703 0ustar neilneil00000000000000Metadata-Version: 2.1 Name: pyocd Version: 0.13.1 Summary: Cortex-M debugger for Python Home-page: https://github.com/mbedmicro/pyOCD Author: Chris Reed, Martin Kojtal, Russ Butler Author-email: chris.reed@arm.com, martin.kojtal@arm.com, russ.butler@arm.com License: Apache 2.0 Description: pyOCD ===== pyOCD is an open source Python package for programming and debugging Arm Cortex-M microcontrollers using multiple supported types of USB debug probes. It is fully cross-platform, with support for Linux, macOS, and Windows. Several command line tools are provided that cover most use cases, or you can make use of the Python API to enable low-level target control. A common use for the Python API is to run and control CI tests. Three tools give you total control over your device: - `pyocd-gdbserver`: GDB remote server allows you to debug using gdb via either [GNU MCU Eclipse plug-in](https://gnu-mcu-eclipse.github.io/) or the console. - `pyocd-flashtool`: Program and erase an MCU's flash memory. - `pyocd-tool`: Interactive REPL control and inspection of the MCU. The API and tools provide these features: - halt, step, resume control - read/write memory - read/write core registers - set/remove hardware and software breakpoints - set/remove watchpoints - write to flash memory - load binary, hex, or ELF files into flash - reset control - access CoreSight DP and APs - and more! Requirements ------------ - Python 2.7.9 or later, or Python 3.6.0 or later - macOS, Linux, or Windows 7 or newer - Microcontroller with an Arm Cortex-M CPU - Supported debug probe - [CMSIS-DAP](http://www.keil.com/pack/doc/CMSIS/DAP/html/index.html), such as an on-board debug probe using [DAPLink](https://os.mbed.com/handbook/DAPLink) firmware. - STLinkV2, either on-board or the standalone version. Status ------ PyOCD is functionally reliable and fully useable. The API is considered unstable because we are planning some breaking changes to bring the naming convention into compliance with PEP8 prior to releasing version 1.0. We also plan to merge the three command line tools into a single tool. Documentation ------------- The pyOCD documentation is located [in the docs directory](docs/). Installing ---------- The latest stable version of pyOCD may be installed via [pip](https://pip.pypa.io/en/stable/index.html) as follows: ``` $ pip install -U pyocd ``` The latest pyOCD package is available [on PyPI](https://pypi.python.org/pypi/pyOCD/) as well as [on GitHub](https://github.com/mbedmicro/pyOCD/releases). To install the latest prerelease version from the HEAD of the master branch, you can do the following: ``` $ pip install --pre -U https://github.com/mbedmicro/pyOCD/archive/master.zip ``` You can also install directly from the source by cloning the git repository and running: ``` $ python setup.py install ``` Note that, depending on your operating system, you may run into permissions issues running these commands. You have a few options here: 1. Under Linux, run with `sudo -H` to install pyOCD and dependencies globally. (Installing with sudo should never be required for macOS.) 2. Specify the `--user` option to install local to your user. 3. Run the command in a [virtualenv](https://virtualenv.pypa.io/en/latest/) local to a specific project working set. ### libusb installation [pyusb](https://github.com/pyusb/pyusb) and its backend library [libusb](https://libusb.info/) are dependencies on all supported operating systems. pyusb is a regular Python package and will be installed along with pyOCD. However, libusb is binary shared library that does not get installed automatically via pip dependency management. How to install libusb depends on your OS: - macOS: use Homebrew: `brew install libusb` - Linux: should already be installed. - Windows: download libusb from [libusb.info](https://libusb.info/) and place the DLL in your Python installation folder next to python.exe. ### udev rules on Linux If you encounter an issue on Linux where `pyocd-tool list` won't detect attached boards without sudo, the reason is most likely USB device access permissions. In Ubuntu 16.04+ these are handled with udev and can be solved by adding a new udev rule. An example udev rule file is included in the [udev](https://github.com/mbedmicro/pyOCD/tree/master/udev) folder in the pyOCD repository. Just copy this file into `etc/udev/rules.d` to enable user access to both [DAPLink](https://os.mbed.com/handbook/DAPLink)-based debug probes as well as STLinkV2 and STLinkV3. If you use different, but compatible, debug probe, you can check the IDs with ``dmesg`` command. - Run ``dmesg`` - Plug in your board - Run ``dmesg`` again and check what was added - Look for line similar to ``usb 2-2.1: New USB device found, idVendor=0d28, idProduct=0204`` Standalone GDB server --------------------- When you install pyOCD via pip or setup.py, you will be able to execute the following in order to start a GDB server powered by pyOCD: ``` $ pyocd-gdbserver ``` You can get additional help by running ``pyocd-gdbserver --help``. Example command line GDB session showing how to connect to a running `pyocd-gdbserver` and load firmware: ``` $ arm-none-eabi-gdb application.elf target remote localhost:3333 load monitor reset ``` The `pyocd-gdbserver` executable is also usable as a drop in place replacement for OpenOCD in existing setups. The primary difference is the set of gdb monitor commands. Recommended GDB and IDE setup ----------------------------- The GDB server works well with [Eclipse](https://www.eclipse.org/) and the [GNU MCU Eclipse plug-ins](https://gnu-mcu-eclipse.github.io/). GNU MCU Eclipse fully supports pyOCD with an included pyOCD debugging plugin. To view peripheral register values either the built-in GNU MCU Eclipse register view can be used, or the Embedded System Register Viewer plugin can be installed. These can be installed from inside Eclipse using the following software update server addresses: - GNU MCU Eclipse: http://gnu-mcu-eclipse.sourceforge.net/updates - Embedded System Register Viewer: http://embsysregview.sourceforge.net/update In Eclipse, select the "Help -> Install New Software…" menu item. Then either click the "Add…" button and fill in the name and URL from above (once for each site), or simply copy the URL into the field where it says "type or select a site". Then you can select the software to install and click Next to start the process. Development setup ----------------- Please see the [Developers' Guide](docs/DEVELOPERS_GUIDE.md) for instructions on how to set up a development environment for pyOCD. Contributions ------------- We welcome contributions to pyOCD in any area. Please see the [contribution guidelines](CONTRIBUTING.md) for details. To report bugs, please [create an issue](https://github.com/mbedmicro/pyOCD/issues/new) in the GitHub project. License ------- PyOCD is licensed with Apache 2.0. See the [LICENSE](LICENSE) file for the full text of the license. Copyright © 2006-2018 Arm Ltd Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development :: Debuggers Classifier: Topic :: Software Development :: Embedded Systems Requires-Python: >=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* Description-Content-Type: text/markdown Provides-Extra: dissassembler pyocd-0.13.1/.travis.yml0000644000175000017500000000032113373511253014722 0ustar neilneil00000000000000dist: trusty sudo: false language: python python: - "2.7" - "3.6" # command to install dependencies install: - pip install -r dev-requirements.txt # command to run tests script: - pytest --cache-clear pyocd-0.13.1/src/0000755000175000017500000000000013373523011013377 5ustar neilneil00000000000000pyocd-0.13.1/src/gdb_test_program/0000755000175000017500000000000013373523011016721 5ustar neilneil00000000000000pyocd-0.13.1/src/gdb_test_program/readme.txt0000644000175000017500000000044213373511253020724 0ustar neilneil00000000000000How to build gdb test program (windows only right now): -Install prerequisites - GNU Tools ARM Embedded 4.9 2014q4 or newer -Add bin directory to path - ex. "C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2015q2\bin" to path -Run build.bat to create/update gdb_test.bin and gdb_test.elf pyocd-0.13.1/src/gdb_test_program/Makefile0000644000175000017500000000261513373511253020372 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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. PREFIX = arm-none-eabi- CC = $(PREFIX)gcc OBJCOPY = $(PREFIX)objcopy TARGET = gdb_test.elf TARGET_BIN = gdb_test.bin OBJECTS = main.o LIBRARIES = INCLUDES = CFLAGS = -std=gnu11 -MMD -MP $(INCLUDES) -O0 -fno-common -ffunction-sections \ -fdata-sections -Wall -Werror -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 \ -gstrict-dwarf -nostdlib -fpie LDFLAGS = -T"linker_script.ld" -Wl,-Map,gdb_test.map,--gc-sections,-emain -nostdlib -fpie .PHONY: all all: $(TARGET) $(TARGET_BIN) .PHONY: clean clean: # @echo "Cleaning output..." rm -f *.o *.d $(TARGET) $(TARGET_BIN) $(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o $@ $(TARGET_BIN): $(TARGET) $(OBJCOPY) -O binary $(TARGET) $(TARGET_BIN) # Include dependency files. -include $(OBJECTS:.o=.d) pyocd-0.13.1/src/gdb_test_program/main.c0000644000175000017500000000427413373511253020025 0ustar neilneil00000000000000/* mbed CMSIS-DAP debugger Copyright (c) 2015-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. */ #include volatile uint8_t run_breakpoint_test; volatile uint8_t watchpoint_write; volatile uint8_t watchpoint_read; volatile uint8_t watchpoint_size; void * volatile write_address; volatile uint32_t watchpoint_write_buffer[3]; void function_1() { } void function_2() { } void function_3() { } void breakpoint_test() { } void watchpoint_test() { if (1 == watchpoint_size) { if (watchpoint_read) { *(volatile uint8_t*) write_address; } if (watchpoint_write) { *(volatile uint8_t*) write_address = 42; } } else if (2 == watchpoint_size) { if (watchpoint_read) { *(volatile uint16_t*) write_address; } if (watchpoint_write) { *(volatile uint16_t*) write_address = 42; } } else if (4 == watchpoint_size) { if (watchpoint_read) { *(volatile uint32_t*) write_address; } if (watchpoint_write) { *(volatile uint32_t*) write_address = 42; } } } int main() { int i; // Initialize variables run_breakpoint_test = 0; watchpoint_write = 0; watchpoint_read = 0; watchpoint_size = 0; write_address = 0; for (i = 0; i < sizeof(watchpoint_write_buffer) / sizeof(watchpoint_write_buffer[0]); i++) { watchpoint_write_buffer[i] = 0; } while(1) { function_1(); function_2(); function_3(); if (run_breakpoint_test) { breakpoint_test(); } if (watchpoint_size) { watchpoint_test(); } } } pyocd-0.13.1/src/gdb_test_program/gdb_test.bin0000755000175000017500000000070413373511253021217 0ustar neilneil00000000000000K{D"pK{D"pK{D"pK{D"pK{D"`#{`K{Dzh!P{h3{`{h+&),K{Dx۲+) K{Dx۲+&F~REFFFFFFFF*K{Dx۲+(K{Dx۲+&K{Dhx%K{Dx۲+<#K{Dh*"p6!K{Dx۲+K{Dx۲+K{DhK{Dx۲+ K{Dh*"K{Dx۲+K{Dx۲+K{DhhK{Dx۲+K{Dh*"`FFuh^SJpyocd-0.13.1/src/gdb_test_program/linker_script.ld0000644000175000017500000000247213373511253022124 0ustar neilneil00000000000000/* mbed CMSIS-DAP debugger Copyright (c) 2006-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. */ /* Memory regions */ MEMORY { /* Ram configurations are for smallest KL25 in family - 4K */ m_all (rwx) : ORIGIN = 0x00000000, LENGTH = 0x600 } /* Define output sections */ SECTIONS { .text : { . = ALIGN(4); /* Entry point */ KEEP(*(.text.main)) *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ . = ALIGN(4); *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >m_all } pyocd-0.13.1/src/gdb_test_program/build.bat0000644000175000017500000000051213373511253020513 0ustar neilneil00000000000000arm-none-eabi-gcc.exe -O0 -fno-common -ffunction-sections -fdata-sections -Wall -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -T"linker_script.ld" -Wl,-Map,gdb_test.map,--gc-sections,-emain -nostdlib -fpie main.c -o gdb_test.elf arm-none-eabi-objcopy.exe --output-target binary gdb_test.elf gdb_test.bin pyocd-0.13.1/src/analyzer/0000755000175000017500000000000013373523011015224 5ustar neilneil00000000000000pyocd-0.13.1/src/analyzer/readme.txt0000644000175000017500000000033713373511253017232 0ustar neilneil00000000000000How to build and update analyzer (windows only right now): -Install prerequisites - GNU Tools ARM Embedded 4.9 2014q4 -Run build.bat to create main.py -Copy contents of main.py into flash.py (overwrite existing 'analyzer') pyocd-0.13.1/src/analyzer/Makefile0000644000175000017500000000276313373511253016701 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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. PREFIX = arm-none-eabi- CC = $(PREFIX)gcc OBJCOPY = $(PREFIX)objcopy TARGET = main.elf TARGET_BIN = main.bin TARGET_PY = main.py OBJECTS = main.o LIBRARIES = INCLUDES = CFLAGS = -std=gnu11 -MMD -MP $(INCLUDES) -O3 -fno-common -ffunction-sections \ -fdata-sections -Wall -Werror -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 \ -gstrict-dwarf -nostdlib -fpic -ffixed-r9 LDFLAGS = -T"linker_script.ld" -Wl,-Map,gdb_test.map,--gc-sections,-ecompute_crc \ -n -nostdlib -fpic -ffixed-r9 .PHONY: all all: $(TARGET_PY) .PHONY: clean clean: rm -f *.o *.d $(TARGET) $(TARGET_BIN) $(TARGET_PY) $(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o $@ $(TARGET_BIN): $(TARGET) $(OBJCOPY) -O binary $(TARGET) $(TARGET_BIN) $(TARGET_PY): $(TARGET_BIN) python generate_python.py $(TARGET_BIN) $(TARGET_PY) # Include dependency files. -include $(OBJECTS:.o=.d) pyocd-0.13.1/src/analyzer/main.c0000644000175000017500000000323013373511253016317 0ustar neilneil00000000000000/* mbed CMSIS-DAP debugger Copyright (c) 2006-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. */ #include typedef struct { uint16_t size; uint16_t addr; } sector_info_t; static uint32_t crc32_tab[256]; static uint32_t crc32(uint32_t crc, const void *buf, uint32_t size) { const uint8_t *p; p = buf; crc = crc ^ ~0U; while (size--) { crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); } return crc ^ ~0U; } static void fill_table(void) { int i; uint32_t byte, crc, mask; for (byte = 0; byte <= 255; byte++) { crc = byte; for (i = 7; i >= 0; i--) { // Do eight times. mask = -(crc & 1); crc = (crc >> 1) ^ (0xEDB88320 & mask); } crc32_tab[byte] = crc; } } int compute_crc(void * data, uint32_t num) { sector_info_t * sectors = data; uint32_t * crcs = data; uint32_t i; uint32_t crc; uint32_t addr; uint32_t size; fill_table(); for (i = 0; i < num; i++) { size = 1 << sectors[i].size; addr = size * sectors[i].addr; crc = crc32(0, (void*)addr, size); crcs[i] = crc; } size = 1 << num; return 0; } pyocd-0.13.1/src/analyzer/linker_script.ld0000644000175000017500000000261713373511253020430 0ustar neilneil00000000000000/* mbed CMSIS-DAP debugger Copyright (c) 2006-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. */ /* Memory regions */ MEMORY { /* Ram configurations are for smallest KL25 in family - 4K */ m_all (rwx) : ORIGIN = 0x00000000, LENGTH = 0x600 } /* Define output sections */ SECTIONS { .text : { . = ALIGN(4); /* Entry point */ KEEP(*(.text.compute_crc)) *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >m_all .data : { . = ALIGN(4); *(.data) /* .data sections */ *(.data*) /* .data* sections */ } >m_all /* Uninitialized data section */ .bss : { . = ALIGN(4); *(.bss) *(.bss*) *(COMMON) } > m_all } pyocd-0.13.1/src/analyzer/build.bat0000644000175000017500000000064013373511253017020 0ustar neilneil00000000000000arm-none-eabi-gcc.exe -O3 -ffunction-sections -fdata-sections -Wall -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -T"linker_script.ld" -Wl,-Map,main.map,--gc-sections,-ecompute_crc -n -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -nostdlib -fpic -ffixed-r9 main.c -o main.elf arm-none-eabi-objcopy.exe --output-target binary main.elf main.bin python.exe generate_python.py main.bin main.py pyocd-0.13.1/src/analyzer/generate_python.py0000644000175000017500000000235713373511253021005 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 __future__ import print_function import sys from struct import unpack INPUT_FILENAME = sys.argv[1] OUTPUT_FILENAME = sys.argv[2] with open(INPUT_FILENAME, "rb") as f: data = f.read() words = len(data) // 4 if len(data) % 4 != 0: print("Warning: input length not word aligned") str = "?$ # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Maximum number of characters on a single line. max-line-length=120 # Maximum number of lines in a module. max-module-lines=2000 # List of optional constructs for which whitespace checking is disabled. `dict- # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. # `trailing-comma` allows a space between comma and closing bracket: (a, ). # `empty-line` allows space-only lines. no-space-check=trailing-comma, dict-separator, empty-line # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no [SIMILARITIES] # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no # Minimum lines number of a similarity. min-similarity-lines=4 [BASIC] # Naming style matching correct argument names. argument-naming-style=any #snake_case # Regular expression matching correct argument names. Overrides argument- # naming-style. #argument-rgx= # Naming style matching correct attribute names. attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style. #attr-rgx= # Bad variable names which should always be refused, separated by a comma. bad-names=foo, bar, baz, toto, tutu, tata # Naming style matching correct class attribute names. class-attribute-naming-style=any # Regular expression matching correct class attribute names. Overrides class- # attribute-naming-style. #class-attribute-rgx= # Naming style matching correct class names. class-naming-style=PascalCase # Regular expression matching correct class names. Overrides class-naming- # style. #class-rgx= # Naming style matching correct constant names. const-naming-style=UPPER_CASE # Regular expression matching correct constant names. Overrides const-naming- # style. #const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 # Naming style matching correct function names. function-naming-style=snake_case # Regular expression matching correct function names. Overrides function- # naming-style. #function-rgx= # Good variable names which should always be accepted, separated by a comma. good-names=i, j, k, ex, Run, _, version, log # Include a hint for the correct naming format with invalid-name. include-naming-hint=no # Naming style matching correct inline iteration names. inlinevar-naming-style=any # Regular expression matching correct inline iteration names. Overrides # inlinevar-naming-style. #inlinevar-rgx= # Naming style matching correct method names. method-naming-style=snake_case # Regular expression matching correct method names. Overrides method-naming- # style. #method-rgx= # Naming style matching correct module names. module-naming-style=snake_case # Regular expression matching correct module names. Overrides module-naming- # style. #module-rgx= # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. # These decorators are taken in consideration only for invalid-name. property-classes=abc.abstractproperty # Naming style matching correct variable names. variable-naming-style=any #snake_case,camelCase # Regular expression matching correct variable names. Overrides variable- # naming-style. #variable-rgx= [IMPORTS] # Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=no # Deprecated modules which should not be used, separated by a comma. deprecated-modules=optparse,tkinter.tix # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled). ext-import-graph= # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled). import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled). int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library= # Force import order to recognize a module as part of a third party library. known-third-party=enchant [CLASSES] # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__, __new__, setUp # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict, _fields, _replace, _source, _make # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=cls [DESIGN] # Maximum number of arguments for function / method. max-args=5 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Maximum number of boolean expressions in an if statement. max-bool-expr=5 # Maximum number of branch for function / method body. max-branches=12 # Maximum number of locals for function / method body. max-locals=15 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of return / yield for function / method body. max-returns=6 # Maximum number of statements in function / method body. max-statements=50 # Minimum number of public methods for a class (see R0903). min-public-methods=2 [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception". overgeneral-exceptions=Exception pyocd-0.13.1/udev/0000755000175000017500000000000013373523011013553 5ustar neilneil00000000000000pyocd-0.13.1/udev/50-pyocd.rules0000644000175000017500000000150213373511253016172 0ustar neilneil00000000000000# 0d28:0204 DAPLink SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", ATTR{idProduct}=="0204", MODE:="666" # 0483:3748 STLinkV2 # 0483:374b STLinkV2-1 # 0483:374a STLinkV2-1 Audio # 0483:3742 STLinkV2-1 No MSD # 0483:374e STLinkV3 # 0483:374f STLinkV3 Bridge # 0483:3753 STLinkV3 2VCP SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374a", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3742", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374e", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374f", MODE:="666" SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3753", MODE:="666" pyocd-0.13.1/docs/0000755000175000017500000000000013373523011013540 5ustar neilneil00000000000000pyocd-0.13.1/docs/MULTICORE_DEBUG.md0000644000175000017500000000325313373511253016343 0ustar neilneil00000000000000Multicore Debug =============== pyOCD supports debugging multicore devices. It does this by serving one gdb server per core, to which you connect independant gdb instances. This is the most reliable method of debugging multicore embedded devices using gdb. `pyocd-gdbserver` automatically creates one `GDBServer` instance per core. The first core is given the user-specified port number. Additional cores have port numbers incremented from there. To prevent reset requests from multiple connected gdb instances causing havoc, the reset monitor commands are only honoured for core 0. To debug a multicore device, run `pyocd-gdbserver` as usual. This will connect to the device, detect the cores, and create the gdb server instances on separate ports. Next, start up two gdb instances and connect to the two gdb server ports. For instance, on a dual core device if you pass 3333 for the port, connect to port 3333 for the first core and port 3334 for the second core. On many devices, secondary cores are by default held in reset until released by the primary core. Because gdb does not have a concept of a core held in reset, pyOCD will report a core held in reset by telling gdb that there is a single thread with the name "Reset". This is visible if you run the show threads gdb command, and will appear in the Eclipe Debug view's list of threads. All register values will be reported as 0 until the core is released from reset. Usually you want to have the primary core load code for the secondary core, so configure the second core's gdb to not load any code to the target. This is highly device-specific, though, and may depend on whether the secondary core's code is running out of flash or RAM. pyocd-0.13.1/docs/resources/0000755000175000017500000000000013373523011015552 5ustar neilneil00000000000000pyocd-0.13.1/docs/resources/Arm_logo_blue_150MN.png0000644000175000017500000000212213373511253021650 0ustar neilneil00000000000000PNG  IHDR*@ pHYs&?IDATxq00@ u*T  lU`oTx; >HH` x.G###R _`~RQRKĶ8)c@Zu u:5ur0D\`W>/@&5/"i j€*W 2@juz65J{K0? 0~ x|L؁ǯrf/o@C i3W;x߫ fӻ&eyBbrhؑvr A YCl̶ׁBܺCm7AREmDcב]V`Q[ a*7ܷXd2? +M+{O4俾5uB{5P Q{D-QwҤ4cLHwpck8DWV6r~e25mNd[/F<,Ovg3XufdW ^ <_12 QCtКݯdhK2zD `]vt#NM߈IĊAUPW]*[q .–UPC&-RoW!Q ߦѮl 9==5)u [1-Ⱥ}>)ewL- tap.G3ㅁQ.1a#8ldW1CY*6G&F6AyhC* cimߕ@8 `N\O.5U#<'[u8, $projectname: $title $title $treeview $search $mathjax $extrastylesheet
$projectname  $projectnumber
$projectbrief
$projectbrief
$searchbox
pyocd-0.13.1/docs/resources/doxygen_layout.xml0000644000175000017500000001372513373511253021363 0ustar neilneil00000000000000 pyocd-0.13.1/docs/resources/doxygen_style.css0000644000175000017500000006631313373511253021177 0ustar neilneil00000000000000/* The standard CSS for doxygen 1.8.14 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; } p.reference, p.definition { font: 400 14px/22px Roboto,sans-serif; } /* @group Heading Levels */ h1.groupheader { font-size: 150%; } .title { font: 400 14px/28px Roboto,sans-serif; font-size: 150%; font-weight: bold; margin: 10px 2px; } h2.groupheader { border-bottom: 1px solid #879ECB; color: #354C7B; font-size: 150%; font-weight: normal; margin-top: 1.75em; padding-top: 8px; padding-bottom: 4px; width: 100%; } h3.groupheader { font-size: 100%; } h1, h2, h3, h4, h5, h6 { -webkit-transition: text-shadow 0.5s linear; -moz-transition: text-shadow 0.5s linear; -ms-transition: text-shadow 0.5s linear; -o-transition: text-shadow 0.5s linear; transition: text-shadow 0.5s linear; margin-right: 15px; } h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { text-shadow: 0 0 15px cyan; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd { margin-top: 2px; } p.starttd { margin-top: 0px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code, a.code:visited, a.line, a.line:visited { color: #4665A2; } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; font-family: monospace, fixed; font-size: 105%; } div.fragment { padding: 8px; margin: 4px 8px 4px 2px; background-color: #F6F7F8; /* border: 1px solid #C4CFE5; */ } div.line { font-family: "Consolas", "Lucida Console", monospace, fixed; font-size: 13px; min-height: 13px; line-height: 1.0; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ white-space: pre-wrap; /* CSS3 */ word-wrap: break-word; /* IE 5.5+ */ text-indent: -53px; padding-left: 53px; padding-bottom: 0px; margin: 0px; -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } div.line:after { content:"\000A"; white-space: pre; } div.line.glow { background-color: cyan; box-shadow: 0 0 10px cyan; } span.lineno { padding-right: 4px; text-align: right; border-right: 2px solid #0F0; background-color: #E8E8E8; white-space: pre; } span.lineno a { background-color: #D8D8D8; } span.lineno a:hover { background-color: #C8C8C8; } .lineno { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } div.ah, span.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); } div.classindex ul { list-style: none; padding-left: 0; } div.classindex span.ai { display: inline-block; } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background-color: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 12px; margin-right: 8px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; white-space: nowrap; vertical-align: top; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } blockquote { background-color: #F7F8FB; border-left: 2px solid #9CAFD4; margin: 0 24px 0 4px; padding: 0 12px 0 16px; } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .memberdecls td, .fieldtable tr { -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } .memberdecls td.glow, .fieldtable tr.glow { background-color: cyan; box-shadow: 0 0 15px cyan; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memSeparator { border-bottom: 1px solid #DEE4F0; line-height: 1px; margin: 0px; padding: 0px; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memItemRight { width: 100%; } .memTemplParams { color: #4665A2; white-space: nowrap; font-size: 80%; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtitle { padding: 8px; border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; border-top-right-radius: 4px; border-top-left-radius: 4px; margin-bottom: -1px; background-image: url('nav_f.png'); background-repeat: repeat-x; background-color: #E2E8F2; line-height: 1.25; font-weight: 300; float:left; } .permalink { font-size: 65%; display: inline-block; vertical-align: middle; } .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 9px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .mempage { width: 100%; } .memitem { padding: 0; margin-bottom: 10px; margin-right: 5px; -webkit-transition: box-shadow 0.5s linear; -moz-transition: box-shadow 0.5s linear; -ms-transition: box-shadow 0.5s linear; -o-transition: box-shadow 0.5s linear; transition: box-shadow 0.5s linear; display: table !important; width: 100%; } .memitem.glow { box-shadow: 0 0 15px cyan; } .memname { font-weight: 400; margin-left: 6px; } .memname td { vertical-align: bottom; } .memproto, dl.reflist dt { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); background-color: #DFE5F1; /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 4px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 4px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 4px; } .overload { font-family: "courier new",courier,monospace; font-size: 65%; } .memdoc, dl.reflist dd { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 10px 2px 10px; background-color: #FBFCFD; border-top-width: 0; background-image:url('nav_g.png'); background-repeat:repeat-x; background-color: #FFFFFF; /* opera specific markup */ border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; /* webkit specific markup */ -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); } dl.reflist dt { padding: 5px; } dl.reflist dd { margin: 0px 0px 10px 0px; padding: 5px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .paramname code { line-height: 14px; } .params, .retval, .exception, .tparams { margin-left: 0px; padding-left: 0px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } table.mlabels { border-spacing: 0px; } td.mlabels-left { width: 100%; padding: 0px; } td.mlabels-right { vertical-align: bottom; padding: 0px; white-space: nowrap; } span.mlabels { margin-left: 8px; } span.mlabel { background-color: #728DC1; border-top:1px solid #5373B4; border-left:1px solid #5373B4; border-right:1px solid #C4CFE5; border-bottom:1px solid #C4CFE5; text-shadow: none; color: white; margin-right: 4px; padding: 2px 3px; border-radius: 3px; font-size: 7pt; white-space: nowrap; vertical-align: middle; } /* @end */ /* these are for tree view inside a (index) page */ div.directory { margin: 10px 0px; border-top: 1px solid #9CAFD4; border-bottom: 1px solid #9CAFD4; width: 100%; } .directory table { border-collapse:collapse; } .directory td { margin: 0px; padding: 0px; vertical-align: top; } .directory td.entry { white-space: nowrap; padding-right: 6px; padding-top: 3px; } .directory td.entry a { outline:none; } .directory td.entry a img { border: none; } .directory td.desc { width: 100%; padding-left: 6px; padding-right: 6px; padding-top: 3px; border-left: 1px solid rgba(0,0,0,0.05); } .directory tr.even { padding-left: 6px; background-color: #F7F8FB; } .directory img { vertical-align: -30%; } .directory .levels { white-space: nowrap; width: 100%; text-align: right; font-size: 9pt; } .directory .levels span { cursor: pointer; padding-left: 2px; padding-right: 2px; color: #3D578C; } .arrow { color: #9CAFD4; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; cursor: pointer; font-size: 80%; display: inline-block; width: 16px; height: 22px; } .icon { font-family: Arial, Helvetica; font-weight: bold; font-size: 12px; height: 14px; width: 16px; display: inline-block; background-color: #728DC1; color: white; text-align: center; border-radius: 4px; margin-left: 2px; margin-right: 2px; } .icona { width: 24px; height: 22px; display: inline-block; } .iconfopen { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('folderopen.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } .iconfclosed { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('folderclosed.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } .icondoc { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('doc.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } table.directory { font: 400 14px Roboto,sans-serif; } /* @end */ div.dynheader { margin-top: 8px; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } address { font-style: normal; color: #2A3D61; } table.doxtable caption { caption-side: top; } table.doxtable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } table.fieldtable { /*width: 100%;*/ margin-bottom: 10px; border: 1px solid #A8B8D9; border-spacing: 0px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } .fieldtable td, .fieldtable th { padding: 3px 7px 2px; } .fieldtable td.fieldtype, .fieldtable td.fieldname { white-space: nowrap; border-right: 1px solid #A8B8D9; border-bottom: 1px solid #A8B8D9; vertical-align: top; } .fieldtable td.fieldname { padding-top: 3px; } .fieldtable td.fielddoc { border-bottom: 1px solid #A8B8D9; /*width: 100%;*/ } .fieldtable td.fielddoc p:first-child { margin-top: 0px; } .fieldtable td.fielddoc p:last-child { margin-bottom: 2px; } .fieldtable tr:last-child td { border-bottom: none; } .fieldtable th { background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; font-size: 90%; color: #253555; padding-bottom: 4px; padding-top: 5px; text-align:left; font-weight: 400; -moz-border-radius-topleft: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid #A8B8D9; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; /* background-image:url('tab_b.png'); */ background-repeat:repeat-x; background-position: 0 -5px; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; color: #283A5D; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; } .navpath li.navelem a:hover { color:#6884BD; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#364D7C; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } table.classindex { margin: 10px; white-space: nowrap; margin-left: 3%; margin-right: 3%; width: 94%; border: 0; border-spacing: 0; padding: 0; } div.ingroups { font-size: 8pt; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } dl { padding: 0 0 0 10px; } /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ dl.section { margin-left: 0px; padding-left: 0px; } dl.note { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #D0C000; } dl.warning, dl.attention { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #FF0000; } dl.pre, dl.post, dl.invariant { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00D000; } dl.deprecated { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #505050; } dl.todo { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00C0E0; } dl.test { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #3030E0; } dl.bug { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #C08050; } dl.section dd { margin-bottom: 6px; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectalign { vertical-align: middle; } #projectname { font: 300% Tahoma, Arial,sans-serif; margin: 0px; padding: 2px 0px; } #projectbrief { font: 120% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 50% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; } .image { text-align: center; } .dotgraph { text-align: center; } .mscgraph { text-align: center; } .plantumlgraph { text-align: center; } .diagraph { text-align: center; } .caption { font-weight: bold; } div.zoom { border: 1px solid #90A5CE; } dl.citelist { margin-bottom:50px; } dl.citelist dt { color:#334975; float:left; font-weight:bold; margin-right:10px; padding:5px; } dl.citelist dd { margin:2px 0; padding:5px 0; } div.toc { padding: 14px 25px; background-color: #F4F6FA; border: 1px solid #D8DFEE; border-radius: 7px 7px 7px 7px; float: right; height: auto; margin: 0 8px 10px 10px; width: 200px; } div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; margin-top: 5px; padding-left: 10px; padding-top: 2px; } div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; border-bottom: 0 none; margin: 0; } div.toc ul { list-style: none outside none; border: medium none; padding: 0px; } div.toc li.level1 { margin-left: 0px; } div.toc li.level2 { margin-left: 15px; } div.toc li.level3 { margin-left: 30px; } div.toc li.level4 { margin-left: 45px; } .inherit_header { font-weight: bold; color: gray; cursor: pointer; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .inherit_header td { padding: 6px 0px 2px 5px; } .inherit { display: none; } tr.heading h2 { margin-top: 12px; margin-bottom: 4px; } /* tooltip related style info */ .ttc { position: absolute; display: none; } #powerTip { cursor: default; white-space: nowrap; background-color: white; border: 1px solid gray; border-radius: 4px 4px 4px 4px; box-shadow: 1px 1px 7px gray; display: none; font-size: smaller; max-width: 80%; opacity: 0.9; padding: 1ex 1em 1em; position: absolute; z-index: 2147483647; } #powerTip div.ttdoc { color: grey; font-style: italic; } #powerTip div.ttname a { font-weight: bold; } #powerTip div.ttname { font-weight: bold; } #powerTip div.ttdeci { color: #006318; } #powerTip div { margin: 0px; padding: 0px; font: 12px/16px Roboto,sans-serif; } #powerTip:before, #powerTip:after { content: ""; position: absolute; margin: 0px; } #powerTip.n:after, #powerTip.n:before, #powerTip.s:after, #powerTip.s:before, #powerTip.w:after, #powerTip.w:before, #powerTip.e:after, #powerTip.e:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.se:after, #powerTip.se:before, #powerTip.nw:after, #powerTip.nw:before, #powerTip.sw:after, #powerTip.sw:before { border: solid transparent; content: " "; height: 0; width: 0; position: absolute; } #powerTip.n:after, #powerTip.s:after, #powerTip.w:after, #powerTip.e:after, #powerTip.nw:after, #powerTip.ne:after, #powerTip.sw:after, #powerTip.se:after { border-color: rgba(255, 255, 255, 0); } #powerTip.n:before, #powerTip.s:before, #powerTip.w:before, #powerTip.e:before, #powerTip.nw:before, #powerTip.ne:before, #powerTip.sw:before, #powerTip.se:before { border-color: rgba(128, 128, 128, 0); } #powerTip.n:after, #powerTip.n:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.nw:after, #powerTip.nw:before { top: 100%; } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { border-top-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.n:before { border-top-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.n:after, #powerTip.n:before { left: 50%; } #powerTip.nw:after, #powerTip.nw:before { right: 14px; } #powerTip.ne:after, #powerTip.ne:before { left: 14px; } #powerTip.s:after, #powerTip.s:before, #powerTip.se:after, #powerTip.se:before, #powerTip.sw:after, #powerTip.sw:before { bottom: 100%; } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { border-bottom-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { border-bottom-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.s:after, #powerTip.s:before { left: 50%; } #powerTip.sw:after, #powerTip.sw:before { right: 14px; } #powerTip.se:after, #powerTip.se:before { left: 14px; } #powerTip.e:after, #powerTip.e:before { left: 100%; } #powerTip.e:after { border-left-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.e:before { border-left-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } #powerTip.w:after, #powerTip.w:before { right: 100%; } #powerTip.w:after { border-right-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.w:before { border-right-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } @media print { #top { display: none; } #side-nav { display: none; } #nav-path { display: none; } body { overflow:visible; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } .summary { display: none; } .memitem { page-break-inside: avoid; } #doc-content { margin-left:0 !important; height:auto !important; width:auto !important; overflow:inherit; display:inline; } } /* @group Markdown */ /* table.markdownTable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.markdownTable td, table.markdownTable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.markdownTableHead tr { } table.markdownTableBodyLeft td, table.markdownTable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } th.markdownTableHeadLeft { text-align: left } th.markdownTableHeadRight { text-align: right } th.markdownTableHeadCenter { text-align: center } */ table.markdownTable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.markdownTable td, table.markdownTable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.markdownTable tr { } th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } th.markdownTableHeadLeft, td.markdownTableBodyLeft { text-align: left } th.markdownTableHeadRight, td.markdownTableBodyRight { text-align: right } th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } /* @end */ pyocd-0.13.1/docs/resources/doxygen_footer.html0000644000175000017500000000127013373511253021500 0ustar neilneil00000000000000 pyocd-0.13.1/docs/DEVELOPERS_GUIDE.md0000644000175000017500000000437013373511253016460 0ustar neilneil00000000000000pyOCD Developers' Guide ======================= PyOCD developers are recommended to setup a working environment using [virtualenv](https://virtualenv.pypa.io/en/latest/). After cloning the code, you can setup a virtualenv and install the pyOCD dependencies for the current platform by following the detailed steps below. ## Setup Install the necessary tools listed below. Skip any step where a compatible tool already exists. * [Install Python](https://www.python.org/downloads/). Version 3.6.0 or above is preferred, while version 2.7.9 or above is also supported. Add to PATH. * [Install Git](https://git-scm.com/downloads). Add to PATH. * [Install virtualenv](https://virtualenv.pypa.io/en/latest/) in your global Python installation, eg: `pip install virtualenv` ## Steps **Step 1.** Get the sources and create a virtual environment ``` $ git clone https://github.com/mbedmicro/pyOCD $ cd pyOCD $ virtualenv venv ``` You may wish to create two virtual environments, for both Python 2.7 and 3.x. ``` $ python2 -mvirtualenv venv2 $ python3 -mvirtualenv venv3 ``` **Step 2.** Activate virtual environment Activate your virtualenv and install the PyOCD dependencies for the current platform by doing the following. Linux or Mac: ``` $ source venv/bin/activate $ pip install -r dev-requirements.txt ``` Windows: ``` $ venv\Scripts\activate $ pip install -r dev-requirements.txt ``` **Step 3.** Develop See the [porting guide](ADDING_NEW_TARGETS.md) for how to add new devices. Of course, we welcome all improvements and changes. See the [contributor statement](../CONTRIBUTING.md) for some guidelines. **Step 4.** Test To run the unit tests, you can execute the following. ``` $ pytest ``` To get code coverage results, do the following: ``` $ pytest --cov-report=html --cov=pyocd $ open htmlcov/index.html ``` The automated test suite also needs to be run: ``` $ cd test $ python ./automated_test.py ``` **Step 5.** Pull request Once you are satisfied with your changes and all automated tests pass, please create a [new pull request](https://github.com/mbedmicro/pyOCD/pull/new/master) on GitHub to share your work. Pull requests should be made once a changeset is [rebased onto Master](https://www.atlassian.com/git/tutorials/merging-vs-rebasing/workflow-walkthrough). pyocd-0.13.1/docs/SESSION_OPTIONS.md0000644000175000017500000000604013373511253016425 0ustar neilneil00000000000000Session Options =============== This guide documents the session options that are supported by pyOCD and how to use them. Many of these options have dedicated command line arguments. Arbitrary options can be set individually with the `-Ooption=value` command line argument. You may also use a YAML config file to set multiple options. And if you are using the Python API, you may pass any session options directly to the `ConnectHelper` methods or `Session` constructor as keyword arguments. ## Config file pyOCD supports a YAML configuration file that lets you provide session options that either apply to all probes or to a single probe, based on the probe's unique ID. The easiest way to use a config file is to use the `--config` command line option, for instance `--config=myconfig.yaml`. Alternatively, you can set the `config_file` session option. The top level of the YAML file is a dictionary. The keys in the top-level dictionary must be names of session options, or the key `probes`. Session options are set to the value corresponding to the dictionary entry. Unrecognized option names are ignored. If there is a top-level `probes` key, its value must be a dictionary with keys that match a substring of debug probe unique IDs. Usually you would just use the complete unique ID shown by listing connected boards (i.e., `pyocd-gdbserver --list`). The values for the unique ID entries are dictionaries containing session options, just like the top level of the YAML file. Of course, these session options are only applied when connecting with the given probe. If the probe unique ID substring listed in the config file matches more than one probe, the corresponding session options will be applied to all matching probes. Example board config file: ````yaml probes: 066EFF555051897267233656: # Probe's unique ID. target_override: stm32l475xg test_binary: stm32l475vg_iot01a.bin # Global options auto_unlock: false frequency: 8000000 # Set 8 MHz SWD default for all probes ```` ## Options list - `auto_unlock`: (bool) If the target is locked, it will by default be automatically mass erased in order to gain debug access. Set this option to False to disable auto unlock. - `config_file`: (str) Relative path to a YAML config file that lets you specify session options either globally or per probe. No default. The format of the file is documented above. - `frequency`: (int) SWD/JTAG frequency in Hertz. Default is 1 MHz. - `halt_on_connect`: (bool) Whether to halt the target immediately upon connecting. Default is True. - `resume_on_disconnect`: (bool) Whether to resume a halted target when disconnecting. Default is True. - `target_override`: (str) Target type name to use instead of default board target or default `cortex_m`. - `test_binary`: (str) Specify the test binary file name used by the functional test suite (in the `test/` directory). The binary must be in the `binaries/` directory. This option is most useful when set in a board config file for running the functional tests on boards that cannot be automatically detected. pyocd-0.13.1/docs/ARCHITECTURE.md0000644000175000017500000000456313373511253015761 0ustar neilneil00000000000000Architecture ============ ## Object graph The diagram below shows the most interesting parts of the pyOCD object graph, i.e. those parts that a user of the Python API will interact with. The connections in the diagram represent composition, not inheritance. ``` Session | |-----> DebugProbe | Board | CoreSightTarget | /---------|-----------\ | | | Flash CortexM[] DebugPort | | MemoryMap AccessPort[] ``` The root of the runtime object graph is a `Session` object. This object holds references to the debug probe and the board. It is also responsible for managing per-session user options that control various features and settings. Attached to the board is a `CoreSightTarget` instance, which represents an MCU. This owns the CoreSight related objects for communicating with the DP and APs, the flash programming interface, and a `CortexM` object for each CPU core on the device. Both `CoreSightTarget` and `CortexM` are subclasses of the abstract `Target` class, which is referenced below, and share most of the same APIs. ## Targets and boards Target and board support are two separate but related pieces of functionality. #### Target support Each supported target enables debugging and flash programming a given MCU. A single target can be used for potentially multiple boards, or there may not be board with the target. Users can override the target type on the command line or when creating the `Session`. Each supported target is defined as a `CoreSightTarget` subclass held in a Python file in the `pyocd/target` directory. If the target has internal or connected flash, then a `Flash` subclass will be paired with it in the same source file. Some device families have family subclasses under `pyocd/target/family`. #### Board information pyOCD can automatically identify a board and its target type using the board information. The board information is stored in the `BOARD_ID_TO_INFO` dictionary in `pyocd/board/board_ids.py`. This dictionary maps a 4-character board ID to a board name, target type, and test firmware binary. The board ID is generally the same as the board's Mbed platform ID, though non-Mbed boards that use [Arm DAPLink](https://github.com/ARMmbed/DAPLink) firmware also have board IDs allocated from the same namespace. pyocd-0.13.1/docs/API_EXAMPLES.md0000644000175000017500000000346313373511253016004 0ustar neilneil00000000000000Python API Examples =================== ### Hello World example code This example shows basic connection, loading a firmware binary, and some simple target control. ```python from pyocd.core.helpers import ConnectHelper import logging logging.basicConfig(level=logging.INFO) with ConnectHelper.session_with_chosen_probe() as session: board = session.board target = board.target flash = board.flash # Load firmware into device. flash.flash_binary("my_firmware.bin") # Reset, run. target.reset_stop_on_reset() target.resume() # Read some registers. print("pc: 0x%X" % target.read_core_register("pc")) target.step() print("pc: 0x%X" % target.read_core_register("pc")) target.resume() target.halt() print("pc: 0x%X" % target.read_core_register("pc")) target.reset_stop_on_reset() print("pc: 0x%X" % target.read_core_register("pc")) ``` ### ELF files and breakpoints Expanding on the above example, this code demonstrates reading a symbol address from an ELF file and setting a breakpoint. Then the target is reset and run until the breakpoint is hit. ```python from pyocd.core.target import Target from pyocd.debug.elf.symbols import ELFSymbolProvider # Set ELF file on target. target.elf = "my_firmware.elf" # Look up address of main(). provider = ELFSymbolProvider(target.elf) addr = provider.get_symbol_value("main") print("main() address: 0x%X" % addr) # Set breakpoint. target.set_breakpoint(addr) # Reset and run. target.reset() # Wait until breakpoint is hit. while target.get_state() != Target.TARGET_HALTED: pass # Print PC. pc = target.read_core_register("pc") print("pc: 0x%X" % pc) assert pc == addr # Remove breakpoint. target.remove_breakpoint() ``` pyocd-0.13.1/docs/ADDING_NEW_TARGETS.md0000644000175000017500000001105313373511253016717 0ustar neilneil00000000000000Adding a new target =================== This guide describes how to manually add support for a new target and/or board to pyOCD. For background information, review the [architecture overview](ARCHITECTURE.md) document first. ### Steps to add a new target 1. Create a new `CoreSightTarget` subclass and `Flash` subclass in a file under `pyocd/target/`. You can copy one of the existing target files like `pyocd/target/target_ncs36510.py` and rename the classes. The target source file name must follow the pattern "target\_\.py", where "\" is the device's `Dname` or `Dvariant` part number value from the appropriate CMSIS Device Family Pack (DFP). For instance, `target_LPC54608J512ET180.py`. You may substitute an "x" for certain fields in the part number, such as a package or pin count code, temperature code, or memory size (if multiple memory sizes are supported via classes within the one source file). 2. Create the target's memory map from information in the device's reference manual. The memory map should be a `memoryMap` class attribute of the target class. Modifying an existing memory map is easiest, and there are many examples in the other targets. 3. To create the flash algo, the recommended method is to use the [`tools/generate_blobs.py`](https://github.com/mbedmicro/FlashAlgo/blob/master/scripts/generate_blobs.py) script from the [FlashAlgo](https://github.com/mbedmicro/FlashAlgo) project. This script will generate output files in several forms, including Python for pyOCD, from an .FLM file that is included as part of a CMSIS DFP. 1. Locate the correct .FLM file from the DFP for your target. 2. Run `generate_blobs.py \`. It will write the output files to the same directory containing the source .FLM file. 3. The `py_blob_orig.py` output file contains the flash algo for pyOCD. Copy the `flash_algo` dictionary into the target source file. 4. Review the addresses in the `flash_algo` dictionary to make sure they are valid. The memory layout should look like: ``` |----------------|-------------|------------|-----|-----------------|-----------------| | load_address | static_base | << (stack) | ... | page_buffers[0] | page_buffers[1] | |----------------|-------------|------------|-----|-----------------|-----------------| ^ ^ ^ RAM start begin_stack (grows down) also begin_data ``` Each of the addresses in the `page_buffers` list points to a buffer of the maximum page size of any flash region. If there is not enough RAM to hold two page buffers, then remove one of the addresses from the list. This will disable double buffered flash programming. 5. To enable efficient scanning for modified pages via CRC checking, you can set the `analyzer_supported` key to True and the `analyzer_address` to the start address for an unused range of (1224 + 4 * number-of-flash-pages) bytes of RAM. 4. Edit `pyocd/target/__init__.py` to import your target source file and add your new target and flash classes to the `TARGET` and `FLASH` dicts. Now your new target is available for use via the `--target` command line option! ### Steps to add a new board This section only applies if your board has an on-board debug probe that either: - Uses the [Arm DAPLink](https://github.com/ARMmbed/DAPLink) firmware. DAPLink presents the board ID as the first 4 characters of the USB serial number. - Uses the STLinkV2-1 firmware and the board is Mbed-enabled. STLinkV2-1 presents the board ID as the first 4 characters of the code in the HTML file on the USB mass storage volume. If neither applies, then pyOCD will be unable to automatically detect the board type. However, you can still use the target. Follow these steps: 1. Identify the 4-character board ID. 2. Insert a row into the `BOARD_ID_TO_INFO` table in `pyocd/board/board_ids.py` with the board ID, board name, target type, and test binary file name. The new row should look similar to this: ``` "0205": BoardInfo( "FRDM-KL28Z", "kl28z", "l1_kl28z.bin", ), ``` Be sure to insert the row in sorted order by board ID. 3. Place a test firmware binary file listed in the board info into the top-level `binaries/` directory. The test firmware can be nothing more than an LED blinky demo. It must not require any user input, and should provide immediate visual feedback that the code is successfully running. pyocd-0.13.1/docs/PYTHON_API.md0000644000175000017500000001246413373511253015610 0ustar neilneil00000000000000Introduction to pyOCD API ========================= Using pyOCD's Python API, you have extreme flexibility and precise control, and can do anything SWD allows, at the expense of more complexity compared to `pyocd-tool`. Using pyOCD like this is particularly useful for situations where other debuggers become ineffective, such as device and board bringup, or automated testing. This document assumes familiarity with the Arm CoreSight debug architecture. See the [architecture](ARCHITECTURE.md) documentation for an overview of the classes and how they are connected. ## Connecting pyOCD provides a handful of helper routines that make it very easy to enumerate and connect to available debug probes. These routines are all available as static methods on the `ConnectHelper` class in `pyocd.core.helpers`. `ConnectHelper.session_with_chosen_probe()` is the primary connection helper. This method returns a single `Session` object, or None. If only a single probe is available, a new session for that probe is returned immediately. But if there are multiple probes available, then by default, it will present a simple console UI that lets the user select which probe they want to use. Other options allow automatically picking the first available probe. One of the most useful parameters for `session_with_chosen_probe()` is `unique_id`. Pass whole or part of a probe's unique ID (aka serial number) to programmatically select a specific probe. User session options may be passed to `session_with_chosen_probe()` in two ways. The `options` parameter accepts a dictionary of session options. Or, you may pass options as keyword parameters. The two methods may be combined. ## DP access The DP is controlled through an instance of the `DebugPort` class (in `pyocd.coresight.dap`). You get the `DebugPort` object via the 'dp' attribute of the target instance, i.e., `session.board.target.dp`. The `DebugPort` class has `read_reg(addr)` and `write_reg(addr, data)` methods. 'addr' must be an integer in the set (0x0, 0x4, 0x8, 0xC). Example: ```py x = session.board.target.dp.read_reg(0x4) session.board.target.dp.write_reg(0x8, 0x1) ``` For completeness, the DebugPort class also has `readDP(addr)`, `writeDP(addr, data)`, `readAP(addr)`, and `writeAP(addr, data)` methods. They work as described below, except that the `readAP()` and `writeAP()` methods require the APSEL in the address (i.e., 0x010000fc to read ID of APSEL=1). The AP will automatically be selected. ## AP access CoreSight APs are represented with `AccessPort` classes defined in `pyocd.coresight.ap`. These include the `MEM_AP` subclass and `AHB_AP` subclass of that. To get the AP objects you can use the 'aps' attribute of the `DebugPort`. This attribute is a dict with the keys being the APSEL number and values being AccessPort instances. For instance, use `session.board.target.aps[1]` to get the AP with APSEL=1, assuming it exists (if not, you'll get an `IndexError` exception). `AccessPort` also has `read_reg(addr)` and `write_reg(addr, data)` methods. For these methods, `addr` is an integer of the register offset. Note that you do not need to include the APSEL in the address, and you do not need to modify the DP's SELECT register prior to accessing AP registers. The AP will automatically be selected in the DP as required. The `MEM_AP`/`AHB_AP` class has the memory access methods that are available on the target, but the access is, of course, performed through that specific AP. This is particularly useful for multicore devices or Cortex-A class devices. Example showing access of the proprietary MDM-AP of NXP Kinetis MCUs: ```py mdm_ap = session.board.target.dp.aps[1] idr = mdm_ap.read_reg(0xfc) # Read IDR. mdm_ap.write_reg(0x4, 0x1) ``` ## Reset control To control reset, there are several options. `DebugPort` methods for performing hardware reset: - `DebugPort.reset()`, asks the debug probe to perform a hardware reset of the target. - `DebugPort.assert_reset(asserted)` to directly control the nRESET signal. Pass True to drive nRESET low, False to drive high. `Target` methods: - `Target.reset(software_reset=None)`. Normally performs a software reset unless the optional parameter is set to False. - `Target.resetStopOnReset(software_reset=None)` to perform a halting reset. Again, the reset defaults to software but may be set to hardware. Another option for performing a halting reset is by setting vector catch with the target's `setVectorCatch()` method, then using a normal reset. This has the benefit of always halting at reset, if you leave the vector catch enabled. Example timed reset using the DP: ``` import time dp = session.board.target.dp # Timed reset. dp.assert_reset(True) time.sleep(1.0) dp.assert_reset(False) ``` ## Notes NXP Kinetis targets will normally automatically perform a mass erase upon connect if flash security is enabled. This can be disabled, but requires slightly different connect code. You are encouraged to look through the code to see what additional functionality is available. The most interesting places to look at are: - `pyocd.core.target`: defines Target class, which is the main API. - `pyocd.coresight.cortex_m`: CortexM class to control a core, implements Target API and adds some stuff. - `pyocd.flash.flash`: flash programming API in the `Flash` class, accessible from the 'flash' attribute on a target (i.e., `session.board.target.flash`). pyocd-0.13.1/docs/AUTOMATED_TESTS.md0000644000175000017500000000433313373511253016377 0ustar neilneil00000000000000Automated Tests =============== Both unit tests and functional tests are used to verify pyOCD. The primary difference between unit tests and functional tests is that unit tests will work without a debug probe connected. Some unit tests do take advantage of a connected probe to expand testing, but those tests will be skipped if no probe is present. In contrast, all functional tests require at least one probe to be connected. ## Unit tests The unit tests are located in the `pyocd/tests/` directory of the repo. They must be executed using pytest, as they rely on the advanced capabilities of this tool. To run the unit tests, simply invoke `pytest` in the root directory of the repo. Read the pytest usage to see the many options it provides. To get code coverage results, do the following: ``` $ pytest --cov-report=html --cov=pyocd $ firefox htmlcov/index.html ``` ## Functional tests A series of quite comprehensive functional tests are provided in the `test/` directory. The primary script for running these tests is `automated_test.py`. It will execute all functional tests in sequence for all connected debug probes, then produce a summary and JUnit-style XML report. This script is used to execute our CI test plan, and we frequently use it on our personal development systems to test prior to creating pull requests. Functional tests: - `basic_test.py`: a simple test that checks a range of basic functionality, from flash programming to accessing memory and core registers. - `blank_test.py`: tests ability to connect to devices with with blank flash. (Not run by `automated_test.py`.) - `connect_test.py`: tests all combinations of the halt on connect and disconnect resume options. - `cortex_test.py`: validates CPU control operations and memory accesses. - `flash_test.py`: comprehensive test of flash programming. - `gdb_server_json_test.py`: validates the JSON output from pyocd-gdbserver used by tools like the GNU MCU Eclipse pyOCD plugin. - `gdb_test.py`: tests the gdbserver by running a script in a gdb process. - `parallel_test.py`: checks for issues with accessing debug probes from multiple processes and threads simultaneously. (Not run by `automated_test.py`.) - `speed_test.py`: performance test for memory reads and writes. pyocd-0.13.1/docs/HOW_TO_BUILD.md0000644000175000017500000000335613373511253016054 0ustar neilneil00000000000000How to Build pyOCD into Single Executable File ============================================== This manual provides a step-by-step guide on how to build a single file executable using [pyinstaller](http://pythonhosted.org/PyInstaller/). It should be possible for PyInstaller to work across all supported operating system, but these steps have only been tested on Windows 7 64-bit and Ubuntu 14.04. pyOCD is an open source GDB server library written in Python and maintained by pyOCD community, it depends on several libraries like pyusb under Linux, and pywinusb under Windows. Pyinstaller was chosen to bundle it into a single executable file, so that the pyOCD executable produced can be run on any computer, whether python and the related library are present or not on the system. Instructions ------------ Follow the following instructions from a fresh checkout of pyOCD to build a single file executable containing the pyOCD GDB server. These instructions assume that you already have Python installed: The following script shows the basic steps that one must follow: ```bash # Install pip and virtualenv sudo apt-get install python-pip python-virtualenv # Setup a virtualenv and install dependencies virtualenv env source env/bin/activate pip install --editable . # We need to use upstream version of pyinstaller due to # http://comments.gmane.org/gmane.comp.python.pyinstaller/6457 pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip # Create single-file executables pyinstaller --onefile pyocd/tools/gdb_server.py pyinstaller --onefile pyocd/tools/flash_tool.py pyinstaller --onefile pyocd/tools/pyocd.py ``` In ./dist folder, there will be a single executable file per tool which is ready to use or distribute it to other library. pyocd-0.13.1/docs/README.md0000644000175000017500000000103213373511253015020 0ustar neilneil00000000000000# pyOCD Documentation ## Table of Contents ### User documentation - [Session options](SESSION_OPTIONS.md) - [Debugging multicore devices](MULTICORE_DEBUG.md) - [Introduction to pyOCD API](PYTHON_API.md) - [Python API Examples](API_EXAMPLES.md) ### Developer documentation - [Developers’ guide](DEVELOPERS_GUIDE.md) - [Architecture overview](ARCHITECTURE.md) - [How to add new targets](ADDING_NEW_TARGETS.md) - [Building a standalone gdb server executable](HOW_TO_BUILD.md) - [Running the automated tests](AUTOMATED_TESTS.md) pyocd-0.13.1/MANIFEST.in0000644000175000017500000000037713373511253014362 0ustar neilneil00000000000000include pytest.ini include Doxyfile include dev-requirements.txt recursive-include udev * recursive-include binaries * recursive-include elf_files * recursive-include src *.ld *.txt *.c *.bat *.py recursive-include test *.py *.sh global-exclude .DS_Store pyocd-0.13.1/pyocd/0000755000175000017500000000000013373523011013726 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/coresight/0000755000175000017500000000000013373523011015715 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/coresight/rom_table.py0000644000175000017500000003571113373511253020247 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 .component import CoreSightComponent from .cortex_m import CortexM from .fpb import FPB from .dwt import DWT from ..utility.mask import invert32 from collections import namedtuple import logging # CoreSight identification register offsets. DEVARCH = 0xfbc DEVID = 0xfc8 DEVTYPE = 0xfcc PIDR4 = 0xfd0 PIDR0 = 0xfe0 CIDR0 = 0xff0 IDR_END = 0x1000 # Range of identification registers to read at once and offsets in results. # # To improve component identification performance, we read all of a components # CoreSight ID registers in a single read. Reading starts at the DEVARCH register. IDR_READ_START = DEVARCH IDR_READ_COUNT = (IDR_END - IDR_READ_START) // 4 DEVARCH_OFFSET = (DEVARCH - IDR_READ_START) // 4 DEVTYPE_OFFSET = (DEVTYPE - IDR_READ_START) // 4 PIDR4_OFFSET = (PIDR4 - IDR_READ_START) // 4 PIDR0_OFFSET = (PIDR0 - IDR_READ_START) // 4 CIDR0_OFFSET = (CIDR0 - IDR_READ_START) // 4 # Component ID register fields. CIDR_PREAMBLE_MASK = 0xffff0fff CIDR_PREAMBLE_VALUE = 0xb105000d CIDR_COMPONENT_CLASS_MASK = 0x0000f000 CIDR_COMPONENT_CLASS_SHIFT = 12 # Component classes. ROM_TABLE_CLASS = 0x1 CORESIGHT_CLASS = 0x9 GENERIC_CLASS = 0xe SYSTEM_CLASS = 0xf # CoreLink, PrimeCell, or other system component with no standard register layout. # Peripheral ID register fields. PIDR_PART_MASK = 0x00000fff PIDR_DESIGNER_MASK = 0x0007f000 # JEP106 ID PIDR_DESIGNER_SHIFT = 12 PIDR_REVISION_MASK = 0x00f00000 PIDR_REVISION_SHIFT = 20 PIDR_DESIGNER2_MASK = 0x0f00000000 # JEP106 continuation PIDR_DESIGNER2_SHIFT = 32 # JEP106 codes # [11:8] continuation # [6:0] ID ARM_ID = 0x43b FSL_ID = 0x00e # ROM table constants. ROM_TABLE_ENTRY_PRESENT_MASK = 0x1 # Mask for ROM table entry size. 1 if 32-bit entries. ROM_TABLE_32BIT_FORMAT_MASK = 0x2 # 2's complement offset to debug component from ROM table base address. ROM_TABLE_ADDR_OFFSET_NEG_MASK = 0x80000000 ROM_TABLE_ADDR_OFFSET_MASK = 0xfffff000 ROM_TABLE_ADDR_OFFSET_SHIFT = 12 # 9 entries is enough entries to cover the standard Cortex-M4 ROM table for devices with ETM. ROM_TABLE_ENTRY_READ_COUNT = 9 ROM_TABLE_MAX_ENTRIES = 960 # DEVARCH register fields. DEVARCH_ARCHITECT_MASK = 0x7ff DEVARCH_ARCHITECT_SHIFT = 21 DEVARCH_PRESENT_MASK = (1<<20) DEVARCH_REVISION_MASK = 0x000f0000 DEVARCH_REVISION_SHIFT = 16 DEVARCH_ARCHID_MASK = 0xffff # CoreSight devtype # Major Type [3:0] # Minor Type [7:4] # # CoreSight Major Types # 0 = Miscellaneous # 1 = Trace Sink # 2 = Trace Link # 3 = Trace Source # 4 = Debug Control # 5 = Debug Logic # # Known devtype values # 0x11 = TPIU # 0x21 = ETB # 0x12 = Trace funnel (CSFT) # 0x13 = CPU trace source (ETM, MTB?) # 0x43 = ITM # 0x14 = ECT/CTI/CTM # 0x31 = MTB # 0x34 = Granular Power Requestor ## Pairs a component name with a factory method. CmpInfo = namedtuple('ComponentInfo', 'name factory') ## Map from (designer, class, part, devtype, archid) to component name and class. COMPONENT_MAP = { # Designer|Component Class |Part |Type |Archid (ARM_ID, CORESIGHT_CLASS, 0x906, 0x14, 0) : CmpInfo('CTI', None ), (ARM_ID, CORESIGHT_CLASS, 0x907, 0x21, 0) : CmpInfo('ETB', None ), (ARM_ID, CORESIGHT_CLASS, 0x908, 0x12, 0) : CmpInfo('CSTF', None ), (ARM_ID, CORESIGHT_CLASS, 0x912, 0x11, 0) : CmpInfo('TPIU', None ), (ARM_ID, CORESIGHT_CLASS, 0x923, 0x11, 0) : CmpInfo('TPIU-M3', None ), (ARM_ID, CORESIGHT_CLASS, 0x924, 0x13, 0) : CmpInfo('ETM-M3', None ), (ARM_ID, CORESIGHT_CLASS, 0x925, 0x13, 0) : CmpInfo('ETM-M4', None ), (ARM_ID, CORESIGHT_CLASS, 0x932, 0x31, 0x0a31) : CmpInfo('MTB-M0+', None ), (ARM_ID, CORESIGHT_CLASS, 0x975, 0x13, 0) : CmpInfo('ETM-M7', None ), (ARM_ID, CORESIGHT_CLASS, 0x9a1, 0x11, 0) : CmpInfo('TPIU-M4', None ), (ARM_ID, CORESIGHT_CLASS, 0x9a4, 0x34, 0x0a34) : CmpInfo('GPR', None ), # Granular Power Requestor (ARM_ID, CORESIGHT_CLASS, 0x9a6, 0x14, 0x1a14) : CmpInfo('CTI', None ), (ARM_ID, CORESIGHT_CLASS, 0x9a9, 0x11, 0) : CmpInfo('TPIU-M7', None ), (ARM_ID, CORESIGHT_CLASS, 0xd20, 0x11, 0) : CmpInfo('TPIU-M23', None ), (ARM_ID, CORESIGHT_CLASS, 0xd20, 0x13, 0) : CmpInfo('ETM-M23', None ), (ARM_ID, CORESIGHT_CLASS, 0xd20, 0x00, 0x1a02) : CmpInfo('DWT', DWT.factory ), # M23 (ARM_ID, CORESIGHT_CLASS, 0xd20, 0x00, 0x1a03) : CmpInfo('BPU', FPB.factory ), # M23 (ARM_ID, CORESIGHT_CLASS, 0xd20, 0x00, 0x2a04) : CmpInfo('SCS-M23', CortexM.factory ), # M23 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x1a01) : CmpInfo('ITM', None ), # M33 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x1a02) : CmpInfo('DWT', DWT.factory ), # M33 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x1a03) : CmpInfo('BPU', FPB.factory ), # M33 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x1a14) : CmpInfo('CTI', None ), # M33 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x2a04) : CmpInfo('SCS-M33', CortexM.factory ), # M33 (ARM_ID, CORESIGHT_CLASS, 0xd21, 0x00, 0x4a13) : CmpInfo('ETM', None ), # M33 (ARM_ID, GENERIC_CLASS, 0x000, 0x00, 0) : CmpInfo('SCS-M3', CortexM.factory ), (ARM_ID, GENERIC_CLASS, 0x001, 0x00, 0) : CmpInfo('ITM', None ), (ARM_ID, GENERIC_CLASS, 0x002, 0x00, 0) : CmpInfo('DWT', DWT.factory ), (ARM_ID, GENERIC_CLASS, 0x003, 0x00, 0) : CmpInfo('FPB', FPB.factory ), (ARM_ID, GENERIC_CLASS, 0x008, 0x00, 0) : CmpInfo('SCS-M0+', CortexM.factory ), (ARM_ID, GENERIC_CLASS, 0x00a, 0x00, 0) : CmpInfo('DWT-M0+', DWT.factory ), (ARM_ID, GENERIC_CLASS, 0x00b, 0x00, 0) : CmpInfo('BPU', FPB.factory ), (ARM_ID, GENERIC_CLASS, 0x00c, 0x00, 0) : CmpInfo('SCS-M4', CortexM.factory ), (ARM_ID, GENERIC_CLASS, 0x00e, 0x00, 0) : CmpInfo('FPB', FPB.factory ), (ARM_ID, SYSTEM_CLASS, 0x101, 0x00, 0) : CmpInfo('TSGEN', None ), # Timestamp Generator (FSL_ID, CORESIGHT_CLASS, 0x000, 0x04, 0) : CmpInfo('MTBDWT', None ), } ## @brief Reads and parses CoreSight architectural component ID registers. # # Reads the CIDR, PIDR, DEVID, and DEVARCH registers present at well known offsets # in the memory map of all CoreSight components. The various fields from these # registers are made available as attributes. class CoreSightComponentID(object): def __init__(self, ap, top_addr): self.ap = ap self.address = top_addr self.top_address = top_addr self.component_class = 0 self.is_rom_table = False self.cidr = 0 self.pidr = 0 self.designer = 0 self.part = 0 self.devarch = 0 self.archid = 0 self.devtype = 0 self.devid = 0 self.name = '' self.factory = None self.valid = False def read_id_registers(self): # Read Component ID, Peripheral ID, and DEVID/DEVARCH registers. This is done as a single # block read for performance reasons. regs = self.ap.read_memory_block32(self.top_address + IDR_READ_START, IDR_READ_COUNT) self.cidr = self._extract_id_register_value(regs, CIDR0_OFFSET) self.pidr = (self._extract_id_register_value(regs, PIDR4_OFFSET) << 32) | self._extract_id_register_value(regs, PIDR0_OFFSET) # Check if the component has a valid CIDR value if (self.cidr & CIDR_PREAMBLE_MASK) != CIDR_PREAMBLE_VALUE: logging.warning("Invalid coresight component, cidr=0x%x", self.cidr) return # Extract class and determine if this is a ROM table. component_class = (self.cidr & CIDR_COMPONENT_CLASS_MASK) >> CIDR_COMPONENT_CLASS_SHIFT is_rom_table = (component_class == ROM_TABLE_CLASS) # Extract JEP106 designer ID. self.designer = ((self.pidr & PIDR_DESIGNER_MASK) >> PIDR_DESIGNER_SHIFT) \ | ((self.pidr & PIDR_DESIGNER2_MASK) >> (PIDR_DESIGNER2_SHIFT - 8)) self.part = self.pidr & PIDR_PART_MASK # For CoreSight-class components, extract additional fields. if component_class == CORESIGHT_CLASS: self.devarch = regs[DEVARCH_OFFSET] self.devid = regs[1:4] self.devtype = regs[DEVTYPE_OFFSET] if self.devarch & DEVARCH_PRESENT_MASK: self.archid = self.devarch & DEVARCH_ARCHID_MASK # Determine component name. if is_rom_table: self.name = 'ROM' self.factory = ROMTable else: key = (self.designer, component_class, self.part, self.devtype, self.archid) info = COMPONENT_MAP.get(key, None) if info is not None: self.name = info.name self.factory = info.factory else: self.name = '???' self.component_class = component_class self.is_rom_table = is_rom_table self.valid = True def _extract_id_register_value(self, regs, offset): result = 0 for i in range(4): value = regs[offset + i] result |= (value & 0xff) << (i * 8) return result def __repr__(self): if not self.valid: return "<%08x:%s cidr=%x, pidr=%x, component invalid>" % (self.address, self.name, self.cidr, self.pidr) if self.component_class == CORESIGHT_CLASS: return "<%08x:%s class=%d designer=%03x part=%03x devtype=%02x archid=%04x devid=%x:%x:%x>" % ( self.address, self.name, self.component_class, self.designer, self.part, self.devtype, self.archid, self.devid[0], self.devid[1], self.devid[2]) else: return "<%08x:%s class=%d designer=%03x part=%03x>" % ( self.address, self.name,self.component_class, self.designer, self.part) class ROMTable(CoreSightComponent): """! @brief CoreSight ROM table component and parser. An object of this class represents a CoreSight ROM table. It supports reading the table and any child tables. For each entry in the table, a CoreSightComponentID object is created that further reads the component's CoreSight identification registers. """ def __init__(self, ap, cmpid=None, addr=None, parent_table=None): # If no table address is provided, use the root ROM table for the AP. if addr is None: addr = ap.rom_addr super(ROMTable, self).__init__(ap, cmpid, addr) self.parent = parent_table self.number = (self.parent.number + 1) if self.parent else 0 self.components = [] self.name = 'ROM' @property def depth_indent(self): return " " * self.number def init(self): if self.cmpid is None: self.cmpid = CoreSightComponentID(self.ap, self.address) self.cmpid.read_id_registers() if not self.cmpid.is_rom_table: logging.warning("Warning: ROM table @ 0x%08x has unexpected CIDR component class (0x%x)", self.address, self.cmpid.component_class) return self._read_table() def _read_table(self): logging.info("%sAP#%d ROM table #%d @ 0x%08x (designer=%03x part=%03x)", self.depth_indent, self.ap.ap_num, self.number, self.address, self.cmpid.designer, self.cmpid.part) self.components = [] entryAddress = self.address foundEnd = False entriesRead = 0 while not foundEnd and entriesRead < ROM_TABLE_MAX_ENTRIES: # Read several entries at a time for performance. readCount = min(ROM_TABLE_MAX_ENTRIES - entriesRead, ROM_TABLE_ENTRY_READ_COUNT) entries = self.ap.read_memory_block32(entryAddress, readCount) entriesRead += readCount for entry in entries: # Zero entry indicates the end of the table. if entry == 0: foundEnd = True break self._handle_table_entry(entry) entryAddress += 4 def _handle_table_entry(self, entry): # Nonzero entries can still be disabled, so check the present bit before handling. if (entry & ROM_TABLE_ENTRY_PRESENT_MASK) == 0: return # Verify the entry format is 32-bit. if (entry & ROM_TABLE_32BIT_FORMAT_MASK) == 0: return # Get the component's top 4k address. offset = entry & ROM_TABLE_ADDR_OFFSET_MASK if (entry & ROM_TABLE_ADDR_OFFSET_NEG_MASK) != 0: offset = ~invert32(offset) address = self.address + offset # Create component instance. cmpid = CoreSightComponentID(self.ap, address) cmpid.read_id_registers() logging.info("%s[%d]%s", self.depth_indent, len(self.components), str(cmpid)) # Recurse into child ROM tables. if cmpid.is_rom_table: cmp = ROMTable(self.ap, cmpid, address, parent_table=self) cmp.init() else: cmp = cmpid if cmp is not None: self.components.append(cmp) def for_each(self, action, filter=None): """! @brief Apply an action to every component defined in the ROM table and child tables. This method iterates over every entry in the ROM table. For each entry it calls the filter function if provided. If the filter passes (returns True or was not provided) then the action function is called. The ROM table must have been initialized by calling init() prior to using this method. @param self This object. @param action Callable that accepts a single parameter, a CoreSightComponentID instance. @param filter Optional filter callable. Must accept a CoreSightComponentID instance and return a boolean indicating whether to perform the action (True applies action). """ for component in self.components: # Recurse into child ROM tables. if isinstance(component, ROMTable): component.for_each(action, filter) continue # Skip component if the filter returns False. if filter is not None and not filter(component): continue # Perform the action. action(component) pyocd-0.13.1/pyocd/coresight/fpb.py0000644000175000017500000001054313373511253017046 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-2017 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 ..core.target import Target from .component import CoreSightComponent from ..debug.breakpoints.provider import (Breakpoint, BreakpointProvider) import logging class HardwareBreakpoint(Breakpoint): def __init__(self, comp_register_addr, provider): super(HardwareBreakpoint, self).__init__(provider) self.comp_register_addr = comp_register_addr self.type = Target.BREAKPOINT_HW class FPB(BreakpointProvider, CoreSightComponent): FP_CTRL = 0xE0002000 FP_CTRL_KEY = 1 << 1 FP_COMP0 = 0xE0002008 @classmethod def factory(cls, ap, cmpid, address): fpb = cls(ap, cmpid, address) assert ap.core ap.core.connect(fpb) return fpb def __init__(self, ap, cmpid=None, addr=None): CoreSightComponent.__init__(self, ap, cmpid, addr) BreakpointProvider.__init__(self) assert self.address == FPB.FP_CTRL, "Unexpected FPB base address 0x%08x" % self.address self.hw_breakpoints = [] self.nb_code = 0 self.nb_lit = 0 self.num_hw_breakpoint_used = 0 self.enabled = False ## @brief Inits the FPB. # # Reads the number of hardware breakpoints available on the core and disable the FPB # (Flash Patch and Breakpoint Unit), which will be enabled when the first breakpoint is set. def init(self): # setup FPB (breakpoint) fpcr = self.ap.read_memory(FPB.FP_CTRL) self.nb_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF) self.nb_lit = (fpcr >> 7) & 0xf logging.info("%d hardware breakpoints, %d literal comparators", self.nb_code, self.nb_lit) for i in range(self.nb_code): self.hw_breakpoints.append(HardwareBreakpoint(FPB.FP_COMP0 + 4*i, self)) # disable FPB (will be enabled on first bp set) self.disable() for bp in self.hw_breakpoints: self.ap.write_memory(bp.comp_register_addr, 0) def bp_type(self): return Target.BREAKPOINT_HW def enable(self): self.ap.write_memory(FPB.FP_CTRL, FPB.FP_CTRL_KEY | 1) self.enabled = True logging.debug('fpb has been enabled') return def disable(self): self.ap.write_memory(FPB.FP_CTRL, FPB.FP_CTRL_KEY | 0) self.enabled = False logging.debug('fpb has been disabled') return def available_breakpoints(self): return len(self.hw_breakpoints) - self.num_hw_breakpoint_used ## @brief Set a hardware breakpoint at a specific location in flash. def set_breakpoint(self, addr): if not self.enabled: self.enable() if addr >= 0x20000000: # Hardware breakpoints are only supported in the range # 0x00000000 - 0x1fffffff on cortex-m devices logging.error('Breakpoint out of range 0x%X', addr) return None if self.available_breakpoints() == 0: logging.error('No more available breakpoint!!, dropped bp at 0x%X', addr) return None for bp in self.hw_breakpoints: if not bp.enabled: bp.enabled = True bp_match = (1 << 30) if addr & 0x2: bp_match = (2 << 30) self.ap.write_memory(bp.comp_register_addr, addr & 0x1ffffffc | bp_match | 1) bp.addr = addr self.num_hw_breakpoint_used += 1 return bp return None ## @brief Remove a hardware breakpoint at a specific location in flash. def remove_breakpoint(self, bp): for hwbp in self.hw_breakpoints: if hwbp.enabled and hwbp.addr == bp.addr: hwbp.enabled = False self.ap.write_memory(hwbp.comp_register_addr, 0) self.num_hw_breakpoint_used -= 1 return pyocd-0.13.1/pyocd/coresight/dwt.py0000644000175000017500000001201113373511253017065 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .fpb import HardwareBreakpoint from ..core.target import Target from .component import CoreSightComponent import logging # Need a local copy to prevent circular import. # Debug Exception and Monitor Control Register DEMCR = 0xE000EDFC # DWTENA in armv6 architecture reference manual DEMCR_TRCENA = (1 << 24) DEMCR_VC_HARDERR = (1 << 10) DEMCR_VC_BUSERR = (1 << 8) DEMCR_VC_CORERESET = (1 << 0) class Watchpoint(HardwareBreakpoint): def __init__(self, comp_register_addr, provider): super(Watchpoint, self).__init__(comp_register_addr, provider) self.addr = 0 self.size = 0 self.func = 0 class DWT(CoreSightComponent): # DWT (data watchpoint & trace) DWT_CTRL = 0xE0001000 DWT_COMP_BASE = 0xE0001020 DWT_MASK_OFFSET = 4 DWT_FUNCTION_OFFSET = 8 DWT_COMP_BLOCK_SIZE = 0x10 WATCH_TYPE_TO_FUNCT = { Target.WATCHPOINT_READ: 5, Target.WATCHPOINT_WRITE: 6, Target.WATCHPOINT_READ_WRITE: 7 } # Only sizes that are powers of 2 are supported # Breakpoint size = MASK**2 WATCH_SIZE_TO_MASK = dict((2**i, i) for i in range(0,32)) @classmethod def factory(cls, ap, cmpid, address): dwt = cls(ap, cmpid, address) assert ap.core ap.core.connect(dwt) return dwt def __init__(self, ap, cmpid=None, addr=None): super(DWT, self).__init__(ap, cmpid, addr) assert self.address == DWT.DWT_CTRL, "Unexpected DWT base address 0x%08x" % self.address self.watchpoints = [] self.watchpoint_used = 0 self.dwt_configured = False ## @brief Inits the DWT. # # Reads the number of hardware watchpoints available on the core and makes sure that they # are all disabled and ready for future use. def init(self): demcr = self.ap.read_memory(DEMCR) demcr = demcr | DEMCR_TRCENA self.ap.write_memory(DEMCR, demcr) dwt_ctrl = self.ap.read_memory(DWT.DWT_CTRL) watchpoint_count = (dwt_ctrl >> 28) & 0xF logging.info("%d hardware watchpoints", watchpoint_count) for i in range(watchpoint_count): self.watchpoints.append(Watchpoint(DWT.DWT_COMP_BASE + DWT.DWT_COMP_BLOCK_SIZE*i, self)) self.ap.write_memory(DWT.DWT_COMP_BASE + DWT.DWT_COMP_BLOCK_SIZE*i + DWT.DWT_FUNCTION_OFFSET, 0) self.dwt_configured = True def find_watchpoint(self, addr, size, type): for watch in self.watchpoints: if watch.addr == addr and watch.size == size and watch.func == DWT.WATCH_TYPE_TO_FUNCT[type]: return watch return None ## @brief Set a hardware watchpoint. def set_watchpoint(self, addr, size, type): if self.dwt_configured is False: self.init() watch = self.find_watchpoint(addr, size, type) if watch != None: return True if type not in DWT.WATCH_TYPE_TO_FUNCT: logging.error("Invalid watchpoint type %i", type) return False for watch in self.watchpoints: if watch.func == 0: watch.addr = addr watch.func = DWT.WATCH_TYPE_TO_FUNCT[type] watch.size = size if size not in DWT.WATCH_SIZE_TO_MASK: logging.error('Watchpoint of size %d not supported by device', size) return False mask = DWT.WATCH_SIZE_TO_MASK[size] self.ap.write_memory(watch.comp_register_addr + DWT.DWT_MASK_OFFSET, mask) if self.ap.read_memory(watch.comp_register_addr + DWT.DWT_MASK_OFFSET) != mask: logging.error('Watchpoint of size %d not supported by device', size) return False self.ap.write_memory(watch.comp_register_addr, addr) self.ap.write_memory(watch.comp_register_addr + DWT.DWT_FUNCTION_OFFSET, watch.func) self.watchpoint_used += 1 return True logging.error('No more available watchpoint!!, dropped watch at 0x%X', addr) return False ## @brief Remove a hardware watchpoint. def remove_watchpoint(self, addr, size, type): watch = self.find_watchpoint(addr, size, type) if watch is None: return watch.func = 0 self.ap.write_memory(watch.comp_register_addr + DWT.DWT_FUNCTION_OFFSET, 0) self.watchpoint_used -= 1 pyocd-0.13.1/pyocd/coresight/ap.py0000644000175000017500000004012113373511253016672 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 ..core import (exceptions, memory_interface) from .rom_table import ROMTable from ..utility import conversion import logging # Set to True to enable logging of all DP and AP accesses. LOG_DAP = False # Common AP register addresses AP_BASE = 0xF8 AP_IDR = 0xFC # MEM-AP register addresses MEM_AP_CSW = 0x00 MEM_AP_TAR = 0x04 MEM_AP_DRW = 0x0C A32 = 0x0c APSEL_SHIFT = 24 APSEL = 0xff000000 APBANKSEL = 0x000000f0 APREG_MASK = 0x000000fc AP_ROM_TABLE_FORMAT_MASK = 0x2 AP_ROM_TABLE_ENTRY_PRESENT_MASK = 0x1 # AP IDR bitfields: # [31:28] Revision # [27:24] JEP106 continuation (0x4 for ARM) # [23:17] JEP106 vendor ID (0x3B for ARM) # [16:13] Class (0b1000=Mem-AP) # [12:8] Reserved # [7:4] AP Variant (non-zero for JTAG-AP) # [3:0] AP Type AP_IDR_REVISION_MASK = 0xf0000000 AP_IDR_REVISION_SHIFT = 28 AP_IDR_JEP106_MASK = 0x0ffe0000 AP_IDR_JEP106_SHIFT = 17 AP_IDR_CLASS_MASK = 0x0001e000 AP_IDR_CLASS_SHIFT = 13 AP_IDR_VARIANT_MASK = 0x000000f0 AP_IDR_VARIANT_SHIFT = 4 AP_IDR_TYPE_MASK = 0x0000000f AP_JEP106_ARM = 0x23b # AP classes AP_CLASS_NONE = 0x00000 # No class defined AP_CLASS_MEM_AP = 0x8 # MEM-AP # MEM-AP type constants AP_TYPE_AHB = 0x1 AP_TYPE_APB = 0x2 AP_TYPE_AXI = 0x4 AP_TYPE_AHB5 = 0x5 # AP Control and Status Word definitions CSW_SIZE = 0x00000007 CSW_SIZE8 = 0x00000000 CSW_SIZE16 = 0x00000001 CSW_SIZE32 = 0x00000002 CSW_ADDRINC = 0x00000030 CSW_NADDRINC = 0x00000000 CSW_SADDRINC = 0x00000010 CSW_PADDRINC = 0x00000020 CSW_DBGSTAT = 0x00000040 CSW_TINPROG = 0x00000080 CSW_HPROT = 0x02000000 CSW_MSTRTYPE = 0x20000000 CSW_MSTRCORE = 0x00000000 CSW_MSTRDBG = 0x20000000 CSW_RESERVED = 0x01000000 CSW_VALUE = (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC) TRANSFER_SIZE = {8: CSW_SIZE8, 16: CSW_SIZE16, 32: CSW_SIZE32 } # Debug Exception and Monitor Control Register DEMCR = 0xE000EDFC # DWTENA in armv6 architecture reference manual DEMCR_TRCENA = (1 << 24) class AccessPort(object): ## @brief Determine if an AP exists with the given AP number. # @param dp DebugPort instance. # @param ap_num The AP number (APSEL) to probe. # @return Boolean indicating if a valid AP exists with APSEL=ap_num. @staticmethod def probe(dp, ap_num): idr = dp.read_ap((ap_num << APSEL_SHIFT) | AP_IDR) return idr != 0 ## @brief Create a new AP object. # # Determines the type of the AP by examining the IDR value and creates a new # AP object of the appropriate class. See #AP_TYPE_MAP for the mapping of IDR # fields to class. # # @param dp DebugPort instance. # @param ap_num The AP number (APSEL) to probe. # @return An AccessPort subclass instance. # # @exception RuntimeError Raised if there is not a valid AP for the ap_num. @staticmethod def create(dp, ap_num): # Attempt to read the IDR for this APSEL. If we get a zero back then there is # no AP present, so we return None. idr = dp.read_ap((ap_num << APSEL_SHIFT) | AP_IDR) if idr == 0: raise RuntimeError("Invalid APSEL=%d", ap_num) # Extract IDR fields used for lookup. designer = (idr & AP_IDR_JEP106_MASK) >> AP_IDR_JEP106_SHIFT apClass = (idr & AP_IDR_CLASS_MASK) >> AP_IDR_CLASS_SHIFT variant = (idr & AP_IDR_VARIANT_MASK) >> AP_IDR_VARIANT_SHIFT apType = idr & AP_IDR_TYPE_MASK # Get the AccessPort class to instantiate. key = (designer, apClass, variant, apType) klass = AP_TYPE_MAP.get(key, AccessPort) ap = klass(dp, ap_num) ap.init() return ap def __init__(self, dp, ap_num): self.dp = dp self.ap_num = ap_num self.link = dp.link self.idr = 0 self.rom_addr = 0 self.has_rom_table = False self.rom_table = None self.core = None if LOG_DAP: self.logger = self.dp.logger.getChild('ap%d' % ap_num) def init(self): self.idr = self.read_reg(AP_IDR) # Init ROM table self.rom_addr = self.read_reg(AP_BASE) self.has_rom_table = (self.rom_addr != 0xffffffff) and ((self.rom_addr & AP_ROM_TABLE_ENTRY_PRESENT_MASK) != 0) self.rom_addr &= 0xfffffffc # clear format and present bits def init_rom_table(self): if self.has_rom_table: self.rom_table = ROMTable(self) self.rom_table.init() def read_reg(self, addr, now=True): return self.dp.read_ap((self.ap_num << APSEL_SHIFT) | addr, now) def write_reg(self, addr, data): self.dp.write_ap((self.ap_num << APSEL_SHIFT) | addr, data) def reset_did_occur(self): pass class MEM_AP(AccessPort, memory_interface.MemoryInterface): def __init__(self, dp, ap_num): super(MEM_AP, self).__init__(dp, ap_num) ## Cached CSW value. self._csw = -1 # Default to the smallest size supported by all targets. # A size smaller than the supported size will decrease performance # due to the extra address writes, but will not create any # read/write errors. self.auto_increment_page_size = 0x400 # Ask the probe for an accelerated memory interface for this AP. If it provides one, # then bind our memory interface APIs to its methods. Otherwise use our standard # memory interface based on AP register accesses. memoryInterface = self.dp.link.get_memory_interface_for_ap(self.ap_num) if memoryInterface is not None: logging.debug("Using accelerated memory access interface") self.write_memory = memoryInterface.write_memory self.read_memory = memoryInterface.read_memory self.write_memory_block32 = memoryInterface.write_memory_block32 self.read_memory_block32 = memoryInterface.read_memory_block32 else: self.write_memory = self._write_memory self.read_memory = self._read_memory self.write_memory_block32 = self._write_memory_block32 self.read_memory_block32 = self._read_memory_block32 def read_reg(self, addr, now=True): ap_regaddr = addr & APREG_MASK if ap_regaddr == MEM_AP_CSW and self._csw != -1 and now: return self._csw return super(MEM_AP, self).read_reg(addr, now) def write_reg(self, addr, data): ap_regaddr = addr & APREG_MASK # Don't need to write CSW if it's not changing value. if ap_regaddr == MEM_AP_CSW: if data == self._csw: if LOG_DAP: num = self.dp.next_access_number self.logger.info("write_ap:%06d cached (addr=0x%08x) = 0x%08x", num, addr, data) return self._csw = data try: super(MEM_AP, self).write_reg(addr, data) except exceptions.ProbeError: # Invalidate cached CSW on exception. if ap_regaddr == MEM_AP_CSW: self._csw = -1 raise def reset_did_occur(self): # TODO use notifications to invalidate CSW cache. self._csw = -1 ## @brief Write a single memory location. # # By default the transfer size is a word def _write_memory(self, addr, data, transfer_size=32): assert (addr & (transfer_size // 8 - 1)) == 0 num = self.dp.next_access_number if LOG_DAP: self.logger.info("write_mem:%06d (addr=0x%08x, size=%d) = 0x%08x {", num, addr, transfer_size, data) self.write_reg(MEM_AP_CSW, CSW_VALUE | TRANSFER_SIZE[transfer_size]) if transfer_size == 8: data = data << ((addr & 0x03) << 3) elif transfer_size == 16: data = data << ((addr & 0x02) << 3) try: self.write_reg(MEM_AP_TAR, addr) self.write_reg(MEM_AP_DRW, data) except exceptions.TransferFaultError as error: # Annotate error with target address. self._handle_error(error, num) error.fault_address = addr error.fault_length = transfer_size // 8 raise except exceptions.Error as error: self._handle_error(error, num) raise if LOG_DAP: self.logger.info("write_mem:%06d }", num) ## @brief Read a memory location. # # By default, a word will be read. def _read_memory(self, addr, transfer_size=32, now=True): assert (addr & (transfer_size // 8 - 1)) == 0 num = self.dp.next_access_number if LOG_DAP: self.logger.info("read_mem:%06d (addr=0x%08x, size=%d) {", num, addr, transfer_size) res = None try: self.write_reg(MEM_AP_CSW, CSW_VALUE | TRANSFER_SIZE[transfer_size]) self.write_reg(MEM_AP_TAR, addr) result_cb = self.read_reg(MEM_AP_DRW, now=False) except exceptions.TransferFaultError as error: # Annotate error with target address. self._handle_error(error, num) error.fault_address = addr error.fault_length = transfer_size // 8 raise except exceptions.Error as error: self._handle_error(error, num) raise def read_mem_cb(): try: res = result_cb() if transfer_size == 8: res = (res >> ((addr & 0x03) << 3) & 0xff) elif transfer_size == 16: res = (res >> ((addr & 0x02) << 3) & 0xffff) if LOG_DAP: self.logger.info("read_mem:%06d %s(addr=0x%08x, size=%d) -> 0x%08x }", num, "" if now else "...", addr, transfer_size, res) except exceptions.TransferFaultError as error: # Annotate error with target address. self._handle_error(error, num) error.fault_address = addr error.fault_length = transfer_size // 8 raise except exceptions.Error as error: self._handle_error(error, num) raise return res if now: result = read_mem_cb() return result else: return read_mem_cb ## @brief Write a single transaction's worth of aligned words. # # The transaction must not cross the MEM-AP's auto-increment boundary. def _write_block32(self, addr, data): assert (addr & 0x3) == 0 num = self.dp.next_access_number if LOG_DAP: self.logger.info("_write_block32:%06d (addr=0x%08x, size=%d) {", num, addr, len(data)) # put address in TAR self.write_reg(MEM_AP_CSW, CSW_VALUE | CSW_SIZE32) self.write_reg(MEM_AP_TAR, addr) try: self.link.write_ap_multiple(MEM_AP_DRW, data) except exceptions.TransferFaultError as error: # Annotate error with target address. self._handle_error(error, num) error.fault_address = addr error.fault_length = len(data) * 4 raise except exceptions.Error as error: self._handle_error(error, num) raise if LOG_DAP: self.logger.info("_write_block32:%06d }", num) ## @brief Read a single transaction's worth of aligned words. # # The transaction must not cross the MEM-AP's auto-increment boundary. def _read_block32(self, addr, size): assert (addr & 0x3) == 0 num = self.dp.next_access_number if LOG_DAP: self.logger.info("_read_block32:%06d (addr=0x%08x, size=%d) {", num, addr, size) # put address in TAR self.write_reg(MEM_AP_CSW, CSW_VALUE | CSW_SIZE32) self.write_reg(MEM_AP_TAR, addr) try: resp = self.link.read_ap_multiple(MEM_AP_DRW, size) except exceptions.TransferFaultError as error: # Annotate error with target address. self._handle_error(error, num) error.fault_address = addr error.fault_length = size * 4 raise except exceptions.Error as error: self._handle_error(error, num) raise if LOG_DAP: self.logger.info("_read_block32:%06d }", num) return resp ## @brief Write a block of aligned words in memory. def _write_memory_block32(self, addr, data): assert (addr & 0x3) == 0 size = len(data) while size > 0: n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1)) if size*4 < n: n = (size*4) & 0xfffffffc self._write_block32(addr, data[:n//4]) data = data[n//4:] size -= n//4 addr += n return ## @brief Read a block of aligned words in memory. # # @return An array of word values def _read_memory_block32(self, addr, size): assert (addr & 0x3) == 0 resp = [] while size > 0: n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1)) if size*4 < n: n = (size*4) & 0xfffffffc resp += self._read_block32(addr, n//4) size -= n//4 addr += n return resp def _handle_error(self, error, num): self.dp._handle_error(error, num) self._csw = -1 class AHB_AP(MEM_AP): def init_rom_table(self): # Turn on DEMCR.TRCENA before reading the ROM table. Some ROM table entries will # come back as garbage if TRCENA is not set. try: demcr = self.read32(DEMCR) self.write32(DEMCR, demcr | DEMCR_TRCENA) self.dp.flush() except exceptions.TransferError: # Ignore exception and read whatever we can of the ROM table. pass # Invoke superclass. super(AHB_AP, self).init_rom_table() ## @brief AHB-AP with a 4k auto increment wrap size. # # The only known AHB-AP with a 4k wrap is the one documented in the CM3 and CM4 TRMs. # It has an IDR of 0x24770011, which decodes to AHB-AP, variant 1, version 2. class AHB_AP_4k_Wrap(AHB_AP): def __init__(self, dp, ap_num): super(AHB_AP_4k_Wrap, self).__init__(dp, ap_num) # Set a 4 kB auto increment wrap size. self.auto_increment_page_size = 0x1000 ## Map from AP IDR fields to AccessPort subclass. # # The dict key is a 4-tuple of (JEP106 code, AP class, variant, type). # # Known AP IDRs: # 0x24770011 AHB-AP with 0x1000 wrap # Used on m4 & m3 - Documented in arm_cortexm4_processor_trm_100166_0001_00_en.pdf # and arm_cortexm3_processor_trm_100165_0201_00_en.pdf # 0x34770001 AHB-AP Documented in DDI0314H_coresight_components_trm.pdf # 0x44770001 AHB-AP Used on m1 - Documented in DDI0413D_cortexm1_r1p0_trm.pdf # 0x04770031 AHB-AP Used on m0+? at least on KL25Z, KL46, LPC812 # 0x04770021 AHB-AP Used on m0? used on nrf51, lpc11u24 # 0x64770001 AHB-AP Used on m7, documented in DDI0480G_coresight_soc_trm.pdf # 0x74770001 AHB-AP Used on m0+ on KL28Z # 0x84770001 AHB-AP Used on K32W042 # 0x14770005 AHB5-AP Used on M33. Note that M33 r0p0 incorrect fails to report this IDR. # 0x54770002 APB-AP used on M33. AP_TYPE_MAP = { (AP_JEP106_ARM, AP_CLASS_MEM_AP, 0, AP_TYPE_AHB) : AHB_AP, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 1, AP_TYPE_AHB) : AHB_AP_4k_Wrap, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 2, AP_TYPE_AHB) : AHB_AP, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 3, AP_TYPE_AHB) : AHB_AP, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 0, AP_TYPE_APB) : MEM_AP, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 0, AP_TYPE_AXI) : MEM_AP, (AP_JEP106_ARM, AP_CLASS_MEM_AP, 0, AP_TYPE_AHB5) : AHB_AP, } pyocd-0.13.1/pyocd/coresight/__init__.py0000644000175000017500000000113513373511253020033 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2017 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. """ pyocd-0.13.1/pyocd/coresight/cortex_m.py0000644000175000017500000010723213373511253020121 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..core.target import Target from ..core import exceptions from ..utility import conversion from ..utility.notification import Notification from .component import CoreSightComponent from .fpb import FPB from .dwt import DWT from ..debug.breakpoints.manager import BreakpointManager from ..debug.breakpoints.software import SoftwareBreakpointProvider import logging from time import (time, sleep) from xml.etree.ElementTree import (Element, SubElement, tostring) # pylint: disable=invalid_name # CPUID PARTNO values ARM_CortexM0 = 0xC20 ARM_CortexM1 = 0xC21 ARM_CortexM3 = 0xC23 ARM_CortexM4 = 0xC24 ARM_CortexM0p = 0xC60 # pylint: enable=invalid_name # User-friendly names for core types. CORE_TYPE_NAME = { ARM_CortexM0 : "Cortex-M0", ARM_CortexM1 : "Cortex-M1", ARM_CortexM3 : "Cortex-M3", ARM_CortexM4 : "Cortex-M4", ARM_CortexM0p : "Cortex-M0+" } # Map from register name to DCRSR register index. # # The CONTROL, FAULTMASK, BASEPRI, and PRIMASK registers are special in that they share the # same DCRSR register index and are returned as a single value. In this dict, these registers # have negative values to signal to the register read/write functions that special handling # is necessary. The values are the byte number containing the register value, plus 1 and then # negated. So -1 means a mask of 0xff, -2 is 0xff00, and so on. The actual DCRSR register index # for these combined registers has the key of 'cfbp'. # # XPSR is always read in its entirety via the debug interface, but we also provide # aliases for the submasks APSR, IPSR and EPSR. These are encoded as 0x10000 plus 3 lower bits # indicating which parts of the PSR we're interested in - encoded the same way as MRS's SYSm. # (Note that 'XPSR' continues to denote the raw 32 bits of the register, as per previous versions, # not the union of the three APSR+IPSR+EPSR masks which don't cover the entire register). CORE_REGISTER = { 'r0': 0, 'r1': 1, 'r2': 2, 'r3': 3, 'r4': 4, 'r5': 5, 'r6': 6, 'r7': 7, 'r8': 8, 'r9': 9, 'r10': 10, 'r11': 11, 'r12': 12, 'sp': 13, 'r13': 13, 'lr': 14, 'r14': 14, 'pc': 15, 'r15': 15, 'xpsr': 16, 'apsr': 0x10000, 'iapsr': 0x10001, 'eapsr': 0x10002, 'ipsr': 0x10005, 'epsr': 0x10006, 'iepsr': 0x10007, 'msp': 17, 'psp': 18, 'cfbp': 20, 'control':-4, 'faultmask':-3, 'basepri':-2, 'primask':-1, 'fpscr': 33, 's0': 0x40, 's1': 0x41, 's2': 0x42, 's3': 0x43, 's4': 0x44, 's5': 0x45, 's6': 0x46, 's7': 0x47, 's8': 0x48, 's9': 0x49, 's10': 0x4a, 's11': 0x4b, 's12': 0x4c, 's13': 0x4d, 's14': 0x4e, 's15': 0x4f, 's16': 0x50, 's17': 0x51, 's18': 0x52, 's19': 0x53, 's20': 0x54, 's21': 0x55, 's22': 0x56, 's23': 0x57, 's24': 0x58, 's25': 0x59, 's26': 0x5a, 's27': 0x5b, 's28': 0x5c, 's29': 0x5d, 's30': 0x5e, 's31': 0x5f, } def register_name_to_index(reg): if isinstance(reg, str): try: reg = CORE_REGISTER[reg.lower()] except KeyError: raise KeyError('cannot find %s core register' % reg) return reg # Returns true for registers holding single-precision float values def is_float_register(index): return 0x40 <= index <= 0x5f def is_fpu_register(index): return index == 33 or is_float_register(index) def is_cfbp_subregister(index): return -4 <= index <= -1 def is_psr_subregister(index): return 0x10000 <= index <= 0x10007 # Generate a PSR mask based on bottom 3 bits of a MRS SYSm value def sysm_to_psr_mask(sysm): mask = 0 if (sysm & 1) != 0: mask |= CortexM.IPSR_MASK if (sysm & 2) != 0: mask |= CortexM.EPSR_MASK if (sysm & 4) == 0: mask |= CortexM.APSR_MASK return mask class CortexM(Target, CoreSightComponent): """ This class has basic functions to access a Cortex M core: - init - read/write memory - read/write core registers - set/remove hardware breakpoints """ # Program Status Register APSR_MASK = 0xF80F0000 EPSR_MASK = 0x0700FC00 IPSR_MASK = 0x000001FF # Debug Fault Status Register DFSR = 0xE000ED30 DFSR_EXTERNAL = (1 << 4) DFSR_VCATCH = (1 << 3) DFSR_DWTTRAP = (1 << 2) DFSR_BKPT = (1 << 1) DFSR_HALTED = (1 << 0) # Debug Exception and Monitor Control Register DEMCR = 0xE000EDFC # DWTENA in armv6 architecture reference manual DEMCR_TRCENA = (1 << 24) DEMCR_VC_HARDERR = (1 << 10) DEMCR_VC_INTERR = (1 << 9) DEMCR_VC_BUSERR = (1 << 8) DEMCR_VC_STATERR = (1 << 7) DEMCR_VC_CHKERR = (1 << 6) DEMCR_VC_NOCPERR = (1 << 5) DEMCR_VC_MMERR = (1 << 4) DEMCR_VC_CORERESET = (1 << 0) # CPUID Register CPUID = 0xE000ED00 # CPUID masks CPUID_IMPLEMENTER_MASK = 0xff000000 CPUID_IMPLEMENTER_POS = 24 CPUID_VARIANT_MASK = 0x00f00000 CPUID_VARIANT_POS = 20 CPUID_ARCHITECTURE_MASK = 0x000f0000 CPUID_ARCHITECTURE_POS = 16 CPUID_PARTNO_MASK = 0x0000fff0 CPUID_PARTNO_POS = 4 CPUID_REVISION_MASK = 0x0000000f CPUID_REVISION_POS = 0 CPUID_IMPLEMENTER_ARM = 0x41 ARMv6M = 0xC ARMv7M = 0xF # Debug Core Register Selector Register DCRSR = 0xE000EDF4 DCRSR_REGWnR = (1 << 16) DCRSR_REGSEL = 0x1F # Debug Halting Control and Status Register DHCSR = 0xE000EDF0 C_DEBUGEN = (1 << 0) C_HALT = (1 << 1) C_STEP = (1 << 2) C_MASKINTS = (1 << 3) C_SNAPSTALL = (1 << 5) S_REGRDY = (1 << 16) S_HALT = (1 << 17) S_SLEEP = (1 << 18) S_LOCKUP = (1 << 19) S_RETIRE_ST = (1 << 24) S_RESET_ST = (1 << 25) # Debug Core Register Data Register DCRDR = 0xE000EDF8 # Coprocessor Access Control Register CPACR = 0xE000ED88 CPACR_CP10_CP11_MASK = (3 << 20) | (3 << 22) NVIC_AIRCR = (0xE000ED0C) NVIC_AIRCR_VECTKEY = (0x5FA << 16) NVIC_AIRCR_VECTRESET = (1 << 0) NVIC_AIRCR_SYSRESETREQ = (1 << 2) DBGKEY = (0xA05F << 16) class RegisterInfo(object): def __init__(self, name, bitsize, reg_type, reg_group): self.name = name self.reg_num = CORE_REGISTER[name] self.gdb_xml_attrib = {} self.gdb_xml_attrib['name'] = str(name) self.gdb_xml_attrib['bitsize'] = str(bitsize) self.gdb_xml_attrib['type'] = str(reg_type) self.gdb_xml_attrib['group'] = str(reg_group) regs_general = [ # Name bitsize type group RegisterInfo('r0', 32, 'int', 'general'), RegisterInfo('r1', 32, 'int', 'general'), RegisterInfo('r2', 32, 'int', 'general'), RegisterInfo('r3', 32, 'int', 'general'), RegisterInfo('r4', 32, 'int', 'general'), RegisterInfo('r5', 32, 'int', 'general'), RegisterInfo('r6', 32, 'int', 'general'), RegisterInfo('r7', 32, 'int', 'general'), RegisterInfo('r8', 32, 'int', 'general'), RegisterInfo('r9', 32, 'int', 'general'), RegisterInfo('r10', 32, 'int', 'general'), RegisterInfo('r11', 32, 'int', 'general'), RegisterInfo('r12', 32, 'int', 'general'), RegisterInfo('sp', 32, 'data_ptr', 'general'), RegisterInfo('lr', 32, 'int', 'general'), RegisterInfo('pc', 32, 'code_ptr', 'general'), RegisterInfo('xpsr', 32, 'int', 'general'), RegisterInfo('msp', 32, 'int', 'general'), RegisterInfo('psp', 32, 'int', 'general'), RegisterInfo('primask', 32, 'int', 'general'), RegisterInfo('control', 32, 'int', 'general'), ] regs_system_armv7_only = [ # Name bitsize type group RegisterInfo('basepri', 32, 'int', 'general'), RegisterInfo('faultmask', 32, 'int', 'general'), ] regs_float = [ # Name bitsize type group RegisterInfo('fpscr', 32, 'int', 'float'), RegisterInfo('s0' , 32, 'float', 'float'), RegisterInfo('s1' , 32, 'float', 'float'), RegisterInfo('s2' , 32, 'float', 'float'), RegisterInfo('s3' , 32, 'float', 'float'), RegisterInfo('s4' , 32, 'float', 'float'), RegisterInfo('s5' , 32, 'float', 'float'), RegisterInfo('s6' , 32, 'float', 'float'), RegisterInfo('s7' , 32, 'float', 'float'), RegisterInfo('s8' , 32, 'float', 'float'), RegisterInfo('s9' , 32, 'float', 'float'), RegisterInfo('s10', 32, 'float', 'float'), RegisterInfo('s11', 32, 'float', 'float'), RegisterInfo('s12', 32, 'float', 'float'), RegisterInfo('s13', 32, 'float', 'float'), RegisterInfo('s14', 32, 'float', 'float'), RegisterInfo('s15', 32, 'float', 'float'), RegisterInfo('s16', 32, 'float', 'float'), RegisterInfo('s17', 32, 'float', 'float'), RegisterInfo('s18', 32, 'float', 'float'), RegisterInfo('s19', 32, 'float', 'float'), RegisterInfo('s20', 32, 'float', 'float'), RegisterInfo('s21', 32, 'float', 'float'), RegisterInfo('s22', 32, 'float', 'float'), RegisterInfo('s23', 32, 'float', 'float'), RegisterInfo('s24', 32, 'float', 'float'), RegisterInfo('s25', 32, 'float', 'float'), RegisterInfo('s26', 32, 'float', 'float'), RegisterInfo('s27', 32, 'float', 'float'), RegisterInfo('s28', 32, 'float', 'float'), RegisterInfo('s29', 32, 'float', 'float'), RegisterInfo('s30', 32, 'float', 'float'), RegisterInfo('s31', 32, 'float', 'float'), ] @classmethod def factory(cls, ap, cmpid, address): # Create a new core instance. root = ap.dp.target core = cls(root, ap, root.memory_map, root._new_core_num, cmpid, address) # Associate this core with the AP. if ap.core is not None: raise RuntimeError("AP#%d has multiple cores associated with it" % ap.ap_num) ap.core = core # Add the new core to the root target. root.add_core(core) root._new_core_num += 1 return core def __init__(self, rootTarget, ap, memoryMap=None, core_num=0, cmpid=None, address=None): Target.__init__(self, rootTarget.session, memoryMap) CoreSightComponent.__init__(self, ap, cmpid, address) self.root_target = rootTarget self.arch = 0 self.core_type = 0 self.has_fpu = False self.core_number = core_num self._run_token = 0 self._target_context = None self._elf = None self.target_xml = None # Set up breakpoints manager. self.sw_bp = SoftwareBreakpointProvider(self) self.bp_manager = BreakpointManager(self) self.bp_manager.add_provider(self.sw_bp, Target.BREAKPOINT_SW) ## @brief Connect related CoreSight components. def connect(self, cmp): if isinstance(cmp, FPB): self.fpb = cmp self.bp_manager.add_provider(cmp, Target.BREAKPOINT_HW) elif isinstance(cmp, DWT): self.dwt = cmp @property def elf(self): return self._elf @elf.setter def elf(self, elffile): self._elf = elffile def init(self): """ Cortex M initialization. The bus must be accessible when this method is called. """ if self.halt_on_connect: self.halt() self._read_core_type() self._check_for_fpu() self.build_target_xml() self.sw_bp.init() def disconnect(self, resume=True): # Remove breakpoints. self.bp_manager.remove_all_breakpoints() # Disable other debug blocks. self.write32(CortexM.DEMCR, 0) # Disable core debug. if resume: self.resume() self.write32(CortexM.DHCSR, CortexM.DBGKEY | 0x0000) def build_target_xml(self): # Build register_list and targetXML self.register_list = [] xml_root = Element('target') xml_regs_general = SubElement(xml_root, "feature", name="org.gnu.gdb.arm.m-profile") for reg in self.regs_general: self.register_list.append(reg) SubElement(xml_regs_general, 'reg', **reg.gdb_xml_attrib) # Check if target has ARMv7 registers if self.core_type in (ARM_CortexM3, ARM_CortexM4): for reg in self.regs_system_armv7_only: self.register_list.append(reg) SubElement(xml_regs_general, 'reg', **reg.gdb_xml_attrib) # Check if target has FPU registers if self.has_fpu: #xml_regs_fpu = SubElement(xml_root, "feature", name="org.gnu.gdb.arm.vfp") for reg in self.regs_float: self.register_list.append(reg) SubElement(xml_regs_general, 'reg', **reg.gdb_xml_attrib) self.target_xml = b'' + tostring(xml_root) ## @brief Read the CPUID register and determine core type. def _read_core_type(self): # Read CPUID register cpuid = self.read32(CortexM.CPUID) implementer = (cpuid & CortexM.CPUID_IMPLEMENTER_MASK) >> CortexM.CPUID_IMPLEMENTER_POS if implementer != CortexM.CPUID_IMPLEMENTER_ARM: logging.warning("CPU implementer is not ARM!") self.arch = (cpuid & CortexM.CPUID_ARCHITECTURE_MASK) >> CortexM.CPUID_ARCHITECTURE_POS self.core_type = (cpuid & CortexM.CPUID_PARTNO_MASK) >> CortexM.CPUID_PARTNO_POS self.cpu_revision = (cpuid & CortexM.CPUID_VARIANT_MASK) >> CortexM.CPUID_VARIANT_POS self.cpu_patch = (cpuid & CortexM.CPUID_REVISION_MASK) >> CortexM.CPUID_REVISION_POS if self.core_type in CORE_TYPE_NAME: logging.info("CPU core is %s r%dp%d", CORE_TYPE_NAME[self.core_type], self.cpu_revision, self.cpu_patch) else: logging.info("CPU core is unknown") ## @brief Determine if a Cortex-M4 has an FPU. # # The core type must have been identified prior to calling this function. def _check_for_fpu(self): if self.core_type != ARM_CortexM4: self.has_fpu = False return originalCpacr = self.read32(CortexM.CPACR) cpacr = originalCpacr | CortexM.CPACR_CP10_CP11_MASK self.write32(CortexM.CPACR, cpacr) cpacr = self.read32(CortexM.CPACR) self.has_fpu = (cpacr & CortexM.CPACR_CP10_CP11_MASK) != 0 # Restore previous value. self.write32(CortexM.CPACR, originalCpacr) if self.has_fpu: logging.info("FPU present") def write_memory(self, addr, value, transfer_size=32): """ write a memory location. By default the transfer size is a word """ self.ap.write_memory(addr, value, transfer_size) def read_memory(self, addr, transfer_size=32, now=True): """ read a memory location. By default, a word will be read """ result = self.ap.read_memory(addr, transfer_size, now) # Read callback returned for async reads. def read_memory_cb(): return self.bp_manager.filter_memory(addr, transfer_size, result()) if now: return self.bp_manager.filter_memory(addr, transfer_size, result) else: return read_memory_cb def read_memory_block8(self, addr, size): """ read a block of unaligned bytes in memory. Returns an array of byte values """ data = self.ap.read_memory_block8(addr, size) return self.bp_manager.filter_memory_unaligned_8(addr, size, data) def write_memory_block8(self, addr, data): """ write a block of unaligned bytes in memory. """ self.ap.write_memory_block8(addr, data) def write_memory_block32(self, addr, data): """ write a block of aligned words in memory. """ self.ap.write_memory_block32(addr, data) def read_memory_block32(self, addr, size): """ read a block of aligned words in memory. Returns an array of word values """ data = self.ap.read_memory_block32(addr, size) return self.bp_manager.filter_memory_aligned_32(addr, size, data) def halt(self): """ halt the core """ self.notify(Notification(event=Target.EVENT_PRE_HALT, source=self, data=Target.HALT_REASON_USER)) self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN | CortexM.C_HALT) self.flush() self.notify(Notification(event=Target.EVENT_POST_HALT, source=self, data=Target.HALT_REASON_USER)) def step(self, disable_interrupts=True): """ perform an instruction level step. This function preserves the previous interrupt mask state """ # Was 'if self.get_state() != TARGET_HALTED:' # but now value of dhcsr is saved dhcsr = self.read_memory(CortexM.DHCSR) if not (dhcsr & (CortexM.C_STEP | CortexM.C_HALT)): logging.error('cannot step: target not halted') return self.notify(Notification(event=Target.EVENT_PRE_RUN, source=self, data=Target.RUN_TYPE_STEP)) self.clear_debug_cause_bits() # Save previous interrupt mask state interrupts_masked = (CortexM.C_MASKINTS & dhcsr) != 0 # Mask interrupts - C_HALT must be set when changing to C_MASKINTS if not interrupts_masked and disable_interrupts: self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN | CortexM.C_HALT | CortexM.C_MASKINTS) # Single step using current C_MASKINTS setting if disable_interrupts or interrupts_masked: self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN | CortexM.C_MASKINTS | CortexM.C_STEP) else: self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN | CortexM.C_STEP) # Wait for halt to auto set (This should be done before the first read) while not self.read_memory(CortexM.DHCSR) & CortexM.C_HALT: pass # Restore interrupt mask state if not interrupts_masked and disable_interrupts: # Unmask interrupts - C_HALT must be set when changing to C_MASKINTS self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN | CortexM.C_HALT) self.flush() self._run_token += 1 self.notify(Notification(event=Target.EVENT_POST_RUN, source=self, data=Target.RUN_TYPE_STEP)) def clear_debug_cause_bits(self): self.write_memory(CortexM.DFSR, CortexM.DFSR_DWTTRAP | CortexM.DFSR_BKPT | CortexM.DFSR_HALTED) def reset(self, software_reset=None): """ reset a core. After a call to this function, the core is running """ self.notify(Notification(event=Target.EVENT_PRE_RESET, source=self)) if software_reset == None: # Default to software reset if nothing is specified software_reset = True self._run_token += 1 if software_reset: # Perform the reset. try: self.write_memory(CortexM.NVIC_AIRCR, CortexM.NVIC_AIRCR_VECTKEY | CortexM.NVIC_AIRCR_SYSRESETREQ) # Without a flush a transfer error can occur self.flush() except exceptions.TransferError: self.flush() else: self.session.probe.reset() # Now wait for the system to come out of reset. Keep reading the DHCSR until # we get a good response with S_RESET_ST cleared, or we time out. startTime = time() while time() - startTime < 2.0: try: dhcsr = self.read32(CortexM.DHCSR) if (dhcsr & CortexM.S_RESET_ST) == 0: break except exceptions.TransferError: self.flush() sleep(0.01) self.notify(Notification(event=Target.EVENT_POST_RESET, source=self)) def reset_stop_on_reset(self, software_reset=None): """ perform a reset and stop the core on the reset handler """ logging.debug("reset stop on Reset") # halt the target self.halt() # Save CortexM.DEMCR demcr = self.read_memory(CortexM.DEMCR) # enable the vector catch self.write_memory(CortexM.DEMCR, demcr | CortexM.DEMCR_VC_CORERESET) self.reset(software_reset) # wait until the unit resets while (self.is_running()): pass # restore vector catch setting self.write_memory(CortexM.DEMCR, demcr) def set_target_state(self, state): if state == "PROGRAM": self.reset_stop_on_reset(True) # Write the thumb bit in case the reset handler # points to an ARM address self.write_core_register('xpsr', 0x1000000) def get_state(self): dhcsr = self.read_memory(CortexM.DHCSR) if dhcsr & CortexM.S_RESET_ST: # Reset is a special case because the bit is sticky and really means # "core was reset since last read of DHCSR". We have to re-read the # DHCSR, check if S_RESET_ST is still set and make sure no instructions # were executed by checking S_RETIRE_ST. newDhcsr = self.read_memory(CortexM.DHCSR) if (newDhcsr & CortexM.S_RESET_ST) and not (newDhcsr & CortexM.S_RETIRE_ST): return Target.TARGET_RESET if dhcsr & CortexM.S_LOCKUP: return Target.TARGET_LOCKUP elif dhcsr & CortexM.S_SLEEP: return Target.TARGET_SLEEPING elif dhcsr & CortexM.S_HALT: return Target.TARGET_HALTED else: return Target.TARGET_RUNNING @property def run_token(self): return self._run_token def is_running(self): return self.get_state() == Target.TARGET_RUNNING def is_halted(self): return self.get_state() == Target.TARGET_HALTED def resume(self): """ resume the execution """ if self.get_state() != Target.TARGET_HALTED: logging.debug('cannot resume: target not halted') return self.notify(Notification(event=Target.EVENT_PRE_RUN, source=self, data=Target.RUN_TYPE_RESUME)) self._run_token += 1 self.clear_debug_cause_bits() self.write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN) self.flush() self.notify(Notification(event=Target.EVENT_POST_RUN, source=self, data=Target.RUN_TYPE_RESUME)) def find_breakpoint(self, addr): return self.bp_manager.find_breakpoint(addr) def read_core_register(self, reg): """ read CPU register Unpack floating point register values """ regIndex = register_name_to_index(reg) regValue = self.read_core_register(regIndex) # Convert int to float. if is_float_register(regIndex): regValue = conversion.u32_to_float32(regValue) return regValue def read_core_register(self, reg): """ read a core register (r0 .. r16). If reg is a string, find the number associated to this register in the lookup table CORE_REGISTER """ vals = self.read_core_registers_raw([reg]) return vals[0] def read_core_registers_raw(self, reg_list): """ Read one or more core registers Read core registers in reg_list and return a list of values. If any register in reg_list is a string, find the number associated to this register in the lookup table CORE_REGISTER. """ # convert to index only reg_list = [register_name_to_index(reg) for reg in reg_list] # Sanity check register values for reg in reg_list: if reg not in CORE_REGISTER.values(): raise ValueError("unknown reg: %d" % reg) elif is_fpu_register(reg) and (not self.has_fpu): raise ValueError("attempt to read FPU register without FPU") # Begin all reads and writes dhcsr_cb_list = [] reg_cb_list = [] for reg in reg_list: if is_cfbp_subregister(reg): reg = CORE_REGISTER['cfbp'] if is_psr_subregister(reg): reg = CORE_REGISTER['xpsr'] # write id in DCRSR self.write_memory(CortexM.DCRSR, reg) # Technically, we need to poll S_REGRDY in DHCSR here before reading DCRDR. But # we're running so slow compared to the target that it's not necessary. # Read it and assert that S_REGRDY is set dhcsr_cb = self.read_memory(CortexM.DHCSR, now=False) reg_cb = self.read_memory(CortexM.DCRDR, now=False) dhcsr_cb_list.append(dhcsr_cb) reg_cb_list.append(reg_cb) # Read all results reg_vals = [] for reg, reg_cb, dhcsr_cb in zip(reg_list, reg_cb_list, dhcsr_cb_list): dhcsr_val = dhcsr_cb() assert dhcsr_val & CortexM.S_REGRDY val = reg_cb() # Special handling for registers that are combined into a single DCRSR number. if is_cfbp_subregister(reg): val = (val >> ((-reg - 1) * 8)) & 0xff if is_psr_subregister(reg): val &= sysm_to_psr_mask(reg) reg_vals.append(val) return reg_vals def write_core_register(self, reg, data): """ write a CPU register. Will need to pack floating point register values before writing. """ regIndex = register_name_to_index(reg) # Convert float to int. if is_float_register(regIndex): data = conversion.float32_to_u32(data) self.write_core_register(regIndex, data) def write_core_register(self, reg, data): """ write a core register (r0 .. r16) If reg is a string, find the number associated to this register in the lookup table CORE_REGISTER """ self.write_core_registers_raw([reg], [data]) def write_core_registers_raw(self, reg_list, data_list): """ Write one or more core registers Write core registers in reg_list with the associated value in data_list. If any register in reg_list is a string, find the number associated to this register in the lookup table CORE_REGISTER. """ assert len(reg_list) == len(data_list) # convert to index only reg_list = [register_name_to_index(reg) for reg in reg_list] # Sanity check register values for reg in reg_list: if reg not in CORE_REGISTER.values(): raise ValueError("unknown reg: %d" % reg) elif is_fpu_register(reg) and (not self.has_fpu): raise ValueError("attempt to write FPU register without FPU") # Read special register if it is present in the list for reg in reg_list: if is_cfbp_subregister(reg): cfbpValue = self.read_core_register(CORE_REGISTER['cfbp']) break if is_psr_subregister(reg): xpsrValue = self.read_core_register(CORE_REGISTER['xpsr']) break # Write out registers dhcsr_cb_list = [] for reg, data in zip(reg_list, data_list): if is_cfbp_subregister(reg): # Mask in the new special register value so we don't modify the other register # values that share the same DCRSR number. shift = (-reg - 1) * 8 mask = 0xffffffff ^ (0xff << shift) data = (cfbpValue & mask) | ((data & 0xff) << shift) cfbpValue = data # update special register for other writes that might be in the list reg = CORE_REGISTER['cfbp'] if is_psr_subregister(reg): mask = sysm_to_psr_mask(reg) data = (xpsrValue & (0xffffffff ^ mask)) | (data & mask) xpsrValue = data reg = CORE_REGISTER['xpsr'] # write DCRDR self.write_memory(CortexM.DCRDR, data) # write id in DCRSR and flag to start write transfer self.write_memory(CortexM.DCRSR, reg | CortexM.DCRSR_REGWnR) # Technically, we need to poll S_REGRDY in DHCSR here to ensure the # register write has completed. # Read it and assert that S_REGRDY is set dhcsr_cb = self.read_memory(CortexM.DHCSR, now=False) dhcsr_cb_list.append(dhcsr_cb) # Make sure S_REGRDY was set for all register # writes for dhcsr_cb in dhcsr_cb_list: dhcsr_val = dhcsr_cb() assert dhcsr_val & CortexM.S_REGRDY ## @brief Set a hardware or software breakpoint at a specific location in memory. # # @retval True Breakpoint was set. # @retval False Breakpoint could not be set. def set_breakpoint(self, addr, type=Target.BREAKPOINT_AUTO): return self.bp_manager.set_breakpoint(addr, type) ## @brief Remove a breakpoint at a specific location. def remove_breakpoint(self, addr): self.bp_manager.remove_breakpoint(addr) def get_breakpoint_type(self, addr): return self.bp_manager.get_breakpoint_type(addr) @property def available_breakpoint_count(self): return self.fpb.available_breakpoints() def find_watchpoint(self, addr, size, type): return self.dwt.find_watchpoint(addr, size, type) def set_watchpoint(self, addr, size, type): """ set a hardware watchpoint """ return self.dwt.set_watchpoint(addr, size, type) def remove_watchpoint(self, addr, size, type): """ remove a hardware watchpoint """ return self.dwt.remove_watchpoint(addr, size, type) @staticmethod def _map_to_vector_catch_mask(mask): result = 0 if mask & Target.CATCH_HARD_FAULT: result |= CortexM.DEMCR_VC_HARDERR if mask & Target.CATCH_BUS_FAULT: result |= CortexM.DEMCR_VC_BUSERR if mask & Target.CATCH_MEM_FAULT: result |= CortexM.DEMCR_VC_MMERR if mask & Target.CATCH_INTERRUPT_ERR: result |= CortexM.DEMCR_VC_INTERR if mask & Target.CATCH_STATE_ERR: result |= CortexM.DEMCR_VC_STATERR if mask & Target.CATCH_CHECK_ERR: result |= CortexM.DEMCR_VC_CHKERR if mask & Target.CATCH_COPROCESSOR_ERR: result |= CortexM.DEMCR_VC_NOCPERR if mask & Target.CATCH_CORE_RESET: result |= CortexM.DEMCR_VC_CORERESET return result @staticmethod def _map_from_vector_catch_mask(mask): result = 0 if mask & CortexM.DEMCR_VC_HARDERR: result |= Target.CATCH_HARD_FAULT if mask & CortexM.DEMCR_VC_BUSERR: result |= Target.CATCH_BUS_FAULT if mask & CortexM.DEMCR_VC_MMERR: result |= Target.CATCH_MEM_FAULT if mask & CortexM.DEMCR_VC_INTERR: result |= Target.CATCH_INTERRUPT_ERR if mask & CortexM.DEMCR_VC_STATERR: result |= Target.CATCH_STATE_ERR if mask & CortexM.DEMCR_VC_CHKERR: result |= Target.CATCH_CHECK_ERR if mask & CortexM.DEMCR_VC_NOCPERR: result |= Target.CATCH_COPROCESSOR_ERR if mask & CortexM.DEMCR_VC_CORERESET: result |= Target.CATCH_CORE_RESET return result def set_vector_catch(self, enableMask): demcr = self.read_memory(CortexM.DEMCR) demcr |= CortexM._map_to_vector_catch_mask(enableMask) demcr &= ~CortexM._map_to_vector_catch_mask(~enableMask) self.write_memory(CortexM.DEMCR, demcr) def get_vector_catch(self): demcr = self.read_memory(CortexM.DEMCR) return CortexM._map_from_vector_catch_mask(demcr) # GDB functions def get_target_xml(self): return self.target_xml def is_debug_trap(self): debugEvents = self.read_memory(CortexM.DFSR) & (CortexM.DFSR_DWTTRAP | CortexM.DFSR_BKPT | CortexM.DFSR_HALTED) return debugEvents != 0 def get_target_context(self, core=None): return self._target_context def set_target_context(self, context): self._target_context = context # Names for built-in Exception numbers found in IPSR CORE_EXCEPTION = [ "Thread", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "SecureFault", "Exception 8", "Exception 9", "Exception 10", "SVCall", "DebugMonitor", "Exception 13", "PendSV", "SysTick", ] def exception_number_to_name(self, exc_num, name_thread=False): if exc_num < len(self.CORE_EXCEPTION): if exc_num == 0 and not name_thread: return None else: return self.CORE_EXCEPTION[num] else: irq_num = exc_num - len(self.CORE_EXCEPTION) name = None if self.root_target.irq_table: name = self.root_target.irq_table.get(irq_num) if name is not None: return "Interrupt[%s]" % name else: return "Interrupt %d" % irq_num pyocd-0.13.1/pyocd/coresight/component.py0000644000175000017500000000250613373511253020301 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 logging log = logging.getLogger("component") ## @brief CoreSight component base class. # # x class CoreSightComponent(object): ## @brief Constructor. # def __init__(self, ap, cmpid=None, addr=None): self._ap = ap self._cmpid = cmpid self._address = addr or (cmpid.address if cmpid else None) @property def ap(self): return self._ap @property def cmpid(self): return self._cmpid @cmpid.setter def cmpid(self, newCmpid): self._cmpid = newCmpid @property def address(self): return self._address @address.setter def address(self, newAddr): self._address = newAddr pyocd-0.13.1/pyocd/coresight/dap.py0000644000175000017500000002421713373511253017046 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 ..core import exceptions from ..probe.debug_probe import DebugProbe from .ap import (MEM_AP_CSW, LOG_DAP, APSEL, APBANKSEL, APREG_MASK, AccessPort) from ..utility.sequencer import CallSequence import logging import logging.handlers import os import os.path import six # DP register addresses. DP_IDCODE = 0x0 # read-only DP_ABORT = 0x0 # write-only DP_CTRL_STAT = 0x4 # read-write DP_SELECT = 0x8 # write-only DP_RDBUFF = 0xC # read-only ABORT_STKERRCLR = 0x00000004 # DP Control / Status Register bit definitions CTRLSTAT_STICKYORUN = 0x00000002 CTRLSTAT_STICKYCMP = 0x00000010 CTRLSTAT_STICKYERR = 0x00000020 DPIDR_MIN_MASK = 0x10000 DPIDR_VERSION_MASK = 0xf000 DPIDR_VERSION_SHIFT = 12 CSYSPWRUPACK = 0x80000000 CDBGPWRUPACK = 0x20000000 CSYSPWRUPREQ = 0x40000000 CDBGPWRUPREQ = 0x10000000 TRNNORMAL = 0x00000000 MASKLANE = 0x00000f00 class DebugPort(object): # DAP log file name. DAP_LOG_FILE = "pyocd_dap.log" def __init__(self, link, target): self.link = link self.target = target self.valid_aps = None self.aps = {} self._access_number = 0 if LOG_DAP: self._setup_logging() @property def next_access_number(self): self._access_number += 1 return self._access_number ## @brief Set up DAP logging. # # A memory handler is created that buffers log records before flushing them to a file # handler that writes to DAP_LOG_FILE. This improves logging performance by writing to the # log file less often. def _setup_logging(self): cwd = os.getcwd() logfile = os.path.join(cwd, self.DAP_LOG_FILE) logging.info("dap logfile: %s", logfile) self.logger = logging.getLogger('dap') self.logger.propagate = False formatter = logging.Formatter('%(relativeCreated)010dms:%(levelname)s:%(name)s:%(message)s') fileHandler = logging.FileHandler(logfile, mode='w+', delay=True) fileHandler.setFormatter(formatter) memHandler = logging.handlers.MemoryHandler(capacity=128, target=fileHandler) self.logger.addHandler(memHandler) self.logger.setLevel(logging.DEBUG) def init(self): # Connect to the target. self.link.connect() self.link.swj_sequence() try: self.read_id_code() except exceptions.TransferError: # If the read of the DP IDCODE fails, retry SWJ sequence. The DP may have been # in a state where it thought the SWJ sequence was an invalid transfer. self.link.swj_sequence() self.read_id_code() self.clear_sticky_err() def read_id_code(self): # Read ID register and get DP version self.dpidr = self.read_reg(DP_IDCODE) self.dp_version = (self.dpidr & DPIDR_VERSION_MASK) >> DPIDR_VERSION_SHIFT self.is_mindp = (self.dpidr & DPIDR_MIN_MASK) != 0 logging.info("DP IDR = 0x%08x", self.dpidr) return self.dpidr def flush(self): try: self.link.flush() except exceptions.ProbeError as error: self._handle_error(error, self.next_access_number) raise def read_reg(self, addr, now=True): return self.read_dp(addr, now) def write_reg(self, addr, data): self.write_dp(addr, data) def power_up_debug(self): # select bank 0 (to access DRW and TAR) self.write_reg(DP_SELECT, 0) self.write_reg(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ) while True: r = self.read_reg(DP_CTRL_STAT) if (r & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK): break self.write_reg(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE) self.write_reg(DP_SELECT, 0) def power_down_debug(self): # select bank 0 (to access DRW and TAR) self.write_reg(DP_SELECT, 0) self.write_reg(DP_CTRL_STAT, 0) def reset(self): for ap in self.aps.values(): ap.reset_did_occur() self.link.reset() def assert_reset(self, asserted): if asserted: for ap in self.aps.values(): ap.reset_did_occur() self.link.assert_reset(asserted) def is_reset_asserted(self): return self.link.is_reset_asserted() def set_clock(self, frequency): self.link.set_clock(frequency) ## @brief Find valid APs. # # Scans for valid APs starting at APSEL=0 and stopping the first time a 0 is returned # when reading the AP's IDR. # # Note that a few MCUs will lock up when accessing invalid APs. Those MCUs will have to # modify the init call sequence to substitute a fixed list of valid APs. In fact, that # is a major reason this method is separated from create_aps(). def find_aps(self): if self.valid_aps is not None: return self.valid_aps = [] ap_num = 0 while True: try: isValid = AccessPort.probe(self, ap_num) if not isValid: return self.valid_aps.append(ap_num) except Exception as e: logging.error("Exception while probing AP#%d: %s", ap_num, repr(e)) break ap_num += 1 ## @brief Init task that returns a call sequence to create APs. # # For each AP in the #valid_aps list, an AccessPort object is created. The new objects # are added to the #aps dict, keyed by their AP number. def create_aps(self): seq = CallSequence() for ap_num in self.valid_aps: seq.append( ('create_ap.{}'.format(ap_num), lambda ap_num=ap_num: self.create_1_ap(ap_num)) ) return seq ## @brief Init task to create a single AP object. def create_1_ap(self, ap_num): try: ap = AccessPort.create(self, ap_num) logging.info("AP#%d IDR = 0x%08x", ap_num, ap.idr) self.aps[ap_num] = ap except Exception as e: logging.error("Exception reading AP#%d IDR: %s", ap_num, repr(e)) ## @brief Init task that generates a call sequence to init all AP ROMs. def init_ap_roms(self): seq = CallSequence() for ap in [x for x in self.aps.values() if x.has_rom_table]: seq.append( ('init_ap.{}'.format(ap.ap_num), ap.init_rom_table) ) return seq def read_dp(self, addr, now=True): num = self.next_access_number try: result_cb = self.link.read_dp(addr, now=False) except exceptions.ProbeError as error: self._handle_error(error, num) raise # Read callback returned for async reads. def read_dp_cb(): try: result = result_cb() if LOG_DAP: self.logger.info("read_dp:%06d %s(addr=0x%08x) -> 0x%08x", num, "" if now else "...", addr.value, result) return result except exceptions.ProbeError as error: self._handle_error(error, num) raise if now: return read_dp_cb() else: if LOG_DAP: self.logger.info("read_dp:%06d (addr=0x%08x) -> ...", num, addr.value) return read_dp_cb def write_dp(self, addr, data): num = self.next_access_number # Write the DP register. try: if LOG_DAP: self.logger.info("write_dp:%06d (addr=0x%08x) = 0x%08x", num, addr.value, data) self.link.write_dp(addr, data) except exceptions.ProbeError as error: self._handle_error(error, num) raise return True def write_ap(self, addr, data): assert type(addr) in (six.integer_types) num = self.next_access_number try: if LOG_DAP: self.logger.info("write_ap:%06d (addr=0x%08x) = 0x%08x", num, addr, data) self.link.write_ap(addr, data) except exceptions.ProbeError as error: self._handle_error(error, num) raise return True def read_ap(self, addr, now=True): assert type(addr) in (six.integer_types) num = self.next_access_number try: result_cb = self.link.read_ap(addr, now=False) except exceptions.ProbeError as error: self._handle_error(error, num) raise # Read callback returned for async reads. def read_ap_cb(): try: result = result_cb() if LOG_DAP: self.logger.info("read_ap:%06d %s(addr=0x%08x) -> 0x%08x", num, "" if now else "...", addr, result) return result except exceptions.ProbeError as error: self._handle_error(error, num) raise if now: return read_ap_cb() else: if LOG_DAP: self.logger.info("read_ap:%06d (addr=0x%08x) -> ...", num, addr) return read_ap_cb def _handle_error(self, error, num): if LOG_DAP: self.logger.info("error:%06d %s", num, error) # Clear sticky error for Fault errors only if isinstance(error, exceptions.TransferFaultError): self.clear_sticky_err() def clear_sticky_err(self): mode = self.link.wire_protocol if mode == DebugProbe.Protocol.SWD: self.write_reg(DP_ABORT, ABORT_STKERRCLR) elif mode == DebugProbe.Protocol.JTAG: self.write_reg(DP_CTRL_STAT, CTRLSTAT_STICKYERR) else: assert False pyocd-0.13.1/pyocd/target/0000755000175000017500000000000013373523011015214 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/target/target_MKV10Z128xxx7.py0000644000175000017500000001551213373511253021167 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8f6f000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9bb, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf89ef000, 0xd1052800, 0x46292300, 0x68e24620, 0xf960f000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4809b510, 0x81c14907, 0x81c14908, 0x08498801, 0x80010049, 0x44484806, 0xf8ecf000, 0xd0002800, 0xbd102001, 0x0000c520, 0x40052000, 0x0000d928, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f8f5, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf96af000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0032800, 0xd801290f, 0xd0012a04, 0x47702004, 0x47702000, 0xd1012800, 0x47702004, 0x1e5bb410, 0x421c460c, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb3, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe32f7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000026a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2000e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd0142800, 0x68c9490c, 0x0e094a0c, 0x447a0049, 0x03095a51, 0x2200d00d, 0x60416002, 0x60812101, 0x61426102, 0x61820289, 0x461060c1, 0x20044770, 0x20644770, 0x00004770, 0x40048040, 0x0000019a, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff22f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff38f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfef0f7ff, 0xd12a2800, 0x686868a9, 0xfd72f7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfef2f7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fed7, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfea2f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeb6f7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00200000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002F9, 'pc_program_page': 0x200002B1, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x00000620, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff800 }; # @brief Flash algorithm for Kinetis KV10Z7 device. class Flash_kv10z7(Flash_Kinetis): def __init__(self, target): super(Flash_kv10z7, self).__init__(target, FLASH_ALGO) class KV10Z7(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff800, length=0x2000) ) def __init__(self, transport): super(KV10Z7, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKV10Z7.svd") pyocd-0.13.1/pyocd/target/target_MK22FN512xxx12.py0000644000175000017500000001344013373511253021205 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x5020f24c, 0x81c84932, 0x1028f64d, 0x460881c8, 0xf0208800, 0x80080001, 0x4448482e, 0xf8dcf000, 0x2001b108, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x4929b510, 0x44484827, 0xf8b8f000, 0xb92c4604, 0x48242100, 0xf0004448, 0x4604f9b5, 0xf837f000, 0xbd104620, 0x4604b570, 0x4448481e, 0x46214b1e, 0xf00068c2, 0x4605f85d, 0x481ab93d, 0x23004448, 0x68c24621, 0xf952f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0xb9674607, 0x22012000, 0x2000e9cd, 0x46224633, 0x90024629, 0x44484809, 0xf990f000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0xf4206840, 0xf5000070, 0x49040070, 0x47706048, 0x40052000, 0x00000004, 0x6b65666b, 0x4001f000, 0x4a0e2070, 0x20807010, 0xbf007010, 0x7800480b, 0x280009c0, 0x4809d0fa, 0xf0017801, 0xb1080020, 0x47702067, 0x0010f001, 0x2068b108, 0xf001e7f9, 0xb1080001, 0xe7f42069, 0xe7f22000, 0x40020000, 0x4df0e92d, 0x460d4604, 0x469a4690, 0xf0004650, 0x4606f899, 0x4630b116, 0x8df0e8bd, 0x46422308, 0x46204629, 0xf874f000, 0xb10e4606, 0xe7f34630, 0x0008eb05, 0x68e01e47, 0xf1f0fbb7, 0x7011fb00, 0x68e0b140, 0xf0f0fbb7, 0x0b01f100, 0xfb0068e0, 0x1e47f00b, 0x480be011, 0x68004478, 0x20096005, 0x71c84909, 0xffacf7ff, 0x69a04606, 0x69a0b108, 0xb1064780, 0x68e0e003, 0x42bd4405, 0xbf00d9eb, 0xe7c94630, 0x00000304, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0xb10e4606, 0xbd704630, 0x2004b90c, 0x2044e7fb, 0x71c84902, 0xff88f7ff, 0x0000e7f5, 0x40020000, 0xb9094601, 0x47702004, 0x6cc0482e, 0x6003f3c0, 0x447b4b2d, 0x0010f833, 0xb90a0302, 0xe7f22064, 0x60082000, 0x2002604a, 0x02806088, 0x482760c8, 0x15807803, 0x61084098, 0x38284824, 0x002bf890, 0x20006148, 0xbf006188, 0x4602e7dd, 0x2004b90a, 0x61914770, 0xe7fb2000, 0x4604b530, 0x2004b90c, 0x1e58bd30, 0xb9104008, 0x40101e58, 0x2065b108, 0x6820e7f6, 0xd8054288, 0x0500e9d4, 0x188d4428, 0xd20142a8, 0xe7eb2066, 0xe7e92000, 0x48104601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0xb90b4603, 0x47702004, 0xd803290f, 0xd0092a04, 0xe7f82004, 0xd8032913, 0xd0032a08, 0xe7f22004, 0xe7f02004, 0xe7ee2000, 0x40048000, 0x00000272, 0x40020028, 0x6b65666b, 0x41f0e92d, 0x46884607, 0x461d4614, 0x2004b914, 0x81f0e8bd, 0x462a2304, 0x46384641, 0xffb2f7ff, 0xb10e4606, 0xe7f34630, 0x480fe019, 0x68004478, 0x8000f8c0, 0x490ccc01, 0x390c4479, 0x60486809, 0x490a2006, 0xf7ff71c8, 0x4606fef5, 0xb10869b8, 0x478069b8, 0xe004b106, 0x0804f108, 0x2d001f2d, 0xbf00d1e3, 0xe7d34630, 0x000001a4, 0x40020000, 0x4dffe92d, 0x4682b082, 0x2308460c, 0x46504621, 0xf7ff9a04, 0x4683ff7f, 0x0f00f1bb, 0x4658d003, 0xe8bdb006, 0xe9da8df0, 0xfbb00101, 0x4260f7f1, 0x40084279, 0x42a54245, 0x443dd100, 0xe0229e04, 0x0804eba5, 0xd90045b0, 0xea4f46b0, 0x900100d8, 0x4478480f, 0x60046800, 0x490e2001, 0x980171c8, 0x72c80a00, 0x72889801, 0x72489805, 0xfeaaf7ff, 0xf1bb4683, 0xd0010f00, 0xe7d14658, 0x0608eba6, 0x443d4444, 0x2e00bf00, 0x2000d1da, 0x0000e7c8, 0x0000010e, 0x40020000, 0x4604b570, 0xb90c460d, 0xbd702004, 0x49032040, 0x460871c8, 0xf7ff7185, 0xe7f6fe89, 0x40020000, 0x4dffe92d, 0x4617460c, 0xe9dd461d, 0xf8ddb80c, 0xb91da038, 0xb0042004, 0x8df0e8bd, 0x463a2304, 0x98004621, 0xff1af7ff, 0xb10e4606, 0xe7f24630, 0x4814e022, 0x68004478, 0x20026004, 0x71c84912, 0xf8804608, 0x490fb00b, 0x39144479, 0x68096828, 0xf7ff6088, 0x4606fe5b, 0xf1b8b15e, 0xd0010f00, 0x4000f8c8, 0x0f00f1ba, 0x2000d002, 0x0000f8ca, 0x1f3fe004, 0x1d241d2d, 0xd1da2f00, 0x4630bf00, 0x0000e7c9, 0x00000074, 0x40020000, 0x00000000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x01000000, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000059, 'pc_erase_sector' : 0x2000007D, 'pc_program_page' : 0x200000AB, 'begin_stack' : 0x20000800, 'begin_data' : 0x20001000, # Analyzer uses a max of 1024 B data (256 pages * 4 bytes / page) 'page_buffers' : [0x20001000, 0x20001800], # Enable double buffering 'static_base' : 0x20000000 + 0x20 + 0x48c, 'min_program_length' : 8, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000 # Analyzer 0x1ffff000..0x1ffff600 }; class Flash_k22f(Flash_Kinetis): def __init__(self, target): super(Flash_k22f, self).__init__(target, FLASH_ALGO) class K22F(Kinetis): # 512kB flash with 2kB sectors, 128kB RAM memoryMap = MemoryMap( FlashRegion( start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x1fff0000, length=0x20000) ) def __init__(self, link): super(K22F, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK22F51212.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_MKL46Z256xxx4.py0000644000175000017500000001571413373511253021171 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x49302000, 0x48306008, 0xf0004448, 0x2800f8e9, 0x2001d001, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x492ab510, 0x44484828, 0xf8c2f000, 0x2c004604, 0x2100d105, 0x44484824, 0xf9bef000, 0xf0004604, 0x4620f838, 0xb570bd10, 0x481f4604, 0x4b1f4448, 0x68c24621, 0xf862f000, 0x2d004605, 0x481ad107, 0x23004448, 0x68c24621, 0xf956f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0x2f004607, 0x2201d10b, 0x46339001, 0x90029200, 0x46294622, 0x44484809, 0xf99af000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0x210168c0, 0x43880289, 0x49041840, 0x477060c8, 0x40048100, 0x00000004, 0x6b65666b, 0xf0003000, 0x4a102070, 0x20807010, 0xbf007010, 0x7800480d, 0x280009c0, 0x480bd0fa, 0x20207801, 0x28004008, 0x2067d001, 0x20104770, 0x28004008, 0x2068d001, 0x07c8e7f8, 0x28000fc0, 0x2069d001, 0x2000e7f2, 0x0000e7f0, 0x40020000, 0xb081b5ff, 0x460d4604, 0xf0009804, 0x4606f89f, 0xd0022e00, 0xb0054630, 0x2304bdf0, 0x46204629, 0xf0009a03, 0x4606f876, 0xd0012e00, 0xe7f24630, 0x18289803, 0x46381e47, 0xf00068e1, 0x2900f983, 0x4638d009, 0xf00068e1, 0x1c40f97d, 0x68e19000, 0x43489800, 0xe0131e47, 0x4478480c, 0x60056800, 0x490b2009, 0xf7ff71c8, 0x4606ffa7, 0x280069a0, 0x69a0d001, 0x2e004780, 0xe003d000, 0x194568e0, 0xd9e942bd, 0x4630bf00, 0x0000e7c5, 0x00000462, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0x2e004606, 0x4630d001, 0x2c00bd70, 0x2004d101, 0x2044e7fa, 0x71c84902, 0xff7ef7ff, 0x0000e7f4, 0x40020000, 0x29004601, 0x2004d101, 0x482a4770, 0x010068c0, 0x00400f00, 0x447b4b28, 0x03025a18, 0xd1012a00, 0xe7f12064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e4, 0xd1012a00, 0x47702004, 0x20006191, 0xb530e7fb, 0x2c004604, 0x2004d101, 0x1e58bd30, 0x28004008, 0x1e58d103, 0x28004010, 0x2065d001, 0x6820e7f4, 0xd8054288, 0x68206865, 0x188d1940, 0xd20142a8, 0xe7e92066, 0xe7e72000, 0x480c4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0x2b004603, 0x2004d101, 0x290f4770, 0x2a04d801, 0x2004d001, 0x2000e7f8, 0x0000e7f6, 0x40048040, 0x000003c0, 0x6b65666b, 0xb081b5ff, 0x46144607, 0x2c00461d, 0x2004d102, 0xbdf0b005, 0x462a2304, 0x99024638, 0xffb7f7ff, 0x2e004606, 0x4630d001, 0xe01ce7f2, 0x44794910, 0x68099802, 0xcc016008, 0x4479490d, 0x6809390c, 0x20066048, 0x71c8490b, 0xfef4f7ff, 0x69b84606, 0xd0012800, 0x478069b8, 0xd0002e00, 0x9802e005, 0x90021d00, 0x2d001f2d, 0xbf00d1e0, 0xe7cf4630, 0x0000030a, 0x40020000, 0xb083b5ff, 0x2304460c, 0x9a054621, 0xf7ff9803, 0x9002ff82, 0x28009802, 0x9802d002, 0xbdf0b007, 0x68919a03, 0xf0006850, 0x4605f88f, 0x42684261, 0x424e4001, 0xd10042a6, 0x9f051976, 0x1b30e027, 0x98019001, 0xd90042b8, 0x98019701, 0x90000880, 0x44784811, 0x60046800, 0x49102001, 0x980071c8, 0x0e010400, 0x72c1480d, 0x9800490c, 0x98067288, 0xf7ff7248, 0x9002fea3, 0x28009802, 0x9802d001, 0x9801e7cc, 0x98011a3f, 0x19761824, 0x2f00bf00, 0x2000d1d5, 0x0000e7c2, 0x0000026e, 0x40020000, 0x4604b570, 0x2c00460d, 0x2004d101, 0x2040bd70, 0x71c84903, 0x71854608, 0xfe80f7ff, 0x0000e7f6, 0x40020000, 0xb081b5ff, 0x4617460c, 0x2d00461d, 0x2004d102, 0xbdf0b005, 0x463a2304, 0x98014621, 0xff19f7ff, 0x2e004606, 0x4630d001, 0xe022e7f2, 0x44784813, 0x60046800, 0x49122002, 0x980a71c8, 0x490f72c8, 0x39124479, 0x68096828, 0xf7ff6088, 0x4606fe55, 0xd00b2e00, 0x2800980b, 0x980bd001, 0x980c6004, 0xd0022800, 0x980c2100, 0xe0046001, 0x1d2d1f3f, 0x2f001d24, 0xbf00d1da, 0xe7c94630, 0x000001ce, 0x40020000, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, 0x2000b501, 0x46c046c0, 0x0002bd02, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000000, 0x00000000, 0x00000020, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000049, 'pc_erase_sector' : 0x2000006F, 'pc_program_page' : 0x2000009F, 'begin_stack' : 0x20000800, 'begin_data' : 0x20000800, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) # Note: 128 pages on KL25 and KL26, 256 pages on KL46 'static_base' : 0x20000000 + 0x20 + 0x5E8, 'min_program_length' : 4, 'page_buffers' : [0x20000800, 0x20000c00], # Enable double buffering 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000 # Analyzer 0x1ffff000..0x1ffff600 }; # @brief Flash algorithm for Kinetis L-series devices. class Flash_kl46z(Flash_Kinetis): def __init__(self, target): super(Flash_kl46z, self).__init__(target, FLASH_ALGO) class KL46Z(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1fffe000, length=0x8000) ) def __init__(self, link): super(KL46Z, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL46Z4.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_K32W042S1M2xxx.py0000644000175000017500000003272013373511253021234 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from ..flash.flash import Flash from ..core.target import Target from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..debug.svd import SVDFile from ..coresight import ap from ..coresight.cortex_m import CortexM from ..utility.timeout import Timeout import logging import os.path from time import sleep SMC0_MR = 0x40020040 SMC1_MR = 0x41020040 SMC_MR_BOOTCFG_MASK = 0x3 MDM_STATUS = 0x00000000 MDM_CTRL = 0x00000004 MDM_CORE_STATUS = 0x00000050 MDM_IDR = 0x000000fc MDM_STATUS_FLASH_MASS_ERASE_ACKNOWLEDGE = (1 << 0) MDM_STATUS_FLASH_READY = (1 << 1) MDM_STATUS_SYSTEM_SECURITY = (1 << 2) MDM_STATUS_MASS_ERASE_ENABLE = (1 << 5) MDM_STATUS_CORE_HALTED = (1 << 16) MDM_CTRL_FLASH_MASS_ERASE_IN_PROGRESS = (1 << 0) MDM_CTRL_DEBUG_REQUEST = (1 << 2) MDM_CTRL_SYSTEM_RESET_REQUEST = (1 << 3) MDM_CTRL_CORE_HOLD_RESET = (1 << 4) MDM_CORE_STATUS_CM4_HALTED = (1 << 7) MDM_CORE_STATUS_CM0P_HALTED = (1 << 15) HALT_TIMEOUT = 2.0 log = logging.getLogger("target.k32w042s") FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4838b510, 0x60414936, 0x60814937, 0x22806801, 0x22204391, 0x60014311, 0x69014834, 0x0f890589, 0xd01c2902, 0x4a322100, 0x444a2900, 0xd0087011, 0x22036901, 0x43910212, 0x69016101, 0x0f890589, 0x482cd1fb, 0x22016841, 0x43110792, 0x482a6041, 0xf0004448, 0x2800f855, 0x2001d000, 0x2101bd10, 0x4823e7e1, 0x78004448, 0xd00d2800, 0x6901481f, 0x02122203, 0x31ff4391, 0x310231ff, 0x69016101, 0x0f890589, 0xd1fa2902, 0x47702000, 0xb510481a, 0x4448491a, 0xf93af000, 0x4601bd10, 0xb5104816, 0x22104b16, 0xf0004448, 0xbd10f8e4, 0x460cb570, 0x4606460b, 0x48104601, 0x4615b084, 0xf0004448, 0x2800f963, 0x9001d10a, 0x21019002, 0x9100480a, 0x4622462b, 0x44484631, 0xfb0bf000, 0xbd70b004, 0xd928c520, 0x4002a000, 0x0000ffff, 0x40020000, 0x00000004, 0x4002b000, 0x00000008, 0x6b65666b, 0xd00a2800, 0x68c949fe, 0x290f0f09, 0x4afdd007, 0x447a0049, 0x02895a51, 0x2004e003, 0x21014770, 0xb4300509, 0x60032300, 0x21026041, 0x02cc7201, 0x49f560c4, 0x158a7a45, 0xd00c2d01, 0x40aa7b0d, 0x7b496142, 0x61816103, 0x06c92109, 0x62016244, 0x2000bc30, 0x7b8d4770, 0x614240aa, 0xe7f17bc9, 0xd0022800, 0x20006101, 0x20044770, 0x48e74770, 0x49e76800, 0x42880a00, 0x48e6d101, 0x48e6e000, 0x22016801, 0x60014311, 0x8f6ff3bf, 0x8f4ff3bf, 0xb5104770, 0xf0002101, 0xbd10fb82, 0x217048df, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x28004770, 0x2004d101, 0xb5704770, 0x4ad24604, 0x605048d2, 0x428148d2, 0x206bd001, 0x2000e000, 0xd10c2800, 0x46202100, 0xfb57f000, 0xf7ff4620, 0x4605ffd3, 0x46202101, 0xfb4ff000, 0xbd704628, 0xd0012800, 0xd1012a00, 0x47702004, 0x2000b410, 0x60906050, 0x611060d0, 0x61906150, 0x621061d0, 0x23ff6250, 0x061b0248, 0x0a4018cc, 0x04892101, 0x60102308, 0xd209428c, 0x4320014c, 0x01886010, 0x60d06111, 0x60911340, 0xe0066050, 0x05002001, 0x12006110, 0x01c06050, 0x20106090, 0x61536190, 0x61d06213, 0x62502004, 0x2000bc10, 0xb5ff4770, 0x4615b08d, 0x460e461c, 0x980daa02, 0xffc0f7ff, 0x9000a802, 0x4631462a, 0x980d9b08, 0xfb19f000, 0xd1082800, 0x428448a2, 0x266bd001, 0x2600e000, 0xd0022e00, 0xb0114630, 0x9c02bdf0, 0x19659f03, 0x46391e6d, 0xf0004628, 0x2900fb37, 0x1c40d002, 0x1e454378, 0x980d2100, 0xfae7f000, 0xd81442ac, 0x20090221, 0x06000a09, 0x488f1809, 0x980d6041, 0xff5af7ff, 0x980d4606, 0x28006900, 0x4780d000, 0xd1022e00, 0x42ac19e4, 0x2101d9ea, 0xf000980d, 0x4630facc, 0xbdf0b011, 0xd1012800, 0x47702004, 0x4604b570, 0x48834a80, 0x48816050, 0xd0014281, 0xe000206b, 0x28002000, 0x2100d10c, 0xf0004620, 0x4620fab4, 0xff30f7ff, 0x21014605, 0xf0004620, 0x4628faac, 0x2800bd70, 0x2004d101, 0xb5704770, 0x4a714604, 0x60504874, 0x42814871, 0x206bd001, 0x2000e000, 0xd10c2800, 0x46202100, 0xfa95f000, 0xf7ff4620, 0x4605ff11, 0x46202101, 0xfa8df000, 0xbd704628, 0xd1012a00, 0x47702004, 0xb08db5ff, 0x461e4614, 0xaa02460d, 0xf7ff980d, 0xa802ff31, 0x46329000, 0x9b074629, 0xf000980d, 0x0007fa8a, 0x2100d132, 0x980d9d02, 0xfa6ff000, 0xd0262e00, 0x4855cc02, 0x99076081, 0xd0022904, 0xd0072908, 0x022ae00e, 0x0a122103, 0x18510649, 0xe0076041, 0x60c1cc02, 0x2107022a, 0x06090a12, 0x60411851, 0xf7ff980d, 0x4607fed1, 0x6900980d, 0xd0002800, 0x2f004780, 0x9807d103, 0x1a361945, 0x2101d1d8, 0xf000980d, 0x4638fa42, 0xbdf0b011, 0xd0012800, 0xd1012a00, 0x47702004, 0x4604b570, 0x0a010608, 0x1809483e, 0x60414838, 0x60816811, 0x60c16851, 0x46202100, 0xfa29f000, 0xf7ff4620, 0x4605fea5, 0x46202101, 0xfa21f000, 0xbd704628, 0xb08db5ff, 0x460c980f, 0xd02a2800, 0x980daa02, 0xfec8f7ff, 0x9000a802, 0x9b094621, 0x980d9a10, 0xfa21f000, 0x28009000, 0x9803d11c, 0x9e029001, 0x980d2100, 0xfa03f000, 0x28009810, 0x9801d06b, 0x900c4240, 0x4270990c, 0x42404008, 0x42b02500, 0x9901d101, 0x99101840, 0x42811989, 0x1b84d904, 0x2004e003, 0xbdf0b011, 0x2c009c10, 0x2701d049, 0x42bc02bf, 0x4627d800, 0x980f08a9, 0x18090089, 0x463a2009, 0xf00006c0, 0x1970fa37, 0x200b0201, 0x06000a09, 0x48091809, 0x46386041, 0xe0199909, 0x40026040, 0x00000872, 0x40023020, 0x40001000, 0x00434d30, 0xf0003034, 0xe0080034, 0x40023000, 0x44ffffff, 0x6b65666b, 0x49ffffff, 0x4bffffff, 0x4300ffff, 0xf9faf000, 0x48f10401, 0x48f11809, 0x980d6081, 0xfe2af7ff, 0x980d9000, 0x28006900, 0x4780d000, 0x28009800, 0x1be4d10d, 0x2c0019ed, 0x08a9d1b5, 0x0089980f, 0x900f1808, 0x19769810, 0x90101b40, 0x2101d196, 0xf000980d, 0x9800f990, 0xbdf0b011, 0xd0012800, 0xd1012a00, 0x47702004, 0x4614b570, 0x4adc0609, 0x4dda0a09, 0x60691889, 0xfdfcf7ff, 0xd1032800, 0x602168a9, 0x606168e9, 0x2800bd70, 0x2900d00e, 0x48d2d00c, 0x07827880, 0x2a020f92, 0x0980d008, 0xd0082802, 0x70082002, 0x47702000, 0x47702004, 0x70082000, 0x2001e7f8, 0x2800e7f5, 0x2900d001, 0x2004d101, 0xb5704770, 0x23004dc4, 0x079278aa, 0x2a020f92, 0x4ac3d026, 0x780c606a, 0x462278cb, 0x061b784c, 0x43220224, 0x0424788c, 0x431a4322, 0x0a12ba12, 0x021278cb, 0x60aa431a, 0x79cb790c, 0x794c4622, 0x0224061b, 0x798c4322, 0x042479c9, 0x431a4322, 0x0a12ba12, 0x430a0212, 0xf7ff60ea, 0x4603fda9, 0xbd704618, 0xd1012800, 0x47702004, 0x04094aad, 0xb5101889, 0x60514aa8, 0xfd9af7ff, 0xb5ffbd10, 0x4614b08d, 0x460d461e, 0x980daa02, 0xfdc4f7ff, 0x9000a802, 0x46294622, 0x980d9b09, 0xf91df000, 0xd12e2800, 0x98049d02, 0x42699000, 0x40014240, 0x42af424f, 0x9800d101, 0x2c00183f, 0x0230d020, 0x1b7e9001, 0xd90042a6, 0x46304626, 0xf0009909, 0x022af937, 0x0a122101, 0x18520609, 0x604a498e, 0x04009a01, 0x30ff4310, 0x980d6088, 0xfd60f7ff, 0xd1062800, 0x1ba49800, 0x183f19ad, 0xd1e02c00, 0xb0112000, 0x2b00bdf0, 0x2004d101, 0xb5ff4770, 0x4616b08d, 0x460c461d, 0x9f16aa02, 0xf7ff980d, 0xa802fd7b, 0x46329000, 0x9b0b4621, 0xf000980d, 0x2800f8d4, 0x9c02d11d, 0xd01a2e00, 0x0638497a, 0x02211847, 0x0a092001, 0x18090640, 0x60414872, 0x68296087, 0x980d60c1, 0xfd2af7ff, 0xd00a2800, 0x29009917, 0x600cd000, 0x29009918, 0x2200d001, 0xb011600a, 0x990bbdf0, 0x08891a76, 0x194d0089, 0x190c990b, 0xd1dc2e00, 0xbdf0b011, 0xd1012800, 0x47702004, 0x04094a65, 0xb5101889, 0x60514a5e, 0xfd06f7ff, 0x2800bd10, 0x2a00d001, 0x2004d101, 0xb5104770, 0x290a4614, 0x000ad222, 0x7912447a, 0x44971892, 0x0d080604, 0x1513110f, 0x68c01917, 0x6840e013, 0x7a01e011, 0xf0006840, 0xe00cf8b1, 0xe00a7a00, 0xe0086800, 0xe0062001, 0xe0046940, 0xe0026980, 0xe0006a00, 0x60206a40, 0xbd102000, 0xbd10206a, 0x28002300, 0x2004d101, 0xb4104770, 0xd0232906, 0x2905dc02, 0xe01fd80d, 0xd01d2909, 0x2907dc04, 0x2908d01a, 0xe017d105, 0x2920b2d4, 0x2921d005, 0x236ad009, 0x4618bc10, 0x2a004770, 0x2a01d001, 0x7244d105, 0x2a00e7f6, 0x2a01d004, 0xbc10d002, 0x47702077, 0xe7ed7284, 0xe7eb2376, 0xd00e2800, 0x680a482c, 0x680a61c2, 0x429a69c3, 0x684ad105, 0x68496182, 0x42816980, 0x2069d003, 0x20044770, 0x20004770, 0x28004770, 0x2900d008, 0x4821d006, 0x600a69c2, 0x60486980, 0x47702000, 0x47702004, 0x47702000, 0x70012100, 0x46087041, 0x29014770, 0x481ed110, 0x491e6800, 0x42880a00, 0x481dd101, 0x481de000, 0x22016801, 0x60014311, 0x8f6ff3bf, 0x8f4ff3bf, 0x28004770, 0x2004d101, 0xb4104770, 0x9c011e5b, 0xd1014219, 0xd002421a, 0x2065bc10, 0x68e04770, 0xd8074288, 0x18896923, 0x428818c0, 0xbc10d302, 0x47702000, 0x2066bc10, 0x00004770, 0x0000ffff, 0x40023000, 0x4100ffff, 0x45ffffff, 0x4000ffff, 0x00ffffff, 0x4a00ffff, 0x40001000, 0x00434d30, 0xf0003034, 0xe0080034, 0x460bb530, 0x20004601, 0x24012220, 0x460de009, 0x429d40d5, 0x461dd305, 0x1b494095, 0x40954625, 0x46151940, 0x2d001e52, 0xbd30dcf1, 0x430b4603, 0xd003079b, 0xc908e009, 0xc0081f12, 0xd2fa2a04, 0x780be003, 0x1c407003, 0x1e521c49, 0x4770d2f9, 0x40023004, 0x4002301c, 0x40023018, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000083, 'pc_program_page': 0x200000cd, 'pc_erase_sector': 0x200000bb, 'pc_eraseAll' : 0x200000ad, 'static_base' : 0x200009c8, 'begin_stack' : 0x20000000 + 0x00001400, 'begin_data' : 0x20000000 + 0x00002000, 'page_size' : 0x00000200, 'analyzer_supported' : True, 'analyzer_address' : 0x8000000, # Analyzer 0x8000000..0x80000600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; # Derive from Flash instead of Flash_Kinetis since the FCF is in IFR and not main flash. class Flash_k32w042s(Flash): def __init__(self, target): super(Flash_k32w042s, self).__init__(target, FLASH_ALGO) class K32W042S(Kinetis): memoryMap = MemoryMap( FlashRegion(name='flash0', start= 0, length=0x100000, blocksize=0x1000, is_boot_memory=True), FlashRegion(name='flash1', start= 0x1000000, length=0x40000, blocksize=0x800), RamRegion( name='m4 itcm', start= 0x8000000, length=0x10000), RomRegion( name='boot rom', start= 0x8800000, length=0xc000), RamRegion( name='m0p tcm', start= 0x9000000, length=0x20000), RamRegion( name='m4 dtcm', start=0x20000000, length=0x30000), RamRegion( name='flexram', start=0x48000000, length=0x1000), RamRegion( name='usb ram', start=0x48010000, length=0x800), ) def __init__(self, link): super(K32W042S, self).__init__(link, self.memoryMap) svdPath = os.path.join(os.path.dirname(__file__), "K32W042S1M2_M4.xml") if os.path.exists(svdPath): self._svd_location = SVDFile(vendor="NXP", filename=svdPath, is_local=True) def create_init_sequence(self): seq = super(K32W042S, self).create_init_sequence() seq.insert_after('create_cores', ('disable_rom_remap', self.disable_rom_remap) ) return seq def perform_halt_on_connect(self): if self.halt_on_connect: # Prevent the target from resetting if it has invalid code with Timeout(HALT_TIMEOUT) as to: while to.check(): self.mdm_ap.write_reg(MDM_CTRL, MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET) if self.mdm_ap.read_reg(MDM_CTRL) & (MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET) == (MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET): break else: raise RuntimeError("Timed out attempting to set DEBUG_REQUEST and CORE_HOLD_RESET in MDM-AP") # We can now deassert reset. self.dp.assert_reset(False) # Enable debug self.aps[0].write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN) # Disable holding the core in reset, leave MDM halt on self.mdm_ap.write_reg(MDM_CTRL, MDM_CTRL_DEBUG_REQUEST) # Wait until the target is halted with Timeout(HALT_TIMEOUT) as to: while to.check(): if self.mdm_ap.read_reg(MDM_CORE_STATUS) & MDM_CORE_STATUS_CM4_HALTED != MDM_CORE_STATUS_CM4_HALTED: break log.debug("Waiting for mdm halt") sleep(0.01) else: raise RuntimeError("Timed out waiting for core to halt") # release MDM halt once it has taken effect in the DHCSR self.mdm_ap.write_reg(MDM_CTRL, 0) # sanity check that the target is still halted if self.get_state() == Target.TARGET_RUNNING: raise RuntimeError("Target failed to stay halted during init sequence") def disable_rom_remap(self): # Disable ROM vector table remapping. self.aps[0].write32(SMC0_MR, SMC_MR_BOOTCFG_MASK) self.aps[0].write32(SMC1_MR, SMC_MR_BOOTCFG_MASK) pyocd-0.13.1/pyocd/target/target_nRF52840_xxAA.py0000644000175000017500000000642413373511253021160 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000, 0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0, 0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041, 0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2, 0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840, 0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000029, 'pc_erase_sector' : 0x20000049, 'pc_program_page' : 0x20000071, 'begin_data' : 0x20002000, # Analyzer uses a max of 0.5 KB data (128 pages * 4 bytes / page) 'page_buffers' : [0x20002000, 0x20003000], # Enable double buffering 'begin_stack' : 0x20001000, 'static_base' : 0x20000170, 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20004000 # Analyzer 0x20004000..0x20004600 } class Flash_nrf52840(Flash): def __init__(self, target): super(Flash_nrf52840, self).__init__(target, FLASH_ALGO) class NRF52840(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x0, length=0x100000, blocksize=0x1000, is_boot_memory=True), # User Information Configation Registers (UICR) as a flash region FlashRegion( start=0x10001000, length=0x100, blocksize=0x100, is_testable=False), RamRegion( start=0x20000000, length=0x40000) ) def __init__(self, link): super(NRF52840, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Nordic", filename="nrf52.svd", is_local=False) def resetn(self): """ reset a core. After a call to this function, the core is running """ self.reset() pyocd-0.13.1/pyocd/target/target_MKE15Z256xxx7.py0000644000175000017500000001413413373511253021154 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2016 Freescale Semiconductor, Inc. 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging RCM_MR = 0x4007f010 RCM_MR_BOOTROM_MASK = 0x6 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4829b510, 0x60414927, 0x60814928, 0x22806801, 0x22204391, 0x60014311, 0x44484825, 0xf84cf000, 0xd0002800, 0xbd102001, 0x47702000, 0xb5104820, 0x44484920, 0xf88ef000, 0xd1042800, 0x2100481c, 0xf0004448, 0xbd10f948, 0x4c19b570, 0x444c4605, 0x4b184601, 0x68e24620, 0xf8b5f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf93ff000, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf8e4f000, 0xd10a2800, 0x90029001, 0x48082101, 0x462b9100, 0x46314622, 0xf0004448, 0xb004f96d, 0x0000bd70, 0xd928c520, 0x40052000, 0x0000ffff, 0x00000004, 0x6b65666b, 0xd00b2800, 0x68c949dd, 0x0f090109, 0xd007290f, 0x00494adb, 0x5a51447a, 0xe0030289, 0x47702004, 0x04892101, 0x2300b430, 0x60416003, 0x02cc2101, 0x608160c4, 0x7a0d49d3, 0x40aa158a, 0x7ac96142, 0x61816103, 0x06892105, 0x62016244, 0x2000bc30, 0x28004770, 0x6101d002, 0x47702000, 0x47702004, 0x48c94602, 0x210168c0, 0x43080289, 0x60c849c6, 0x48c64770, 0x70012170, 0x70012180, 0x06097801, 0x7800d5fc, 0xd5010681, 0x47702067, 0xd50106c1, 0x47702068, 0xd0fc07c0, 0x47702069, 0xd1012800, 0x47702004, 0x4604b510, 0x48b94ab8, 0x48b96050, 0xd0014281, 0xe000206b, 0x28002000, 0x4620d107, 0xffd7f7ff, 0x46204603, 0xffcaf7ff, 0xbd104618, 0xd1012800, 0x47702004, 0x4614b510, 0x60622200, 0x60e260a2, 0x61626122, 0x61e261a2, 0x68c16021, 0x68816061, 0xf0006840, 0x60a0f953, 0x60e02008, 0x61606120, 0x200461a0, 0x200061e0, 0xb5ffbd10, 0x4615b089, 0x466a460c, 0xf7ff9809, 0x462affd9, 0x9b044621, 0xf0009809, 0x0007f90c, 0x9c00d130, 0x19659e01, 0x46311e6d, 0xf0004628, 0x2900f931, 0x1c40d002, 0x1e454370, 0xd81d42ac, 0x20090221, 0x06000a09, 0x488d1809, 0x498e6041, 0x4288980c, 0x206bd001, 0x2000e000, 0xd1112800, 0xf7ff9809, 0x4607ff80, 0x69009809, 0xd0002800, 0x2f004780, 0x19a4d102, 0xd9e142ac, 0xf7ff9809, 0x4638ff69, 0xbdf0b00d, 0xd1012a00, 0x47702004, 0xb089b5ff, 0x461e4614, 0x466a460d, 0xf7ff9809, 0x4632ff91, 0x9b034629, 0xf0009809, 0x0007f8c4, 0x9d00d12d, 0xd0262e00, 0x4871cc02, 0x99036081, 0xd0022904, 0xd0072908, 0x022ae00e, 0x0a122103, 0x18510649, 0xe0076041, 0x60c1cc02, 0x2107022a, 0x06090a12, 0x60411851, 0xf7ff9809, 0x4607ff3c, 0x69009809, 0xd0002800, 0x2f004780, 0x9803d103, 0x1a361945, 0x9809d1d8, 0xff24f7ff, 0xb00d4638, 0x2800bdf0, 0x4a5dd005, 0x18890409, 0x60514a58, 0x2004e721, 0xb5ff4770, 0x4614b08b, 0x460d461e, 0x980b466a, 0xff46f7ff, 0x46294622, 0x980b9b05, 0xf879f000, 0xd1332800, 0x4629466a, 0xf7ff980b, 0x9d00ff39, 0x90089802, 0x42404269, 0x424f4001, 0xd10142af, 0x183f9808, 0xd0202c00, 0x90090230, 0x42a61b7e, 0x4626d900, 0x99054630, 0xf88af000, 0x2101022a, 0x06090a12, 0x493d1852, 0x9a09604a, 0x43100400, 0x608830ff, 0xf7ff980b, 0x2800fee4, 0x9808d106, 0x19ad1ba4, 0x2c00183f, 0x2000d1e0, 0xbdf0b00f, 0xd1012b00, 0x47702004, 0xb089b5ff, 0x461d4616, 0x466a460c, 0x98099f12, 0xfefaf7ff, 0x46214632, 0x98099b07, 0xf82df000, 0xd11d2800, 0x2e009c00, 0x492ad01a, 0x18470638, 0x20010221, 0x06400a09, 0x48221809, 0x60876041, 0x60c16829, 0xf7ff9809, 0x2800feb0, 0x9913d00a, 0xd0002900, 0x9914600c, 0xd0012900, 0x600a2200, 0xbdf0b00d, 0x1a769907, 0x00890889, 0x9907194d, 0x2e00190c, 0xb00dd1dc, 0x2800bdf0, 0x2004d101, 0xb4104770, 0x460c1e5b, 0xd101421c, 0xd002421a, 0x2065bc10, 0x68034770, 0xd804428b, 0x18896840, 0x42881818, 0xbc10d202, 0x47702066, 0x2000bc10, 0x00004770, 0x40048040, 0x000003bc, 0x40020020, 0xf0003000, 0x40020000, 0x44ffffff, 0x6b65666b, 0x4000ffff, 0x00ffffff, 0x460bb530, 0x20004601, 0x24012220, 0x460de009, 0x429d40d5, 0x461dd305, 0x1b494095, 0x40954625, 0x46151940, 0x2d001e52, 0xbd30dcf1, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000049, 'pc_program_page': 0x2000008F, 'pc_erase_sector': 0x20000069, 'pc_eraseAll' : 0x2000004D, 'static_base' : 0x20000000 + 0x00000020 + 0x000004ac, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000800, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_ke15z7(Flash_Kinetis): def __init__(self, target): super(Flash_ke15z7, self).__init__(target, FLASH_ALGO) class KE15Z7(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x1fffe000, length=0x8000) ) def __init__(self, link): super(KE15Z7, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKE15Z7.svd") def create_init_sequence(self): seq = super(KE15Z7, self).create_init_sequence() seq.insert_after('create_cores', ('disable_rom_remap', self.disable_rom_remap) ) return seq def disable_rom_remap(self): # Disable ROM vector table remapping. self.write32(RCM_MR, RCM_MR_BOOTROM_MASK) pyocd-0.13.1/pyocd/target/target_STM32F412xx.py0000644000175000017500000001147313373511253020674 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile class DBGMCU: CR = 0xE0042004 CR_VALUE = 0x7 # DBG_STANDBY | DBG_STOP | DBG_SLEEP APB1_FZ = 0xE0042008 APB1_FZ_VALUE = 0x07E01DFF APB2_FZ = 0xE004200C APB2_FZ_VALUE = 0x00070003 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x03004601, 0x28200e00, 0x0940d302, 0xe0051d00, 0xd3022810, 0x1cc00900, 0x0880e000, 0xd50102c9, 0x43082110, 0x48424770, 0x60414940, 0x60414941, 0x60012100, 0x22f068c1, 0x60c14311, 0x06806940, 0x483ed406, 0x6001493c, 0x60412106, 0x6081493c, 0x47702000, 0x69014836, 0x43110542, 0x20006101, 0xb5104770, 0x69014832, 0x43212404, 0x69016101, 0x431103a2, 0x49336101, 0xe0004a30, 0x68c36011, 0xd4fb03db, 0x43a16901, 0x20006101, 0xb530bd10, 0xffb6f7ff, 0x68ca4926, 0x431a23f0, 0x240260ca, 0x690a610c, 0x0e0006c0, 0x610a4302, 0x03e26908, 0x61084310, 0x4a214823, 0x6010e000, 0x03ed68cd, 0x6908d4fb, 0x610843a0, 0x060068c8, 0xd0030f00, 0x431868c8, 0x200160c8, 0xb570bd30, 0x1cc94d14, 0x68eb0889, 0x26f00089, 0x60eb4333, 0x612b2300, 0xe0174b15, 0x431c692c, 0x6814612c, 0x68ec6004, 0xd4fc03e4, 0x0864692c, 0x612c0064, 0x062468ec, 0xd0040f24, 0x433068e8, 0x200160e8, 0x1d00bd70, 0x1f091d12, 0xd1e52900, 0xbd702000, 0x45670123, 0x40023c00, 0xcdef89ab, 0x00005555, 0x40003000, 0x00000fff, 0x0000aaaa, 0x00000201, 0x00000000 ], 'pc_init' : 0x20000047, 'pc_unInit': 0x20000075, 'pc_program_page': 0x200000fb, 'pc_erase_sector': 0x200000af, 'pc_eraseAll' : 0x20000083, 'static_base' : 0x20000000 + 0x00000020 + 0x0000014c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20020000, 'page_buffers' : [0x20020000], # Disable double buffering, sectors are too large to fit 2 in RAM. 'min_program_length' : 2, 'analyzer_supported' : True, 'analyzer_address' : 0x20002000 }; # @brief Flash algorithm for STM32F412xx device. class Flash_stm32f412xx(Flash): def __init__(self, target): super(Flash_stm32f412xx, self).__init__(target, FLASH_ALGO) class STM32F412xE(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x10000, blocksize=0x4000, is_boot_memory=True), FlashRegion( start=0x08010000, length=0x10000, blocksize=0x10000), FlashRegion( start=0x08020000, length=0x20000, blocksize=0x20000), RamRegion( start=0x20000000, length=0x40000) ) def __init__(self, transport): super(STM32F412xE, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F41x.svd") def create_init_sequence(self): seq = super(STM32F412xE, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): self.write32(DBGMCU.CR, DBGMCU.CR_VALUE) self.write32(DBGMCU.APB1_FZ, DBGMCU.APB1_FZ_VALUE) self.write32(DBGMCU.APB2_FZ, DBGMCU.APB2_FZ_VALUE) class STM32F412xG(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x10000, blocksize=0x4000, is_boot_memory=True), FlashRegion( start=0x08010000, length=0x10000, blocksize=0x10000), FlashRegion( start=0x08020000, length=0x60000, blocksize=0x20000), RamRegion( start=0x20000000, length=0x40000) ) def __init__(self, transport): super(STM32F412xG, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F41x.svd") def create_init_sequence(self): seq = super(STM32F412xG, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): self.write32(DBGMCU.CR, DBGMCU.CR_VALUE) self.write32(DBGMCU.APB1_FZ, DBGMCU.APB1_FZ_VALUE) self.write32(DBGMCU.APB2_FZ, DBGMCU.APB2_FZ_VALUE) pyocd-0.13.1/pyocd/target/target_MKW41Z512xxx4.py0000644000175000017500000001342213373511253021164 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4937b510, 0x60082000, 0x78414836, 0x0f890649, 0xd0152902, 0x4a342100, 0x444a2900, 0xd0077011, 0x229f7841, 0x70414011, 0x06497841, 0xd1fb0f89, 0x4448482e, 0xf85ef000, 0xd0002800, 0xbd102001, 0xe7e82101, 0x44484828, 0x28007800, 0x4825d00a, 0x229f7841, 0x31404011, 0x78417041, 0x0f890649, 0xd1fa2902, 0x47702000, 0xb5104820, 0x44484920, 0xf88cf000, 0xd1042800, 0x2100481c, 0xf0004448, 0xbd10f946, 0x4c19b570, 0x444c4605, 0x4b184601, 0x68e24620, 0xf8b3f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf93df000, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf8e2f000, 0xd10a2800, 0x90029001, 0x48082101, 0x462b9100, 0x46314622, 0xf0004448, 0xb004f96b, 0x0000bd70, 0x40048100, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xd00b2800, 0x68c949db, 0x0f090109, 0xd007290f, 0x00494ad9, 0x5a51447a, 0xe0030289, 0x47702004, 0x04c92101, 0x2200b410, 0x60416002, 0x60812102, 0x60c10289, 0x7a0c49d1, 0x40a3158b, 0x7ac96143, 0x62026102, 0x61816242, 0x2000bc10, 0x28004770, 0x6101d002, 0x47702000, 0x47702004, 0x48c84602, 0x210168c0, 0x43080289, 0x60c849c5, 0x48c54770, 0x70012170, 0x70012180, 0x06097801, 0x7800d5fc, 0xd5010681, 0x47702067, 0xd50106c1, 0x47702068, 0xd0fc07c0, 0x47702069, 0xd1012800, 0x47702004, 0x4604b510, 0x48b84ab7, 0x48b86050, 0xd0014281, 0xe000206b, 0x28002000, 0x4620d107, 0xffd7f7ff, 0x46204603, 0xffcaf7ff, 0xbd104618, 0xd1012800, 0x47702004, 0x4614b510, 0x60622200, 0x60e260a2, 0x61626122, 0x61e261a2, 0x68c16021, 0x68816061, 0xf0006840, 0x60a0f951, 0x20042108, 0x60e06121, 0x616161a0, 0x200061e0, 0xb5ffbd10, 0x4615b089, 0x466a460c, 0xf7ff9809, 0x462affd9, 0x9b044621, 0xf0009809, 0x0007f90c, 0x9c00d130, 0x19659e01, 0x46311e6d, 0xf0004628, 0x2900f92f, 0x1c40d002, 0x1e454370, 0xd81d42ac, 0x20090221, 0x06000a09, 0x488c1809, 0x498d6041, 0x4288980c, 0x206bd001, 0x2000e000, 0xd1112800, 0xf7ff9809, 0x4607ff80, 0x69009809, 0xd0002800, 0x2f004780, 0x19a4d102, 0xd9e142ac, 0xf7ff9809, 0x4638ff69, 0xbdf0b00d, 0xd1012a00, 0x47702004, 0xb089b5ff, 0x461e4614, 0x466a460d, 0xf7ff9809, 0x4632ff91, 0x9b034629, 0xf0009809, 0x0007f8c4, 0x9d00d12d, 0xd0262e00, 0x4870cc02, 0x99036081, 0xd0022904, 0xd0072908, 0x022ae00e, 0x0a122103, 0x18510649, 0xe0076041, 0x60c1cc02, 0x2107022a, 0x06090a12, 0x60411851, 0xf7ff9809, 0x4607ff3c, 0x69009809, 0xd0002800, 0x2f004780, 0x9803d103, 0x1a361945, 0x9809d1d8, 0xff24f7ff, 0xb00d4638, 0x2800bdf0, 0x4a5cd005, 0x18890409, 0x60514a57, 0x2004e721, 0xb5ff4770, 0x4614b08b, 0x460d461e, 0x980b466a, 0xff46f7ff, 0x46294622, 0x980b9b05, 0xf879f000, 0xd1332800, 0x4629466a, 0xf7ff980b, 0x9d00ff39, 0x90089802, 0x42404269, 0x424f4001, 0xd10142af, 0x183f9808, 0xd0202c00, 0x90090230, 0x42a61b7e, 0x4626d900, 0x99054630, 0xf888f000, 0x2101022a, 0x06090a12, 0x493c1852, 0x9a09604a, 0x43100400, 0x608830ff, 0xf7ff980b, 0x2800fee4, 0x9808d106, 0x19ad1ba4, 0x2c00183f, 0x2000d1e0, 0xbdf0b00f, 0xd1012b00, 0x47702004, 0xb089b5ff, 0x461d4616, 0x466a460c, 0x98099f12, 0xfefaf7ff, 0x46214632, 0x98099b07, 0xf82df000, 0xd11d2800, 0x2e009c00, 0x4929d01a, 0x18470638, 0x20010221, 0x06400a09, 0x48211809, 0x60876041, 0x60c16829, 0xf7ff9809, 0x2800feb0, 0x9913d00a, 0xd0002900, 0x9914600c, 0xd0012900, 0x600a2200, 0xbdf0b00d, 0x1a769907, 0x00890889, 0x9907194d, 0x2e00190c, 0xb00dd1dc, 0x2800bdf0, 0x2004d101, 0xb4104770, 0x42191e5b, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x40048040, 0x000003b4, 0x40020020, 0xf0003000, 0x40020000, 0x44ffffff, 0x6b65666b, 0x4000ffff, 0x00ffffff, 0x460bb530, 0x20004601, 0x24012220, 0x460de009, 0x429d40d5, 0x461dd305, 0x1b494095, 0x40954625, 0x46151940, 0x2d001e52, 0xbd30dcf1, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000065, 'pc_program_page': 0x200000CB, 'pc_erase_sector': 0x200000A5, 'pc_eraseAll' : 0x20000089, 'static_base' : 0x20000000 + 0x00000020 + 0x000004e0, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000200, 'analyzer_supported' : False, 'analyzer_address' : 0x00000000 # ITCM, Analyzer 0x00000000..0x000000600 }; class Flash_kw41z4(Flash_Kinetis): def __init__(self, target): super(Flash_kw41z4, self).__init__(target, FLASH_ALGO) class KW41Z4(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x1fff8000, length=0x20000) ) def __init__(self, transport): super(KW41Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKW41Z4.svd") pyocd-0.13.1/pyocd/target/target_LPC1768.py0000644000175000017500000001404113373511253020105 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash, PageInfo, DEFAULT_PAGE_PROGRAM_WEIGHT, DEFAULT_PAGE_ERASE_WEIGHT from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) LARGE_PAGE_START_ADDR = 0x10000 SMALL_PAGE_SIZE = 0x1000 LARGE_PAGE_SIZE = 0x8000 LARGE_TO_SMALL_RATIO = LARGE_PAGE_SIZE / SMALL_PAGE_SIZE WRITE_SIZE = 1024 FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2, 0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x28100b00, 0x210ed302, 0x00d0eb01, 0x486c4770, 0x7801b510, 0x0102f021, 0x22aa7001, 0x23557302, 0x78017303, 0x0101f021, 0x73027001, 0xf8d07303, 0xf0411120, 0xf8c00120, 0xf1a01120, 0xf8d00080, 0x064911a0, 0xf100d5fb, 0x24010080, 0x408cf880, 0x0113f04f, 0x73026041, 0x78017303, 0x0101f041, 0x73027001, 0xf1a07303, 0xf8d00080, 0x01491088, 0xf100d5fb, 0x2107006d, 0x1097f880, 0x0109f04f, 0x109bf880, 0xf0417cc1, 0x74c10102, 0x77c377c2, 0x4c2df800, 0xf64e494b, 0x44492060, 0xf04f6008, 0xbd100000, 0x47702000, 0x41f0e92d, 0x20324c46, 0x2500444c, 0xe884271d, 0xf10400a1, 0x4e430114, 0x46204688, 0x696047b0, 0x2034b960, 0x00a1e884, 0x4641483c, 0x68004448, 0x462060e0, 0x696047b0, 0xd0002800, 0xe8bd2001, 0xe92d81f0, 0xf7ff41f0, 0x4d35ff87, 0x444d4604, 0xe9c52032, 0xf1050400, 0x4e320114, 0x4628460f, 0x47b060ac, 0xb9686968, 0xe9c52034, 0x482b0400, 0x444860ac, 0x68004639, 0x462860e8, 0x696847b0, 0xd0dc2800, 0xe7da2001, 0x41f0e92d, 0x46140006, 0x4925d11d, 0x02fcf8d4, 0xd03a4288, 0x42884923, 0x4923d037, 0xd0344288, 0x4131ea4f, 0xd0304288, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xff42f7ff, 0x21324d12, 0x4f12444d, 0x1000e9c5, 0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033, 0xf44f0600, 0xe9c56080, 0x48074002, 0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d095, 0x0000e793, 0x400fc080, 0x00000004, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x00000000, 0x00000000 ], 'pc_init' : 0x10000047, 'pc_eraseAll' : 0x100000e1, 'pc_erase_sector' : 0x10000123, 'pc_program_page' : 0x10000169, 'begin_data' : 0x2007c000, # Analyzer uses a max of 120 B data (30 pages * 4 bytes / page) # Double buffering is not supported since there is not enough ram 'begin_stack' : 0x10001000, 'static_base' : 0x10000214, 'min_program_length' : 256, 'analyzer_supported' : True, 'analyzer_address' : 0x10002000 # Analyzer 0x10002000..0x10002600 }; class Flash_lpc1768(Flash): def __init__(self, target): super(Flash_lpc1768, self).__init__(target, FLASH_ALGO) def erase_page(self, flashPtr): Flash.erase_page(self, flashPtr) def program_page(self, flashPtr, bytes): if flashPtr < LARGE_PAGE_START_ADDR: assert len(bytes) <= SMALL_PAGE_SIZE else: assert len(bytes) <= LARGE_PAGE_SIZE pages = (len(bytes) + WRITE_SIZE - 1) // WRITE_SIZE for i in range(0, pages): data = bytes[i * WRITE_SIZE : (i + 1) * WRITE_SIZE] Flash.program_page(self, flashPtr + i * WRITE_SIZE, data) def get_page_info(self, addr): info = PageInfo() if addr < LARGE_PAGE_START_ADDR: info.erase_weight = DEFAULT_PAGE_ERASE_WEIGHT info.program_weight = DEFAULT_PAGE_PROGRAM_WEIGHT info.size = SMALL_PAGE_SIZE else: info.erase_weight = DEFAULT_PAGE_ERASE_WEIGHT * LARGE_TO_SMALL_RATIO info.program_weight = DEFAULT_PAGE_PROGRAM_WEIGHT * LARGE_TO_SMALL_RATIO info.size = LARGE_PAGE_SIZE info.base_addr = addr - (addr % info.size) return info class LPC1768(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x10000, blocksize=0x1000, is_boot_memory=True), FlashRegion( start=0x10000, length=0x70000, blocksize=0x8000), RamRegion( start=0x10000000, length=0x8000), RamRegion( start=0x2007C000, length=0x8000) ) def __init__(self, link): super(LPC1768, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="NXP", filename="LPC176x5x_v0.2.svd", is_local=False) def reset(self, software_reset=False): super(LPC1768, self).reset(False) def reset_stop_on_reset(self, software_reset=False, map_to_user=True): super(LPC1768, self).reset_stop_on_reset() # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x400FC040, 1) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MK64FN1M0xxx12.py0000644000175000017500000001324513373511253021244 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x5020f24c, 0x81c84932, 0x1028f64d, 0x460881c8, 0xf0208800, 0x80080001, 0x4448482e, 0xf8dcf000, 0x2001b108, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x4929b510, 0x44484827, 0xf8b8f000, 0xb92c4604, 0x48242100, 0xf0004448, 0x4604f9a9, 0xf837f000, 0xbd104620, 0x4604b570, 0x4448481e, 0x46214b1e, 0xf00068c2, 0x4605f85d, 0x481ab93d, 0x23004448, 0x68c24621, 0xf946f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf8f8f000, 0xb9674607, 0x22012000, 0x2000e9cd, 0x46224633, 0x90024629, 0x44484809, 0xf984f000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0xf4206840, 0xf5000070, 0x49040070, 0x47706048, 0x40052000, 0x00000004, 0x6b65666b, 0x4001f000, 0x4a0e2070, 0x20807010, 0xbf007010, 0x7800480b, 0x280009c0, 0x4809d0fa, 0xf0017801, 0xb1080020, 0x47702067, 0x0010f001, 0x2068b108, 0xf001e7f9, 0xb1080001, 0xe7f42069, 0xe7f22000, 0x40020000, 0x4df0e92d, 0x460d4604, 0x469a4690, 0xf0004650, 0x4606f891, 0x4630b116, 0x8df0e8bd, 0x46422310, 0x46204629, 0xf86cf000, 0xb10e4606, 0xe7f34630, 0x0008eb05, 0x68e01e47, 0xf1f0fbb7, 0x7011fb00, 0x68e0b140, 0xf0f0fbb7, 0x0b01f100, 0xfb0068e0, 0x1e47f00b, 0x480be011, 0x68004478, 0x20096005, 0x71c84909, 0xffacf7ff, 0x69a04606, 0x69a0b108, 0xb1064780, 0x68e0e003, 0x42bd4405, 0xbf00d9eb, 0xe7c94630, 0x000002ec, 0x40020000, 0x4604b570, 0x4628460d, 0xf84ef000, 0xb10e4606, 0xbd704630, 0x2004b90c, 0x2044e7fb, 0x71c84902, 0xff88f7ff, 0x0000e7f5, 0x40020000, 0xb9094601, 0x47702004, 0x6cc04826, 0x6003f3c0, 0x447b4b25, 0x0010f833, 0xb90a0302, 0xe7f22064, 0x60082000, 0x2002604a, 0x02c06088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e5, 0x2004b90a, 0x61914770, 0xe7fb2000, 0x4604b530, 0x2004b90c, 0x1e58bd30, 0xb9104008, 0x40101e58, 0x2065b108, 0x6820e7f6, 0xd8054288, 0x0500e9d4, 0x188d4428, 0xd20142a8, 0xe7eb2066, 0xe7e92000, 0x480b4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0xb90b4603, 0x47702004, 0xd801290f, 0xd0012a04, 0xe7f82004, 0xe7f62000, 0x40048000, 0x0000025a, 0x6b65666b, 0x41f0e92d, 0x46884607, 0x461d4614, 0x2004b914, 0x81f0e8bd, 0x462a2308, 0x46384641, 0xffbcf7ff, 0xb10e4606, 0xe7f34630, 0x4812e01f, 0x68004478, 0x8000f8c0, 0x490fcc01, 0x390c4479, 0x60486809, 0x490ccc01, 0x39184479, 0x60886809, 0x490a2007, 0xf7ff71c8, 0x4606ff01, 0xb10869b8, 0x478069b8, 0xe004b106, 0x0808f108, 0x2d003d08, 0xbf00d1dd, 0xe7cd4630, 0x000001b0, 0x40020000, 0x4dffe92d, 0x4682b082, 0x2310460c, 0x46504621, 0xf7ff9a04, 0x4683ff83, 0x0f00f1bb, 0x4658d003, 0xe8bdb006, 0xe9da8df0, 0xfbb00101, 0x4260f7f1, 0x40084279, 0x42a54245, 0x443dd100, 0xe0229e04, 0x0804eba5, 0xd90045b0, 0xea4f46b0, 0x90011018, 0x4478480f, 0x60046800, 0x490e2001, 0x980171c8, 0x72c80a00, 0x72889801, 0x72489805, 0xfeb6f7ff, 0xf1bb4683, 0xd0010f00, 0xe7d14658, 0x0608eba6, 0x443d4444, 0x2e00bf00, 0x2000d1da, 0x0000e7c8, 0x0000010e, 0x40020000, 0x4604b570, 0xb90c460d, 0xbd702004, 0x49032040, 0x460871c8, 0xf7ff7185, 0xe7f6fe95, 0x40020000, 0x4dffe92d, 0x4617460c, 0xe9dd461d, 0xf8ddb80c, 0xb91da038, 0xb0042004, 0x8df0e8bd, 0x463a2304, 0x98004621, 0xff1ef7ff, 0xb10e4606, 0xe7f24630, 0x4814e022, 0x68004478, 0x20026004, 0x71c84912, 0xf8804608, 0x490fb00b, 0x39144479, 0x68096828, 0xf7ff6088, 0x4606fe67, 0xf1b8b15e, 0xd0010f00, 0x4000f8c8, 0x0f00f1ba, 0x2000d002, 0x0000f8ca, 0x1f3fe004, 0x1d241d2d, 0xd1da2f00, 0x4630bf00, 0x0000e7c9, 0x00000074, 0x40020000, 0x00000000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x01000000, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000059, 'pc_erase_sector' : 0x2000007D, 'pc_program_page' : 0x200000AB, 'begin_stack' : 0x20001000, 'begin_data' : 0x20003000, # Analyzer uses a max of 1024 B data (256 pages * 4 bytes / page) 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'static_base' : 0x20000000 + 0x20 + 0x474, 'min_program_length' : 8, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000 # Analyzer 0x1ffff000..0x1ffff600 }; class Flash_k64f(Flash_Kinetis): def __init__(self, target): super(Flash_k64f, self).__init__(target, FLASH_ALGO) class K64F(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x100000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1fff0000, length=0x40000) ) def __init__(self, link): super(K64F, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK64F12.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_LPC4088FBD144.py0000644000175000017500000001115013373511253020646 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash, PageInfo, DEFAULT_PAGE_PROGRAM_WEIGHT, DEFAULT_PAGE_ERASE_WEIGHT from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) LARGE_PAGE_START_ADDR = 0x10000 SMALL_PAGE_SIZE = 0x1000 LARGE_PAGE_SIZE = 0x8000 LARGE_TO_SMALL_RATIO = LARGE_PAGE_SIZE / SMALL_PAGE_SIZE WRITE_SIZE = 512 FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x28100b00, 0x210ebf24, 0x00d0eb01, 0xf6424770, 0x494d60e0, 0x60084449, 0x2100484c, 0x21aa7001, 0x21557301, 0x21017301, 0x1c40f800, 0x47702000, 0x47702000, 0x41f0e92d, 0x20324c45, 0x2700444c, 0x60a5251d, 0x0700e9c4, 0xf1044e42, 0x46200114, 0x696047b0, 0x2034b980, 0xe9c460a5, 0x483a0700, 0x0114f104, 0x68004448, 0x462060e0, 0x696047b0, 0xbf082800, 0x81f0e8bd, 0xe8bd2001, 0xb57081f0, 0x2c100b04, 0x200ebf24, 0x04d4eb00, 0x4d302032, 0x444d4e30, 0x0114f105, 0x0400e9c5, 0x60ac4628, 0x696847b0, 0x2034b978, 0x0400e9c5, 0x60ac4826, 0xf1054448, 0x68000114, 0x462860e8, 0x696847b0, 0xbf082800, 0x2001bd70, 0xe92dbd70, 0x461441f0, 0xd10e0005, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x0b2961e0, 0xbf242910, 0xeb00200e, 0x203201d1, 0x4f144e13, 0xe9c6444e, 0x60b10100, 0x0114f106, 0x47b84630, 0xb9986970, 0xe9c62033, 0xf44f0500, 0xe9c67000, 0x48084002, 0x0114f106, 0x68004448, 0x46306130, 0x697047b8, 0xbf082800, 0x81f0e8bd, 0xe8bd2001, 0x000081f0, 0x00000004, 0x400fc080, 0x00000008, 0x1fff1ff1, 0x00000000, 0x00000000, ], 'pc_init' : 0x1000002F, 'pc_unInit': 0x10000051, 'pc_program_page': 0x100000EB, 'pc_erase_sector': 0x1000009F, 'pc_eraseAll' : 0x10000055, 'static_base' : 0x10000000 + 0x00000020 + 0x00000200, 'begin_stack' : 0x10000000 + 0x00000800, # Double buffering is not supported since there is not enough ram 'begin_data' : 0x10000000 + 0x00000A00, # Analyzer uses a max of 120 B data (30 pages * 4 bytes / page) 'page_size' : 0x00001000, 'min_program_length' : 512, 'analyzer_supported' : True, 'analyzer_address' : 0x10002000 # Analyzer 0x10002000..0x10002600 } class Flash_lpc4088(Flash): def __init__(self, target, algo=None): if algo is None: algo = FLASH_ALGO super(Flash_lpc4088, self).__init__(target, algo) def program_page(self, flashPtr, bytes): if flashPtr < LARGE_PAGE_START_ADDR: assert len(bytes) <= SMALL_PAGE_SIZE else: assert len(bytes) <= LARGE_PAGE_SIZE pages = (len(bytes) + WRITE_SIZE - 1) // WRITE_SIZE for i in range(0, pages): data = bytes[i * WRITE_SIZE: (i + 1) * WRITE_SIZE] Flash.program_page(self, flashPtr + i * WRITE_SIZE, data) class LPC4088(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x10000, blocksize=0x1000, is_boot_memory=True), FlashRegion( start=0x10000, length=0x70000, blocksize=0x8000), RamRegion( start=0x10000000, length=0x10000), ) def __init__(self, link, mem_map=None): if mem_map is None: mem_map = self.memoryMap super(LPC4088, self).__init__(link, mem_map) self.ignoreReset = False self._svd_location = SVDFile(vendor="NXP", filename="LPC408x_7x_v0.7.svd", is_local=False) def reset(self, software_reset=None): # Use hardware reset since software reset cause a debug logic reset super(LPC4088, self).reset(False) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC4088, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x400FC040, 1) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MK66FN2M0xxx18.py0000644000175000017500000001307113373511253021252 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510482e, 0x5120f24c, 0xf64d81c1, 0x81c11128, 0xf0218801, 0x80010101, 0x44484829, 0xf856f000, 0xbf182800, 0xbd102001, 0x47702000, 0xb5104824, 0x44484924, 0xf926f000, 0x4821b920, 0x44482100, 0xf9daf000, 0x684a4920, 0x0270f442, 0xbd10604a, 0x4c1bb570, 0x444c4605, 0x4b1a4601, 0x68e24620, 0xf88ef000, 0x2300b928, 0x46204629, 0xf00068e2, 0x4915f91f, 0xf442684a, 0x604a0270, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf8b8f000, 0x2000b958, 0xe9cd2101, 0x90021000, 0x462b4807, 0x46314622, 0xf0004448, 0x4906f963, 0xf442684a, 0x604a0270, 0xbd70b004, 0x40052000, 0x00000004, 0x6b65666b, 0x4001f000, 0xbf042800, 0x47702004, 0x6cc94926, 0x0e094a26, 0xf832447a, 0x03091011, 0x2064bf04, 0x22004770, 0x2100e9c0, 0x60812104, 0x60c10289, 0x780b491f, 0x7c80f44f, 0xf303fa0c, 0x78c96103, 0x1205e9c0, 0x47704610, 0xbf0e2800, 0x61812004, 0x47702000, 0xbf042800, 0x47702004, 0x42191e5b, 0x421abf0e, 0x47702065, 0x428b6803, 0x6840d806, 0x44184411, 0xbf244288, 0x47702000, 0x47702066, 0x4288490c, 0x206bbf14, 0x47702000, 0x290fb140, 0x2a04d802, 0xe005d104, 0xbf982913, 0xd0012a08, 0x47702004, 0x47702000, 0x40048000, 0x0000036c, 0x40020028, 0x6b65666b, 0x4df0e92d, 0x46154606, 0x4618460c, 0xffdcf7ff, 0xbf182800, 0x8df0e8bd, 0x462a2310, 0x46304621, 0xffbcf7ff, 0xbf180007, 0x8df0e8bd, 0x1e451960, 0xfbb568f0, 0xfb00f1f0, 0xb1125211, 0x43481c49, 0x42ac1e45, 0xf8dfd817, 0x44f88034, 0xb030f8df, 0x0a09f04f, 0x0000f8d8, 0xf88b6004, 0xf000a007, 0x4607f917, 0x280069b0, 0x4780bf18, 0x68f0b91f, 0x42ac4404, 0x4638d9ee, 0x8df0e8bd, 0x0000027a, 0x40020000, 0xbf042a00, 0x47702004, 0x4df0e92d, 0x4614461d, 0x4607460e, 0x462a2308, 0xff7ef7ff, 0x0b00ea5f, 0xe8bdbf18, 0x2d008df0, 0xf8dfbf1e, 0x44f8804c, 0x0a07f04f, 0xf8d8d01c, 0x60060000, 0x1000f8d8, 0x0b04f854, 0xf8d86048, 0xf8541000, 0x60880b04, 0xf880480a, 0xf000a007, 0x4683f8d9, 0x280069b8, 0x4780bf18, 0x0f00f1bb, 0x3608d102, 0xd1e23d08, 0xe8bd4658, 0x00008df0, 0x00000212, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff5d, 0xbd10bf18, 0xbf042c00, 0xbd102004, 0x49032044, 0xe8bd71c8, 0xf0004010, 0x0000b8b3, 0x40020000, 0x4df0e92d, 0x4614469a, 0x4605460e, 0xf7ff2310, 0x2800ff2d, 0xe8bdbf18, 0xe9d58df0, 0xfbb00101, 0x4270f8f1, 0x0100f1c8, 0x42474008, 0xbf0842b7, 0x2c004447, 0xf8dfbf18, 0xd01cb044, 0x42a51bbd, 0x4625bf88, 0x490e0928, 0x68094479, 0x2101600e, 0x1007f88b, 0xf88b0a01, 0xf88b100b, 0xf88b000a, 0xf000a009, 0x2800f87d, 0xe8bdbf18, 0x1b648df0, 0x4447442e, 0x2000d1e2, 0x8df0e8bd, 0x40020000, 0x0000014c, 0xbf122800, 0x20042a00, 0x29084770, 0xe8dfd215, 0x0604f001, 0x0c0a0806, 0x68c0100e, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2001e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xbf042b00, 0x47702004, 0x4df0e92d, 0xe9dd461c, 0x46158709, 0x2304460e, 0xa020f8dd, 0xfec4f7ff, 0xbf182800, 0x8df0e8bd, 0xbf1a2d00, 0xb04cf8df, 0xe8bd44fb, 0xf8db8df0, 0x60060000, 0x21024810, 0xf88071c1, 0xf8dba00b, 0x68201000, 0xf0006088, 0xb150f825, 0x0f00f1b8, 0xf8c8bf18, 0x2f006000, 0x2100bf1c, 0xe8bd6039, 0x1f2d8df0, 0x0404f104, 0x0604f106, 0xe8bdd1df, 0x00008df0, 0x000000a0, 0x40020000, 0xbf042800, 0x47702004, 0x48022240, 0x718171c2, 0xb802f000, 0x40020000, 0x2170480c, 0x21807001, 0x78017001, 0x0f80f011, 0x7800d0fb, 0x0f20f010, 0x2067bf1c, 0xf0104770, 0xbf1c0f10, 0x47702068, 0x0001f010, 0x2069bf18, 0x00004770, 0x40020000, 0x40020004, 0x00000000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000049, 'pc_program_page': 0x2000009F, 'pc_erase_sector': 0x20000071, 'pc_eraseAll' : 0x2000004D, 'static_base' : 0x20000000 + 0x00000020 + 0x0000046c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_k66f18(Flash_Kinetis): def __init__(self, target): super(Flash_k66f18, self).__init__(target, FLASH_ALGO) class K66F18(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x200000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1fff0000, length=0x40000), RamRegion( start=0x14000000, length=0x1000) ) def __init__(self, transport): super(K66F18, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK66F18.svd") pyocd-0.13.1/pyocd/target/target_MKL25Z128xxx4.py0000644000175000017500000001571413373511253021164 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x49302000, 0x48306008, 0xf0004448, 0x2800f8e9, 0x2001d001, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x492ab510, 0x44484828, 0xf8c2f000, 0x2c004604, 0x2100d105, 0x44484824, 0xf9bef000, 0xf0004604, 0x4620f838, 0xb570bd10, 0x481f4604, 0x4b1f4448, 0x68c24621, 0xf862f000, 0x2d004605, 0x481ad107, 0x23004448, 0x68c24621, 0xf956f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0x2f004607, 0x2201d10b, 0x46339001, 0x90029200, 0x46294622, 0x44484809, 0xf99af000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0x210168c0, 0x43880289, 0x49041840, 0x477060c8, 0x40048100, 0x00000004, 0x6b65666b, 0xf0003000, 0x4a102070, 0x20807010, 0xbf007010, 0x7800480d, 0x280009c0, 0x480bd0fa, 0x20207801, 0x28004008, 0x2067d001, 0x20104770, 0x28004008, 0x2068d001, 0x07c8e7f8, 0x28000fc0, 0x2069d001, 0x2000e7f2, 0x0000e7f0, 0x40020000, 0xb081b5ff, 0x460d4604, 0xf0009804, 0x4606f89f, 0xd0022e00, 0xb0054630, 0x2304bdf0, 0x46204629, 0xf0009a03, 0x4606f876, 0xd0012e00, 0xe7f24630, 0x18289803, 0x46381e47, 0xf00068e1, 0x2900f983, 0x4638d009, 0xf00068e1, 0x1c40f97d, 0x68e19000, 0x43489800, 0xe0131e47, 0x4478480c, 0x60056800, 0x490b2009, 0xf7ff71c8, 0x4606ffa7, 0x280069a0, 0x69a0d001, 0x2e004780, 0xe003d000, 0x194568e0, 0xd9e942bd, 0x4630bf00, 0x0000e7c5, 0x00000462, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0x2e004606, 0x4630d001, 0x2c00bd70, 0x2004d101, 0x2044e7fa, 0x71c84902, 0xff7ef7ff, 0x0000e7f4, 0x40020000, 0x29004601, 0x2004d101, 0x482a4770, 0x010068c0, 0x00400f00, 0x447b4b28, 0x03025a18, 0xd1012a00, 0xe7f12064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e4, 0xd1012a00, 0x47702004, 0x20006191, 0xb530e7fb, 0x2c004604, 0x2004d101, 0x1e58bd30, 0x28004008, 0x1e58d103, 0x28004010, 0x2065d001, 0x6820e7f4, 0xd8054288, 0x68206865, 0x188d1940, 0xd20142a8, 0xe7e92066, 0xe7e72000, 0x480c4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0x2b004603, 0x2004d101, 0x290f4770, 0x2a04d801, 0x2004d001, 0x2000e7f8, 0x0000e7f6, 0x40048040, 0x000003c0, 0x6b65666b, 0xb081b5ff, 0x46144607, 0x2c00461d, 0x2004d102, 0xbdf0b005, 0x462a2304, 0x99024638, 0xffb7f7ff, 0x2e004606, 0x4630d001, 0xe01ce7f2, 0x44794910, 0x68099802, 0xcc016008, 0x4479490d, 0x6809390c, 0x20066048, 0x71c8490b, 0xfef4f7ff, 0x69b84606, 0xd0012800, 0x478069b8, 0xd0002e00, 0x9802e005, 0x90021d00, 0x2d001f2d, 0xbf00d1e0, 0xe7cf4630, 0x0000030a, 0x40020000, 0xb083b5ff, 0x2304460c, 0x9a054621, 0xf7ff9803, 0x9002ff82, 0x28009802, 0x9802d002, 0xbdf0b007, 0x68919a03, 0xf0006850, 0x4605f88f, 0x42684261, 0x424e4001, 0xd10042a6, 0x9f051976, 0x1b30e027, 0x98019001, 0xd90042b8, 0x98019701, 0x90000880, 0x44784811, 0x60046800, 0x49102001, 0x980071c8, 0x0e010400, 0x72c1480d, 0x9800490c, 0x98067288, 0xf7ff7248, 0x9002fea3, 0x28009802, 0x9802d001, 0x9801e7cc, 0x98011a3f, 0x19761824, 0x2f00bf00, 0x2000d1d5, 0x0000e7c2, 0x0000026e, 0x40020000, 0x4604b570, 0x2c00460d, 0x2004d101, 0x2040bd70, 0x71c84903, 0x71854608, 0xfe80f7ff, 0x0000e7f6, 0x40020000, 0xb081b5ff, 0x4617460c, 0x2d00461d, 0x2004d102, 0xbdf0b005, 0x463a2304, 0x98014621, 0xff19f7ff, 0x2e004606, 0x4630d001, 0xe022e7f2, 0x44784813, 0x60046800, 0x49122002, 0x980a71c8, 0x490f72c8, 0x39124479, 0x68096828, 0xf7ff6088, 0x4606fe55, 0xd00b2e00, 0x2800980b, 0x980bd001, 0x980c6004, 0xd0022800, 0x980c2100, 0xe0046001, 0x1d2d1f3f, 0x2f001d24, 0xbf00d1da, 0xe7c94630, 0x000001ce, 0x40020000, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, 0x2000b501, 0x46c046c0, 0x0002bd02, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000000, 0x00000000, 0x00000020, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000049, 'pc_erase_sector' : 0x2000006F, 'pc_program_page' : 0x2000009F, 'begin_stack' : 0x20000800, 'begin_data' : 0x20000800, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) # Note: 128 pages on KL25 and KL26, 256 pages on KL46 'static_base' : 0x20000000 + 0x20 + 0x5E8, 'min_program_length' : 4, 'page_buffers' : [0x20000800, 0x20000c00], # Enable double buffering 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000 # Analyzer 0x1ffff000..0x1ffff600 }; # @brief Flash algorithm for Kinetis L-series devices. class Flash_kl25z(Flash_Kinetis): def __init__(self, target): super(Flash_kl25z, self).__init__(target, FLASH_ALGO) class KL25Z(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x4000) ) def __init__(self, link): super(KL25Z, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL25Z4.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_MKL05Z32xxx4.py0000644000175000017500000001551613373511253021074 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x49302000, 0x48306008, 0xf0004448, 0x2800f8e9, 0x2001d001, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x492ab510, 0x44484828, 0xf8c2f000, 0x2c004604, 0x2100d105, 0x44484824, 0xf9bef000, 0xf0004604, 0x4620f838, 0xb570bd10, 0x481f4604, 0x4b1f4448, 0x68c24621, 0xf862f000, 0x2d004605, 0x481ad107, 0x23004448, 0x68c24621, 0xf956f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0x2f004607, 0x2201d10b, 0x46339001, 0x90029200, 0x46294622, 0x44484809, 0xf99af000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0x210168c0, 0x43880289, 0x49041840, 0x477060c8, 0x40048100, 0x00000004, 0x6b65666b, 0xf0003000, 0x4a102070, 0x20807010, 0xbf007010, 0x7800480d, 0x280009c0, 0x480bd0fa, 0x20207801, 0x28004008, 0x2067d001, 0x20104770, 0x28004008, 0x2068d001, 0x07c8e7f8, 0x28000fc0, 0x2069d001, 0x2000e7f2, 0x0000e7f0, 0x40020000, 0xb081b5ff, 0x460d4604, 0xf0009804, 0x4606f89f, 0xd0022e00, 0xb0054630, 0x2304bdf0, 0x46204629, 0xf0009a03, 0x4606f876, 0xd0012e00, 0xe7f24630, 0x18289803, 0x46381e47, 0xf00068e1, 0x2900f983, 0x4638d009, 0xf00068e1, 0x1c40f97d, 0x68e19000, 0x43489800, 0xe0131e47, 0x4478480c, 0x60056800, 0x490b2009, 0xf7ff71c8, 0x4606ffa7, 0x280069a0, 0x69a0d001, 0x2e004780, 0xe003d000, 0x194568e0, 0xd9e942bd, 0x4630bf00, 0x0000e7c5, 0x00000462, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0x2e004606, 0x4630d001, 0x2c00bd70, 0x2004d101, 0x2044e7fa, 0x71c84902, 0xff7ef7ff, 0x0000e7f4, 0x40020000, 0x29004601, 0x2004d101, 0x482a4770, 0x010068c0, 0x00400f00, 0x447b4b28, 0x03025a18, 0xd1012a00, 0xe7f12064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e4, 0xd1012a00, 0x47702004, 0x20006191, 0xb530e7fb, 0x2c004604, 0x2004d101, 0x1e58bd30, 0x28004008, 0x1e58d103, 0x28004010, 0x2065d001, 0x6820e7f4, 0xd8054288, 0x68206865, 0x188d1940, 0xd20142a8, 0xe7e92066, 0xe7e72000, 0x480c4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0x2b004603, 0x2004d101, 0x290f4770, 0x2a04d801, 0x2004d001, 0x2000e7f8, 0x0000e7f6, 0x40048040, 0x000003c0, 0x6b65666b, 0xb081b5ff, 0x46144607, 0x2c00461d, 0x2004d102, 0xbdf0b005, 0x462a2304, 0x99024638, 0xffb7f7ff, 0x2e004606, 0x4630d001, 0xe01ce7f2, 0x44794910, 0x68099802, 0xcc016008, 0x4479490d, 0x6809390c, 0x20066048, 0x71c8490b, 0xfef4f7ff, 0x69b84606, 0xd0012800, 0x478069b8, 0xd0002e00, 0x9802e005, 0x90021d00, 0x2d001f2d, 0xbf00d1e0, 0xe7cf4630, 0x0000030a, 0x40020000, 0xb083b5ff, 0x2304460c, 0x9a054621, 0xf7ff9803, 0x9002ff82, 0x28009802, 0x9802d002, 0xbdf0b007, 0x68919a03, 0xf0006850, 0x4605f88f, 0x42684261, 0x424e4001, 0xd10042a6, 0x9f051976, 0x1b30e027, 0x98019001, 0xd90042b8, 0x98019701, 0x90000880, 0x44784811, 0x60046800, 0x49102001, 0x980071c8, 0x0e010400, 0x72c1480d, 0x9800490c, 0x98067288, 0xf7ff7248, 0x9002fea3, 0x28009802, 0x9802d001, 0x9801e7cc, 0x98011a3f, 0x19761824, 0x2f00bf00, 0x2000d1d5, 0x0000e7c2, 0x0000026e, 0x40020000, 0x4604b570, 0x2c00460d, 0x2004d101, 0x2040bd70, 0x71c84903, 0x71854608, 0xfe80f7ff, 0x0000e7f6, 0x40020000, 0xb081b5ff, 0x4617460c, 0x2d00461d, 0x2004d102, 0xbdf0b005, 0x463a2304, 0x98014621, 0xff19f7ff, 0x2e004606, 0x4630d001, 0xe022e7f2, 0x44784813, 0x60046800, 0x49122002, 0x980a71c8, 0x490f72c8, 0x39124479, 0x68096828, 0xf7ff6088, 0x4606fe55, 0xd00b2e00, 0x2800980b, 0x980bd001, 0x980c6004, 0xd0022800, 0x980c2100, 0xe0046001, 0x1d2d1f3f, 0x2f001d24, 0xbf00d1da, 0xe7c94630, 0x000001ce, 0x40020000, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, 0x2000b501, 0x46c046c0, 0x0002bd02, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000000, 0x00000000, 0x00000020, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000049, 'pc_erase_sector' : 0x2000006F, 'pc_program_page' : 0x2000009F, 'begin_stack' : 0x20000800, 'begin_data' : 0x20000800, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) # Note: 128 pages on KL25 and KL26, 256 pages on KL46 'static_base' : 0x20000000 + 0x20 + 0x5E8, 'min_program_length' : 4, 'analyzer_supported' : False # Not enough space on KL02 and KL05 }; # @brief Flash algorithm for Kinetis L-series devices. class Flash_kl05z(Flash_Kinetis): def __init__(self, target): super(Flash_kl05z, self).__init__(target, FLASH_ALGO) class KL05Z(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffffc00, length=0x1000) ) def __init__(self, link): super(KL05Z, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL05Z4.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_MKW24D512xxx5.py0000644000175000017500000001401213373511253021134 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510483e, 0x5120f24c, 0xf64d81c1, 0x81c11128, 0xf0218801, 0x80010101, 0x78414839, 0x0160f001, 0xbf0c2940, 0x21002101, 0x444a4a36, 0xb1397011, 0xf0217841, 0x70410160, 0xf0117841, 0xd1fb0f60, 0x44484831, 0xf864f000, 0xbf182800, 0xbd102001, 0x4448482c, 0xb1587800, 0x78414829, 0x0160f021, 0x0140f041, 0x78417041, 0x0160f001, 0xd1fa2940, 0x47702000, 0xb5104824, 0x44484924, 0xf893f000, 0xbf182800, 0x2100bd10, 0xe8bd481f, 0x44484010, 0xb959f000, 0x4c1cb570, 0x444c4605, 0x4b1b4601, 0x68e24620, 0xf8b7f000, 0xbf182800, 0x2300bd70, 0x68e24629, 0x4070e8bd, 0x44484813, 0xb94df000, 0x460cb570, 0x4606460b, 0x480f4601, 0x4615b084, 0xf0004448, 0x2800f8ec, 0xb004bf1c, 0x2000bd70, 0xe9cd2101, 0x90021000, 0x462b4807, 0x46314622, 0xf0004448, 0xb004f980, 0x0000bd70, 0x40052000, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xbf042800, 0x47702004, 0x6cc949eb, 0x6103f3c1, 0xbf08290f, 0x2100f44f, 0x4ae8bf1f, 0xf832447a, 0x02891011, 0xe9c02200, 0x21022100, 0x61426081, 0x61820289, 0x1203e9c0, 0x51a0f04f, 0xf44f6201, 0x62415180, 0x47704610, 0xbf0e2800, 0x61012004, 0x47702000, 0x48da4602, 0x49d96840, 0x0070f440, 0x47706048, 0x217048d7, 0x21807001, 0x78017001, 0x0f80f011, 0x7800d0fb, 0x0f20f010, 0x2067bf1c, 0xf0104770, 0xbf1c0f10, 0x47702068, 0x0001f010, 0x2069bf18, 0x28004770, 0x2004bf04, 0xb5104770, 0x4ac84604, 0x403bf06f, 0x48c76050, 0xbf144281, 0x2000206b, 0xbf182800, 0x4620bd10, 0xffd2f7ff, 0x46204603, 0xffc6f7ff, 0xbd104618, 0xbf042800, 0x47702004, 0x60532300, 0x60d36093, 0x61536113, 0x61d36193, 0x68c16011, 0xe9d06051, 0xfbb11001, 0x6090f0f0, 0x21082004, 0x0103e9c2, 0x1005e9c2, 0x200061d0, 0xe92d4770, 0xb0884df0, 0x46984615, 0x4682460c, 0xf7ff466a, 0x462affd9, 0x46504621, 0xf0009b04, 0x0007f931, 0xb008bf1c, 0x8df0e8bd, 0x4600e9dd, 0x1e451960, 0xf0f6fbb5, 0x5010fb06, 0xfbb5b120, 0x1c40f0f6, 0x1e454370, 0xbf9842ac, 0xb270f8df, 0xf024d81c, 0xf040407f, 0xf8cb6010, 0x48990004, 0xbf144580, 0x2000206b, 0xbf1c2800, 0xe8bdb008, 0x46508df0, 0xff74f7ff, 0xf8da4607, 0x28000010, 0x4780bf18, 0x4434b917, 0xd9e242ac, 0xf7ff4650, 0xb008ff5f, 0xe8bd4638, 0x2a008df0, 0x2004bf04, 0xe92d4770, 0xb08945f0, 0x461e4614, 0x4680460d, 0xf7ff466a, 0x4632ff89, 0x46404629, 0xf0009b03, 0x0007f8e1, 0xb009bf1c, 0x85f0e8bd, 0x2e009d00, 0xf8dfbf18, 0xd025a1ec, 0x0b04f854, 0x0008f8ca, 0x28049803, 0xf025bf04, 0xf040407f, 0xd00960c0, 0xd1092808, 0x0b04f854, 0x000cf8ca, 0x407ff025, 0x60e0f040, 0x0004f8ca, 0xf7ff4640, 0xf8d8ff29, 0x46071010, 0xbf182900, 0xb91f4788, 0x44059803, 0xd1d91a36, 0xf7ff4640, 0xb009ff13, 0xe8bd4638, 0x280085f0, 0x2004bf04, 0x4a634770, 0x4101ea42, 0x60514a5f, 0xe92de70c, 0xb0884dff, 0x469a4614, 0x466a460d, 0xf7ff9808, 0x4622ff37, 0x9b054629, 0xf0009808, 0x2800f88f, 0xb00cbf1c, 0x8df0e8bd, 0x4629466a, 0xf7ff9808, 0x9e00ff27, 0x8008f8dd, 0xf1c84270, 0x40080100, 0x42b74247, 0x4447bf08, 0xbf182c00, 0xb128f8df, 0x1bbdd01f, 0xbf8842a5, 0x98054625, 0x417ff026, 0xf0f0fbb5, 0x7180f041, 0x1004f8cb, 0xea400400, 0xf040200a, 0xf8cb00ff, 0x98080008, 0xfeccf7ff, 0xbf1c2800, 0xe8bdb00c, 0x1b648df0, 0x4447442e, 0xb00cd1df, 0xe8bd2000, 0x2b008df0, 0x2004bf04, 0xe92d4770, 0xb0884dff, 0xe9dd4616, 0x461d7a14, 0x466a460c, 0x8058f8dd, 0xf7ff9808, 0xe9ddfee1, 0x46323007, 0xf0004621, 0x2800f839, 0xb00cbf1c, 0x8df0e8bd, 0x2e009c00, 0xb00cbf04, 0x8df0e8bd, 0xb094f8df, 0x407ff06f, 0x6707ea40, 0x407ff024, 0x7000f040, 0x0004f8cb, 0x7008f8cb, 0xf8cb6828, 0x9808000c, 0xfe88f7ff, 0xf1bab168, 0xbf180f00, 0x4000f8ca, 0x0f00f1b8, 0x2100bf1c, 0x1000f8c8, 0xe8bdb00c, 0x99078df0, 0xf0211a76, 0x440d0103, 0x440c9907, 0xb00cd1da, 0x8df0e8bd, 0xbf042800, 0x47702004, 0x0301f1a3, 0xbf0e4219, 0x2065421a, 0x68034770, 0xd806428b, 0x44116840, 0x42884418, 0x2000bf24, 0x20664770, 0x00004770, 0x40048000, 0x000003b8, 0x4001f000, 0x40020000, 0x6b65666b, 0x4000ffff, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000071, 'pc_program_page': 0x200000E1, 'pc_erase_sector': 0x200000B5, 'pc_eraseAll' : 0x20000095, 'static_base' : 0x20000000 + 0x00000020 + 0x00000508, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff800 }; # @brief Flash algorithm for Kinetis KW24D5 device. class Flash_kw24d5(Flash_Kinetis): def __init__(self, target): super(Flash_kw24d5, self).__init__(target, FLASH_ALGO) class KW24D5(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x1fff8000, length=0x10000) ) def __init__(self, transport): super(KW24D5, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKW24D5.svd") pyocd-0.13.1/pyocd/target/target_MK28FN2M0xxx15.py0000644000175000017500000001316513373511253021251 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510482e, 0x5120f24c, 0xf64d81c1, 0x81c11128, 0xf0218801, 0x80010101, 0x44484829, 0xf856f000, 0xbf182800, 0xbd102001, 0x47702000, 0xb5104824, 0x44484924, 0xf926f000, 0x4821b920, 0x44482100, 0xf9daf000, 0x684a4920, 0x0270f442, 0xbd10604a, 0x4c1bb570, 0x444c4605, 0x4b1a4601, 0x68e24620, 0xf88ef000, 0x2300b928, 0x46204629, 0xf00068e2, 0x4915f91f, 0xf442684a, 0x604a0270, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf8b8f000, 0x2000b958, 0xe9cd2101, 0x90021000, 0x462b4807, 0x46314622, 0xf0004448, 0x4906f963, 0xf442684a, 0x604a0270, 0xbd70b004, 0x40052000, 0x00000004, 0x6b65666b, 0x4001f000, 0xbf042800, 0x47702004, 0x6cc94926, 0x0e094a26, 0xf832447a, 0x03091011, 0x2064bf04, 0x22004770, 0x2100e9c0, 0x60812104, 0x60c10289, 0x780b491f, 0x7c80f44f, 0xf303fa0c, 0x78c96103, 0x1205e9c0, 0x47704610, 0xbf0e2800, 0x61812004, 0x47702000, 0xbf042800, 0x47702004, 0x42191e5b, 0x421abf0e, 0x47702065, 0x428b6803, 0x6840d806, 0x44184411, 0xbf244288, 0x47702000, 0x47702066, 0x4288490c, 0x206bbf14, 0x47702000, 0x290fb140, 0x2a04d802, 0xe005d104, 0xbf982913, 0xd0012a08, 0x47702004, 0x47702000, 0x40048000, 0x0000036c, 0x40020028, 0x6b65666b, 0x4df0e92d, 0x46154606, 0x4618460c, 0xffdcf7ff, 0xbf182800, 0x8df0e8bd, 0x462a2310, 0x46304621, 0xffbcf7ff, 0xbf180007, 0x8df0e8bd, 0x1e451960, 0xfbb568f0, 0xfb00f1f0, 0xb1125211, 0x43481c49, 0x42ac1e45, 0xf8dfd817, 0x44f88034, 0xb030f8df, 0x0a09f04f, 0x0000f8d8, 0xf88b6004, 0xf000a007, 0x4607f917, 0x280069b0, 0x4780bf18, 0x68f0b91f, 0x42ac4404, 0x4638d9ee, 0x8df0e8bd, 0x0000027a, 0x40020000, 0xbf042a00, 0x47702004, 0x4df0e92d, 0x4614461d, 0x4607460e, 0x462a2308, 0xff7ef7ff, 0x0b00ea5f, 0xe8bdbf18, 0x2d008df0, 0xf8dfbf1e, 0x44f8804c, 0x0a07f04f, 0xf8d8d01c, 0x60060000, 0x1000f8d8, 0x0b04f854, 0xf8d86048, 0xf8541000, 0x60880b04, 0xf880480a, 0xf000a007, 0x4683f8d9, 0x280069b8, 0x4780bf18, 0x0f00f1bb, 0x3608d102, 0xd1e23d08, 0xe8bd4658, 0x00008df0, 0x00000212, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff5d, 0xbd10bf18, 0xbf042c00, 0xbd102004, 0x49032044, 0xe8bd71c8, 0xf0004010, 0x0000b8b3, 0x40020000, 0x4df0e92d, 0x4614469a, 0x4605460e, 0xf7ff2310, 0x2800ff2d, 0xe8bdbf18, 0xe9d58df0, 0xfbb00101, 0x4270f8f1, 0x0100f1c8, 0x42474008, 0xbf0842b7, 0x2c004447, 0xf8dfbf18, 0xd01cb044, 0x42a51bbd, 0x4625bf88, 0x490e0928, 0x68094479, 0x2101600e, 0x1007f88b, 0xf88b0a01, 0xf88b100b, 0xf88b000a, 0xf000a009, 0x2800f87d, 0xe8bdbf18, 0x1b648df0, 0x4447442e, 0x2000d1e2, 0x8df0e8bd, 0x40020000, 0x0000014c, 0xbf122800, 0x20042a00, 0x29084770, 0xe8dfd215, 0x0604f001, 0x0c0a0806, 0x68c0100e, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2001e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xbf042b00, 0x47702004, 0x4df0e92d, 0xe9dd461c, 0x46158709, 0x2304460e, 0xa020f8dd, 0xfec4f7ff, 0xbf182800, 0x8df0e8bd, 0xbf1a2d00, 0xb04cf8df, 0xe8bd44fb, 0xf8db8df0, 0x60060000, 0x21024810, 0xf88071c1, 0xf8dba00b, 0x68201000, 0xf0006088, 0xb150f825, 0x0f00f1b8, 0xf8c8bf18, 0x2f006000, 0x2100bf1c, 0xe8bd6039, 0x1f2d8df0, 0x0404f104, 0x0604f106, 0xe8bdd1df, 0x00008df0, 0x000000a0, 0x40020000, 0xbf042800, 0x47702004, 0x48022240, 0x718171c2, 0xb802f000, 0x40020000, 0x2170480c, 0x21807001, 0x78017001, 0x0f80f011, 0x7800d0fb, 0x0f20f010, 0x2067bf1c, 0xf0104770, 0xbf1c0f10, 0x47702068, 0x0001f010, 0x2069bf18, 0x00004770, 0x40020000, 0x40020004, 0x00000000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000049, 'pc_program_page': 0x2000009F, 'pc_erase_sector': 0x20000071, 'pc_eraseAll' : 0x2000004D, 'static_base' : 0x20000000 + 0x00000020 + 0x0000046c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_k28f15(Flash_Kinetis): def __init__(self, target): super(Flash_k28f15, self).__init__(target, FLASH_ALGO) class K28F15(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x200000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1ffC0000, length=0x80000), RamRegion( start=0x34000000, length=0x80000), RamRegion( start=0x14000000, length=0x1000) ) def __init__(self, transport): super(K28F15, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK28F15.svd") pyocd-0.13.1/pyocd/target/target_LPC54114J256BD64.py0000644000175000017500000001055713373511253021115 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..coresight import ap from ..coresight.cortex_m import CortexM SYSCON_DEVICE_ID0 = 0x400000FF8 LPC54114J256 = 0x36454114 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x21002210, 0xf8c00690, 0x4a2c2630, 0xf0236813, 0x60134380, 0x1280f8c0, 0x1284f8c0, 0x68134a28, 0x4370f423, 0xf8c06013, 0x21021380, 0x20006001, 0x20004770, 0xb5104770, 0x20002107, 0xf844f000, 0xbf182800, 0x4a1fbd10, 0xe8bd2107, 0x20004010, 0xb864f000, 0x0bc4b510, 0x46084621, 0xf834f000, 0xbf182800, 0x4a17bd10, 0xe8bd4621, 0x46084010, 0xb854f000, 0x4614b570, 0xd10e0005, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x0be861e0, 0xf0004601, 0x2800f813, 0xbd70bf18, 0x46214b06, 0xe8bd4628, 0xf44f4070, 0xf0007280, 0x0000b818, 0x40000500, 0x40000400, 0x00b71b00, 0xb08bb500, 0x92002232, 0x0101e9cd, 0x46684a39, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0xb500bd00, 0xf04fb08b, 0x92030c33, 0xc000f8cd, 0x0101e9cd, 0x707af44f, 0xf0f0fbb3, 0x4a2d9004, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x93002334, 0x0101e9cd, 0x707af44f, 0xf0f0fbb2, 0x4a229003, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x9300233b, 0x0101e9cd, 0x707af44f, 0xf0f0fbb2, 0x4a179003, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x92002235, 0x0101e9cd, 0x46684a0e, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0xb500bd00, 0x2338b08b, 0x93009203, 0x0101e9cd, 0x46684a05, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0x0000bd00, 0x03000205, 0x00000000 ], # Relative function addresses 'pc_init': 0x20000021, 'pc_unInit': 0x20000053, 'pc_program_page': 0x20000095, 'pc_erase_sector': 0x20000075, 'pc_eraseAll': 0x20000057, 'begin_stack' : 0x20001000, 'begin_data' : 0x20003000, 'page_buffers' : [0x20003000], 'static_base' : 0x200001dc, 'page_size' : 0x00000100, 'min_program_length' : 256, 'analyzer_supported' : False }; class Flash_lpc54114(Flash): def __init__(self, target): super(Flash_lpc54114, self).__init__(target, FLASH_ALGO) def program_page(self, flashPtr, bytes): write_size = 256 for i in range(0, 128): data = bytes[i * write_size : (i + 1) * write_size] Flash.program_page(self, flashPtr + i * write_size, data) class LPC54114(CoreSightTarget): memoryMap = MemoryMap( FlashRegion(name='flash', start=0, length=0x40000, blocksize=0x8000, is_boot_memory=True), RamRegion( name='sramx', start=0x04000000, length=0x8000), RamRegion( name='sram0', start=0x20000000, length=0x10000), RamRegion( name='sram1', start=0x20010000, length=0x10000), RamRegion( name='sram2', start=0x20020000, length=0x8000) ) def __init__(self, link): super(LPC54114, self).__init__(link, self.memoryMap) self.ignoreReset = False self._svd_location = SVDFile(vendor="NXP", filename="LPC54114_cm0plus.svd", is_local=False) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC54114, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40000000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_ncs36510.py0000644000175000017500000001303113373511253020321 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging FLASH_ALGO = { 'load_address' : 0x3fff4000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4770ba40, 0x4770bac0, 0x4770ba40, 0x4770bac0, 0xf2402a03, 0xf0108030, 0xf0000c03, 0xf8118015, 0xf1bc3b01, 0x44620f02, 0xf811bf98, 0xf800cb01, 0xbf383b01, 0x3b01f811, 0x0204f1a2, 0xf800bf98, 0xbf38cb01, 0x3b01f800, 0x0303f011, 0x8025f000, 0xf0c03a08, 0xf8518008, 0x3a083b04, 0xcb04f851, 0x1008e8a0, 0x1d12e7f5, 0xf851bf5c, 0xf8403b04, 0xf3af3b04, 0x07d28000, 0xf811bf24, 0xf8113b01, 0xbf48cb01, 0x2b01f811, 0xf800bf24, 0xf8003b01, 0xbf48cb01, 0x2b01f800, 0xb5104770, 0xf0c03a20, 0xe8b1800b, 0x3a205018, 0x5018e8a0, 0x5018e8b1, 0x5018e8a0, 0xaff5f4bf, 0x7c02ea5f, 0xe8b1bf24, 0xe8a05018, 0xbf445018, 0xc018c918, 0x4010e8bd, 0x7c82ea5f, 0xf851bf24, 0xf8403b04, 0xbf083b04, 0x07d24770, 0xf831bf28, 0xbf483b02, 0x2b01f811, 0xf820bf28, 0xbf483b02, 0x2b01f800, 0x20004770, 0x00004770, 0xb5104803, 0xf0004478, 0x2000f8b5, 0x0000bd10, 0x00000390, 0x9800b501, 0x5f00f5b0, 0x2001bf3c, 0xf410bd08, 0x466a1f80, 0x0102f04f, 0x4804bf1c, 0xbf044478, 0x44784803, 0xf80ef000, 0xbd082000, 0x00000370, 0x0000035e, 0x69c14770, 0x0f01f011, 0x69c0bf18, 0x00004770, 0x4c44b410, 0xc110f8df, 0xd27f2906, 0xf001e8df, 0x562a037e, 0x6801704a, 0x1f80f411, 0xf44fbf14, 0xf44f1181, 0x68425100, 0x684160d1, 0x6801610c, 0x1f80f411, 0xbf146841, 0xc018f8c1, 0xc014f8c1, 0x68422102, 0x68016091, 0xf4116840, 0xd0041f80, 0xf0116801, 0xd1fb0f02, 0x6801e058, 0x0f01f011, 0xe053d1fb, 0x68426811, 0x68026114, 0x1f80f412, 0xbf146842, 0xc018f8c2, 0xc014f8c2, 0x60d16842, 0x21016842, 0x68016091, 0xf4116840, 0xd0041f80, 0xf0116801, 0xd1fb0f02, 0x6801e038, 0x0f01f011, 0xe033d1fb, 0x68406801, 0x1f80f411, 0xbf146841, 0x0101f041, 0x0102f041, 0xe0276041, 0xf4116801, 0x68411f80, 0xbf14684a, 0x0201f022, 0x0202f022, 0x6801604a, 0xf4116840, 0xd0041f80, 0xf0116801, 0xd1fb0f02, 0x6801e012, 0x0f01f011, 0xe00dd1fb, 0x68406801, 0x1f80f411, 0x6801d004, 0x0f02f011, 0xe003d1fb, 0xf0116801, 0xd1fb0f01, 0x2001bc10, 0x00004770, 0xbb781ae9, 0xb56d9099, 0xf4116801, 0x68411f80, 0xf44fbf14, 0xf44f1281, 0x60ca5200, 0x49076842, 0x68016111, 0xf4116842, 0x49051f80, 0x6191bf14, 0x21026151, 0x60816840, 0x00004770, 0xbb781ae9, 0xb56d9099, 0x4a086843, 0x6802611a, 0xf4126843, 0x4a061f80, 0x619abf14, 0x6842615a, 0x684060d1, 0x60812101, 0x00004770, 0xbb781ae9, 0xb56d9099, 0x68406801, 0x1f80f411, 0xbf146841, 0x0101f041, 0x0102f041, 0x47706041, 0x68406801, 0x1f80f411, 0xbf146841, 0x0101f021, 0x0102f021, 0x47706041, 0x1e5b6808, 0xf810d305, 0xf802cb01, 0x1e5bcb01, 0x6008d2f9, 0x47702001, 0x68406801, 0x1f80f411, 0x6801d004, 0x0f02f011, 0x4770d1fb, 0xf0116801, 0xd1fb0f01, 0x00004770, 0x49056842, 0x68016111, 0xf4116840, 0x49031f80, 0x6181bf14, 0x47706141, 0xbb781ae9, 0xb56d9099, 0x4614b510, 0x68084602, 0x5f00f5b0, 0x010af3c0, 0xb131d20b, 0x0c0af3c0, 0x6100f5cc, 0xd905428b, 0xf5b3e00a, 0xd8076f00, 0xb139e00b, 0x0c0af3c0, 0x6100f5cc, 0xd904428b, 0xbd102000, 0x6f00f5b3, 0xf8d2d8fa, 0xf8dcc004, 0xf0411004, 0xf8cc0140, 0xf8d21004, 0x4908c004, 0x1010f8cc, 0x68526811, 0x1f80f411, 0xbf144905, 0x61516191, 0x4621461a, 0xfe1af7ff, 0xbd102001, 0xbb781ae9, 0xb56d9099, 0xb5104916, 0xf422690a, 0x610a0200, 0x22e0f04f, 0xf8c2211f, 0xf8c21180, 0x4a111280, 0x6120f04f, 0xf4106011, 0xf04f1f80, 0xf04f0200, 0xd0080103, 0x4478480c, 0xfe9ef7ff, 0x2200480b, 0x44782104, 0x480ae007, 0xf7ff4478, 0x4808fe95, 0x21042200, 0xf7ff4478, 0x2000fe8f, 0x0000bd10, 0x4001b000, 0xe000ed04, 0x0000008a, 0x00000072, 0x0000006c, 0x9800b507, 0x5f00f5b0, 0x460bd310, 0x1f80f410, 0xbf1c4669, 0x44784807, 0x4807bf04, 0xf7ff4478, 0x2801ff77, 0x2000bf02, 0xbd00b003, 0xb0032001, 0x0000bd00, 0x00000036, 0x00000024, 0x47702000, 0x47702000, 0x00000000, 0x40017000, 0x00000008, 0x00100000, 0x40017000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, ], 'pc_init' : 0x3FFF4409, 'pc_verify' : 0x3FFF44B9, 'pc_uninit' : 0x3FFF44B5, 'pc_eraseAll' : 0x3FFF4125, 'pc_program_page' : 0x3FFF4479, 'pc_erase_sector' : 0x3FFF4139, 'static_base' : 0x3fff4000 + 0x00000020 + 0x000004b4, 'begin_data' : 0x3fff4000 + 0x00000A00, 'begin_stack' : 0x3fff4800, 'page_size' : 0x00000800, 'min_program_length' : 0x00000800, 'analyzer_supported' : False, } class Flash_ncs36510(Flash): def __init__(self, target): super(Flash_ncs36510, self).__init__(target, FLASH_ALGO) class NCS36510(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x2000, length=0x50000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x3FFF4000, length=0xC000) ) def __init__(self, link): super(NCS36510, self).__init__(link, self.memoryMap) pyocd-0.13.1/pyocd/target/target_MKL26Z256xxx4.py0000644000175000017500000001571413373511253021167 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x49302000, 0x48306008, 0xf0004448, 0x2800f8e9, 0x2001d001, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x492ab510, 0x44484828, 0xf8c2f000, 0x2c004604, 0x2100d105, 0x44484824, 0xf9bef000, 0xf0004604, 0x4620f838, 0xb570bd10, 0x481f4604, 0x4b1f4448, 0x68c24621, 0xf862f000, 0x2d004605, 0x481ad107, 0x23004448, 0x68c24621, 0xf956f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0x2f004607, 0x2201d10b, 0x46339001, 0x90029200, 0x46294622, 0x44484809, 0xf99af000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0x210168c0, 0x43880289, 0x49041840, 0x477060c8, 0x40048100, 0x00000004, 0x6b65666b, 0xf0003000, 0x4a102070, 0x20807010, 0xbf007010, 0x7800480d, 0x280009c0, 0x480bd0fa, 0x20207801, 0x28004008, 0x2067d001, 0x20104770, 0x28004008, 0x2068d001, 0x07c8e7f8, 0x28000fc0, 0x2069d001, 0x2000e7f2, 0x0000e7f0, 0x40020000, 0xb081b5ff, 0x460d4604, 0xf0009804, 0x4606f89f, 0xd0022e00, 0xb0054630, 0x2304bdf0, 0x46204629, 0xf0009a03, 0x4606f876, 0xd0012e00, 0xe7f24630, 0x18289803, 0x46381e47, 0xf00068e1, 0x2900f983, 0x4638d009, 0xf00068e1, 0x1c40f97d, 0x68e19000, 0x43489800, 0xe0131e47, 0x4478480c, 0x60056800, 0x490b2009, 0xf7ff71c8, 0x4606ffa7, 0x280069a0, 0x69a0d001, 0x2e004780, 0xe003d000, 0x194568e0, 0xd9e942bd, 0x4630bf00, 0x0000e7c5, 0x00000462, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0x2e004606, 0x4630d001, 0x2c00bd70, 0x2004d101, 0x2044e7fa, 0x71c84902, 0xff7ef7ff, 0x0000e7f4, 0x40020000, 0x29004601, 0x2004d101, 0x482a4770, 0x010068c0, 0x00400f00, 0x447b4b28, 0x03025a18, 0xd1012a00, 0xe7f12064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e4, 0xd1012a00, 0x47702004, 0x20006191, 0xb530e7fb, 0x2c004604, 0x2004d101, 0x1e58bd30, 0x28004008, 0x1e58d103, 0x28004010, 0x2065d001, 0x6820e7f4, 0xd8054288, 0x68206865, 0x188d1940, 0xd20142a8, 0xe7e92066, 0xe7e72000, 0x480c4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0x2b004603, 0x2004d101, 0x290f4770, 0x2a04d801, 0x2004d001, 0x2000e7f8, 0x0000e7f6, 0x40048040, 0x000003c0, 0x6b65666b, 0xb081b5ff, 0x46144607, 0x2c00461d, 0x2004d102, 0xbdf0b005, 0x462a2304, 0x99024638, 0xffb7f7ff, 0x2e004606, 0x4630d001, 0xe01ce7f2, 0x44794910, 0x68099802, 0xcc016008, 0x4479490d, 0x6809390c, 0x20066048, 0x71c8490b, 0xfef4f7ff, 0x69b84606, 0xd0012800, 0x478069b8, 0xd0002e00, 0x9802e005, 0x90021d00, 0x2d001f2d, 0xbf00d1e0, 0xe7cf4630, 0x0000030a, 0x40020000, 0xb083b5ff, 0x2304460c, 0x9a054621, 0xf7ff9803, 0x9002ff82, 0x28009802, 0x9802d002, 0xbdf0b007, 0x68919a03, 0xf0006850, 0x4605f88f, 0x42684261, 0x424e4001, 0xd10042a6, 0x9f051976, 0x1b30e027, 0x98019001, 0xd90042b8, 0x98019701, 0x90000880, 0x44784811, 0x60046800, 0x49102001, 0x980071c8, 0x0e010400, 0x72c1480d, 0x9800490c, 0x98067288, 0xf7ff7248, 0x9002fea3, 0x28009802, 0x9802d001, 0x9801e7cc, 0x98011a3f, 0x19761824, 0x2f00bf00, 0x2000d1d5, 0x0000e7c2, 0x0000026e, 0x40020000, 0x4604b570, 0x2c00460d, 0x2004d101, 0x2040bd70, 0x71c84903, 0x71854608, 0xfe80f7ff, 0x0000e7f6, 0x40020000, 0xb081b5ff, 0x4617460c, 0x2d00461d, 0x2004d102, 0xbdf0b005, 0x463a2304, 0x98014621, 0xff19f7ff, 0x2e004606, 0x4630d001, 0xe022e7f2, 0x44784813, 0x60046800, 0x49122002, 0x980a71c8, 0x490f72c8, 0x39124479, 0x68096828, 0xf7ff6088, 0x4606fe55, 0xd00b2e00, 0x2800980b, 0x980bd001, 0x980c6004, 0xd0022800, 0x980c2100, 0xe0046001, 0x1d2d1f3f, 0x2f001d24, 0xbf00d1da, 0xe7c94630, 0x000001ce, 0x40020000, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, 0x2000b501, 0x46c046c0, 0x0002bd02, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000000, 0x00000000, 0x00000020, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000049, 'pc_erase_sector' : 0x2000006F, 'pc_program_page' : 0x2000009F, 'begin_stack' : 0x20000800, 'begin_data' : 0x20000800, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) # Note: 128 pages on KL25 and KL26, 256 pages on KL46 'static_base' : 0x20000000 + 0x20 + 0x5E8, 'min_program_length' : 4, 'page_buffers' : [0x20000800, 0x20000c00], # Enable double buffering 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000 # Analyzer 0x1ffff000..0x1ffff600 }; # @brief Flash algorithm for Kinetis L-series devices. class Flash_kl26z(Flash_Kinetis): def __init__(self, target): super(Flash_kl26z, self).__init__(target, FLASH_ALGO) class KL26Z(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x4000) ) def __init__(self, link): super(KL26Z, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL26Z4.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_MKV11Z128xxx7.py0000644000175000017500000001564013373511253021172 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8fcf000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9c9, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf8a4f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf96ef000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4809b510, 0x81c14907, 0x81c14908, 0x08498801, 0x80010049, 0x44484806, 0xf8f2f000, 0xd0002800, 0xbd102001, 0x0000c520, 0x40052000, 0x0000d928, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f903, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf978f000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0082800, 0xd802290f, 0xd1042a04, 0x2913e005, 0x2a08d801, 0x2004d001, 0x20004770, 0x28004770, 0x2004d101, 0xb4104770, 0x460c1e5b, 0xd101421c, 0xd002421a, 0x2065bc10, 0x68034770, 0xd804428b, 0x18896840, 0x42881818, 0xbc10d202, 0x47702066, 0x2000bc10, 0x00004770, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb2, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe2cf7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000027a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2001e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd00a2800, 0x68c9490f, 0x0e094a0f, 0x447a0049, 0x03095a51, 0x2064d103, 0x20044770, 0xb4104770, 0x60032300, 0x21016041, 0x02896081, 0x490760c1, 0x158a7a0c, 0x610240a2, 0x61837ac9, 0xbc106141, 0x47704618, 0x40048040, 0x000001aa, 0x40020020, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff19f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff30f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfee7f7ff, 0xd12a2800, 0x686868a9, 0xfd64f7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfeeaf7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fecf, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfe99f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeaef7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00200000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002F9, 'pc_program_page': 0x200002B1, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x0000063c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff800 }; # @brief Flash algorithm for Kinetis KV11Z7 device. class Flash_kv11z7(Flash_Kinetis): def __init__(self, target): super(Flash_kv11z7, self).__init__(target, FLASH_ALGO) class KV11Z7(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x4000) ) def __init__(self, transport): super(KV11Z7, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKV11Z7.svd") pyocd-0.13.1/pyocd/target/target_LPC4330.py0000644000175000017500000010742113373511253020076 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash, DEFAULT_CHIP_ERASE_WEIGHT, FlashInfo from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2, 0x4770ba40, 0x4770bac0, 0xb5104935, 0x22004449, 0x604a600a, 0x608a4a33, 0x32fff04f, 0x220860ca, 0x4931610a, 0x60084449, 0x48304931, 0x49316708, 0x600820f3, 0x610820d3, 0x608860c8, 0x20136048, 0x48276148, 0x4448230c, 0x210322c0, 0xf0003880, 0x2800fb23, 0x2001d000, 0x2000bd10, 0x48204770, 0x44482100, 0xf1a06001, 0x68890180, 0x491d6041, 0x21046081, 0x46016101, 0xf0013880, 0x491ab890, 0x4449b510, 0x1a416809, 0x44484815, 0xf44f6001, 0x60415180, 0x60814913, 0x61012120, 0x38804601, 0xf87df001, 0xd0002800, 0xbd102001, 0x4a0e4613, 0x444ab510, 0x1a826812, 0x44484809, 0x2100e9c0, 0x60814908, 0x60c12100, 0x61012108, 0x46194602, 0xf0003880, 0x2800ff3e, 0x2001d000, 0xbd10, 0x88, 0x10080000, 0x4, 0x1000800, 0x40050000, 0x4008618c, 0x604849f9, 0xc800480, 0x2801d006, 0x2802d008, 0x2803d008, 0x6948d008, 0x79269ca, 0x4770d4fc, 0xe7f97d08, 0xe7f78a88, 0x7d0a8a88, 0x4002ea40, 0xb510e7f2, 0x1400f44f, 0x5141eb04, 0x6000ea41, 0x4002ea40, 0xbd104318, 0x3406a80, 0xf44fd502, 0x477010c0, 0x47702000, 0x4604b510, 0x46084613, 0x46112200, 0xffe5f7ff, 0x46204601, 0xffecf7ff, 0x4010e8bd, 0xe7c34308, 0xb5004bdb, 0xf7ff609a, 0x4308ffe3, 0xeb04f85d, 0xb530e7ba, 0x46054cd6, 0x46114608, 0x230060a3, 0xf7ff461a, 0x4601ffca, 0xf7ff4628, 0x4301ffd1, 0x69e06061, 0xd4fc0780, 0x2200bd30, 0xe7cf2106, 0x460db5f0, 0x461f4616, 0xf7ff4604, 0x463bfff6, 0x46294632, 0xe8bd4620, 0xe7da40f0, 0x460db5f0, 0x461c4616, 0xf7ff4607, 0x49c1ffe8, 0x4638608e, 0xffaef7ff, 0xf4404328, 0x60484000, 0xc8004a8, 0x2801d007, 0xb2a2d00b, 0xd00a2802, 0xd0042803, 0x69c8614c, 0xd4fc0780, 0x828abdf0, 0x750c0c24, 0x828ae7f7, 0x49b2e7f5, 0xf01369cb, 0xd0190f06, 0x61ca2210, 0xf01269ca, 0xd1fb0f16, 0xd511075a, 0xf40269c2, 0xf5b20260, 0xd30b0f40, 0x730a22ff, 0xf36f69c0, 0xf100000f, 0x60480001, 0x69c87d08, 0xd4fc0780, 0xe92d4770, 0x460541f0, 0x46882400, 0x21017cea, 0xf102fa01, 0x46204f9d, 0x69f9b2ce, 0xd4fc0789, 0x6c20f644, 0x45641c64, 0x2201d207, 0x46282105, 0xff64f7ff, 0x4230b2c0, 0x4230d0f4, 0x75284e94, 0xea5fd00a, 0xd00c0008, 0xd00c2801, 0xd0062802, 0xf03f1b8, 0xe008d10b, 0xe8bd4630, 0x4c8d81f0, 0x4c8de005, 0x4c8de003, 0xf04fe001, 0x462834ff, 0xff3cf7ff, 0x4308498a, 0x43087ce9, 0x69f86078, 0xd5020780, 0xd1fa1e64, 0xb1ece01e, 0x75287d38, 0xf00f1b8, 0x6ae8d01e, 0xb2c1b1e0, 0xd0172905, 0x46282201, 0xff2af7ff, 0x7568b2c0, 0xea106ae9, 0xd00f2f11, 0x4107f3c1, 0x2200b119, 0xf7ff4628, 0x4873ff1d, 0xe7c81c80, 0xf7ff4628, 0xe7c3ff7a, 0xe7eb7d28, 0xe7c02000, 0x4615b530, 0x460b4604, 0x46112200, 0xf7ff2001, 0x4601fef6, 0x2200462b, 0xf7ff4620, 0x6aa0ff41, 0xd5010480, 0xbd302000, 0xe8bd4620, 0x21004030, 0xb5f0e77b, 0x69c44605, 0x26a66a80, 0xd50b0581, 0x120f404, 0xf00f5b1, 0xf444d106, 0x61ec1400, 0xf4416a29, 0x62291100, 0xd5180681, 0xd5010540, 0xe0002702, 0x1d3f2701, 0x21852201, 0xf7ff4628, 0xf000fed9, 0x69e80307, 0x110f1c7, 0x20e0f400, 0x430340c8, 0x21812201, 0xf7ff4628, 0x6aa8fefb, 0xd00707c0, 0x22032300, 0x462821a3, 0xfedbf7ff, 0xd1fd1e76, 0x5142f3c4, 0x29064842, 0x21a5d304, 0xf4247301, 0xe0010440, 0x730121ff, 0xbdf06184, 0x4604b510, 0x6006a80, 0x2201d511, 0x4620212b, 0xfea8f7ff, 0x6aa17560, 0xf4210600, 0xd5023170, 0x3080f44f, 0xf44fe001, 0x43014080, 0xbd1062a1, 0x2300b530, 0x84836381, 0x84c32307, 0x8c83e010, 0x442388cc, 0x790b8483, 0x88cd8cc4, 0xd00107db, 0xe0002302, 0xfb052301, 0x31084303, 0x3a0884c3, 0xd2ec2a08, 0x1ccf3c3, 0xbd3084c1, 0xb1226b82, 0x8c82b109, 0x8cc0800a, 0xb1114770, 0xc126882, 0x6880800a, 0x47700cc0, 0x4604b510, 0x33cf100, 0xf7ff2100, 0x1ffeb, 0x6aa0d01f, 0x7080f440, 0x462062a0, 0xfe56f7ff, 0x201ea40, 0x43024817, 0x60424810, 0x7d02e002, 0x2b01f803, 0xf1a1000a, 0xb2890101, 0x2100d1f7, 0x42a33480, 0xf803d202, 0xe7fa1b01, 0x78969c1, 0xbd10d4fc, 0x22011c49, 0xf04f408a, 0x60826100, 0xd900428a, 0x60c2460a, 0x4770, 0x40003000, 0x20003, 0x38270, 0x419ce0, 0xa408300, 0x5204000, 0x72200000, 0x41f0e92d, 0x460d4604, 0x49fe69c0, 0x46984616, 0xd06e4288, 0x62a54620, 0xff6af7ff, 0xf1b068a0, 0xd9197f80, 0xf4406aa0, 0x62a07000, 0x28017c20, 0x2820d006, 0x28c2d00b, 0xf04fd009, 0xe6b81002, 0x22012380, 0x46202117, 0xfe1df7ff, 0x2200e004, 0x462021b7, 0xfdfef7ff, 0xd5040568, 0x680148ea, 0x5180f041, 0x4fe96001, 0xd5240768, 0x21352201, 0xf7ff4620, 0xb2c0fdef, 0x7817560, 0x7c0d455, 0x2201d135, 0x46202105, 0xfde4f7ff, 0xf0417d61, 0xea400102, 0xb2822001, 0x46202102, 0xfec8f7ff, 0xd1cc2800, 0x21352201, 0xf7ff4620, 0x7560fdd3, 0x7080ea4f, 0x4e8e019, 0x2201d51c, 0x46202105, 0xfdc8f7ff, 0x7520b2c0, 0xd42e0641, 0x240f040, 0x46202101, 0xfeacf7ff, 0xd1b02800, 0x21052201, 0xf7ff4620, 0x7520fdb7, 0x28000640, 0x4638db1d, 0xe04ee65f, 0xd5180728, 0x213f2201, 0xf7ff4620, 0xb2c0fda9, 0x6017560, 0xf040d40f, 0x22010380, 0x4620213e, 0xfdcef7ff, 0x213f2201, 0xf7ff4620, 0x7560fd99, 0x6000ea4f, 0x7a8e7df, 0x2200d505, 0x46202138, 0xfd8ef7ff, 0x6e8e017, 0x568d515, 0x2740d501, 0x2780e000, 0x21652201, 0xf7ff4620, 0xb2c0fd81, 0x42387560, 0xf040d007, 0x43bb03c8, 0x21612201, 0xf7ff4620, 0xf3c6fda5, 0x280340c1, 0xd0106aa0, 0x2080f420, 0x52862a0, 0xf3c6d507, 0x1e5b4302, 0x21c02201, 0xf7ff4620, 0xe9c4fd7c, 0x20006807, 0xf440e60d, 0xe7ed2080, 0x41f0e92d, 0x46044e99, 0x69b0460f, 0x46984615, 0xf40f410, 0x4601d04d, 0x40c1f3c0, 0x280361e1, 0x2000d04a, 0x462062a0, 0xfda9f7ff, 0x21ff2200, 0xf7ff4620, 0x2200fd41, 0x46112301, 0xf7ff2065, 0xf440fd28, 0xf7ff10c0, 0xf1a0fd0b, 0x29800140, 0x681d208, 0xf040d406, 0x220103c0, 0x46202161, 0xfd5af7ff, 0x46202180, 0xfcbff001, 0xc1f005, 0xd02428c1, 0x2170f44f, 0x4107ea01, 0x50c0ea41, 0x71fff64f, 0x60304408, 0x219f2203, 0xf7ff4620, 0xf04ffd13, 0x61204100, 0x1600e9c4, 0xf06fb130, 0x4288417f, 0x4973d002, 0xd10b4288, 0x1d404870, 0xf440e5b1, 0xe7af0140, 0x2080f44f, 0x486ce7b2, 0xe5a81e40, 0x4080f44f, 0x201c62a0, 0x209c8360, 0x4f658320, 0xd50107a8, 0xe0004638, 0xf8444866, 0x48660f1c, 0x20206060, 0x200c7620, 0x20d87520, 0x201076a0, 0xf81475a0, 0xf1a40c0c, 0x287f041c, 0xdc0cd029, 0xd01d281f, 0x2801dc04, 0x281cd014, 0xe014d139, 0xd0182820, 0xd1342837, 0x28c2e018, 0xdc04d022, 0xd019288c, 0xd12c28bf, 0x28c8e019, 0x28efd01d, 0xe01dd127, 0x447b4b51, 0x4b51e01c, 0xe019447b, 0x447b4b50, 0x4b50e016, 0xe013447b, 0x447b4b4f, 0x4b4fe010, 0xe00d447b, 0x447b4b4e, 0x4b4ee00a, 0xe007447b, 0x447b4b4d, 0x4b4de004, 0xe001447b, 0x447b4b4c, 0x4642b12b, 0x46204629, 0x46064798, 0x4e3ae001, 0xb3061d36, 0x61e72500, 0xf0014628, 0x2103fb1a, 0x22002301, 0xf7ff4608, 0x4601fc78, 0x46202200, 0xfc96f7ff, 0xb10d4601, 0xe00020ff, 0x42812000, 0x1c6dd102, 0xdbe72d02, 0xd10a2d02, 0xf4406aa0, 0x62a07000, 0x6aa0e005, 0xd5020400, 0xf7ff4620, 0x4620fe01, 0xfd73f7ff, 0xe5184630, 0x4dffe92d, 0x4683b08a, 0x90032000, 0x68c6980b, 0xf7ff4658, 0x4658fcc2, 0xfdaaf7ff, 0x8028f8db, 0x4048ea5f, 0xf8bbd576, 0xf0080018, 0xf4000104, 0x4308407f, 0x2001d000, 0x22014682, 0x46582105, 0xfc48f7ff, 0x14f88b, 0xaea5f, 0x2201d004, 0x46582135, 0xfc3ef7ff, 0x15f88b, 0x4014f8bb, 0xd0311c70, 0xf8bbb16e, 0xea240018, 0x40300200, 0xf10a4302, 0xb2c10001, 0xf7ff4658, 0x9003fd19, 0xe02ce067, 0x3803fff, 0x40003000, 0x20005, 0xcccccc, 0xb813fff, 0x2808000, 0x13e1, 0xe51, 0xc57, 0x1243, 0xbab, 0xd5d, 0xeef, 0x1461, 0x104f, 0xf99, 0x1529, 0x7800980c, 0x980db310, 0xf8bb8802, 0x4002001a, 0x43224384, 0xf8bbe7c9, 0x4220001a, 0x990cd037, 0x25002001, 0x980d7008, 0xf10a8004, 0xb2c70001, 0x1af8bb, 0xea244639, 0x46580200, 0xfcd4f7ff, 0xb1209003, 0x2d031c6d, 0xe189dbf2, 0x20a6e01f, 0xd1fd1e40, 0x21052201, 0xf7ff4658, 0xf88bfbd7, 0xea5f0014, 0xd004000a, 0x21352201, 0xf7ff4658, 0xf88bfbcd, 0xf8bb0015, 0xf8bb0014, 0x4208101a, 0x48f9d002, 0xe16b9003, 0x28009803, 0xf418d1dd, 0xd0da3f60, 0xf8db2000, 0x46045038, 0x20019006, 0xb10e9008, 0xe00020ff, 0x90092000, 0x90002000, 0xf44f980b, 0xe9d03780, 0x44081000, 0xf10b9002, 0x4682003c, 0xf8db9005, 0xa907001c, 0x5040f3c0, 0x90011cc0, 0xf7ff4658, 0x9004fd1d, 0xf8bdb915, 0x9006001c, 0x4008ea5f, 0xea5fd505, 0xd40250c8, 0xf7ff4658, 0x1c70fd1d, 0xb1b6d001, 0x980ce104, 0xb1587800, 0x4008ea5f, 0xe9ddd5f8, 0x990d2004, 0xfa9ef001, 0xf8ad2000, 0xe0f5001c, 0xf7ff4658, 0x2000fc7c, 0xe8bdb00e, 0x990c8df0, 0x70082000, 0x4008ea5f, 0xe9ddd5e2, 0x980d2104, 0xfa88f001, 0x9806e0e2, 0x88e8bb28, 0x68289006, 0xf9959000, 0x28000005, 0x4240da00, 0x40872701, 0x7c07928, 0x1b0d021, 0x1006ea40, 0x86ea40, 0xb2c04330, 0x20029009, 0x2c409008, 0x2c10d00c, 0x2c04d00a, 0x2c01d008, 0x2c20d006, 0x2c08d00a, 0x2c02d008, 0xe017d006, 0xf7ff4658, 0xf04ffc40, 0xe7c11002, 0x454ea44, 0xb10ee00e, 0xe00020ff, 0x90092000, 0x90082001, 0xd0032c30, 0xd0012c0c, 0xd1012c03, 0x444ea04, 0xb125b934, 0x7c07928, 0x24c0d001, 0x2480e000, 0x6801980b, 0x44389800, 0xd2784281, 0x98029900, 0xd9744288, 0x3f40f418, 0x1c70d063, 0x2e00d00b, 0xea5fdd1b, 0xd50b30c8, 0x2136460b, 0x9a014658, 0xfb32f7ff, 0xf89ae04e, 0x42200000, 0xe049d1f1, 0x22002301, 0x990120e5, 0xfae3f7ff, 0x23014601, 0x9a004658, 0xfb2ef7ff, 0xd13be03c, 0x30c8ea5f, 0x203cd501, 0x20e8e000, 0x22002301, 0xf7ff9901, 0x4601fad0, 0x9a004658, 0xfaeef7ff, 0xea5fb2c0, 0xd5023188, 0x78943c1, 0x7c0d00b, 0xea5fd025, 0xd50b30c8, 0x3200e9dd, 0x46582139, 0xfafcf7ff, 0x4658e010, 0xfbcff7ff, 0xe751487a, 0x22002301, 0x990120e5, 0xfaadf7ff, 0x23004601, 0x9a004658, 0xfaf8f7ff, 0x2001990c, 0xf89a7008, 0x43200000, 0xf88a, 0xbbe89803, 0xf89ae011, 0x43a00000, 0xf89ae7f6, 0x99092000, 0x4ea22, 0x43084021, 0xd0044282, 0xf88a, 0x2001990c, 0x98087008, 0xd10140c4, 0xa01f10a, 0xf995b135, 0x28000005, 0xf1c7da02, 0xe0000000, 0x99004638, 0x90004408, 0xf1a09806, 0x4000001, 0x90060c00, 0xb10dd102, 0x508f105, 0x1cf8bd, 0x101f1a0, 0x101cf8ad, 0xf47f2800, 0x980caf14, 0xb1187800, 0x4008ea5f, 0xe000d51c, 0x4658e01a, 0xfa9bf7ff, 0x99054658, 0xfa62f7ff, 0x43109a04, 0x43104a4b, 0x60504a4b, 0xf811e002, 0x75100b01, 0xf1a09804, 0xb29b0301, 0x28009304, 0x69d0d1f5, 0xd4fc0780, 0xf7ff4658, 0x9803fb5a, 0xb570e6dc, 0x6886680a, 0x6803b1ce, 0xd8064293, 0x684d68c4, 0x4415441c, 0xd30042ac, 0x42961ad2, 0x684bd910, 0x42b34413, 0x690cd80c, 0xf30f014, 0x68c0d002, 0xd8054283, 0x600a2000, 0x4830bd70, 0xbd701c80, 0x1e40482e, 0xb570bd70, 0x4615460c, 0xf7ff4606, 0x4630fa8a, 0xfa51f7ff, 0x608d492a, 0xf7ff4630, 0x6a32fa17, 0x260f402, 0x6204ea42, 0x60484310, 0xd0072cc7, 0xd0052c60, 0x46302101, 0x4070e8bd, 0xba91f7ff, 0xe7f82103, 0x460db570, 0x46044616, 0xfa33f7ff, 0x6085481b, 0x43316a21, 0xbd706041, 0x4df0e92d, 0x460e4683, 0x46984617, 0xf8df681c, 0x6855a054, 0x693be067, 0xb2d0683a, 0x7480f5c0, 0x42a5b113, 0x462cd200, 0xe0024621, 0x1e6d1c76, 0x7b01e64, 0x7830d009, 0xd11828ff, 0x2c00b1f5, 0xe01bd1f4, 0x1f2d1d36, 0x68301f24, 0xd10e1c40, 0xd30c2d04, 0xd2f52c04, 0xe00a, 0x20005, 0x42208000, 0x40003000, 0x1e6d1c76, 0xb12d1e64, 0x2c04b124, 0x7830d202, 0xd0f528ff, 0x44101b08, 0xb3956038, 0xd0c72c00, 0x46224601, 0xf7ff4658, 0x6838ffab, 0x60384420, 0x2c00e001, 0x4650d0bb, 0xd00b07b1, 0xb14cb1c5, 0x1b01f816, 0x1e6d7501, 0xe7f51e64, 0x6141ce02, 0x1f241f2d, 0xd3072d04, 0xd2f72c04, 0xf816e005, 0x75011b01, 0x1e641e6d, 0x2c00b115, 0xe000d1f7, 0x2102b92c, 0xf7ff4658, 0x2800fa12, 0x2d00d104, 0x2000d1d7, 0x4000f8c8, 0x6800e613, 0xe0044408, 0x1c496801, 0x1d00d104, 0x2a001f12, 0x2000d1f8, 0x68134770, 0x44186800, 0x40486010, 0xd0010780, 0x47702000, 0x47702001, 0x460cb53f, 0xaa02461d, 0xffeff7ff, 0xb948b335, 0x9802e022, 0x1b01f814, 0x42917802, 0x1c40d11f, 0x90021e6d, 0xd00b07a0, 0xd1f22d00, 0x9802e016, 0x68026821, 0xd1124291, 0x1d241d00, 0x90021f2d, 0xd2f42d04, 0x9802e008, 0x1b01f814, 0x42917802, 0x1c40d105, 0x90021e6d, 0xd1f42d00, 0xb0042000, 0xb5f8bd30, 0x6811460c, 0x68559100, 0x43de469c, 0x4621466a, 0xffb9f7ff, 0xf00cb385, 0xb1e803ff, 0x7a0b2f1, 0xb34dd018, 0xf8149f00, 0xf8170b01, 0x40582b01, 0x4210404a, 0xd11b9700, 0xe7f01e6d, 0x68209a00, 0xea806811, 0x4071000c, 0xd1114208, 0x1d241d12, 0x92001f2d, 0xd2f12d04, 0xb16db2f1, 0xf8149e00, 0xf8160b01, 0x40582b01, 0x4210404a, 0xd0019600, 0xbdf82001, 0xe7f01e6d, 0x2000e7ff, 0xe92dbdf8, 0x46174df7, 0x468bb09d, 0x46392214, 0xf001a802, 0x2500f85c, 0x5068f88d, 0x687ca902, 0xf7ff981d, 0x6fe9c, 0x9802d138, 0x4420901b, 0x46289018, 0x69389005, 0xd4070580, 0xaa1aab07, 0x981da902, 0xfc72f7ff, 0xd1270006, 0x981de0b1, 0xa01f04f, 0x1030f890, 0xf001fa0a, 0x1e429902, 0xeb004391, 0x91010801, 0xeba89902, 0x42ac0501, 0x4625d200, 0x69389503, 0xd4060740, 0xaa022300, 0x981d4659, 0xff7df7ff, 0x2001b100, 0x91199902, 0xd07d2800, 0x7006938, 0x48ead502, 0xe53cb020, 0xb30868b8, 0x1201e9dd, 0xa01eba2, 0x46429918, 0xd2034541, 0x9a184611, 0xe0001a89, 0x46882100, 0x10aea5f, 0x460ad005, 0xf0009901, 0x9801ffbb, 0xf1b89002, 0xd00a0f00, 0x464268b9, 0xaeb01, 0xf0009918, 0xe002ffaf, 0x800f04f, 0x981d46c2, 0xf8909a01, 0xf7ff1034, 0x6fe56, 0x981dd003, 0xf985f7ff, 0x6938e066, 0xd5100680, 0xf7ff981d, 0x981df97e, 0x99012201, 0x30f890, 0x981d4082, 0xfee7f7ff, 0xd1b92800, 0xf7ff981d, 0x2000f8cc, 0x90069000, 0xa00cf8cd, 0xaa02466b, 0x981d68b9, 0xfe5ef7ff, 0x95034606, 0xf00f1b8, 0x2000d003, 0xb1169006, 0x2001e008, 0x466be7fa, 0x4659aa02, 0xf7ff981d, 0x4606fe4d, 0xf8cd2001, 0x9006800c, 0x68b9b966, 0x4451466b, 0x981daa02, 0xfe40f7ff, 0xd1030006, 0xb1089800, 0x1602f04f, 0xe000981d, 0xf7ffe056, 0xb9eef93c, 0x6c06938, 0x462bd507, 0x9a194659, 0xf7ff981d, 0x6febb, 0x44abd112, 0x2c001b64, 0xaf4bf47f, 0xb15868f8, 0x981b9005, 0x68789002, 0xab079003, 0xa902aa1a, 0xf7ff981d, 0x4606fbad, 0xe7614630, 0xfff041, 0x1c6d1a45, 0xd20042ac, 0xf04f4625, 0xaa0233ff, 0x95034659, 0xf7ff981d, 0xb1f0fec6, 0xf7ff981d, 0x2000f864, 0x466b9000, 0x4659aa02, 0xa018f8cd, 0xf7ff981d, 0x4606fdf7, 0xf7ff981d, 0x2e00f8fa, 0x6938d1da, 0xd50b06c0, 0x4659462b, 0x981d9a19, 0xfe78f7ff, 0xd1cf0006, 0x9802e002, 0x90024428, 0x1b6444ab, 0xd0b92c00, 0x45419902, 0xaf01f4bf, 0xe92de7c4, 0xb09e4df3, 0x2214460c, 0xf000a802, 0x2600ff38, 0x606cf88d, 0x90016860, 0xf890981e, 0x20011030, 0x901a4088, 0x9618a902, 0xf7ff981e, 0x5fd70, 0x9605d17e, 0x5806920, 0xab07d407, 0xa902aa1b, 0xf7ff981e, 0x5fb4b, 0xe9ddd172, 0x44080101, 0x9000911c, 0xd16c2900, 0x6881981e, 0x42819801, 0x981ed867, 0x6406a80, 0x981ed463, 0xf803f7ff, 0x461a2300, 0x981e21c7, 0xffcaf7fe, 0x981e2103, 0xf819f7ff, 0x981e4605, 0xf899f7ff, 0x2703e09f, 0x4438981e, 0xf890901d, 0x28000030, 0x2101d07e, 0xf800fa01, 0xf1a89802, 0xea200101, 0xeba00b01, 0xeb0b060b, 0x90190008, 0x42819900, 0x1a40d201, 0x2000e000, 0x981a4682, 0xd2794286, 0xd2774582, 0xb16868a0, 0x4632b11e, 0xf0004659, 0xf1bafe8b, 0xd0050f00, 0x465268a0, 0x99004430, 0xfe82f000, 0x465a981e, 0xf8904438, 0x981e1034, 0xfd2bf7ff, 0x981e4605, 0xf85bf7ff, 0xd1702d00, 0x6806920, 0x981dd50a, 0x46592201, 0x30f890, 0x981e4082, 0xfdbff7ff, 0xd1030005, 0xb3c068a0, 0xe0012001, 0xe048e05e, 0xb1fe9006, 0xf7fe981e, 0xe9cdff9c, 0xab18b602, 0x68a1aa02, 0xf7ff981e, 0x4605fd31, 0xf7ff981e, 0xb925f834, 0xb1109818, 0x1502f04f, 0x6920e045, 0xd50606c0, 0x465a4633, 0x981e68a1, 0xfdaef7ff, 0xbbd54605, 0xf00f1ba, 0x981ed017, 0xff79f7fe, 0xe9cd9800, 0x68a00a02, 0x1981ab18, 0x981eaa02, 0xfd0cf7ff, 0xe0014605, 0xe006e010, 0xf7ff981e, 0xbb15f80c, 0x28009818, 0x9819d1d6, 0x98019002, 0xd90b4540, 0x8eba0, 0xe0029001, 0xf57f1e7f, 0x9801af65, 0xf47f2800, 0xb975af60, 0xb16068e0, 0x9002981c, 0x90036860, 0x900568e0, 0xaa1bab07, 0x981ea902, 0xfa78f7ff, 0x46284605, 0xe62c, 0x2000b, 0x41f0e92d, 0x7c847c46, 0x460f4605, 0xd0042e30, 0xd0072e40, 0xe8bd481c, 0xf1a481f0, 0x28070010, 0xe009d211, 0x15f1a4, 0xd20c2802, 0x401cf244, 0xf2448368, 0x832850fc, 0x46281e61, 0xf878f7ff, 0xd1052e40, 0x4810e002, 0xe7e41e40, 0xd50805f8, 0xf44f480e, 0x2c164188, 0x4b0dd301, 0x6a2be005, 0x480ce003, 0xf2444b0c, 0x2c160104, 0x2206d301, 0x2204e000, 0x5242ea40, 0x43024808, 0xe8bd4628, 0xf7ff41f0, 0xb86f, 0x20008, 0xbb010000, 0xa2888000, 0xeb030000, 0x32888000, 0x103fff, 0x41f0e92d, 0x7c404605, 0xf44f460f, 0x7ca94680, 0x343f1a0, 0xb24c3a, 0x800f04f, 0xd8252b05, 0xd140094b, 0x432f1a0, 0x28444616, 0x2845d006, 0x2846d00b, 0xf444d33d, 0xe03a7480, 0x22204931, 0x46284479, 0xffcef7fe, 0x2901e033, 0x492dd131, 0x44792220, 0x4628310e, 0xffc4f7fe, 0x219f2204, 0xf7fe4628, 0xe00fe59, 0xe022d1e5, 0xd0092865, 0xd0072866, 0xd0142886, 0xd0122887, 0x1c404820, 0x81f0e8bd, 0x456f1a0, 0xd0082865, 0x8368206c, 0x80f040, 0x20008328, 0x32f885, 0x2004e009, 0x949e7f5, 0x4620d001, 0x3872e7ea, 0x7440f440, 0x20524616, 0x35f885, 0xf885200f, 0xf2420031, 0x62e80005, 0x11ff004, 0xf7fe4628, 0xf414ffe1, 0xd0127f40, 0x7f40f5b4, 0x5f8d301, 0xf446d504, 0x4a096180, 0xe0034b09, 0x4b0a4a09, 0x108f046, 0xe8bd4628, 0xf7fe41f0, 0x4640bfe5, 0xe7bf62ae, 0x20007, 0xc54, 0x3b893fff, 0xa2888000, 0x6b893fff, 0x32888000, 0x4605b570, 0x7cac7c40, 0x289d460e, 0x482dd001, 0xf1a4bd70, 0x28010013, 0x380cd918, 0xd8032803, 0xf4443c11, 0xe0117480, 0xd0072c2f, 0x44f1a4, 0xd8062802, 0xf4443c31, 0xe0077440, 0x7487f44f, 0xf1a4e004, 0x2802007c, 0x3c6cd820, 0x11ff004, 0xd8022910, 0xf885200f, 0xf5b40032, 0xd3037f45, 0x8368203c, 0x832820bc, 0xf7fe4628, 0xf414ff85, 0xd0cd7040, 0x7040f44f, 0xd3014284, 0xd50d05f1, 0x4188f44f, 0xd9044284, 0xe0034a0f, 0x1e40480d, 0x4a0ebd70, 0x431a4b0e, 0xe0036a2b, 0x4b0e4a0d, 0x41a0f44f, 0xd9014284, 0xe0002006, 0xea422004, 0xf6435240, 0x430270ff, 0xe8bd4628, 0xf7fe4070, 0xbf75, 0x20008, 0xbb100000, 0x3b080000, 0x13fff, 0xeb133fff, 0x32888000, 0x41f0e92d, 0x7c867c45, 0x460f4604, 0xd0082d20, 0xbef005, 0xd0042830, 0xd0022d38, 0xe8bd4824, 0xf1a681f0, 0x28090010, 0x4821d302, 0xe7f61e40, 0xd8032e11, 0xf884200f, 0xe00c0032, 0xd10a2d20, 0xd1082e17, 0xf8042010, 0x20d80f30, 0x20007120, 0xf1a470a0, 0x1e710430, 0xf7fe4620, 0x2e16ff1f, 0x2d30d006, 0x2d70d002, 0xe005d002, 0xd3032e16, 0x8360203c, 0x832020bc, 0xbff005, 0xd0012830, 0xe7cc2000, 0x6a238b60, 0xc0f040, 0x5f88320, 0xf44fd503, 0x4a074188, 0x4a07e004, 0x102f244, 0x13c0f443, 0xe8bd4620, 0xf7fe41f0, 0xbf11, 0x20008, 0xbb913fff, 0xebdb3fff, 0x41f0e92d, 0x7c857c44, 0x460f4606, 0xd00a2c20, 0xd0082c21, 0xd0062c30, 0xd0042c40, 0xd0022c41, 0xe8bd4820, 0xf1a581f0, 0x28050013, 0x481dd302, 0xe7f61e40, 0xd0012c30, 0xd1052c41, 0x833020bc, 0xd1012c41, 0x8370203c, 0x46301e69, 0xfec8f7fe, 0xd5010660, 0xd50a05f8, 0x4188f44f, 0xd5010660, 0xe0004a11, 0x48124a11, 0x43026a33, 0x2d16e007, 0xf44fd009, 0x4a0f5080, 0xf4404b0f, 0xf0144180, 0xd0020f9f, 0x2004e005, 0x2d16e7f5, 0xf441d101, 0x6605100, 0xf442d501, 0x46300280, 0x41f0e8bd, 0xbeb8f7fe, 0x20008, 0xbb100000, 0x3b080000, 0x813fff, 0xeb933fff, 0x32888000, 0x41f0e92d, 0x6a064604, 0x7ca57c40, 0x2840460f, 0x4822d002, 0x81f0e8bd, 0x10f1a5, 0xd83a2807, 0xf8842052, 0x200f0035, 0x31f884, 0xd00b2d10, 0xd3052d14, 0xf88420d2, 0x20110037, 0x33f884, 0xd2052d16, 0xe005201c, 0xf8842000, 0xe7f90032, 0x1cf244, 0x2d168360, 0xf44fd202, 0xe00170fe, 0x50fcf244, 0x1e698320, 0xf7fe4620, 0x5f8fe5b, 0xf244d503, 0x4a0a4101, 0x4a0ae005, 0x105f244, 0xd3002d16, 0x48094e08, 0x43024633, 0xe8bd4620, 0xf7fe41f0, 0x4801be61, 0xe7bb1e40, 0x20008, 0xbb110000, 0xeb130000, 0x32888000, 0xc03fff, 0x4ff7e92d, 0x7c847c45, 0xf04f4606, 0xf44f0b00, 0x2d204a80, 0x2d24d008, 0x2d25d006, 0x2d5ed004, 0x485ad002, 0x8ffee8bd, 0x81ff004, 0x10f1a8, 0xd8722809, 0x101f1a8, 0xf7fe4630, 0x4954fe1b, 0xff004, 0x2c104479, 0x83705c08, 0x80f040, 0xd1028330, 0xf8862000, 0x22010032, 0x46302105, 0xfc4cf7fe, 0x7530b2c0, 0x740f010, 0xf040d119, 0xf0800040, 0x21010204, 0xf7fe4630, 0xea5ffd2d, 0xd1cf0b00, 0x21052201, 0xf7fe4630, 0xf080fc37, 0xb2c20004, 0xf0027532, 0x21010740, 0xf7fe4630, 0x2d20fd1b, 0x2d25d002, 0xe00fd004, 0xd3122c16, 0xe010b937, 0x33f1a4, 0xd9012806, 0xd30e2c53, 0xf8862052, 0x200f0035, 0x31f886, 0xd0022d20, 0xd0042d25, 0x2c17e01b, 0xb917d319, 0x2c34e034, 0xf1a8d315, 0x28060014, 0xe8dfd20f, 0x703f000, 0x26211c17, 0x22104927, 0xe0034479, 0x22104925, 0x31084479, 0xf7fe4630, 0xf04ffd5f, 0xb1cf0a80, 0xf4109801, 0xd1197f80, 0xe033e02b, 0x2210491d, 0x39084479, 0x491be7ee, 0x44792218, 0xe7e91e89, 0x22184918, 0x310c4479, 0x4916e7e4, 0x44792218, 0xe7df311a, 0xd11b2d20, 0xd3192c15, 0x2d20b137, 0x2c18d101, 0x20bbd902, 0xe0012102, 0x2101203b, 0xea400600, 0x480c42c1, 0x6180f44a, 0x6a334302, 0x4b0ae002, 0x46514a0a, 0xf7fe4630, 0x4683fd95, 0xe74f4658, 0x1e404801, 0xe74c, 0x20008, 0x8ec, 0x7c0, 0x813fff, 0x38908000, 0xebd33fff, 0x4602b50c, 0xe9d0a053, 0xe9cd3000, 0x5c83000, 0x2a4bd505, 0x2001d801, 0x2002bd0c, 0x2000bd0c, 0x5c0b4669, 0xd2024293, 0x28051c40, 0x1c40d3f9, 0xe92dbd0c, 0x46044df0, 0x468b4610, 0x7ca67c65, 0xffdef7ff, 0xf44fb2c7, 0xf04f4880, 0x2d200a0c, 0x2dbad00e, 0x2dbbd00c, 0x20dbd00a, 0x2d802108, 0x2d40d01a, 0x2d71d024, 0x483cd028, 0x8df0e8bd, 0xf88420d8, 0x2e110034, 0x200fd801, 0x2d20e006, 0x2e18d103, 0x2012d301, 0x2010e000, 0x30f884, 0xf8842000, 0xe0110032, 0x430f104, 0x70217120, 0x20f04f, 0xf8847160, 0xf1a4a001, 0xe0050430, 0x34f884, 0x1030f884, 0x840f04f, 0x10f1a6, 0xd302280a, 0x1e404825, 0x1e71e7d0, 0xf7fe4620, 0x2e13fcff, 0xf8a4d202, 0xe006a01a, 0xd3042dba, 0xd3042e17, 0x8360205c, 0x2d71e001, 0x2dbad011, 0x2dbbd00f, 0x2000d00d, 0xf0408b61, 0x43080080, 0x2d718320, 0xd106d322, 0x3111f44f, 0x4b154a14, 0x2020e017, 0x4814e7f0, 0xea5f62e0, 0xd50650cb, 0xf2444812, 0xea404130, 0x4b114207, 0x4811e005, 0xf2444b11, 0xea400130, 0x2e184207, 0xf441d301, 0x46203100, 0x4df0e8bd, 0xbcdcf7fe, 0xf8c42000, 0xe78b8028, 0x5f4e3b27, 0x6c, 0x20008, 0x3b893fff, 0xa2888000, 0x503070, 0xbbd83fff, 0xd2988000, 0xebd83fff, 0x12988000, 0x4604b510, 0x219f2205, 0xfae8f7fe, 0x28030e00, 0x4930d001, 0x493062e1, 0xb1197d09, 0xd0052901, 0xbd10482e, 0xf8842012, 0xe0030030, 0xd1012803, 0x8360203c, 0x46207ca1, 0xf7fe1e49, 0x2000fc8b, 0xb570bd10, 0x460d4604, 0x7ca17c40, 0xf88422d8, 0x22102034, 0x2030f884, 0xf8842200, 0x4a1f2032, 0x28021c52, 0x2820d003, 0x1c50d013, 0xf1a1bd70, 0x28020012, 0x4620d803, 0xfc6cf7fe, 0xf1a1e013, 0x28010015, 0x4813d802, 0xe7f462e0, 0xd0042919, 0x2918e001, 0x4610d001, 0x4620bd70, 0xffb0f7ff, 0xfff010, 0x6ae0d1f8, 0xd0f52800, 0xf4408b60, 0x83205036, 0xd50405e8, 0x4188f44f, 0x6a234a08, 0x4a08e003, 0xf2444b08, 0x46200104, 0x4070e8bd, 0xbc5af7fe, 0x306005, 0x40003000, 0x20006, 0xbbd13fff, 0xebd33fff, 0x32888000, 0x4604b570, 0x7c807c41, 0x29264a26, 0x2925d003, 0x1c50d02d, 0xf000bd70, 0x290301df, 0x2107d829, 0x210074e1, 0x507f000, 0x1032f884, 0x113f105, 0xf7fe4620, 0x2d01fc19, 0x2d02d004, 0x2d03d006, 0xe00fd10b, 0x22284918, 0xe0034479, 0x22284916, 0x31204479, 0xf7fe4620, 0x4b14fbb1, 0xf2484a14, 0xe01a0102, 0x22284910, 0x31304479, 0x284be7f2, 0x4610d001, 0x2116bd70, 0xf7fe4620, 0x203cfbf5, 0x20bc8360, 0x20528320, 0x35f884, 0x4b09200f, 0xf8844a09, 0xf44f0031, 0x462041c8, 0x4070e8bd, 0xbbfcf7fe, 0x20007, 0x4e8, 0x2988000, 0xb993fff, 0xa2888000, 0xbb913fff, 0x4602b508, 0x4669a039, 0x90006800, 0x5c0b2000, 0xd2024293, 0x28031c40, 0x1c40d3f9, 0xe92dbd08, 0x469041f0, 0x460b7c47, 0x4a317c86, 0xf44f4604, 0xf44f4580, 0x2f304188, 0xf017d003, 0xd0090f8f, 0xf1a6e029, 0x28040010, 0x8b20d20a, 0x20f040, 0xe0108320, 0xd01e2f70, 0x12f1a6, 0xd3022808, 0xe8bd4610, 0xf24481f0, 0x8360001c, 0x10fcf244, 0x5d88320, 0x460dd500, 0x46201e71, 0xfb96f7fe, 0xf8842052, 0x200f0035, 0x31f884, 0xd5050568, 0x6a234a18, 0x4816e011, 0xe7e21c40, 0xd00f2f60, 0x21022203, 0x504f244, 0x4122001, 0x42c1ea42, 0x430a4911, 0xea414911, 0x2f4043c0, 0xe00ed009, 0x504f644, 0xf7ff4640, 0xb2c2ff9b, 0x46012003, 0x2e14e7eb, 0x2e16d303, 0xf045d801, 0x46290501, 0xe8bd4620, 0xf7fe41f0, 0xbb7b, 0x50321e, 0x20007, 0xbbd13fff, 0xebc03fff, 0x32808000, 0x49514a52, 0x4a526011, 0x112f04f, 0xf1026011, 0xf04f0204, 0x60110142, 0xf04f494e, 0xfb000280, 0xf44ff001, 0xfbb011e1, 0x484bf1f1, 0xb2ca60c2, 0xea4f6002, 0x60412111, 0x107f04f, 0xf04f60c1, 0x60810147, 0xb1284770, 0xd0052801, 0x494320d3, 0x47706008, 0xe7fa20db, 0xe7f820c3, 0x20f34940, 0xf04f6008, 0x610800d3, 0x608860c8, 0xf04f6048, 0x61480013, 0xb5f04770, 0x4c34460f, 0x3ca02100, 0x4b3861a1, 0x6163e005, 0x2116962, 0xf3c2d4fc, 0x3978214d, 0xd2f62929, 0xd90128a0, 0xe00220a0, 0xd200280a, 0xf44f200a, 0xfbb171a0, 0x4358f3f0, 0xfbb0210c, 0x4a2cf0f1, 0xea421e41, 0x6c624501, 0x40164e2a, 0xd01342ae, 0xf3c66ee6, 0x2e0c6604, 0x4e27d101, 0x7d666e6, 0xf042d106, 0x64620201, 0x1c522200, 0xd9fc2aff, 0x6c216465, 0xd0fc07c9, 0x140eb00, 0x7296f44f, 0xf81ebb2, 0x2103d201, 0x2296e006, 0xf81ebb2, 0x2102d201, 0x2101e000, 0x1f12008a, 0x6210f042, 0x9a64a2, 0xf0421f12, 0x65a26210, 0x66e24a08, 0x67224a12, 0x40eb00, 0xfbb50085, 0x4620f4f1, 0xff62f7ff, 0x603cb107, 0xf0f3fbb5, 0xbdf0, 0xc000800, 0x400500a0, 0x40086634, 0xf4240, 0x40082000, 0x40086198, 0x4008618c, 0x6800078, 0x6000080, 0xfff33c3, 0x1000800, 0x10000800, 0xf2402a03, 0xf0108030, 0xf0000c03, 0xf8118015, 0xf1bc3b01, 0x44620f02, 0xf811bf98, 0xf800cb01, 0xbf383b01, 0x3b01f811, 0x204f1a2, 0xf800bf98, 0xbf38cb01, 0x3b01f800, 0x303f011, 0x8025f000, 0xf0c03a08, 0xf8518008, 0x3a083b04, 0xcb04f851, 0x1008e8a0, 0x1d12e7f5, 0xf851bf5c, 0xf8403b04, 0xf3af3b04, 0x7d28000, 0xf811bf24, 0xf8113b01, 0xbf48cb01, 0x2b01f811, 0xf800bf24, 0xf8003b01, 0xbf48cb01, 0x2b01f800, 0xb5104770, 0xf0c03a20, 0xe8b1800b, 0x3a205018, 0x5018e8a0, 0x5018e8b1, 0x5018e8a0, 0xaff5f4bf, 0x7c02ea5f, 0xe8b1bf24, 0xe8a05018, 0xbf445018, 0xc018c918, 0x4010e8bd, 0x7c82ea5f, 0xf851bf24, 0xf8403b04, 0xbf083b04, 0x7d24770, 0xf831bf28, 0xbf483b02, 0x2b01f811, 0xf820bf28, 0xbf483b02, 0x2b01f800, 0xf04f4770, 0xb5000200, 0x46944613, 0x39204696, 0xe8a0bf22, 0xe8a0500c, 0xf1b1500c, 0xf4bf0120, 0x709aff7, 0xe8a0bf28, 0xbf48500c, 0xf85dc00c, 0x89eb04, 0xf840bf28, 0xbf082b04, 0xbf484770, 0x2b02f820, 0x4f80f011, 0xf800bf18, 0x47702b01, 0x0, 0x71000, 0x70000, 0x10f00, 0x78000, 0x20d00, 0x7c000, 0x10e00, 0x0, 0xf1000, 0xf0000, 0x10e00, 0xf4000, 0x20d00, 0xf8000, 0x10f00, 0x0, 0x100c00, 0x10000, 0xf1000, 0x0, 0x100c00, 0x10000, 0x1f1000, 0x0, 0x100c00, 0x10000, 0x3f1000, 0x0, 0x100c00, 0x10000, 0x7e1000, 0x7f000, 0x100c00, 0x0, 0x100c00, 0x10000, 0xfe1000, 0xff000, 0x100c00, 0x0, 0x100c00, 0x10000, 0x1fe1000, 0x1ff000, 0x100c00, 0x3c7c0c0c, 0x3c3c3c3c, 0x3c3c, 0x1fe000, 0x4f301, 0x6000, 0x4f301, 0x1f0000, 0x1f100, 0x8000, 0x1f100, 0x1e0000, 0x1ef000, 0x3fe000, 0x4f301, 0x6000, 0x4f301, 0x3f0000, 0x1f100, 0x8000, 0x1f100, 0x3e0000, 0x3ef000, 0x7fe000, 0x4f301, 0x6000, 0x4f301, 0x7f0000, 0x1f100, 0x8000, 0x1f100, 0x7e0000, 0x7ef000, 0x0, 0x00000000, 0x06802005, # movs r0, #5 ; Call pc_init routine with r0 forced to start of FLASH. # lsls r0, r0, #26 ; start of FLASH = 5 << 26 = 0x14000000 0xbef6f7fd, # b 0x10000028 0x00000000 ], 'pc_init' : 0x10002234, # Call through thunk added to force r0 to 0x14000000 'pc_eraseAll' : 0x1000007F, 'pc_erase_sector' : 0x1000009F, 'pc_program_page' : 0x100000CD, 'begin_data' : 0x10004000, # Analyzer uses a max of 128 KB data (32,768 pages * 4 bytes / page) 'page_buffers' : [0x10004000, 0x10004800], # Enable double buffering 'begin_stack' : 0x10008000, 'static_base' : 0x10002240, 'min_program_length' : 512, 'analyzer_supported' : False, # Analyzer works, but would fail if a full ROM analysis was performed since there is not enough ram 'analyzer_address' : 0x10005000 # Analyzer 0x10005000..0x10005600 }; class Flash_lpc4330(Flash): def __init__(self, target): super(Flash_lpc4330, self).__init__(target, FLASH_ALGO) def get_flash_info(self): info = FlashInfo() info.rom_start = 0x14000000 info.erase_weight = DEFAULT_CHIP_ERASE_WEIGHT return info class LPC4330(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x14000000, length=0x4000000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x10000000, length=0x20000), RamRegion( start=0x10080000, length=0x12000), RamRegion( start=0x20000000, length=0x8000), RamRegion( start=0x20008000, length=0x8000) ) def __init__(self, link): super(LPC4330, self).__init__(link, self.memoryMap) self.ignoreReset = False self._svd_location = SVDFile(vendor="NXP", filename="LPC43xx_svd_v5.svd", is_local=False) def reset(self, software_reset=False): # Always use software reset for LPC4330 since the hardware version # will reset the DAP. super(LPC4330, self).reset(True) def reset_stop_on_reset(self, software_reset=False): if self.ignoreReset: return # Set core up to run some code in RAM that is guaranteed to be valid # since FLASH could be corrupted and that is what user is trying to fix. self.write_memory(0x10000000, 0x10087ff0) # Initial SP self.write_memory(0x10000004, 0x1000000d) # Reset Handler self.write_memory(0x10000008, 0x1000000d) # Hard Fault Handler self.write_memory(0x1000000c, 0xe7fee7fe) # Infinite loop self.write_memory(0x40043100, 0x10000000) # Shadow 0x0 to RAM # Always use software reset for LPC4330 since the hardware version # will reset the DAP. super(LPC4330, self).reset_stop_on_reset(True) # Map shadow memory to SPIFI FLASH self.write_memory(0x40043100, 0x80000000) # The LPC4330 flash init routine can be used to remount FLASH. self.ignoreReset = True self.flash.init() self.ignoreReset = False # Set SP and PC based on interrupt vector in SPIFI_FLASH sp = self.read_memory(0x14000000) pc = self.read_memory(0x14000004) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MK82FN256xxx15.py0000644000175000017500000001405313373511253021224 0ustar neilneil00000000000000""" Flash OS Routines (Automagically Generated) Copyright (c) 2009-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510483e, 0x5120f24c, 0xf64d81c1, 0x81c11128, 0xf0218801, 0x80010101, 0x78414839, 0x0160f001, 0xbf0c2940, 0x21002101, 0x444a4a36, 0xb1397011, 0xf0217841, 0x70410160, 0xf0117841, 0xd1fb0f60, 0x44484831, 0xf864f000, 0xbf182800, 0xbd102001, 0x4448482c, 0xb1587800, 0x78414829, 0x0160f021, 0x0140f041, 0x78417041, 0x0160f001, 0xd1fa2940, 0x47702000, 0xb5104824, 0x44484924, 0xf897f000, 0xbf182800, 0x2100bd10, 0xe8bd481f, 0x44484010, 0xb95df000, 0x4c1cb570, 0x444c4605, 0x4b1b4601, 0x68e24620, 0xf8bbf000, 0xbf182800, 0x2300bd70, 0x68e24629, 0x4070e8bd, 0x44484813, 0xb951f000, 0x460cb570, 0x4606460b, 0x480f4601, 0x4615b084, 0xf0004448, 0x2800f8f0, 0xb004bf1c, 0x2000bd70, 0xe9cd2101, 0x90021000, 0x462b4807, 0x46314622, 0xf0004448, 0xb004f984, 0x0000bd70, 0x40052000, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xbf042800, 0x47702004, 0x6cc949ec, 0x6103f3c1, 0xbf08290f, 0x2180f44f, 0x4ae9bf1f, 0xf832447a, 0x02891011, 0xe9c02200, 0x21012100, 0x03096081, 0x49e460c1, 0x3f28f811, 0x7c80f44f, 0xf303fa0c, 0x78c96143, 0x62026102, 0x61816242, 0x47704610, 0xbf0e2800, 0x61012004, 0x47702000, 0x48da4602, 0x49d96840, 0x0070f440, 0x47706048, 0x217048d5, 0x21807001, 0x78017001, 0x0f80f011, 0x7800d0fb, 0x0f20f010, 0x2067bf1c, 0xf0104770, 0xbf1c0f10, 0x47702068, 0x0001f010, 0x2069bf18, 0x28004770, 0x2004bf04, 0xb5104770, 0x4ac64604, 0x403bf06f, 0x48c66050, 0xbf144281, 0x2000206b, 0xbf182800, 0x4620bd10, 0xffd2f7ff, 0x46204603, 0xffc6f7ff, 0xbd104618, 0xbf042800, 0x47702004, 0x60532300, 0x60d36093, 0x61536113, 0x61d36193, 0x68c16011, 0xe9d06051, 0xfbb11001, 0x6090f0f0, 0x21102004, 0x0103e9c2, 0x1005e9c2, 0x200061d0, 0xe92d4770, 0xb0884df0, 0x46984615, 0x4682460c, 0xf7ff466a, 0x462affd9, 0x46504621, 0xf0009b04, 0x0007f931, 0xb008bf1c, 0x8df0e8bd, 0x4600e9dd, 0x1e451960, 0xf0f6fbb5, 0x5010fb06, 0xfbb5b120, 0x1c40f0f6, 0x1e454370, 0xbf9842ac, 0xb268f8df, 0xf024d81c, 0xf040407f, 0xf8cb6010, 0x48980004, 0xbf144580, 0x2000206b, 0xbf1c2800, 0xe8bdb008, 0x46508df0, 0xff74f7ff, 0xf8da4607, 0x28000010, 0x4780bf18, 0x4434b917, 0xd9e242ac, 0xf7ff4650, 0xb008ff5f, 0xe8bd4638, 0x2a008df0, 0x2004bf04, 0xe92d4770, 0xb08945f0, 0x461e4614, 0x4680460d, 0xf7ff466a, 0x4632ff89, 0x46404629, 0xf0009b03, 0x0007f8e1, 0xb009bf1c, 0x85f0e8bd, 0x2e009d00, 0xf8dfbf18, 0xd025a1e4, 0x0b04f854, 0x0008f8ca, 0x28049803, 0xf025bf04, 0xf040407f, 0xd00960c0, 0xd1092808, 0x0b04f854, 0x000cf8ca, 0x407ff025, 0x60e0f040, 0x0004f8ca, 0xf7ff4640, 0xf8d8ff29, 0x46071010, 0xbf182900, 0xb91f4788, 0x44059803, 0xd1d91a36, 0xf7ff4640, 0xb009ff13, 0xe8bd4638, 0x280085f0, 0x2004bf04, 0x4a624770, 0x4101ea42, 0x60514a5d, 0xe92de70c, 0xb0884dff, 0x469a4614, 0x466a460d, 0xf7ff9808, 0x4622ff37, 0x9b054629, 0xf0009808, 0x2800f88f, 0xb00cbf1c, 0x8df0e8bd, 0x4629466a, 0xf7ff9808, 0x9e00ff27, 0x8008f8dd, 0xf1c84270, 0x40080100, 0x42b74247, 0x4447bf08, 0xbf182c00, 0xb120f8df, 0x1bbdd01f, 0xbf8842a5, 0x98054625, 0x417ff026, 0xf0f0fbb5, 0x7180f041, 0x1004f8cb, 0xea400400, 0xf040200a, 0xf8cb00ff, 0x98080008, 0xfeccf7ff, 0xbf1c2800, 0xe8bdb00c, 0x1b648df0, 0x4447442e, 0xb00cd1df, 0xe8bd2000, 0x2b008df0, 0x2004bf04, 0xe92d4770, 0xb0884dff, 0xe9dd4616, 0x461d7a14, 0x466a460c, 0x8058f8dd, 0xf7ff9808, 0xe9ddfee1, 0x46323007, 0xf0004621, 0x2800f839, 0xb00cbf1c, 0x8df0e8bd, 0x2e009c00, 0xb00cbf04, 0x8df0e8bd, 0xb08cf8df, 0x407ff06f, 0x6707ea40, 0x407ff024, 0x7000f040, 0x0004f8cb, 0x7008f8cb, 0xf8cb6828, 0x9808000c, 0xfe88f7ff, 0xf1bab168, 0xbf180f00, 0x4000f8ca, 0x0f00f1b8, 0x2100bf1c, 0x1000f8c8, 0xe8bdb00c, 0x99078df0, 0xf0211a76, 0x440d0103, 0x440c9907, 0xb00cd1da, 0x8df0e8bd, 0xbf042800, 0x47702004, 0x42191e5b, 0x421abf0e, 0x47702065, 0x428b6803, 0x6840d806, 0x44184411, 0xbf244288, 0x47702000, 0x47702066, 0x40048000, 0x000003bc, 0x40020000, 0x4001f000, 0x6b65666b, 0x4000ffff, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000071, 'pc_program_page': 0x200000E1, 'pc_erase_sector': 0x200000B5, 'pc_eraseAll' : 0x20000095, 'static_base' : 0x20000000 + 0x00000020 + 0x0000050c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000200, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_k82f25615(Flash_Kinetis): def __init__(self, target): super(Flash_k82f25615, self).__init__(target, FLASH_ALGO) class K82F25615(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1fff0000, length=0x40000) ) def __init__(self, transport): super(K82F25615, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK82F25615.svd") pyocd-0.13.1/pyocd/target/target_w7500.py0000644000175000017500000000447313373511253017733 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4c11b430, 0xbc3046a4, 0x20004760, 0x20004770, 0x23004770, 0x461ab510, 0x20144619, 0xfff0f7ff, 0xbd102000, 0x2300b510, 0x461a4601, 0xf7ff2012, 0x2000ffe7, 0x460bbd10, 0x4601b510, 0xf7ff2022, 0x2000ffdf, 0x0000bd10, 0x1fff1001, 0x00000000, ], 'pc_init' : 0x2000002B, 'pc_eraseAll' : 0x20000033, 'pc_erase_sector' : 0x20000045, 'pc_program_page' : 0x20000057, 'static_base' : 0x2000006C, 'begin_data' : 0x20002000, # Analyzer uses a max of 256 B data (64 pages * 4 bytes / page) 'begin_stack' : 0x20004000, 'page_size' : 256, 'analyzer_supported' : True, 'analyzer_address' : 0x20001000 # Analyzer 0x20001000..0x20001600 }; class Flash_w7500(Flash): def __init__(self, target): super(Flash_w7500, self).__init__(target, FLASH_ALGO) class W7500(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x00000000, length=0x20000, blocksize=0x100, is_boot_memory=True), RamRegion( start=0x20000000, length=0x4000) ) def __init__(self, link): super(W7500, self).__init__(link, self.memoryMap) pyocd-0.13.1/pyocd/target/target_MK20DX128xxx5.py0000644000175000017500000001321013373511253021133 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2017 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x5020f24c, 0x81c84932, 0x1028f64d, 0x460881c8, 0xf0208800, 0x80080001, 0x4448482e, 0xf8dcf000, 0x2001b108, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x4929b510, 0x44484827, 0xf8b8f000, 0xb92c4604, 0x48242100, 0xf0004448, 0x4604f9a3, 0xf837f000, 0xbd104620, 0x4604b570, 0x4448481e, 0x46214b1e, 0xf00068c2, 0x4605f85d, 0x481ab93d, 0x23004448, 0x68c24621, 0xf940f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf8f8f000, 0xb9674607, 0x22012000, 0x2000e9cd, 0x46224633, 0x90024629, 0x44484809, 0xf97ef000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0xf4206840, 0xf5000070, 0x49040070, 0x47706048, 0x40052000, 0x00000004, 0x6b65666b, 0x4001f000, 0x4a0e2070, 0x20807010, 0xbf007010, 0x7800480b, 0x280009c0, 0x4809d0fa, 0xf0017801, 0xb1080020, 0x47702067, 0x0010f001, 0x2068b108, 0xf001e7f9, 0xb1080001, 0xe7f42069, 0xe7f22000, 0x40020000, 0x4df0e92d, 0x460d4604, 0x469a4690, 0xf0004650, 0x4606f891, 0x4630b116, 0x8df0e8bd, 0x46422304, 0x46204629, 0xf86cf000, 0xb10e4606, 0xe7f34630, 0x0008eb05, 0x68e01e47, 0xf1f0fbb7, 0x7011fb00, 0x68e0b140, 0xf0f0fbb7, 0x0b01f100, 0xfb0068e0, 0x1e47f00b, 0x480be011, 0x68004478, 0x20096005, 0x71c84909, 0xffacf7ff, 0x69a04606, 0x69a0b108, 0xb1064780, 0x68e0e003, 0x42bd4405, 0xbf00d9eb, 0xe7c94630, 0x000002e0, 0x40020000, 0x4604b570, 0x4628460d, 0xf84ef000, 0xb10e4606, 0xbd704630, 0x2004b90c, 0x2044e7fb, 0x71c84902, 0xff88f7ff, 0x0000e7f5, 0x40020000, 0xb9094601, 0x47702004, 0x6cc04826, 0x6003f3c0, 0x447b4b25, 0x0010f833, 0xb90a0302, 0xe7f22064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e5, 0x2004b90a, 0x61914770, 0xe7fb2000, 0x4604b530, 0x2004b90c, 0x1e58bd30, 0xb9104008, 0x40101e58, 0x2065b108, 0x6820e7f6, 0xd8054288, 0x0500e9d4, 0x188d4428, 0xd20142a8, 0xe7eb2066, 0xe7e92000, 0x480b4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0xb90b4603, 0x47702004, 0xd801290f, 0xd0012a04, 0xe7f82004, 0xe7f62000, 0x40048000, 0x0000024e, 0x6b65666b, 0x41f0e92d, 0x46884607, 0x461d4614, 0x2004b914, 0x81f0e8bd, 0x462a2304, 0x46384641, 0xffbcf7ff, 0xb10e4606, 0xe7f34630, 0x480fe019, 0x68004478, 0x8000f8c0, 0x490ccc01, 0x390c4479, 0x60486809, 0x490a2006, 0xf7ff71c8, 0x4606ff07, 0xb10869b8, 0x478069b8, 0xe004b106, 0x0804f108, 0x2d001f2d, 0xbf00d1e3, 0xe7d34630, 0x000001a4, 0x40020000, 0x4dffe92d, 0x4682b082, 0x2304460c, 0x46504621, 0xf7ff9a04, 0x4683ff89, 0x0f00f1bb, 0x4658d003, 0xe8bdb006, 0xe9da8df0, 0xfbb00101, 0x4260f7f1, 0x40084279, 0x42a54245, 0x443dd100, 0xe0229e04, 0x0804eba5, 0xd90045b0, 0xea4f46b0, 0x90010098, 0x4478480f, 0x60046800, 0x490e2001, 0x980171c8, 0x72c80a00, 0x72889801, 0x72489805, 0xfebcf7ff, 0xf1bb4683, 0xd0010f00, 0xe7d14658, 0x0608eba6, 0x443d4444, 0x2e00bf00, 0x2000d1da, 0x0000e7c8, 0x0000010e, 0x40020000, 0x4604b570, 0xb90c460d, 0xbd702004, 0x49032040, 0x460871c8, 0xf7ff7185, 0xe7f6fe9b, 0x40020000, 0x4dffe92d, 0x4617460c, 0xe9dd461d, 0xf8ddb80c, 0xb91da038, 0xb0042004, 0x8df0e8bd, 0x463a2304, 0x98004621, 0xff24f7ff, 0xb10e4606, 0xe7f24630, 0x4814e022, 0x68004478, 0x20026004, 0x71c84912, 0xf8804608, 0x490fb00b, 0x39144479, 0x68096828, 0xf7ff6088, 0x4606fe6d, 0xf1b8b15e, 0xd0010f00, 0x4000f8c8, 0x0f00f1ba, 0x2000d002, 0x0000f8ca, 0x1f3fe004, 0x1d241d2d, 0xd1da2f00, 0x4630bf00, 0x0000e7c9, 0x00000074, 0x40020000, 0x00000000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x01000000, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000059, 'pc_erase_sector' : 0x2000007D, 'pc_program_page' : 0x200000AB, 'begin_stack' : 0x20000c00, 'begin_data' : 0x20001c00, # Analyzer uses a max of 512 B data (128 pages * 4 bytes / page) 'page_buffers' : [0x20001800, 0x20001c00], # Enable double buffering 'static_base' : 0x20000000 + 0x20 + 0x468, 'min_program_length' : 8, 'analyzer_supported' : True, 'analyzer_address' : 0x1fffe000 # Analyzer 0x1fffe000..0x1fffe600 }; class Flash_k20d50m(Flash_Kinetis): def __init__(self, target): super(Flash_k20d50m, self).__init__(target, FLASH_ALGO) class K20D50M(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1fffe000, length=0x4000) ) def __init__(self, link): super(K20D50M, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK20D5.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_MKL28Z512xxx7.py0000644000175000017500000002553313373511253021167 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..coresight import ap from ..coresight.cortex_m import CortexM from ..debug.svd import SVDFile import logging import os.path from time import (time, sleep) SIM_SDID = 0x40075024 SIM_SDID_KEYATTR_MASK = 0x70 SIM_SDID_KEYATTR_SHIFT = 4 KEYATTR_DUAL_CORE = 1 RCM_MR = 0x4007f010 RCM_MR_BOOTROM_MASK = 0x6 SCG_CSR = 0x4007B010 SCG_RCCR = 0x4007B014 SCS_MASK = 0x0F000000 SCS_SHIFT = 24 DIVCORE_MASK = 0x000F0000 DIVCORE_SHIFT = 16 DIVSLOW_MASK = 0x0000000F DIVSLOW_SHIFT = 0 SCG_FIRCCSR = 0x4007B300 FIRCEN_MASK = 1 SCG_FIRCCFG = 0x4007B308 RECOVER_TIMEOUT = 1.0 # 1 second FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4832b510, 0x60414930, 0x60814931, 0x22806801, 0x22204391, 0x60014311, 0x4448482e, 0xf860f000, 0xd0002800, 0xbd102001, 0x47702000, 0xb5104829, 0x44484929, 0xf922f000, 0xd1042800, 0x21004825, 0xf0004448, 0x4a25f9c3, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x4c1fb570, 0x444c4605, 0x4b1e4601, 0x68e24620, 0xf89ef000, 0xd1052800, 0x46292300, 0x68e24620, 0xf916f000, 0x68ca4918, 0x029b2301, 0x60ca431a, 0xb570bd70, 0x460b460c, 0x46014606, 0xb0844810, 0x44484615, 0xf8bef000, 0xd10a2800, 0x90029001, 0x480b2101, 0x462b9100, 0x46314622, 0xf0004448, 0x4909f957, 0x230168ca, 0x431a029b, 0xb00460ca, 0x0000bd70, 0xd928c520, 0x40076000, 0x0000ffff, 0x00000004, 0x6b65666b, 0xf0003000, 0xd00a2800, 0x68c9492b, 0x0e094a2b, 0x447a0049, 0x03095a51, 0x2064d103, 0x20044770, 0xb4104770, 0x60032300, 0x21026041, 0x02896081, 0x492360c1, 0x158a7a0c, 0x610240a2, 0x61837ac9, 0xbc106141, 0x47704618, 0xd0022800, 0x20006181, 0x20044770, 0x28004770, 0x2004d101, 0xb4104770, 0x42191e5b, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x4288490d, 0x206bd001, 0x20004770, 0x28004770, 0x290fd008, 0x2a04d802, 0xe005d104, 0xd8012913, 0xd0012a08, 0x47702004, 0x47702000, 0x40075040, 0x00000512, 0x40020020, 0x6b65666b, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffdb, 0x2308d12b, 0x46214632, 0xf7ff4628, 0x0007ffb8, 0x19a6d123, 0x1e7668e9, 0x91004630, 0xf922f000, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf00071c8, 0x4607f8f9, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x00000416, 0x40020000, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff7ff7ff, 0xd11a0007, 0xd0172c00, 0x4478480d, 0x600e6801, 0x6800cd02, 0x490b6041, 0x71c82006, 0xf8caf000, 0x98014607, 0x28006980, 0x4780d000, 0xd1032f00, 0x1d361f24, 0xd1e72c00, 0xb0054638, 0x0000bdf0, 0x000003be, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff71, 0x2c00d106, 0x4904d005, 0x71c82044, 0xf8a8f000, 0x2004bd10, 0x0000bd10, 0x40020000, 0xb081b5ff, 0x460e4614, 0x23084605, 0xff3ff7ff, 0xd12a2800, 0x686868a9, 0xf8acf000, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908e8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xf876f000, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x0000031a, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2001e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfedbf7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xf824f000, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1d24bdf8, 0x1d361f2d, 0xd1e12d00, 0x0000bdf8, 0x00000276, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf0007181, 0xbd10f803, 0x40020000, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0x40020004, 0x00000000, 0x00000000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x00000000, 0x00800000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000049, 'pc_program_page': 0x200000A7, 'pc_erase_sector': 0x20000075, 'pc_eraseAll' : 0x2000004D, 'static_base' : 0x20000000 + 0x00000020 + 0x00000624, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000200, # All keys above are auto-generated. The following are added or modified. 'analyzer_supported' : True, # [modified] default is False 'analyzer_address' : 0x1fffa000, # [modified] default is zero. Use 8K block before flash algo. Can be any unused SRAM. 'page_buffers' : [0x20000a00, 0x20001200], # [added] Use areas above algo. Note 'begin_data' is unused if double buffering. Can be any unused SRAM. 'min_program_length' : 4 # [added] See FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE in KSDK features header file }; class Flash_kl28z(Flash_Kinetis): def __init__(self, target): super(Flash_kl28z, self).__init__(target, FLASH_ALGO) self._saved_firccsr = 0 self._saved_rccr = 0 ## # This function sets up target clocks to ensure that flash is clocked at the maximum # of 24MHz. Doing so gets the best flash programming performance. The FIRC clock source # is used so that there is no dependency on an external crystal frequency. def init(self, reset=True): super(Flash_kl28z, self).init(reset) # Enable FIRC. value = self.target.read32(SCG_FIRCCSR) self._saved_firccsr = value value |= FIRCEN_MASK self.target.write32(SCG_FIRCCSR, value) # Switch system to FIRC, core=48MHz (/1), slow=24MHz (/2). # Flash and the bus are clocked from the slow clock, and its max is 24MHz, # so there is no benefit from raising the core clock further. self._saved_rccr = self.target.read32(SCG_RCCR) self.target.write32(SCG_RCCR, (0x3 << SCS_SHIFT) | (1 << DIVSLOW_SHIFT)) csr = self.target.read32(SCG_CSR) logging.debug("SCG_CSR = 0x%08x", csr) ## # Restore clock registers to original values. def cleanup(self): self.target.write32(SCG_FIRCCSR, self._saved_firccsr) self.target.write32(SCG_RCCR, self._saved_rccr) class KL28x(Kinetis): singleMap = MemoryMap( FlashRegion(name='flash', start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion(name='ram', start=0x1fff8000, length=0x20000), RamRegion(name='usb ram', start=0x40100000, length=0x800) ) dualMap = MemoryMap( FlashRegion(name='flash', start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RomRegion(name='core1 imem alias', start=0x1d200000, length=0x40000), RamRegion(name='core0 ram', start=0x1fffa000, length=0x18000), RomRegion(name='core1 imem', start=0x2d200000, length=0x40000), RamRegion(name='core1 dmem', start=0x2d300000, length=0x8000), RamRegion(name='usb ram', start=0x40100000, length=0x800) ) def __init__(self, link): super(KL28x, self).__init__(link, self.singleMap) self.is_dual_core = False self._svd_location = SVDFile(vendor="Freescale", filename="MKL28T7_CORE0.svd", is_local=False) def create_init_sequence(self): seq = super(KL28x, self).create_init_sequence() # The KL28 will lock up if an invalid AP is accessed, so replace the AP scan with a # fixed list of known APs. seq.replace_task('find_aps', self.create_kl28_aps) # Before creating cores, determine which memory map should be used. seq.insert_before('create_cores', ('detect_dual_core', self.detect_dual_core) ) seq.insert_after('create_cores', ('disable_rom_remap', self.disable_rom_remap) ) return seq ## @brief Set the fixed list of valid AP numbers for KL28. def create_kl28_aps(self): self.dp.valid_aps = [0, 1, 2] def detect_dual_core(self): # Check if this is the dual core part. sdid = self.aps[0].read_memory(SIM_SDID) keyattr = (sdid & SIM_SDID_KEYATTR_MASK) >> SIM_SDID_KEYATTR_SHIFT logging.debug("KEYATTR=0x%x SDID=0x%08x", keyattr, sdid) self.is_dual_core = (keyattr == KEYATTR_DUAL_CORE) if self.is_dual_core: logging.info("KL28 is dual core") self.memory_map = self.dualMap def disable_rom_remap(self): # Disable ROM vector table remapping. self.aps[0].write32(RCM_MR, RCM_MR_BOOTROM_MASK) pyocd-0.13.1/pyocd/target/target_STM32F439xx.py0000644000175000017500000001244013373511253020700 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile class DBGMCU: CR = 0xE0042004 CR_VALUE = 0x7 # DBG_STANDBY | DBG_STOP | DBG_SLEEP APB1_FZ = 0xE0042008 APB1_FZ_VALUE = 0x06e01dff APB2_FZ = 0xE004200C APB2_FZ_VALUE = 0x00070003 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x03004601, 0x28200e00, 0x0940d302, 0xe0051d00, 0xd3022810, 0x1cc00900, 0x0880e000, 0xd50102c9, 0x43082110, 0x48464770, 0x60414944, 0x60414945, 0x60012100, 0x22f068c1, 0x60c14311, 0x06806940, 0x4842d406, 0x60014940, 0x60412106, 0x60814940, 0x47702000, 0x6901483a, 0x43110542, 0x20006101, 0xb5304770, 0x69014836, 0x43212404, 0x69016101, 0x43290365, 0x69016101, 0x431103a2, 0x49356101, 0xe0004a32, 0x68c36011, 0xd4fb03db, 0x43a16901, 0x69016101, 0x610143a9, 0xbd302000, 0xf7ffb530, 0x4927ffaf, 0x23f068ca, 0x60ca431a, 0x610c2402, 0x06c0690a, 0x43020e00, 0x6908610a, 0x431003e2, 0x48246108, 0xe0004a21, 0x68cd6010, 0xd4fb03ed, 0x43a06908, 0x68c86108, 0x0f000600, 0x68c8d003, 0x60c84318, 0xbd302001, 0x4d15b570, 0x08891cc9, 0x008968eb, 0x433326f0, 0x230060eb, 0x4b16612b, 0x692ce017, 0x612c431c, 0x60046814, 0x03e468ec, 0x692cd4fc, 0x00640864, 0x68ec612c, 0x0f240624, 0x68e8d004, 0x60e84330, 0xbd702001, 0x1d121d00, 0x29001f09, 0x2000d1e5, 0x0000bd70, 0x45670123, 0x40023c00, 0xcdef89ab, 0x00005555, 0x40003000, 0x00000fff, 0x0000aaaa, 0x00000201, 0x00000000 ], 'pc_init' : 0x20000047, 'pc_unInit': 0x20000075, 'pc_program_page': 0x20000109, 'pc_erase_sector': 0x200000bd, 'pc_eraseAll' : 0x20000083, 'static_base' : 0x20000171, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20001000, 'page_buffers' : [0x20001000], # Disable double buffering, sectors are too large to fit 2 in RAM. 'min_program_length' : 1, 'analyzer_supported' : True, 'analyzer_address' : 0x20002000 }; # @brief Flash algorithm for STM32F439xx device. class Flash_stm32f439xx(Flash): # Chip erase takes a really long time. CHIP_ERASE_WEIGHT = 15.0 def __init__(self, target): super(Flash_stm32f439xx, self).__init__(target, FLASH_ALGO) def get_flash_info(self): info = super(Flash_stm32f439xx, self).get_flash_info() info.erase_weight = self.CHIP_ERASE_WEIGHT return info class STM32F439xG(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x10000, blocksize=0x4000, is_boot_memory=True), FlashRegion( start=0x08010000, length=0x10000, blocksize=0x10000), FlashRegion( start=0x08020000, length=0x60000, blocksize=0x20000), RamRegion( start=0x20000000, length=0x40000) ) def __init__(self, transport): super(STM32F439xG, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F439x.svd") def create_init_sequence(self): seq = super(STM32F439xG, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): self.write32(DBGMCU.CR, DBGMCU.CR_VALUE) self.write32(DBGMCU.APB1_FZ, DBGMCU.APB1_FZ_VALUE) self.write32(DBGMCU.APB2_FZ, DBGMCU.APB2_FZ_VALUE) class STM32F439xI(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x10000, blocksize=0x4000, is_boot_memory=True), FlashRegion( start=0x08010000, length=0x10000, blocksize=0x10000), FlashRegion( start=0x08020000, length=0xe0000, blocksize=0x20000), FlashRegion( start=0x08100000, length=0x10000, blocksize=0x4000), FlashRegion( start=0x08110000, length=0x10000, blocksize=0x10000), FlashRegion( start=0x08120000, length=0xe0000, blocksize=0x20000), RamRegion( start=0x20000000, length=0x30000) ) def __init__(self, transport): super(STM32F439xI, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F439x.svd") def create_init_sequence(self): seq = super(STM32F439xI, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): self.write32(DBGMCU.CR, DBGMCU.CR_VALUE) self.write32(DBGMCU.APB1_FZ, DBGMCU.APB1_FZ_VALUE) self.write32(DBGMCU.APB2_FZ, DBGMCU.APB2_FZ_VALUE) pyocd-0.13.1/pyocd/target/target_MKW01Z128xxx4.py0000644000175000017500000001541313373511253021165 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8ecf000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9b1, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf894f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf956f000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4905b510, 0x60082000, 0x44484804, 0xf8e8f000, 0xd0002800, 0xbd102001, 0x40048100, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f8f5, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf96af000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0032800, 0xd801290f, 0xd0012a04, 0x47702004, 0x47702000, 0xd1012800, 0x47702004, 0x1e5bb410, 0x421c460c, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb3, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe3cf7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000026a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2000e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd0142800, 0x68c9490c, 0x0e094a0c, 0x447a0049, 0x03095a51, 0x2200d00d, 0x60416002, 0x60812102, 0x61426102, 0x61820249, 0x461060c1, 0x20044770, 0x20644770, 0x00004770, 0x40048040, 0x0000019a, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff22f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff38f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfef0f7ff, 0xd12a2800, 0x686868a9, 0xfd7cf7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfef2f7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fed7, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfea2f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeb6f7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00200000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002E5, 'pc_program_page': 0x2000029D, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x0000060c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff800 }; # @brief Flash algorithm for Kinetis KW01Z4 device. class Flash_kw01z4(Flash_Kinetis): def __init__(self, target): super(Flash_kw01z4, self).__init__(target, FLASH_ALGO) class KW01Z4(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x4000) ) def __init__(self, transport): super(KW01Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKW01Z4.svd") pyocd-0.13.1/pyocd/target/target_lpc800.py0000644000175000017500000001000213373511253020140 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x47700a80, 0x484e494f, 0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x49496382, 0x39402002, 0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x4622260f, 0x4621c261, 0x4f423114, 0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448, 0x462060e0, 0x47b89900, 0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0a844d35, 0x2032444d, 0x4629606c, 0x311460ac, 0x4e326028, 0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829, 0x68004448, 0x462860e8, 0x696847b0, 0xd0002800, 0xbdf82001, 0x4614b5f8, 0xd11e0006, 0x0180200b, 0x6bc11820, 0x42814823, 0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861, 0x184068e2, 0x188968a1, 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0ab0, 0x60682132, 0x60a86029, 0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033, 0x20016028, 0x60e80280, 0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001, 0x00002ee0, 0x00000004, 0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x43218765 ], 'pc_init' : 0x10000024, 'pc_eraseAll' : 0x10000052, 'pc_erase_sector' : 0x10000092, 'pc_program_page' : 0x100000d4, 'begin_data' : 0x10000400, # Analyzer uses a max of 128 B data (32 pages * 4 bytes / page) # Double buffering is not supported since there is not enough ram 'begin_stack' : 0x10001000, 'static_base' : 0x10000300, 'min_program_length' : 64, 'analyzer_supported' : True, 'analyzer_address' : 0x10000800 # Analyzer 0x10000800..0x10000e00 }; class Flash_lpc800(Flash): def __init__(self, target): super(Flash_lpc800, self).__init__(target, FLASH_ALGO) class LPC800(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x4000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x10000000, length=0x1000) ) def __init__(self, link): super(LPC800, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="NXP", filename="LPC800_v0.3.svd", is_local=False) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC800, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40048000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MK22FN1M0Axxx12.py0000644000175000017500000001555213373511253021342 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging SIM_FCFG1 = 0x4004804C SIM_FCFG2 = 0x40048050 SIM_FCFG2_PFLSH = (1 << 23) log = logging.getLogger("target.k22fa12") FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510483e, 0x5120f24c, 0xf64d81c1, 0x81c11128, 0xf0218801, 0x80010101, 0x78414839, 0x0160f001, 0xbf0c2940, 0x21002101, 0x444a4a36, 0xb1397011, 0xf0217841, 0x70410160, 0xf0117841, 0xd1fb0f60, 0x44484831, 0xf864f000, 0xbf182800, 0xbd102001, 0x4448482c, 0xb1587800, 0x78414829, 0x0160f021, 0x0140f041, 0x78417041, 0x0160f001, 0xd1fa2940, 0x47702000, 0xb5104824, 0x44484924, 0xf891f000, 0xbf182800, 0x2100bd10, 0xe8bd481f, 0x44484010, 0xb958f000, 0x4c1cb570, 0x444c4605, 0x4b1b4601, 0x68e24620, 0xf8b6f000, 0xbf182800, 0x2300bd70, 0x68e24629, 0x4070e8bd, 0x44484813, 0xb94cf000, 0x460cb570, 0x4606460b, 0x480f4601, 0x4615b084, 0xf0004448, 0x2800f8eb, 0xb004bf1c, 0x2000bd70, 0xe9cd2101, 0x90021000, 0x462b4807, 0x46314622, 0xf0004448, 0xb004f97f, 0x0000bd70, 0x40052000, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xbf042800, 0x47702004, 0x6cc949ea, 0x6103f3c1, 0xbf08290f, 0x1180f44f, 0x4ae7bf1f, 0xf832447a, 0x02891011, 0xe9c02200, 0x21022100, 0x61426081, 0x618202c9, 0x1203e9c0, 0x52a0f04f, 0x2108e9c0, 0x47702000, 0xbf0e2800, 0x61012004, 0x47702000, 0x48da4602, 0x49d96840, 0x0070f440, 0x47706048, 0x217048d7, 0x21807001, 0x78017001, 0x0f80f011, 0x7800d0fb, 0x0f20f010, 0x2067bf1c, 0xf0104770, 0xbf1c0f10, 0x47702068, 0x0001f010, 0x2069bf18, 0x28004770, 0x2004bf04, 0xb5104770, 0x4ac84604, 0x403bf06f, 0x48c76050, 0xbf144281, 0x2000206b, 0xbf182800, 0x4620bd10, 0xffd2f7ff, 0x46204603, 0xffc6f7ff, 0xbd104618, 0xbf042800, 0x47702004, 0x60532300, 0x60d36093, 0x61536113, 0x61d36193, 0x68c16011, 0xe9d06051, 0xfbb11001, 0x6090f0f0, 0x21102008, 0x0103e9c2, 0x1005e9c2, 0x61d02004, 0x47702000, 0x4df0e92d, 0x4615b088, 0x460c4698, 0x466a4682, 0xffd8f7ff, 0x4621462a, 0x9b044650, 0xf931f000, 0xbf1c0007, 0xe8bdb008, 0xe9dd8df0, 0x19604600, 0xfbb51e45, 0xfb06f0f6, 0xb1205010, 0xf0f6fbb5, 0x43701c40, 0x42ac1e45, 0xf8dfbf98, 0xd81cb270, 0x407ff024, 0x6010f040, 0x0004f8cb, 0x45804898, 0x206bbf14, 0x28002000, 0xb008bf1c, 0x8df0e8bd, 0xf7ff4650, 0x4607ff73, 0x0010f8da, 0xbf182800, 0xb9174780, 0x42ac4434, 0x4650d9e2, 0xff5ef7ff, 0x4638b008, 0x8df0e8bd, 0xbf042a00, 0x47702004, 0x45f0e92d, 0x4614b089, 0x460d461e, 0x466a4680, 0xff88f7ff, 0x46294632, 0x9b034640, 0xf8e1f000, 0xbf1c0007, 0xe8bdb009, 0x9d0085f0, 0xbf182e00, 0xa1e8f8df, 0xf854d025, 0xf8ca0b04, 0x98030008, 0xbf042804, 0x407ff025, 0x60c0f040, 0x2808d009, 0xf854d109, 0xf8ca0b04, 0xf025000c, 0xf040407f, 0xf8ca60e0, 0x46400004, 0xff28f7ff, 0x1010f8d8, 0x29004607, 0x4788bf18, 0x9803b91f, 0x1a364405, 0x4640d1d9, 0xff12f7ff, 0x4638b009, 0x85f0e8bd, 0xbf042800, 0x47702004, 0xea424a62, 0x4a5f4101, 0xe70b6051, 0x4dffe92d, 0x4614b088, 0x460d469a, 0x9808466a, 0xff36f7ff, 0x46294622, 0x98089b05, 0xf88ff000, 0xbf1c2800, 0xe8bdb00c, 0x466a8df0, 0x98084629, 0xff26f7ff, 0xf8dd9e00, 0x42708008, 0x0100f1c8, 0x42474008, 0xbf0842b7, 0x2c004447, 0xf8dfbf18, 0xd01fb128, 0x42a51bbd, 0x4625bf88, 0xf0269805, 0xfbb5417f, 0xf041f0f0, 0xf8cb7180, 0x04001004, 0x200aea40, 0x00fff040, 0x0008f8cb, 0xf7ff9808, 0x2800fecb, 0xb00cbf1c, 0x8df0e8bd, 0x442e1b64, 0xd1df4447, 0x2000b00c, 0x8df0e8bd, 0xbf042b00, 0x47702004, 0x4dffe92d, 0x4616b088, 0x7a14e9dd, 0x460c461d, 0xf8dd466a, 0x98088058, 0xfee0f7ff, 0x3007e9dd, 0x46214632, 0xf839f000, 0xbf1c2800, 0xe8bdb00c, 0x9c008df0, 0xbf042e00, 0xe8bdb00c, 0xf8df8df0, 0xf06fb094, 0xea40407f, 0xf0246707, 0xf040407f, 0xf8cb7000, 0xf8cb0004, 0x68287008, 0x000cf8cb, 0xf7ff9808, 0xb168fe87, 0x0f00f1ba, 0xf8cabf18, 0xf1b84000, 0xbf1c0f00, 0xf8c82100, 0xb00c1000, 0x8df0e8bd, 0x1a769907, 0x0103f021, 0x9907440d, 0xd1da440c, 0xe8bdb00c, 0x28008df0, 0x2004bf04, 0x1e5b4770, 0xbf0e4219, 0x2065421a, 0x68034770, 0xd806428b, 0x44116840, 0x42884418, 0x2000bf24, 0x20664770, 0x00004770, 0x40048000, 0x000003b4, 0x4001f000, 0x40020000, 0x6b65666b, 0x4000ffff, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000071, 'pc_program_page': 0x200000E1, 'pc_erase_sector': 0x200000B5, 'pc_eraseAll' : 0x20000095, 'static_base' : 0x20000000 + 0x00000020 + 0x00000504, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000200, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_k22fa12(Flash_Kinetis): def __init__(self, target): super(Flash_k22fa12, self).__init__(target, FLASH_ALGO) class K22FA12(Kinetis): # 1MB flash with 4kB sectors, 128kB RAM memoryMap = MemoryMap( FlashRegion( start=0, length=0x100000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1fff0000, length=0x20000) ) def __init__(self, link): super(K22FA12, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MK22FA12.svd", is_local=False) def create_init_sequence(self): seq = super(K22FA12, self).create_init_sequence() # Modify the memory map for FlexNVM devices. seq.insert_before('create_cores', ('fixup_memory_map', self.fixup_memory_map) ) return seq def fixup_memory_map(self): # If the device has FlexNVM, then it has half-sized program flash. fcfg2 = self.dp.aps[0].read32(SIM_FCFG2) if (fcfg2 & SIM_FCFG2_PFLSH) == 0: log.debug("%s: device has FlexNVM", self.part_number) rgn = self.memory_map.get_region_for_address(0) rgn._end = 0x7ffff else: log.debug("%s: device does not have FlexNVM", self.part_number) pyocd-0.13.1/pyocd/target/family/0000755000175000017500000000000013373523011016475 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/target/family/flash_cortex_m.py0000644000175000017500000000276013373511253022056 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ...flash.flash import Flash class Flash_cortex_m(Flash): def __init__(self, target): super(Flash_cortex_m, self).__init__(target, None) def init(self): raise Exception("Unsupported flash operation on generic cortex_m") def compute_crcs(self, sectors): raise Exception("Unsupported flash operation on generic cortex_m") def erase_all(self): raise Exception("Unsupported flash operation on generic cortex_m") def erase_page(self, flashPtr): raise Exception("Unsupported flash operation on generic cortex_m") def program_page(self, flashPtr, bytes): raise Exception("Unsupported flash operation on generic cortex_m") def get_page_info(self, addr): raise Exception("Unsupported flash operation on generic cortex_m") def get_flash_info(self): raise Exception("Unsupported flash operation on generic cortex_m") pyocd-0.13.1/pyocd/target/family/target_kinetis.py0000644000175000017500000002636113373511253022100 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ...coresight import (dap, ap) from ...coresight.cortex_m import CortexM from ...core import exceptions from ...core.target import Target from ...core.coresight_target import CoreSightTarget from ...utility.timeout import Timeout import logging from time import sleep MDM_STATUS = 0x00000000 MDM_CTRL = 0x00000004 MDM_IDR = 0x000000fc MDM_STATUS_FLASH_MASS_ERASE_ACKNOWLEDGE = (1 << 0) MDM_STATUS_FLASH_READY = (1 << 1) MDM_STATUS_SYSTEM_SECURITY = (1 << 2) MDM_STATUS_MASS_ERASE_ENABLE = (1 << 5) MDM_STATUS_CORE_HALTED = (1 << 16) MDM_CTRL_FLASH_MASS_ERASE_IN_PROGRESS = (1 << 0) MDM_CTRL_DEBUG_REQUEST = (1 << 2) MDM_CTRL_SYSTEM_RESET_REQUEST = (1 << 3) MDM_CTRL_CORE_HOLD_RESET = (1 << 4) MDM_IDR_EXPECTED = 0x001c0000 MDM_IDR_VERSION_MASK = 0xf0 MDM_IDR_VERSION_SHIFT = 4 HALT_TIMEOUT = 2.0 MASS_ERASE_TIMEOUT = 10.0 ACCESS_TEST_ATTEMPTS = 10 log = logging.getLogger("target.family.kinetis") class Kinetis(CoreSightTarget): def __init__(self, link, memoryMap=None): super(Kinetis, self).__init__(link, memoryMap) self.mdm_ap = None def create_init_sequence(self): seq = super(Kinetis, self).create_init_sequence() # Must check whether security is enabled, and potentially auto-unlock, before # any init tasks that require system bus access. seq.insert_before('init_ap_roms', ('check_mdm_ap_idr', self.check_mdm_ap_idr), ('check_flash_security', self.check_flash_security), ) # Perform the halt sequence after cores are created. (This needs work.) seq.insert_after('create_cores', ('halt_on_connect', self.perform_halt_on_connect) ) return seq def check_mdm_ap_idr(self): self.mdm_ap = self.dp.aps[1] # Check MDM-AP ID. if (self.mdm_ap.idr & ~MDM_IDR_VERSION_MASK) != MDM_IDR_EXPECTED: log.error("%s: bad MDM-AP IDR (is 0x%08x)", self.part_number, self.mdm_ap.idr) self.mdm_ap_version = (self.mdm_ap.idr & MDM_IDR_VERSION_MASK) >> MDM_IDR_VERSION_SHIFT log.debug("MDM-AP version %d", self.mdm_ap_version) ## @brief Check security and unlock device. # # This init task determines whether the device is locked (flash security enabled). If it is, # and if auto unlock is enabled, then perform a mass erase to unlock the device. # # This whole sequence is greatly complicated by some behaviour of the device when flash is # blank. If flash is blank and the device does not have a ROM, then it will repeatedly enter # lockup and then reset. # # Immediately after reset asserts, the flash controller begins to initialise. The device is # always locked, and flash security reads as enabled, until the flash controller has finished # its init sequence. Thus, depending on exactly when the debugger reads the MDM-AP status # register, a blank, unlocked device may be detected as locked. # # There is also the possibility that the device will be (correctly) detected as unlocked, but # it resets again before the core can be halted, thus causing connect to fail. # # This init task runs *before* cores are created. def check_flash_security(self): # check for flash security isLocked = self.is_locked() # Test whether we can reliably access the memory and the core. This test can fail if flash # is blank and the device is auto-resetting. if isLocked: canAccess = False else: try: for attempt in range(ACCESS_TEST_ATTEMPTS): self.aps[0].read32(CortexM.DHCSR) except exceptions.TransferError: log.debug("Access test failed with fault") canAccess = False else: canAccess = True # Verify locked status under reset. We only want to assert reset if the device looks locked # or accesses fail, otherwise we could not support attach mode debugging. if not canAccess: # Keep the target in reset until is had been erased and halted. It will be deasserted # later, in perform_halt_on_connect(). # # Ideally we would use the MDM-AP to hold the device in reset, but SYSTEM_RESET_REQUEST # cannot be written in MDM_CTRL when the device is locked in MDM-AP version 0. self.dp.assert_reset(True) # Re-read locked status under reset. isLocked = self.is_locked() # If the device isn't really locked, we have no choice but to halt on connect. if not isLocked and not self.halt_on_connect: log.warning("Forcing halt on connect in order to gain control of device") self.halt_on_connect = True # Only do a mass erase if the device is actually locked. if isLocked: if self.auto_unlock: log.warning("%s in secure state: will try to unlock via mass erase", self.part_number) # Do the mass erase. if not self.mass_erase(): self.dp.assert_reset(False) self.mdm_ap.write_reg(MDM_CTRL, 0) log.error("%s: mass erase failed", self.part_number) raise RuntimeError("unable to unlock device") # Assert that halt on connect was forced above. Reset will stay asserted # until halt on connect is executed. assert self.halt_on_connect isLocked = False else: log.warning("%s in secure state: not automatically unlocking", self.part_number) else: log.info("%s not in secure state", self.part_number) # This init task runs *after* cores are created. def perform_halt_on_connect(self): if self.halt_on_connect: # Prevent the target from resetting if it has invalid code with Timeout(HALT_TIMEOUT) as to: while to.check(): self.mdm_ap.write_reg(MDM_CTRL, MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET) if self.mdm_ap.read_reg(MDM_CTRL) & (MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET) == (MDM_CTRL_DEBUG_REQUEST | MDM_CTRL_CORE_HOLD_RESET): break else: raise RuntimeError("Timed out attempting to set DEBUG_REQUEST and CORE_HOLD_RESET in MDM-AP") # We can now deassert reset. self.dp.assert_reset(False) # Enable debug self.aps[0].write_memory(CortexM.DHCSR, CortexM.DBGKEY | CortexM.C_DEBUGEN) # Disable holding the core in reset, leave MDM halt on self.mdm_ap.write_reg(MDM_CTRL, MDM_CTRL_DEBUG_REQUEST) # Wait until the target is halted with Timeout(HALT_TIMEOUT) as to: while to.check(): if self.mdm_ap.read_reg(MDM_STATUS) & MDM_STATUS_CORE_HALTED == MDM_STATUS_CORE_HALTED: break log.debug("Waiting for mdm halt") sleep(0.01) else: raise RuntimeError("Timed out waiting for core to halt") # release MDM halt once it has taken effect in the DHCSR self.mdm_ap.write_reg(MDM_CTRL, 0) # sanity check that the target is still halted if self.get_state() == Target.TARGET_RUNNING: raise RuntimeError("Target failed to stay halted during init sequence") def is_locked(self): self._wait_for_flash_init() val = self.mdm_ap.read_reg(MDM_STATUS) return (val & MDM_STATUS_SYSTEM_SECURITY) != 0 def _wait_for_flash_init(self): # Wait until flash is inited. with Timeout(MASS_ERASE_TIMEOUT) as to: while to.check(): status = self.mdm_ap.read_reg(MDM_STATUS) if status & MDM_STATUS_FLASH_READY: break sleep(0.01) return not to.did_time_out ## @brief Perform a mass erase operation. # @note Reset is held for the duration of this function. # @return True Mass erase succeeded. # @return False Mass erase failed or is disabled. def mass_erase(self): # Read current reset state so we can restore it, then assert reset if needed. wasResetAsserted = self.dp.is_reset_asserted() if not wasResetAsserted: self.dp.assert_reset(True) # Perform the erase. result = self._mass_erase() # Restore previous reset state. if not wasResetAsserted: self.dp.assert_reset(False) return result ## @brief Private mass erase routine. def _mass_erase(self): # Flash must finish initing before we can mass erase. if not self._wait_for_flash_init(): log.error("Mass erase timeout waiting for flash to finish init") return False # Check if mass erase is enabled. status = self.mdm_ap.read_reg(MDM_STATUS) if not (status & MDM_STATUS_MASS_ERASE_ENABLE): log.error("Mass erase disabled. MDM status: 0x%x", status) return False # Set Flash Mass Erase in Progress bit to start erase. self.mdm_ap.write_reg(MDM_CTRL, MDM_CTRL_FLASH_MASS_ERASE_IN_PROGRESS) # Wait for Flash Mass Erase Acknowledge to be set. with Timeout(MASS_ERASE_TIMEOUT) as to: while to.check(): val = self.mdm_ap.read_reg(MDM_STATUS) if val & MDM_STATUS_FLASH_MASS_ERASE_ACKNOWLEDGE: break sleep(0.1) else: #if to.did_time_out: log.error("Mass erase timeout waiting for Flash Mass Erase Ack to set") return False # Wait for Flash Mass Erase in Progress bit to clear when erase is completed. with Timeout(MASS_ERASE_TIMEOUT) as to: while to.check(): val = self.mdm_ap.read_reg(MDM_CTRL) if ((val & MDM_CTRL_FLASH_MASS_ERASE_IN_PROGRESS) == 0): break sleep(0.1) else: #if to.did_time_out: log.error("Mass erase timeout waiting for Flash Mass Erase in Progress to clear") return False # Confirm the part was unlocked val = self.mdm_ap.read_reg(MDM_STATUS) if (val & MDM_STATUS_SYSTEM_SECURITY) == 0: log.warning("%s secure state: unlocked successfully", self.part_number) return True else: log.error("Failed to unlock. MDM status: 0x%x", val) return False pyocd-0.13.1/pyocd/target/family/__init__.py0000644000175000017500000000112713373511253020614 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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. """ pyocd-0.13.1/pyocd/target/family/flash_kinetis.py0000644000175000017500000000717013373511253021704 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ...flash.flash import Flash import logging # Kinetis security values and addresses SECURITY_START = 0x400 SECURITY_SIZE = 16 FPROT_ADDR = 0x408 FPROT_ADDR_END = 0x40c FPROT_SIZE = 4 FSEC_ADDR = 0x40c FSEC_VAL = 0xFE FOPT_ADDR = 0x40d FOPT_VAL = 0xFF FEPROT_ADDR = 0x40e FEPROT_VAL = 0xFF FDPROT_ADDR = 0x40f FDPROT_VAL = 0xFF # @brief Base flash algorithm class for Freescale Kinetis devices. class Flash_Kinetis(Flash): # @brief Check security bytes. # # Override Flash Configuration Field bytes at address 0x400-0x40f to ensure that flash security # won't be enabled. If flash security is enabled, then the chip is inaccessible via SWD. # # FCF bytes: # [0x0-0x7]=backdoor key # [0x8-0xb]=flash protection bytes # [0xc]=FSEC: # [7:6]=KEYEN (2'b10 is backdoor key enabled, all others backdoor key disabled) # [5:4]=MEEN (2'b10 mass erase disabled, all other mass erase enabled) # [3:2]=FSLACC (2'b00 and 2'b11 factory access enabled, 2'b01 and 2'b10 factory access disabled) # [1:0]=SEC (2'b10 flash security disabled, all other flash security enabled) # [0xd]=FOPT # [0xe]=EEPROM protection bytes (FlexNVM devices only) # [0xf]=data flash protection bytes (FlexNVM devices only) # # This function enforces that: # - 0x8-0xb==0xff # - 0xe-0xf==0xff # - FSEC=0xfe # # FOPT can be set to any value except 0x00. # # @retval Data with modified security bits def override_security_bits(self, address, data): # Check if the data passed in contains the security bits if (address <= SECURITY_START and address + len(data) >= SECURITY_START + SECURITY_SIZE): # convert data to a list so it can be modified data = list(data) # FPROT must be 0xff (erase protection disabled) for i in range(FPROT_ADDR, FPROT_ADDR_END): if (data[i - address] != 0xff): data[i - address] = 0xff logging.debug("FCF[%d] at addr 0x%X changed to 0x%X", i - FPROT_ADDR, i, data[i - address]) # FSEC must be 0xff if data[FSEC_ADDR - address] != FSEC_VAL: data[FSEC_ADDR - address] = FSEC_VAL logging.debug("FSEC at addr 0x%X changed to 0x%X", FSEC_ADDR, FSEC_VAL) # FOPT must not be 0x00, any other value is acceptable. if data[FOPT_ADDR - address] == 0x00: logging.debug("FOPT is restricted value 0x00") # FEPROT must be 0xff if data[FEPROT_ADDR - address] != FEPROT_VAL: data[FEPROT_ADDR - address] = FEPROT_VAL logging.debug("FEPROT at addr 0x%X changed to 0x%X", FEPROT_ADDR, FEPROT_VAL) # FDPROT must be 0xff if data[FDPROT_ADDR - address] != FDPROT_VAL: data[FDPROT_ADDR - address] = FDPROT_VAL logging.debug("FDPROT at addr 0x%X changed to 0x%X", FDPROT_ADDR, FDPROT_VAL) # convert back to tuple data = tuple(data) return data pyocd-0.13.1/pyocd/target/__init__.py0000644000175000017500000002034113373511253017332 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..core.coresight_target import CoreSightTarget from .family import (target_kinetis, flash_cortex_m) from . import target_MKE15Z256xxx7 from . import target_MKE18F256xxx16 from . import target_MKL02Z32xxx4 from . import target_MKL05Z32xxx4 from . import target_MKL25Z128xxx4 from . import target_MKL26Z256xxx4 from . import target_MKL27Z256xxx4 from . import target_MKL28Z512xxx7 from . import target_MKL43Z256xxx4 from . import target_MKL46Z256xxx4 from . import target_MKL82Z128xxx7 from . import target_MKV10Z128xxx7 from . import target_MKV11Z128xxx7 from . import target_MKW01Z128xxx4 from . import target_MKW24D512xxx5 from . import target_MKW36Z512xxx4 from . import target_MKW40Z160xxx4 from . import target_MKW41Z512xxx4 from . import target_MK22FN1M0Axxx12 from . import target_MK22FN512xxx12 from . import target_MK28FN2M0xxx15 from . import target_MK64FN1M0xxx12 from . import target_MK66FN2M0xxx18 from . import target_MK82FN256xxx15 from . import target_MK20DX128xxx5 from . import target_K32W042S1M2xxx from . import target_lpc800 from . import target_LPC11U24FBD64_401 from . import target_LPC1768 from . import target_LPC4330 from . import target_nRF51822_xxAA from . import target_nRF52832_xxAA from . import target_nRF52840_xxAA from . import target_STM32F103RC from . import target_STM32F051T8 from . import target_STM32F412xx from . import target_STM32F439xx from . import target_STM32L475xx from . import target_MAX32600 from . import target_w7500 from . import target_LPC1114FN28_102 from . import target_LPC824M201JHI33 from . import target_LPC54114J256BD64 from . import target_LPC54608J512ET180 from . import target_ncs36510 from . import target_LPC4088FBD144 from . import target_lpc4088qsb from . import target_lpc4088dm from . import target_RTL8195AM from . import target_CC3220SF TARGET = { 'cortex_m': CoreSightTarget, 'kinetis': target_kinetis.Kinetis, 'ke15z7': target_MKE15Z256xxx7.KE15Z7, 'ke18f16': target_MKE18F256xxx16.KE18F16, 'kl02z': target_MKL02Z32xxx4.KL02Z, 'kl05z': target_MKL05Z32xxx4.KL05Z, 'kl25z': target_MKL25Z128xxx4.KL25Z, 'kl26z': target_MKL26Z256xxx4.KL26Z, 'kl27z4': target_MKL27Z256xxx4.KL27Z4, 'kl28z': target_MKL28Z512xxx7.KL28x, 'kl43z4': target_MKL43Z256xxx4.KL43Z4, 'kl46z': target_MKL46Z256xxx4.KL46Z, 'kl82z7': target_MKL82Z128xxx7.KL82Z7, 'kv10z7': target_MKV10Z128xxx7.KV10Z7, 'kv11z7': target_MKV11Z128xxx7.KV11Z7, 'kw01z4': target_MKW01Z128xxx4.KW01Z4, 'kw24d5': target_MKW24D512xxx5.KW24D5, 'kw36z4': target_MKW36Z512xxx4.KW36Z4, 'kw40z4': target_MKW40Z160xxx4.KW40Z4, 'kw41z4': target_MKW41Z512xxx4.KW41Z4, 'k20d50m': target_MK20DX128xxx5.K20D50M, 'k22fa12': target_MK22FN1M0Axxx12.K22FA12, 'k22f': target_MK22FN512xxx12.K22F, 'k28f15': target_MK28FN2M0xxx15.K28F15, 'k64f': target_MK64FN1M0xxx12.K64F, 'k66f18': target_MK66FN2M0xxx18.K66F18, 'k82f25615': target_MK82FN256xxx15.K82F25615, 'k32w042s': target_K32W042S1M2xxx.K32W042S, 'lpc800': target_lpc800.LPC800, 'lpc11u24': target_LPC11U24FBD64_401.LPC11U24, 'lpc1768': target_LPC1768.LPC1768, 'lpc4330': target_LPC4330.LPC4330, 'nrf51': target_nRF51822_xxAA.NRF51, 'nrf52' : target_nRF52832_xxAA.NRF52, 'nrf52840' : target_nRF52840_xxAA.NRF52840, 'stm32f103rc': target_STM32F103RC.STM32F103RC, 'stm32f051': target_STM32F051T8.STM32F051, 'stm32f412xe' : target_STM32F412xx.STM32F412xE, 'stm32f412xg' : target_STM32F412xx.STM32F412xG, 'stm32f439xg' : target_STM32F439xx.STM32F439xG, 'stm32f439xi' : target_STM32F439xx.STM32F439xI, 'stm32l475xc' : target_STM32L475xx.STM32L475xC, 'stm32l475xe' : target_STM32L475xx.STM32L475xE, 'stm32l475xg' : target_STM32L475xx.STM32L475xG, 'max32600': target_MAX32600.MAX32600, 'w7500': target_w7500.W7500, 'lpc11xx_32': target_LPC1114FN28_102.LPC11XX_32, 'lpc824': target_LPC824M201JHI33.LPC824, 'lpc54114': target_LPC54114J256BD64.LPC54114, 'lpc54608': target_LPC54608J512ET180.LPC54608, 'lpc4088': target_LPC4088FBD144.LPC4088, 'ncs36510': target_ncs36510.NCS36510, 'lpc4088qsb': target_lpc4088qsb.LPC4088qsb, 'lpc4088dm': target_lpc4088dm.LPC4088dm, 'rtl8195am': target_RTL8195AM.RTL8195AM, 'cc3220sf': target_CC3220SF.CC3220SF, } FLASH = { 'cortex_m': flash_cortex_m.Flash_cortex_m, 'kinetis': flash_cortex_m.Flash_cortex_m, 'ke15z7': target_MKE15Z256xxx7.Flash_ke15z7, 'ke18f16': target_MKE18F256xxx16.Flash_ke18f16, 'kl02z': target_MKL02Z32xxx4.Flash_kl02z, 'kl05z': target_MKL05Z32xxx4.Flash_kl05z, 'kl25z': target_MKL25Z128xxx4.Flash_kl25z, 'kl26z': target_MKL26Z256xxx4.Flash_kl26z, 'kl27z4': target_MKL27Z256xxx4.Flash_kl27z4, 'kl28z': target_MKL28Z512xxx7.Flash_kl28z, 'kl43z4': target_MKL43Z256xxx4.Flash_kl43z4, 'kl46z': target_MKL46Z256xxx4.Flash_kl46z, 'kl82z7': target_MKL82Z128xxx7.Flash_mkl82z7, 'kv10z7': target_MKV10Z128xxx7.Flash_kv10z7, 'kv11z7': target_MKV11Z128xxx7.Flash_kv11z7, 'kw01z4': target_MKW01Z128xxx4.Flash_kw01z4, 'kw24d5': target_MKW24D512xxx5.Flash_kw24d5, 'kw36z4': target_MKW36Z512xxx4.Flash_kw36z4, 'kw40z4': target_MKW40Z160xxx4.Flash_kw40z4, 'kw41z4': target_MKW41Z512xxx4.Flash_kw41z4, 'k20d50m': target_MK20DX128xxx5.Flash_k20d50m, 'k22fa12': target_MK22FN1M0Axxx12.Flash_k22fa12, 'k22f': target_MK22FN512xxx12.Flash_k22f, 'k28f15': target_MK28FN2M0xxx15.Flash_k28f15, 'k64f': target_MK64FN1M0xxx12.Flash_k64f, 'k66f18': target_MK66FN2M0xxx18.Flash_k66f18, 'k82f25615': target_MK82FN256xxx15.Flash_k82f25615, 'k32w042s': target_K32W042S1M2xxx.Flash_k32w042s, 'lpc800': target_lpc800.Flash_lpc800, 'lpc11u24': target_LPC11U24FBD64_401.Flash_lpc11u24, 'lpc1768': target_LPC1768.Flash_lpc1768, 'lpc4330': target_LPC4330.Flash_lpc4330, 'nrf51': target_nRF51822_xxAA.Flash_nrf51, 'nrf52': target_nRF52832_xxAA.Flash_nrf52, 'nrf52840': target_nRF52840_xxAA.Flash_nrf52840, 'stm32f103rc': target_STM32F103RC.Flash_stm32f103rc, 'stm32f051': target_STM32F051T8.Flash_stm32f051, 'stm32f412xe' : target_STM32F412xx.Flash_stm32f412xx, 'stm32f412xg' : target_STM32F412xx.Flash_stm32f412xx, 'stm32f439xg' : target_STM32F439xx.Flash_stm32f439xx, 'stm32f439xi' : target_STM32F439xx.Flash_stm32f439xx, 'stm32l475xc' : target_STM32L475xx.Flash_stm32l475xx, 'stm32l475xe' : target_STM32L475xx.Flash_stm32l475xx, 'stm32l475xg' : target_STM32L475xx.Flash_stm32l475xx, 'max32600': target_MAX32600.Flash_max32600, 'w7500': target_w7500.Flash_w7500, 'lpc11xx_32': target_LPC1114FN28_102.Flash_lpc11xx_32, 'lpc824': target_LPC824M201JHI33.Flash_lpc824, 'lpc4088': target_LPC4088FBD144.Flash_lpc4088, 'lpc54114': target_LPC54114J256BD64.Flash_lpc54114, 'lpc54608': target_LPC54608J512ET180.Flash_lpc54608, 'ncs36510': target_ncs36510.Flash_ncs36510, 'lpc4088qsb': target_lpc4088qsb.Flash_lpc4088qsb_dm, 'lpc4088dm': target_lpc4088dm.Flash_lpc4088qsb_dm, 'rtl8195am': target_RTL8195AM.Flash_rtl8195am, 'cc3220sf': target_CC3220SF.Flash_cc3220sf, } pyocd-0.13.1/pyocd/target/target_lpc4088qsb.py0000644000175000017500000001234513373511253020756 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from .target_LPC4088FBD144 import (Flash_lpc4088, LPC4088) SPIFI_START = 0x28000000 SPIFI_SIZE = 16 * 1024 * 1024 SPIFI_SECTOR_SIZE = 4 * 1024 FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x28100b00, 0x210ebf24, 0x00d0eb01, 0xe92d4770, 0xf8df4df0, 0x4606831c, 0x460c44c8, 0x0000f8d8, 0x1c402500, 0x0000f8c8, 0x0f01f010, 0x461749c1, 0x2080f44f, 0x63c8bf14, 0x05306388, 0xa2f8f8df, 0xf04f0d00, 0x44ca0b00, 0xf8cad111, 0xf44fb010, 0xf8ca5080, 0xe9ca6000, 0xf8ca0b01, 0xf8d8b00c, 0x4651000c, 0xf1a16882, 0x47900080, 0x2018b9c0, 0xb008f8ca, 0xb003e9ca, 0xf5b4b1cc, 0xbf8c7f80, 0x7b80f44f, 0x197046a3, 0x0b00e9ca, 0x000cf8d8, 0x19794aa9, 0x6843444a, 0x0080f1a2, 0xb1104798, 0xe8bd2001, 0x445d8df0, 0x040bebb4, 0x2000d1e5, 0x8df0e8bd, 0x41f0e92d, 0x8274f8df, 0x60e0f642, 0x4d9e44c8, 0x0008f8c8, 0x70282000, 0x732820aa, 0x73282055, 0xf8052001, 0x22000c40, 0xf0002112, 0x2200f91a, 0x4610210d, 0xf915f000, 0x210d2200, 0xf0002001, 0x2200f910, 0x20022113, 0xf90bf000, 0x68204c8c, 0x5000f440, 0x6a206020, 0x2084f440, 0x6c206220, 0x2000f440, 0xf44f6420, 0x63e72780, 0x61a6117e, 0xf4406c68, 0x64683080, 0xf8c52002, 0x22050134, 0xf0002107, 0x2205f8ee, 0x20002116, 0xf8e9f000, 0x210f2205, 0xf0002000, 0x2205f8e4, 0x20002110, 0xf8dff000, 0x21112205, 0xf0002000, 0x2205f8da, 0x20002112, 0xf8d5f000, 0xf44f4874, 0x6800727a, 0xf8c86940, 0xf8d8000c, 0xfbb11008, 0xf8d5f1f2, 0xf8d02134, 0xf002c000, 0xfbb1021f, 0x496cf3f2, 0xfba1486c, 0x08892103, 0x444822c0, 0x280047e0, 0x61e6bf04, 0x81f0e8bd, 0x61e663a7, 0xe8bd2001, 0x200081f0, 0xe92d4770, 0x4c6341f0, 0x444c2032, 0x251d2700, 0xe9c460a5, 0x4e600700, 0x0114f104, 0x47b04620, 0xb9806960, 0x60a52034, 0x0700e9c4, 0xf1044852, 0x44480114, 0x60e06880, 0x47b04620, 0x28006960, 0xe8bdbf08, 0x200181f0, 0x81f0e8bd, 0x5f20f1b0, 0xf5b0bf32, 0x20002f00, 0xb5704770, 0x2c100b04, 0x200ebf24, 0x04d4eb00, 0x4d4a2032, 0x444d4e4a, 0x0114f105, 0x0400e9c5, 0x60ac4628, 0x696847b0, 0x2034b978, 0x0400e9c5, 0x60ac483b, 0xf1054448, 0x68800114, 0x462860e8, 0x696847b0, 0xbf082800, 0x2001bd70, 0xe92dbd70, 0x4f3341f0, 0x444f4605, 0x68784614, 0x1c404a31, 0xf0106078, 0xf44f0f01, 0xbf145000, 0x619061d0, 0x5f20f1b5, 0x4622d305, 0x5020f1a5, 0x41f0e8bd, 0xf5b5e6bd, 0xd3052f00, 0xf5a54622, 0xe8bd2000, 0xe6b441f0, 0xe9d4b975, 0x44080100, 0x1202e9d4, 0x44084411, 0x44086921, 0x44086961, 0x440869a1, 0x61e04240, 0x28100b28, 0x210ebf24, 0x00d0eb01, 0x4e1e2132, 0x8078f8df, 0xe9c6444e, 0x60b01000, 0x0114f106, 0x47c04630, 0xb9886970, 0xe9c62033, 0xf44f0500, 0xe9c67000, 0x68b84002, 0xf1066130, 0x46300114, 0x697047c0, 0xbf082800, 0x81f0e8bd, 0xe8bd2001, 0xeb0181f0, 0x490e1040, 0x0080eb01, 0xf0216801, 0x60010107, 0x43116801, 0x47706001, 0x00000004, 0x20098000, 0x000000b4, 0x400fc080, 0x1fff1ff8, 0xcccccccd, 0x00000034, 0x00000014, 0x1fff1ff1, 0x4002c000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, ], 'pc_init' : 0x100000D5, 'pc_unInit': 0x100001D7, 'pc_program_page': 0x1000027F, 'pc_erase_sector': 0x10000225, 'pc_eraseAll' : 0x100001DB, 'static_base' : 0x10000000 + 0x00000020 + 0x00000400, 'begin_stack' : 0x10000000 + 0x00000800, # Double buffering is not supported since there is not enough ram 'begin_data' : 0x10000000 + 0x00000A00, # Analyzer uses a max of 120 B data (30 pages * 4 bytes / page) 'page_size' : 0x00000200, 'analyzer_supported' : False, 'min_program_length' : 512, 'analyzer_supported' : True, 'analyzer_address' : 0x10002000 # Analyzer 0x10002000..0x10002600 } class Flash_lpc4088qsb_dm(Flash_lpc4088): def __init__(self, target): super(Flash_lpc4088qsb_dm, self).__init__(target, FLASH_ALGO) def program_page(self, flashPtr, bytes): if SPIFI_START <= flashPtr < SPIFI_START + SPIFI_SIZE: assert len(bytes) <= SPIFI_SECTOR_SIZE Flash.program_page(self, flashPtr, bytes) else: super(Flash_lpc4088qsb_dm, self).program_page(flashPtr, bytes) class LPC4088qsb(LPC4088): memoryMap = MemoryMap( FlashRegion( start=0, length=0x10000, blocksize=0x1000, is_boot_memory=True), FlashRegion( start=0x10000, length=0x70000, blocksize=0x8000), FlashRegion( start=0x28000000, length=0x800000, blocksize=0x400), RamRegion( start=0x10000000, length=0x10000), ) def __init__(self, link): super(LPC4088qsb, self).__init__(link, self.memoryMap) pyocd-0.13.1/pyocd/target/target_nRF51822_xxAA.py0000644000175000017500000000707213373511253021157 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging # NRF51 specific registers RESET = 0x40000544 RESET_ENABLE = (1 << 0) FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000, 0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0, 0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041, 0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2, 0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840, 0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000029, 'pc_erase_sector' : 0x20000049, 'pc_program_page' : 0x20000071, 'begin_data' : 0x20002000, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) 'page_buffers' : [0x20002000, 0x20002400], # Enable double buffering 'begin_stack' : 0x20001000, 'static_base' : 0x20000170, 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20003000 # Analyzer 0x20003000..0x20003600 } class Flash_nrf51(Flash): def __init__(self, target): super(Flash_nrf51, self).__init__(target, FLASH_ALGO) class NRF51(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x400, is_boot_memory=True), # User Information Configation Registers (UICR) as a flash region FlashRegion( start=0x10001000, length=0x100, blocksize=0x100, is_testable=False), RamRegion( start=0x20000000, length=0x4000) ) def __init__(self, link): super(NRF51, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Nordic", filename="nrf51.svd", is_local=False) def resetn(self): """ reset a core. After a call to this function, the core is running """ #Regular reset will kick NRF out of DBG mode logging.debug("target_nrf51.reset: enable reset pin") self.write_memory(RESET, RESET_ENABLE) #reset logging.debug("target_nrf51.reset: trigger nRST pin") self.reset() pyocd-0.13.1/pyocd/target/target_LPC1114FN28_102.py0000644000175000017500000000731013373511253021047 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) WRITE_SIZE = 256 FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4c0fb5f8, 0x25002032, 0x2607444c, 0x490d60a6, 0x60206065, 0x4f0c4449, 0x91004620, 0x696047b8, 0xd10b2800, 0x203460a6, 0x60206065, 0x60e04807, 0x99004620, 0x696047b8, 0xd0002800, 0xbdf82001, 0x00000004, 0x00000018, 0x1fff1ff1, 0x00002ee0, 0x4d0fb5f8, 0x444d0b04, 0x490e606c, 0x60ac2032, 0x60284449, 0x460f4e0c, 0x47b04628, 0x28006968, 0x606cd10b, 0x60ac2034, 0x48086028, 0x463960e8, 0x47b04628, 0x28006968, 0x2001d000, 0x0000bdf8, 0x00000004, 0x00000018, 0x1fff1ff1, 0x00002ee0, 0x47700b00, 0x21004807, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x49036382, 0x60082002, 0x47702000, 0x40048040, 0x40048000, 0x4614b5f8, 0xd10e0005, 0x68206861, 0x184068e2, 0x188968a1, 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4e1061e0, 0x444e0b28, 0x60702132, 0x490e6031, 0x444960b0, 0x46304f0d, 0x47b89100, 0x28006970, 0x6075d10e, 0x60b42033, 0x20ff6030, 0x60f03001, 0x61304807, 0x99004630, 0x697047b8, 0xd0002800, 0xbdf82001, 0x00000004, 0x00000018, 0x1fff1ff1, 0x00002ee0, 0x47702000, 0x00000000, ], 'pc_eraseAll' : 0x10000021, 'pc_init' : 0x100000C5, #'pc_UnInit' : 0x10000165, 'pc_program_page' : 0x100000ED, 'pc_erase_sector' : 0x10000071, 'static_base' : 0x10000000 + 0x00000020 + 0x00000148, 'begin_data' : 0x10000000 + 0x00000A00, # Double buffering is not supported since there is not enough ram 'begin_stack' : 0x10000800, 'page_size' : 0x00001000, 'min_program_length' : 1024, 'analyzer_supported' : False, }; class Flash_lpc11xx_32(Flash): def __init__(self, target): super(Flash_lpc11xx_32, self).__init__(target, FLASH_ALGO) # Override program_page and break the operation into 4 1KB writes # since there isn't enough ram to do a 4K sector write directly def program_page(self, flashPtr, bytes): pages = (len(bytes) + WRITE_SIZE - 1) // WRITE_SIZE for i in range(0, pages): data = bytes[i * WRITE_SIZE : (i + 1) * WRITE_SIZE] Flash.program_page(self, flashPtr + i * WRITE_SIZE, data) class LPC11XX_32(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x10000000, length=0x1000) ) def __init__(self, link): super(LPC11XX_32, self).__init__(link, self.memoryMap) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC11XX_32, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40048000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MKL82Z128xxx7.py0000644000175000017500000001466613373511253021177 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x483bb510, 0x81c14939, 0x81c1493a, 0x08498801, 0x80010049, 0x78414838, 0x0f890649, 0xd0152902, 0x4a362100, 0x444a2900, 0xd0077011, 0x229f7841, 0x70414011, 0x06497841, 0xd1fb0f89, 0x44484830, 0xf862f000, 0xd0002800, 0xbd102001, 0xe7e82101, 0x4448482a, 0x28007800, 0x4827d00a, 0x229f7841, 0x31404011, 0x78417041, 0x0f890649, 0xd1fa2902, 0x47702000, 0xb5104822, 0x44484922, 0xf890f000, 0xd1042800, 0x2100481e, 0xf0004448, 0xbd10f94a, 0x4c1bb570, 0x444c4605, 0x4b1a4601, 0x68e24620, 0xf8b7f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf941f000, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480f, 0x44484615, 0xf8e6f000, 0xd10a2800, 0x90029001, 0x480a2101, 0x462b9100, 0x46314622, 0xf0004448, 0xb004f96f, 0x0000bd70, 0x0000c520, 0x40052000, 0x0000d928, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xd00b2800, 0x68c949db, 0x0f090109, 0xd007290f, 0x00494ad9, 0x5a51447a, 0xe0030289, 0x47702004, 0x04492101, 0x2200b410, 0x60416002, 0x60812101, 0x60c102c9, 0x7a0c49d1, 0x40a3158b, 0x7ac96143, 0x62026102, 0x61816242, 0x2000bc10, 0x28004770, 0x6101d002, 0x47702000, 0x47702004, 0x48c84602, 0x210168c0, 0x43080289, 0x60c849c5, 0x48c54770, 0x70012170, 0x70012180, 0x06097801, 0x7800d5fc, 0xd5010681, 0x47702067, 0xd50106c1, 0x47702068, 0xd0fc07c0, 0x47702069, 0xd1012800, 0x47702004, 0x4604b510, 0x48b84ab7, 0x48b86050, 0xd0014281, 0xe000206b, 0x28002000, 0x4620d107, 0xffd7f7ff, 0x46204603, 0xffcaf7ff, 0xbd104618, 0xd1012800, 0x47702004, 0x4614b510, 0x60622200, 0x60e260a2, 0x61626122, 0x61e261a2, 0x68c16021, 0x68816061, 0xf0006840, 0x60a0f951, 0x20042108, 0x60e06121, 0x616161a0, 0x200061e0, 0xb5ffbd10, 0x4615b089, 0x466a460c, 0xf7ff9809, 0x462affd9, 0x9b044621, 0xf0009809, 0x0007f90c, 0x9c00d130, 0x19659e01, 0x46311e6d, 0xf0004628, 0x2900f92f, 0x1c40d002, 0x1e454370, 0xd81d42ac, 0x20090221, 0x06000a09, 0x488c1809, 0x498d6041, 0x4288980c, 0x206bd001, 0x2000e000, 0xd1112800, 0xf7ff9809, 0x4607ff80, 0x69009809, 0xd0002800, 0x2f004780, 0x19a4d102, 0xd9e142ac, 0xf7ff9809, 0x4638ff69, 0xbdf0b00d, 0xd1012a00, 0x47702004, 0xb089b5ff, 0x461e4614, 0x466a460d, 0xf7ff9809, 0x4632ff91, 0x9b034629, 0xf0009809, 0x0007f8c4, 0x9d00d12d, 0xd0262e00, 0x4870cc02, 0x99036081, 0xd0022904, 0xd0072908, 0x022ae00e, 0x0a122103, 0x18510649, 0xe0076041, 0x60c1cc02, 0x2107022a, 0x06090a12, 0x60411851, 0xf7ff9809, 0x4607ff3c, 0x69009809, 0xd0002800, 0x2f004780, 0x9803d103, 0x1a361945, 0x9809d1d8, 0xff24f7ff, 0xb00d4638, 0x2800bdf0, 0x4a5cd005, 0x18890409, 0x60514a57, 0x2004e721, 0xb5ff4770, 0x4614b08b, 0x460d461e, 0x980b466a, 0xff46f7ff, 0x46294622, 0x980b9b05, 0xf879f000, 0xd1332800, 0x4629466a, 0xf7ff980b, 0x9d00ff39, 0x90089802, 0x42404269, 0x424f4001, 0xd10142af, 0x183f9808, 0xd0202c00, 0x90090230, 0x42a61b7e, 0x4626d900, 0x99054630, 0xf888f000, 0x2101022a, 0x06090a12, 0x493c1852, 0x9a09604a, 0x43100400, 0x608830ff, 0xf7ff980b, 0x2800fee4, 0x9808d106, 0x19ad1ba4, 0x2c00183f, 0x2000d1e0, 0xbdf0b00f, 0xd1012b00, 0x47702004, 0xb089b5ff, 0x461d4616, 0x466a460c, 0x98099f12, 0xfefaf7ff, 0x46214632, 0x98099b07, 0xf82df000, 0xd11d2800, 0x2e009c00, 0x4929d01a, 0x18470638, 0x20010221, 0x06400a09, 0x48211809, 0x60876041, 0x60c16829, 0xf7ff9809, 0x2800feb0, 0x9913d00a, 0xd0002900, 0x9914600c, 0xd0012900, 0x600a2200, 0xbdf0b00d, 0x1a769907, 0x00890889, 0x9907194d, 0x2e00190c, 0xb00dd1dc, 0x2800bdf0, 0x2004d101, 0xb4104770, 0x42191e5b, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x40048040, 0x000003b4, 0x40020020, 0xf0003000, 0x40020000, 0x44ffffff, 0x6b65666b, 0x4000ffff, 0x00ffffff, 0x460bb530, 0x20004601, 0x24012220, 0x460de009, 0x429d40d5, 0x461dd305, 0x1b494095, 0x40954625, 0x46151940, 0x2d001e52, 0xbd30dcf1, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000071, 'pc_program_page': 0x200000D7, 'pc_erase_sector': 0x200000B1, 'pc_eraseAll' : 0x20000095, 'static_base' : 0x20000000 + 0x00000020 + 0x000004f4, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00000200, # All keys above are auto-generated. The following are added or modified. 'analyzer_supported' : True, # [modified] default is False 'analyzer_address' : 0x1fffa000, # [modified] default is zero. Use 8K block before flash algo. Can be any unused SRAM. 'page_buffers' : [0x20000a00, 0x20001200], # [added] Use areas above algo. Note 'begin_data' is unused if double buffering. Can be any unused SRAM. 'min_program_length' : 4 # [added] See FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE in KSDK features header file }; class Flash_mkl82z7(Flash_Kinetis): def __init__(self, target): super(Flash_mkl82z7, self).__init__(target, FLASH_ALGO) class KL82Z7(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x20000, blocksize=0x800, is_boot_memory=True), RomRegion( start=0x1c000000, end=0x1c007fff), RomRegion( start=0x68000000, end=0x6fffffff), RamRegion( start=0x1fffA000, length=0x18000) ) def __init__(self, link): super(KL82Z7, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL82Z7.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_CC3220SF.py0000644000175000017500000001714613373511253020177 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core import exceptions from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..coresight.cortex_m import (CortexM) from ..coresight import(ap, dap) from ..core.memory_map import (RomRegion, FlashRegion, RamRegion, MemoryMap) import logging import time FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xd1fd3801, 0x49964770, 0x6e48b418, 0x0000f440, 0x4b946648, 0xf241681a, 0x380140d5, 0xf042d1fd, 0x60180010, 0x40d5f241, 0xd1fd3801, 0xf8d24a8e, 0xf040016c, 0xf8c2003c, 0x4b8c016c, 0xf0406c98, 0x64980001, 0x6480f44f, 0x6cd86820, 0x0001f040, 0xf04f64d8, 0xf8cd0c00, 0x9800c000, 0x90001c40, 0xd3fa2810, 0xf0206cd8, 0x64d80001, 0xf0206c98, 0x64980001, 0x68c0487e, 0x0ffff010, 0x487dd106, 0xc000f8c0, 0x40d5f241, 0xd1fd3801, 0x00c8f8d1, 0x2802b2c0, 0xf8d2d113, 0xf0200110, 0xf420000f, 0xf0406040, 0xf8c20002, 0xf8d20110, 0xf0200114, 0xf420000f, 0xf0406040, 0xf8c20002, 0xf8d20114, 0xf0400184, 0xf8c20002, 0x486b0184, 0xf3c06800, 0x280e5083, 0x00b0f8d1, 0x007cf420, 0xf440bf0c, 0xf4400048, 0xf8c10024, 0x486400b0, 0xf0236803, 0x60035380, 0xb2806820, 0xd2062802, 0x00a8f8d1, 0x0004f040, 0x00a8f8c1, 0x6820e022, 0xd01f0c00, 0x0188f8d2, 0x00e1f040, 0x0188f8c2, 0x68034858, 0x0f01f013, 0x6803d014, 0x0301f023, 0xf8d26003, 0xf4400188, 0xf8c27000, 0x48520188, 0xf0226802, 0x60020201, 0xf8c01d00, 0x1d00c000, 0xc000f8c0, 0x6800484d, 0xf3c00f02, 0x2a036003, 0xd22cd00f, 0x6800484a, 0x1080f3c0, 0x6a88b158, 0x0080f020, 0x69086288, 0x4070f020, 0x5080f040, 0xb9e0e01c, 0x6a48e7ee, 0x000ff020, 0x6070f420, 0x30c0f420, 0x0001f040, 0x60a0f440, 0x3080f440, 0x6a886248, 0x0080f020, 0x4070f020, 0x007ff420, 0x104cf440, 0x69086288, 0x4070f020, 0xbc186108, 0x0000f04f, 0x20004770, 0x48324770, 0x2201f640, 0x49316142, 0x68816081, 0x0f04f011, 0x68c0d1fb, 0xbf184010, 0x47702001, 0x2201f640, 0x614a4929, 0x482a6008, 0x68886088, 0x0f02f010, 0x68c8d1fb, 0xbf184010, 0x47702001, 0xf242b430, 0x4b216c01, 0xc014f8c3, 0xbf182900, 0xc084f8df, 0xf020d01e, 0x601c047f, 0xf000e00b, 0xf105057c, 0xf5054580, 0xf852257d, 0xf8c54b04, 0x1d004100, 0xf0101f09, 0xd1010f7c, 0xb90c6b1c, 0xd1ec2900, 0xc020f8c3, 0xf0146a1c, 0xd1fb0f01, 0xd1e02900, 0x2000bc30, 0x00004770, 0x4402f000, 0x4402fc18, 0x4402e000, 0x44025000, 0x4402d000, 0x4402f804, 0x4402dc78, 0x4402fc74, 0x4402fc20, 0x4402f818, 0x4402dc80, 0x4402f840, 0x400fd000, 0xa4420004, 0xa4420002, 0xa4420001, 0x00000004, 0x00000008, 0x00000014, 0x00000018, 0x00000024, 0x00000028, 0x00000030, 0x00000034, 0x00000040, 0x00000044, 0x00000048, 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, 0x00000064, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, 0x000000ac, 0x000000b8, 0x000000bc, 0x000000c8, 0x000000cc, 0x000000d8, 0x000000dc, 0x00000000, ], 'pc_init' : 0x20000027, 'pc_eraseAll' : 0x200001e7, 'pc_erase_sector' : 0x20000205, 'pc_program_page' : 0x20000225, 'begin_data' : 0x20002000, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) 'page_buffers' : [0x20002000, 0x20004000], # Enable double buffering 'begin_stack' : 0x20000800, 'static_base' : 0x20000368, 'min_program_length' : 4, 'analyzer_supported' : False, 'analyzer_address' : 0x20003000 # Analyzer 0x20003000..0x20003600 } class Flash_cc3220sf(Flash): def __init__(self, target): super(Flash_cc3220sf, self).__init__(target, FLASH_ALGO) def init(self): """ Download the flash algorithm in RAM """ self.target.halt() self.target.set_target_state("PROGRAM") # update core register to execute the init subroutine result = self._call_function_and_wait(self.flash_algo['pc_init'], init=True) # check the return code if result != 0: logging.error('init error: %i', result) # erase the cookie which take up one page self.erase_page(0x01000000) time.sleep(.5) #do a hardware reset which will put the pc looping in rom self.target.dp.reset() time.sleep(1.3) # reconnect to the board self.target.dp.init() self.target.dp.power_up_debug() self.target.halt() self.target.set_target_state("PROGRAM") # update core register to execute the init subroutine result = self._call_function_and_wait(self.flash_algo['pc_init'], init=True) # check the return code if result != 0: logging.error('init error: %i', result) class CC3220SF(CoreSightTarget): memoryMap = MemoryMap( RomRegion(start=0x00000000, length=0x00080000), FlashRegion(start=0x01000000, length=0x00100000, blocksize=0x800, is_boot_memory=True), RamRegion(start=0x20000000, length=0x40000) ) def __init__(self, link): super(CC3220SF, self).__init__(link, self.memoryMap) def create_init_sequence(self): seq = super(CC3220SF,self).create_init_sequence() seq.replace_task('create_cores', self.create_CC3220SF_core) return seq def create_CC3220SF_core(self): core0 = CortexM_CC3220SF(self, self.aps[0], self.memory_map) self.aps[0].core = core0 core0.init() self.add_core(core0) class CortexM_CC3220SF(CortexM): def __init__(self, rootTarget, ap, memoryMap=None, core_num=0, cmpid=None, address=None): super(CortexM_CC3220SF, self).__init__(rootTarget, ap, memoryMap, core_num, cmpid, address) def reset(self, software_reset=None): if software_reset: # Perform the reset. try: self.write_memory(CortexM.NVIC_AIRCR, CortexM.NVIC_AIRCR_VECTKEY | CortexM.NVIC_AIRCR_VECTRESET) # Without a flush a transfer error can occur self.flush() except exceptions.TransferError: self.flush() pyocd-0.13.1/pyocd/target/target_STM32F051T8.py0000644000175000017500000001077613373511253020534 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging #DBGMCU clock RCC_APB2ENR_CR = 0x40021018 RCC_APB2ENR_DBGMCU = 0x00400000 DBGMCU_CR = 0x40015804 DBGMCU_APB1_CR = 0x40015808 DBGMCU_APB2_CR = 0x4001580C #0000 0000 0000 0000 0000 0000 0000 0100 #BGMCU_CR_VAL = 0x00000000 #0000 0010 0010 0000 0001 1101 0011 0011 DBGMCU_APB1_VAL = 0x02201D33 #0000 0000 0000 0111 0000 1000 0000 0000 DBGMCU_APB2_VAL = 0x00070800 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x49544853, 0x48546048, 0x20006048, 0xb5104770, 0x20344603, 0x60e04c4f, 0xbd102000, 0x20004601, 0xb5004770, 0x23002200, 0x6902484a, 0x40102080, 0xd1012880, 0xffe4f7ff, 0x4846bf00, 0x07d868c3, 0xd1fa0fc0, 0x69024843, 0x43022004, 0x61024841, 0x20406902, 0x483f4302, 0xbf006102, 0x68c3483d, 0x0fc007d8, 0x483bd1fa, 0x21046902, 0x43884610, 0x48384602, 0x20006102, 0xb510bd00, 0x22004603, 0x48342400, 0x20806902, 0x28804010, 0xf7ffd101, 0xbf00ffb7, 0x68c4482f, 0x0fc007e0, 0x482dd1fa, 0x20026902, 0x482b4302, 0x61436102, 0x20406902, 0x48284302, 0xbf006102, 0x68c44826, 0x0fc007e0, 0x4824d1fa, 0x21026902, 0x43884610, 0x48214602, 0x20006102, 0xb5f7bd10, 0x22004615, 0x27002600, 0x462c9b00, 0x6902481b, 0x40102080, 0xd1012880, 0xff86f7ff, 0x4817bf00, 0x07f068c6, 0xd1fa0fc0, 0x4814e01b, 0x20016902, 0x48124302, 0x88206102, 0xbf008018, 0x68c6480f, 0x0fc007f0, 0x8820d1fa, 0x42888819, 0x480bd006, 0x08526902, 0x61020052, 0xbdfe2001, 0x1ca41c9b, 0x98011c7f, 0x42b80840, 0x4804d8df, 0x08526902, 0x61020052, 0xe7f02000, 0x45670123, 0x40022000, 0xcdef89ab, 0x00000000, ], 'pc_init' : 0x2000002F, 'pc_eraseAll' : 0x20000043, 'pc_erase_sector' : 0x2000009B, 'pc_program_page' : 0x200000F7, 'static_base' : 0x200001A0, 'begin_data' : 0x20000400, # Analyzer uses a max of 256 B data (64 pages * 4 bytes / page) 'page_buffers' : [0x20000400, 0x20000800], # Enable double buffering 'begin_stack' : 0x20001000, 'min_program_length' : 2, 'analyzer_supported' : True, 'analyzer_address' : 0x20001400 # Analyzer 0x20001400..0x20001A00 }; class Flash_stm32f051(Flash): def __init__(self, target): super(Flash_stm32f051, self).__init__(target, FLASH_ALGO) class STM32F051(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x10000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x20000000, length=0x2000) ) def __init__(self, link): super(STM32F051, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F0xx.svd", is_local=False) def create_init_sequence(self): seq = super(STM32F051, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): logging.debug('stm32f051 init') enclock = self.read_memory(RCC_APB2ENR_CR) enclock |= RCC_APB2ENR_DBGMCU self.write_memory(RCC_APB2ENR_CR, enclock) self.write_memory(DBGMCU_APB1_CR, DBGMCU_APB1_VAL) self.write_memory(DBGMCU_APB2_CR, DBGMCU_APB2_VAL) pyocd-0.13.1/pyocd/target/target_MKE18F256xxx16.py0000644000175000017500000001434013373511253021212 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2016 Freescale Semiconductor, Inc. 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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging RCM_MR = 0x4007f010 RCM_MR_BOOTROM_MASK = 0x6 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0xb510482d, 0x6041492b, 0x71fff64f, 0x68016081, 0x0180f021, 0x0120f041, 0x48286001, 0xf0004448, 0x2800f851, 0x2001bf18, 0x2000bd10, 0x48234770, 0x4923b510, 0xf0004448, 0x2800f89d, 0xbd10bf18, 0x481e2100, 0x4010e8bd, 0xf0004448, 0xb570b962, 0x46054c1a, 0x4601444c, 0x46204b19, 0xf00068e2, 0x2800f8c2, 0xbd70bf18, 0x46292300, 0xe8bd68e2, 0x48124070, 0xf0004448, 0xb570b956, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf8f5f000, 0xbf1c2800, 0xbd70b004, 0x21012000, 0x1000e9cd, 0x48069002, 0x4622462b, 0x44484631, 0xf989f000, 0xbd70b004, 0xd928c520, 0x40052000, 0x00000004, 0x6b65666b, 0xbf042800, 0x47702004, 0x6cc949f0, 0x6103f3c1, 0xbf08290f, 0x2100f44f, 0x4aedbf1f, 0xf832447a, 0x02891011, 0x2200b410, 0x2100e9c0, 0x60812101, 0x03094be8, 0xf89360c1, 0x110cc000, 0xfc0cfa04, 0xc014f8c0, 0x618378db, 0xf04f6102, 0xe9c052a0, 0xbc102108, 0x47702000, 0xbf0e2800, 0x61012004, 0x47702000, 0x48dc4602, 0x49db6800, 0x0020f040, 0x46086008, 0xf0406800, 0x60080010, 0x48d74770, 0x70012170, 0x70012180, 0xf0117801, 0xd0fb0f80, 0xf0107800, 0xbf1c0f20, 0x47702067, 0x0f10f010, 0x2068bf1c, 0xf0104770, 0xbf180001, 0x47702069, 0xbf042800, 0x47702004, 0x4604b510, 0xf06f4ac7, 0x6050403b, 0x428148c6, 0x206bbf14, 0x28002000, 0xbd10bf18, 0xf7ff4620, 0x4603ffd2, 0xf7ff4620, 0x4618ffc1, 0x2800bd10, 0x2004bf04, 0x23004770, 0x60936053, 0x611360d3, 0x61936153, 0x601161d3, 0x605168c1, 0x1001e9d0, 0xf0f0fbb1, 0x20086090, 0xe9c22110, 0xe9c20103, 0x20041005, 0x200061d0, 0xe92d4770, 0xb0884df0, 0x46984615, 0x4682460c, 0xf7ff466a, 0x462affd8, 0x46504621, 0xf0009b04, 0x0007f92f, 0xb008bf1c, 0x8df0e8bd, 0x4600e9dd, 0x1e451960, 0xf0f6fbb5, 0x5110fb06, 0x1c40b111, 0x1e454370, 0xbf9842ac, 0xb270f8df, 0xf024d81c, 0xf040407f, 0xf8cb6010, 0x48990004, 0xbf144580, 0x2000206b, 0xbf1c2800, 0xe8bdb008, 0x46508df0, 0xff75f7ff, 0xf8da4607, 0x28000010, 0x4780bf18, 0x4434b917, 0xd9e242ac, 0xf7ff4650, 0xb008ff5b, 0xe8bd4638, 0x2a008df0, 0x2004bf04, 0xe92d4770, 0xb08945f0, 0x461e4614, 0x4680460d, 0xf7ff466a, 0x4632ff8a, 0x46404629, 0xf0009b03, 0x0007f8e1, 0xb009bf1c, 0x85f0e8bd, 0x2e009d00, 0xf8dfbf18, 0xd025a1ec, 0x0b04f854, 0x0008f8ca, 0x28049803, 0xf025bf04, 0xf040407f, 0xd00960c0, 0xd1092808, 0x0b04f854, 0x000cf8ca, 0x407ff025, 0x60e0f040, 0x0004f8ca, 0xf7ff4640, 0xf8d8ff2a, 0x46071010, 0xbf182900, 0xb91f4788, 0x44059803, 0xd1d91a36, 0xf7ff4640, 0xb009ff0f, 0xe8bd4638, 0x280085f0, 0x2004bf04, 0x4a634770, 0x4101ea42, 0x60514a5f, 0xe92de70d, 0xb0884dff, 0x469a4614, 0x466a460d, 0xf7ff9808, 0x4622ff38, 0x9b054629, 0xf0009808, 0x2800f88f, 0xb00cbf1c, 0x8df0e8bd, 0x4629466a, 0xf7ff9808, 0x9e00ff28, 0x8008f8dd, 0xf1c84270, 0x40080100, 0x42b74247, 0x4447bf08, 0xbf182c00, 0xb128f8df, 0x1bbdd01f, 0xbf8842a5, 0x98054625, 0x417ff026, 0xf0f0fbb5, 0x7180f041, 0x1004f8cb, 0xea400400, 0xf040200a, 0xf8cb00ff, 0x98080008, 0xfecdf7ff, 0xbf1c2800, 0xe8bdb00c, 0x1b648df0, 0x4447442e, 0xb00cd1df, 0xe8bd2000, 0x2b008df0, 0x2004bf04, 0xe92d4770, 0xb0884dff, 0xe9dd4616, 0x461d7a14, 0x466a460c, 0x8058f8dd, 0xf7ff9808, 0xe9ddfee2, 0x46323007, 0xf0004621, 0x2800f839, 0xb00cbf1c, 0x8df0e8bd, 0x2e009c00, 0xb00cbf04, 0x8df0e8bd, 0xb094f8df, 0x407ff06f, 0x6707ea40, 0x407ff024, 0x7000f040, 0x0004f8cb, 0x7008f8cb, 0xf8cb6828, 0x9808000c, 0xfe89f7ff, 0xf1bab168, 0xbf180f00, 0x4000f8ca, 0x0f00f1b8, 0x2100bf1c, 0x1000f8c8, 0xe8bdb00c, 0x99078df0, 0xf0211a76, 0x440d0103, 0x440c9907, 0xb00cd1da, 0x8df0e8bd, 0xbf042800, 0x47702004, 0x42191e5b, 0x421abf0e, 0x47702065, 0x428b6803, 0x6840d806, 0x44184411, 0xbf244288, 0x47702000, 0x47702066, 0x40048000, 0x000003d0, 0x40020028, 0x40001400, 0x40020000, 0x6b65666b, 0x4000ffff, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_unInit': 0x2000004B, 'pc_program_page': 0x2000009B, 'pc_erase_sector': 0x2000006F, 'pc_eraseAll' : 0x2000004F, 'static_base' : 0x20000000 + 0x00000020 + 0x000004d4, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_size' : 0x00001000, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff000, # Analyzer 0x1ffff000..0x1ffff600 'page_buffers' : [0x20003000, 0x20004000], # Enable double buffering 'min_program_length' : 8, }; class Flash_ke18f16(Flash_Kinetis): def __init__(self, target): super(Flash_ke18f16, self).__init__(target, FLASH_ALGO) class KE18F16(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x80000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x1fff8000, length=0x10000) ) def __init__(self, link): super(KE18F16, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKE18F16.svd") def create_init_sequence(self): seq = super(KE18F16, self).create_init_sequence() seq.insert_after('create_cores', ('disable_rom_remap', self.disable_rom_remap) ) return seq def disable_rom_remap(self): # Disable ROM vector table remapping. self.write32(RCM_MR, RCM_MR_BOOTROM_MASK) pyocd-0.13.1/pyocd/target/target_lpc4088dm.py0000644000175000017500000001234313373511253020567 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from .target_LPC4088FBD144 import (Flash_lpc4088, LPC4088) SPIFI_START = 0x28000000 SPIFI_SIZE = 16 * 1024 * 1024 SPIFI_SECTOR_SIZE = 4 * 1024 FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x28100b00, 0x210ebf24, 0x00d0eb01, 0xe92d4770, 0xf8df4df0, 0x4606831c, 0x460c44c8, 0x0000f8d8, 0x1c402500, 0x0000f8c8, 0x0f01f010, 0x461749c1, 0x2080f44f, 0x63c8bf14, 0x05306388, 0xa2f8f8df, 0xf04f0d00, 0x44ca0b00, 0xf8cad111, 0xf44fb010, 0xf8ca5080, 0xe9ca6000, 0xf8ca0b01, 0xf8d8b00c, 0x4651000c, 0xf1a16882, 0x47900080, 0x2018b9c0, 0xb008f8ca, 0xb003e9ca, 0xf5b4b1cc, 0xbf8c7f80, 0x7b80f44f, 0x197046a3, 0x0b00e9ca, 0x000cf8d8, 0x19794aa9, 0x6843444a, 0x0080f1a2, 0xb1104798, 0xe8bd2001, 0x445d8df0, 0x040bebb4, 0x2000d1e5, 0x8df0e8bd, 0x41f0e92d, 0x8274f8df, 0x60e0f642, 0x4d9e44c8, 0x0008f8c8, 0x70282000, 0x732820aa, 0x73282055, 0xf8052001, 0x22000c40, 0xf0002112, 0x2200f91a, 0x4610210d, 0xf915f000, 0x210d2200, 0xf0002001, 0x2200f910, 0x20022113, 0xf90bf000, 0x68204c8c, 0x5000f440, 0x6a206020, 0x2084f440, 0x6c206220, 0x2000f440, 0xf44f6420, 0x63e72780, 0x61a6117e, 0xf4406c68, 0x64683080, 0xf8c52002, 0x22050134, 0xf0002107, 0x2205f8ee, 0x20002116, 0xf8e9f000, 0x210f2205, 0xf0002000, 0x2205f8e4, 0x20002110, 0xf8dff000, 0x21112205, 0xf0002000, 0x2205f8da, 0x20002112, 0xf8d5f000, 0xf44f4874, 0x6800727a, 0xf8c86940, 0xf8d8000c, 0xfbb11008, 0xf8d5f1f2, 0xf8d02134, 0xf002c000, 0xfbb1021f, 0x496cf3f2, 0xfba1486c, 0x08892103, 0x444822c0, 0x280047e0, 0x61e6bf04, 0x81f0e8bd, 0x61e663a7, 0xe8bd2001, 0x200081f0, 0xe92d4770, 0x4c6341f0, 0x444c2032, 0x251d2700, 0xe9c460a5, 0x4e600700, 0x0114f104, 0x47b04620, 0xb9806960, 0x60a52034, 0x0700e9c4, 0xf1044852, 0x44480114, 0x60e06880, 0x47b04620, 0x28006960, 0xe8bdbf08, 0x200181f0, 0x81f0e8bd, 0x5f20f1b0, 0xf5b0bf32, 0x20002f00, 0xb5704770, 0x2c100b04, 0x200ebf24, 0x04d4eb00, 0x4d4a2032, 0x444d4e4a, 0x0114f105, 0x0400e9c5, 0x60ac4628, 0x696847b0, 0x2034b978, 0x0400e9c5, 0x60ac483b, 0xf1054448, 0x68800114, 0x462860e8, 0x696847b0, 0xbf082800, 0x2001bd70, 0xe92dbd70, 0x4f3341f0, 0x444f4605, 0x68784614, 0x1c404a31, 0xf0106078, 0xf44f0f01, 0xbf145000, 0x619061d0, 0x5f20f1b5, 0x4622d305, 0x5020f1a5, 0x41f0e8bd, 0xf5b5e6bd, 0xd3052f00, 0xf5a54622, 0xe8bd2000, 0xe6b441f0, 0xe9d4b975, 0x44080100, 0x1202e9d4, 0x44084411, 0x44086921, 0x44086961, 0x440869a1, 0x61e04240, 0x28100b28, 0x210ebf24, 0x00d0eb01, 0x4e1e2132, 0x8078f8df, 0xe9c6444e, 0x60b01000, 0x0114f106, 0x47c04630, 0xb9886970, 0xe9c62033, 0xf44f0500, 0xe9c67000, 0x68b84002, 0xf1066130, 0x46300114, 0x697047c0, 0xbf082800, 0x81f0e8bd, 0xe8bd2001, 0xeb0181f0, 0x490e1040, 0x0080eb01, 0xf0216801, 0x60010107, 0x43116801, 0x47706001, 0x00000004, 0x20098000, 0x000000b4, 0x400fc080, 0x1fff1ff8, 0xcccccccd, 0x00000034, 0x00000014, 0x1fff1ff1, 0x4002c000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, ], 'pc_init' : 0x100000D5, 'pc_unInit': 0x100001D7, 'pc_program_page': 0x1000027F, 'pc_erase_sector': 0x10000225, 'pc_eraseAll' : 0x100001DB, 'static_base' : 0x10000000 + 0x00000020 + 0x00000400, 'begin_stack' : 0x10000000 + 0x00000800, # Double buffering is not supported since there is not enough ram 'begin_data' : 0x10000000 + 0x00000A00, # Analyzer uses a max of 120 B data (30 pages * 4 bytes / page) 'page_size' : 0x00000200, 'analyzer_supported' : False, 'min_program_length' : 512, 'analyzer_supported' : True, 'analyzer_address' : 0x10002000 # Analyzer 0x10002000..0x10002600 } class Flash_lpc4088qsb_dm(Flash_lpc4088): def __init__(self, target): super(Flash_lpc4088qsb_dm, self).__init__(target, FLASH_ALGO) def program_page(self, flashPtr, bytes): if SPIFI_START <= flashPtr < SPIFI_START + SPIFI_SIZE: assert len(bytes) <= SPIFI_SECTOR_SIZE Flash.program_page(self, flashPtr, bytes) else: super(Flash_lpc4088qsb_dm, self).program_page(flashPtr, bytes) class LPC4088dm(LPC4088): memoryMap = MemoryMap( FlashRegion( start=0, length=0x10000, blocksize=0x1000, is_boot_memory=True), FlashRegion( start=0x10000, length=0x70000, blocksize=0x8000), FlashRegion( start=0x28000000, length=0x1000000, blocksize=0x400), RamRegion( start=0x10000000, length=0x10000), ) def __init__(self, link): super(LPC4088dm, self).__init__(link, self.memoryMap) pyocd-0.13.1/pyocd/target/target_LPC824M201JHI33.py0000644000175000017500000000706713373511253021070 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x47700a80, 0x21004842, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x493e6382, 0x70082002, 0x47702000, 0x47702000, 0x4c3bb5f8, 0x25002032, 0x261f444c, 0x493960a6, 0x60206065, 0x4f384449, 0x91004620, 0x696047b8, 0xd10b2800, 0x203460a6, 0x60206065, 0x60e04833, 0x99004620, 0x696047b8, 0xd0002800, 0xbdf82001, 0x4d2bb5f8, 0x444d0a84, 0x492a606c, 0x60ac2032, 0x60284449, 0x460f4e28, 0x47b04628, 0x28006968, 0x606cd10b, 0x60ac2034, 0x48246028, 0x463960e8, 0x47b04628, 0x28006968, 0x2001d000, 0xb5f8bdf8, 0x00054614, 0x6861d10e, 0x68e26820, 0x68a11840, 0x18401889, 0x18406921, 0x18406961, 0x184069a1, 0x61e04240, 0x0aa84e12, 0x2132444e, 0x60316070, 0x60b04910, 0x4f104449, 0x91004630, 0x697047b8, 0xd10e2800, 0x20336075, 0x603060b4, 0x02402001, 0x480a60f0, 0x46306130, 0x47b89900, 0x28006970, 0x2001d000, 0x0000bdf8, 0x40048040, 0x40048000, 0x00000004, 0x00000018, 0x1fff1ff1, 0x00002ee0, 0x00000000, ], 'pc_init' : 0x10000025, 'pc_erase_sector' : 0x10000089, 'pc_program_page' : 0x100000C7, 'pc_eraseAll' : 0x10000049, # Double buffering is not supported since sector size differs from page size 'static_base' : 0x10000000 + 0x00000020 + 0x00000128, 'begin_data' : 0x10000000 + 0x00000800, # Analyzer uses a max of 128 B data (32 pages * 4 bytes / page) 'begin_stack' : 0x10000800, 'min_program_length' : 1024, 'analyzer_supported' : True, 'analyzer_address' : 0x10001000 # Analyzer 0x10001000..0x10000600 } class Flash_lpc824(Flash): def __init__(self, target): super(Flash_lpc824, self).__init__(target, FLASH_ALGO) # TODO - temporary until flash algo is rebuilt with 1K page program size def program_page(self, flashPtr, bytes): write_size = 512 for i in range(0, 2): data = bytes[i * write_size : (i + 1) * write_size] Flash.program_page(self, flashPtr + i * write_size, data) class LPC824(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x10000000, length=0x2000) ) def __init__(self, link): super(LPC824, self).__init__(link, self.memoryMap) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC824, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40048000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_nRF52832_xxAA.py0000644000175000017500000000641013373511253021154 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000, 0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0, 0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041, 0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2, 0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840, 0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000029, 'pc_erase_sector' : 0x20000049, 'pc_program_page' : 0x20000071, 'begin_data' : 0x20002000, # Analyzer uses a max of 0.5 KB data (128 pages * 4 bytes / page) 'page_buffers' : [0x20002000, 0x20003000], # Enable double buffering 'begin_stack' : 0x20001000, 'static_base' : 0x20000170, 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20004000 # Analyzer 0x20004000..0x20004600 } class Flash_nrf52(Flash): def __init__(self, target): super(Flash_nrf52, self).__init__(target, FLASH_ALGO) class NRF52(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x0, length=0x80000, blocksize=0x1000, is_boot_memory=True), # User Information Configation Registers (UICR) as a flash region FlashRegion( start=0x10001000, length=0x100, blocksize=0x100, is_testable=False), RamRegion( start=0x20000000, length=0x10000) ) def __init__(self, link): super(NRF52, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Nordic", filename="nrf52.svd", is_local=False) def resetn(self): """ reset a core. After a call to this function, the core is running """ self.reset() pyocd-0.13.1/pyocd/target/target_MKL27Z256xxx4.py0000644000175000017500000001545013373511253021165 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8ecf000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9b1, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf894f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf956f000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4905b510, 0x60082000, 0x44484804, 0xf8e8f000, 0xd0002800, 0xbd102001, 0x40048100, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f8f5, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf96af000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0032800, 0xd801290f, 0xd0012a04, 0x47702004, 0x47702000, 0xd1012800, 0x47702004, 0x1e5bb410, 0x421c460c, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb3, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe3cf7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000026a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2000e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd0142800, 0x68c9490c, 0x0e094a0c, 0x447a0049, 0x03095a51, 0x2200d00d, 0x60416002, 0x60812102, 0x61426102, 0x61820249, 0x461060c1, 0x20044770, 0x20644770, 0x00004770, 0x40048040, 0x0000019a, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff22f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff38f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfef0f7ff, 0xd12a2800, 0x686868a9, 0xfd7cf7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfef2f7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fed7, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfea2f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeb6f7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00100000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002E5, 'pc_program_page': 0x2000029D, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x0000060c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20002000 }; # @brief Flash algorithm for Kinetis KL27Z4 device. class Flash_kl27z4(Flash_Kinetis): def __init__(self, target): super(Flash_kl27z4, self).__init__(target, FLASH_ALGO) class KL27Z4(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x10000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x4000) ) def __init__(self, transport): super(KL27Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL27Z644.svd") pyocd-0.13.1/pyocd/target/target_MKL43Z256xxx4.py0000644000175000017500000001541313373511253021162 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8ecf000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9b1, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf894f000, 0xd1052800, 0x46292300, 0x68e24620, 0xf956f000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4905b510, 0x60082000, 0x44484804, 0xf8e8f000, 0xd0002800, 0xbd102001, 0x40048100, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f8f5, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf96af000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0032800, 0xd801290f, 0xd0012a04, 0x47702004, 0x47702000, 0xd1012800, 0x47702004, 0x1e5bb410, 0x421c460c, 0x421ad101, 0xbc10d002, 0x47702065, 0x428b6803, 0x6840d804, 0x18181889, 0xd2024288, 0x2066bc10, 0xbc104770, 0x47702000, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb3, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe3cf7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000026a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2000e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd0142800, 0x68c9490c, 0x0e094a0c, 0x447a0049, 0x03095a51, 0x2200d00d, 0x60416002, 0x60812102, 0x61426102, 0x61820249, 0x461060c1, 0x20044770, 0x20644770, 0x00004770, 0x40048040, 0x0000019a, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff22f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff38f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfef0f7ff, 0xd12a2800, 0x686868a9, 0xfd7cf7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfef2f7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fed7, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfea2f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeb6f7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00400000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002E5, 'pc_program_page': 0x2000029D, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x0000060c, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20002000 }; # @brief Flash algorithm for Kinetis KL43Z4 device. class Flash_kl43z4(Flash_Kinetis): def __init__(self, target): super(Flash_kl43z4, self).__init__(target, FLASH_ALGO) class KL43Z4(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1fffe000, length=0x8000) ) def __init__(self, transport): super(KL43Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL43Z4.svd") pyocd-0.13.1/pyocd/target/target_MKW36Z512xxx4.py0000644000175000017500000003212513373511253021171 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger 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. """ from .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, AliasRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4937b510, 0x60082000, 0x78414836, 0x0f890649, 0xd0152902, 0x4a342100, 0x444a2900, 0xd0077011, 0x229f7841, 0x70414011, 0x06497841, 0xd1fb0f89, 0x4448482e, 0xf85ef000, 0xd0002800, 0xbd102001, 0xe7e82101, 0x44484828, 0x28007800, 0x4825d00a, 0x229f7841, 0x31404011, 0x78417041, 0x0f890649, 0xd1fa2902, 0x47702000, 0xb5104820, 0x44484920, 0xf89df000, 0xd1042800, 0x2100481c, 0xf0004448, 0xbd10fb06, 0x4c19b570, 0x444c4605, 0x4b184601, 0x68e24620, 0xf8c7f000, 0xd1052800, 0x46292300, 0x68e24620, 0xfb00f000, 0xb570bd70, 0x460b460c, 0x46014606, 0xb084480d, 0x44484615, 0xf92af000, 0xd10a2800, 0x90029001, 0x48082101, 0x462b9100, 0x46314622, 0xf0004448, 0xb004fb2e, 0x0000bd70, 0x40048100, 0x4007e000, 0x00000004, 0x00000008, 0x6b65666b, 0xd00b2800, 0x68c949fe, 0x0f090109, 0xd007290f, 0x00494afc, 0x5a51447a, 0xe0030289, 0x47702004, 0x04c92101, 0x2300b410, 0x60416003, 0x72012102, 0x60c10289, 0x7a0c49f4, 0x40a2158a, 0x7ac96142, 0x61816103, 0x06892105, 0x21016201, 0x62410349, 0x2000bc10, 0x28004770, 0x6101d002, 0x47702000, 0x47702004, 0x680148e9, 0x02922201, 0x60014311, 0x8f6ff3bf, 0x8f4ff3bf, 0x48e44770, 0x22016801, 0x43110292, 0xf3bf6001, 0xf3bf8f6f, 0x47708f4f, 0x217048df, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x28004770, 0x2004d101, 0xb5104770, 0x4ad24604, 0x605048d2, 0x428148d2, 0x206bd001, 0x2000e000, 0xd1072800, 0xf7ff4620, 0x4603ffd7, 0xf7ff4620, 0x4618ffc8, 0x2800bd10, 0x2004d101, 0xb5104770, 0x22004614, 0x60626022, 0x60e260a2, 0x61626122, 0x61e261a2, 0x1a896802, 0x68c16021, 0x7a016061, 0xf0006840, 0x60a0fd7b, 0x60e02008, 0x61606120, 0x200461a0, 0x200061e0, 0xb5ffbd10, 0x4615b089, 0x466a460c, 0xf7ff9809, 0x462affd6, 0x9b044621, 0xf0009809, 0x0007fd3b, 0x9c00d130, 0x19659e01, 0x46311e6d, 0xf0004628, 0x2900fd59, 0x1c40d002, 0x1e454370, 0xd81d42ac, 0x20090221, 0x06000a09, 0x48a51809, 0x49a66041, 0x4288980c, 0x206bd001, 0x2000e000, 0xd1112800, 0xf7ff9809, 0x4607ff7d, 0x69009809, 0xd0002800, 0x2f004780, 0x19a4d102, 0xd9e142ac, 0xf7ff9809, 0x4638ff64, 0xbdf0b00d, 0xd1012800, 0x47702004, 0x4604b510, 0x48954a92, 0x48936050, 0xd0014281, 0xe000206b, 0x28002000, 0x4620d107, 0xff58f7ff, 0x46204603, 0xff49f7ff, 0xbd104618, 0xd1012800, 0x47702004, 0x4604b510, 0x48894a85, 0x48866050, 0xd0014281, 0xe000206b, 0x28002000, 0x4620d107, 0xff3ef7ff, 0x46204603, 0xff2ff7ff, 0xbd104618, 0xd1012a00, 0x47702004, 0xb089b5ff, 0x461e4614, 0x466a460d, 0xf7ff9809, 0x4632ff5a, 0x9b034629, 0xf0009809, 0x0007fcbf, 0x9d00d12d, 0xd0262e00, 0x486fcc02, 0x99036081, 0xd0022904, 0xd0072908, 0x022ae00e, 0x0a122103, 0x18510649, 0xe0076041, 0x60c1cc02, 0x2107022a, 0x06090a12, 0x60411851, 0xf7ff9809, 0x4607ff05, 0x69009809, 0xd0002800, 0x2f004780, 0x9803d103, 0x1a361945, 0x9809d1d8, 0xfeebf7ff, 0xb00d4638, 0x2800bdf0, 0x2a00d001, 0x2004d101, 0xb5104770, 0x06084604, 0x48590a01, 0x49531808, 0x68106048, 0x68506088, 0x462060c8, 0xfedef7ff, 0x46204603, 0xfecff7ff, 0xbd104618, 0xb08bb5ff, 0x460c980d, 0xd0242800, 0x980b466a, 0xfefdf7ff, 0x9b054621, 0x980b9a0e, 0xfc62f000, 0x28009008, 0x9801d118, 0x980e9009, 0x28009e00, 0x9809d05d, 0x900a4240, 0x4270990a, 0x42404008, 0x42b02500, 0x9909d101, 0x990e1840, 0x42811989, 0x1b84d904, 0x2004e003, 0xbdf0b00f, 0x2c009c0e, 0x2701d03b, 0x42bc02bf, 0x4627d800, 0x980d08a9, 0x18090089, 0x463a2005, 0xf0000680, 0x1970fc71, 0x200b0201, 0x06000a09, 0x48291809, 0x46386041, 0xf0009905, 0x0401fc4f, 0x1809482b, 0x60814824, 0xf7ff980b, 0x9008fe85, 0x6900980b, 0xd0002800, 0x98084780, 0xd00c2800, 0x6801481c, 0x02922201, 0x60014311, 0x8f6ff3bf, 0x8f4ff3bf, 0xb00f9808, 0x1be4bdf0, 0x2c0019ed, 0x08a9d1c3, 0x0089980d, 0x900d1808, 0x1976980e, 0x900e1b40, 0x980bd1a4, 0xfe53f7ff, 0xb5ffe7ea, 0x9809b089, 0x461d9f12, 0x460e4614, 0xd0242800, 0xd0222c00, 0xf7ff466a, 0x9806fe7e, 0x1e40463a, 0xd1184206, 0xe0154205, 0x40048040, 0x00000c54, 0x40020020, 0xf000300c, 0x40020000, 0x44ffffff, 0x6b65666b, 0x49ffffff, 0x4bffffff, 0x4300ffff, 0x0000ffff, 0x2065d004, 0x2004e021, 0xbdf0b00d, 0x20001971, 0x2a011e49, 0x2f00d002, 0xe003d006, 0xd1012e08, 0xd0122d08, 0xe0102004, 0x02922201, 0xd30c4291, 0x42960212, 0x4afed302, 0xd9064291, 0x05db2301, 0xd3ef429e, 0x42914afb, 0x2800d8ec, 0x2d00d1dc, 0x49f9d0da, 0x18470638, 0x20030231, 0x06000a09, 0x48f61809, 0x98066041, 0xd0022804, 0xd0032808, 0x48f2e004, 0xe00160c7, 0x608748f0, 0xf7ff9809, 0x2800fdf1, 0x49edd1c0, 0xc404688a, 0x2a089a06, 0x68c9d101, 0x9906c402, 0x1a6d198e, 0xb00dd1dc, 0x2800bdf0, 0x2a00d001, 0x2004d101, 0xb5704770, 0x06094614, 0x0a094ae2, 0x18894de0, 0xf7ff6069, 0x2800fdd1, 0x68a9d103, 0x68e96021, 0xbd706061, 0xd00e2800, 0xd00c2900, 0x788048d8, 0x0f920782, 0xd0082a02, 0x28020980, 0x2002d008, 0x20007008, 0x20044770, 0x20004770, 0xe7f87008, 0xe7f52001, 0xd0012800, 0xd1012900, 0x47702004, 0x4dcbb570, 0x78aa2300, 0x0f920792, 0xd0262a02, 0x606a4ac9, 0x78cb780c, 0x784c4622, 0x0224061b, 0x788c4322, 0x43220424, 0xba12431a, 0x78cb0a12, 0x431a0212, 0x790c60aa, 0x462279cb, 0x061b794c, 0x43220224, 0x79c9798c, 0x43220424, 0xba12431a, 0x02120a12, 0x60ea430a, 0xfd7ef7ff, 0x46184603, 0x2800bd70, 0x2004d101, 0x4ab44770, 0x18890409, 0x4aafb510, 0xf7ff6051, 0xbd10fd6f, 0xb08bb5ff, 0x461e4614, 0x466a460d, 0xf7ff980b, 0x4622fd94, 0x9b054629, 0xf000980b, 0x2800faf9, 0x466ad133, 0x980b4629, 0xfd87f7ff, 0x98029d00, 0x42699008, 0x40014240, 0x42af424f, 0x9808d101, 0x2c00183f, 0x0230d020, 0x1b7e9009, 0xd90042a6, 0x46304626, 0xf0009905, 0x022afb03, 0x0a122101, 0x18520609, 0x604a4993, 0x04009a09, 0x30ff4310, 0x980b6088, 0xfd32f7ff, 0xd1062800, 0x1ba49808, 0x183f19ad, 0xd1e02c00, 0xb00f2000, 0x2b00bdf0, 0x2004d101, 0xb5ff4770, 0x4616b089, 0x460c461d, 0x9f12466a, 0xf7ff9809, 0x4632fd48, 0x9b074621, 0xf0009809, 0x2800faad, 0x9c00d11d, 0xd01a2e00, 0x0638497b, 0x02211847, 0x0a092001, 0x18090640, 0x60414878, 0x68296087, 0x980960c1, 0xfcfef7ff, 0xd00a2800, 0x29009913, 0x600cd000, 0x29009914, 0x2200d001, 0xb00d600a, 0x9907bdf0, 0x08891a76, 0x194d0089, 0x190c9907, 0xd1dc2e00, 0xbdf0b00d, 0xd1012800, 0x47702004, 0x04094a6a, 0xb5101889, 0x60514a64, 0xfcdaf7ff, 0x2b00bd10, 0x2004d101, 0xb5f04770, 0xb0ad461d, 0x460c4616, 0x23084607, 0xfa66f000, 0xd1782800, 0xd00c2f00, 0x90019000, 0x683a9002, 0x92006879, 0x92022220, 0x42910292, 0x0949d903, 0x2004e003, 0x2101e002, 0x91010289, 0x28004684, 0x19a0d161, 0x9b012100, 0x434b9e00, 0x008e18f3, 0x5193aa03, 0x1c499b02, 0xd2f4428b, 0x4f482200, 0x2b00ae24, 0xe027d802, 0xd2042a08, 0x40d17c39, 0x0fc907c9, 0x4611e01b, 0x29083908, 0x7c7bd205, 0x07d940cb, 0x54b10fc9, 0x4611e012, 0x29083910, 0x7cbbd205, 0x07d940cb, 0x54b10fc9, 0x4611e008, 0x29083918, 0x7cfbd208, 0x07d940cb, 0x54b10fc9, 0x1c529902, 0xd8d74291, 0x460b2100, 0x4284460a, 0x008ed21b, 0x59bfaf03, 0xd80c42a7, 0x19f6af03, 0x42a66876, 0xae24d907, 0x1c5b5c76, 0xd1002e00, 0x9e011c52, 0x1c491934, 0xd3ea4284, 0xd0042a00, 0xd105429a, 0xe0042001, 0x2000e005, 0xe0017028, 0x70282002, 0xb02d4660, 0x2b00bdf0, 0x2004d101, 0xb5f04770, 0xb085461f, 0x460c4616, 0x23084605, 0xf9dcf000, 0xd1572800, 0xd0372d00, 0x90019000, 0x68289002, 0x69689000, 0x69a89001, 0x20009002, 0x28009003, 0x9801d148, 0x424019a6, 0x42714602, 0x40224008, 0x25001880, 0x99014240, 0xf9e6f000, 0x42b49004, 0x9800d232, 0x1a209901, 0xf9def000, 0xe00f2820, 0x000403ff, 0x008003ff, 0x00ffffff, 0x40020000, 0x4100ffff, 0x45ffffff, 0x4000ffff, 0x4a00ffff, 0x49dfd204, 0xe00769c9, 0xe7cf2004, 0x42819902, 0x49dbd90b, 0x38206989, 0x40822201, 0xd000438a, 0x98011c6d, 0x42b41904, 0x2d00d3d3, 0x9804d004, 0xd2044285, 0xe0032002, 0x70382000, 0x2001e001, 0x98037038, 0xbdf0b005, 0xd00d2800, 0xd00b2a00, 0xd222290a, 0x447b000b, 0x18db791b, 0x0806449f, 0x110f0d0a, 0x19171513, 0x47702004, 0xe01168c0, 0xe00f6840, 0x08406840, 0x7a00e00c, 0x6800e00a, 0x2001e008, 0x6940e006, 0x6980e004, 0x6a00e002, 0x6a40e000, 0x20006010, 0x206a4770, 0x46034770, 0x2b002000, 0x2905d005, 0xdc04d01b, 0xd80e2904, 0x2004e017, 0x29084770, 0xdc04d013, 0xd0102906, 0xd1042907, 0x2909e00d, 0x2921d00b, 0x206ad001, 0x2a004770, 0x2a01d003, 0x2077d001, 0x729a4770, 0x20764770, 0xb5704770, 0x0003461c, 0x2c00d005, 0x0748d003, 0x2065d003, 0x2004bd70, 0x6858bd70, 0x42880840, 0x2001d904, 0x1a080280, 0xd801280f, 0xbd702075, 0xd01f2a01, 0xd01d2a02, 0xd01b2a04, 0xd0192a08, 0xd0172a10, 0x28002004, 0x0208d1f1, 0x0a002123, 0x4d920649, 0x60681840, 0x06104991, 0x60a81840, 0xf7ff4618, 0x7aa9fb65, 0x7a697021, 0x7a297061, 0xbd7070a1, 0xe7e62000, 0x2000b5f7, 0x43c0b08c, 0xab019001, 0x990d2208, 0xf7ff980c, 0x2800ffba, 0x990ed115, 0xd00b2901, 0x79094669, 0xd27d2906, 0x447a000a, 0x18927912, 0x1c154497, 0x08857f36, 0x79004668, 0xd0042805, 0xd0052800, 0xb00f2074, 0x2000bdf0, 0xbdf0b00f, 0x2210ab01, 0x980c990d, 0xff97f7ff, 0xab01e06f, 0x990d2201, 0xf7ff980c, 0xe068ff90, 0x23082100, 0x9c0d9100, 0xaa02980c, 0xf7ff03d9, 0x2800fcc0, 0x4669d105, 0x00c98909, 0xd000428c, 0x28002075, 0xab01d1dc, 0x990d2202, 0xf7ff980c, 0xe04eff76, 0x9000980c, 0x25086840, 0x980d0841, 0x180caa02, 0x900a485e, 0x98004621, 0xfb2df7ff, 0x4621462a, 0x98009b06, 0xf892f000, 0xd1380007, 0x9e039c02, 0x46311de5, 0xf0004628, 0x2900f8b1, 0x1c40d002, 0x1e454370, 0xd81f42ac, 0x20090221, 0x06000a09, 0x484c1809, 0x494d6041, 0x4288980a, 0x206bd001, 0x2000e000, 0xd11a2800, 0xf7ff9800, 0x4607fad5, 0x69009800, 0xd0002800, 0x2f004780, 0x19a4d104, 0xe00042ac, 0xd9dfe017, 0xf7ff9800, 0x4638faba, 0xab01e005, 0x990d2204, 0xf7ff980c, 0x2800ff26, 0x4669d184, 0x29047909, 0xe75ed000, 0x2900990e, 0xb00fd1fb, 0x2004bdf0, 0xbdf0b00f, 0xd0082800, 0x680a4830, 0x68096102, 0x42816900, 0x2069d003, 0x20044770, 0x20004770, 0x28004770, 0x2900d006, 0x4828d004, 0x60086900, 0x47702000, 0x47702004, 0x68032201, 0x03d24926, 0xd00c1c5b, 0x4393680b, 0x6842600b, 0x03802001, 0x680a2a00, 0x4382d00c, 0x2000600a, 0x68404770, 0xd0032800, 0x43106808, 0xe7f66008, 0x47702078, 0xe7f14302, 0x60012100, 0x49186041, 0x4a1868c9, 0xd502040b, 0x60426002, 0x0449e002, 0x6042d400, 0x47702000, 0xd1012800, 0x47702004, 0x1e5bb410, 0xd1014219, 0xd002421a, 0x2065bc10, 0x68034770, 0xd807428b, 0x18896840, 0x42881818, 0xbc10d302, 0x47702000, 0x2066bc10, 0x00004770, 0x40020000, 0x00ffffff, 0x6b65666b, 0xf000300c, 0xf0003000, 0xffffffff, 0x460bb530, 0x20004601, 0x24012220, 0x460de009, 0x429d40d5, 0x461dd305, 0x1b494095, 0x40954625, 0x46151940, 0x2d001e52, 0xbd30dcf1, 0x430b4603, 0xd003079b, 0xc908e009, 0xc0081f12, 0xd2fa2a04, 0x780be003, 0x1c407003, 0x1e521c49, 0x4770d2f9, 0x40020004, 0x40020010, 0x00100008, 0x00200018, 0x00400030, 0x00800060, 0x010000c0, 0x02000180, 0x04000300, 0x00000600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 ], 'pc_init' : 0x20000021, 'pc_unInit': 0x20000065, 'pc_program_page': 0x200000CB, 'pc_erase_sector': 0x200000A5, 'pc_eraseAll' : 0x20000089, 'static_base' : 0x20000000 + 0x00000020 + 0x00000da0, 'begin_stack' : 0x20000000 + 0x00001000, 'begin_data' : 0x20000000 + 0x00001000, 'page_size' : 0x00000200, 'page_buffers' : [0x20001000, 0x20002000], # Enable double buffering 'min_program_length' : 8, 'analyzer_supported' : True, 'analyzer_address' : 0x1fffc000 }; class Flash_kw36z4(Flash_Kinetis): def __init__(self, target): super(Flash_kw36z4, self).__init__(target, FLASH_ALGO) class KW36Z4(Kinetis): _dflash = \ FlashRegion(name="Dflash", start=0x10040000, length=0x40000, blocksize=0x800) memoryMap = MemoryMap( FlashRegion(name="Pflash", start=0, length=0x40000, blocksize=0x800, is_boot_memory=True), AliasRegion(name="Dflash alias", start=0x00040000, length=0x40000, blocksize=0x800, aliasOf=_dflash), _dflash, RamRegion( name="FlexRAM", start=0x14000000, length=0x2000), RamRegion( name="SRAM", start=0x1fffc000, length=0x10000) ) def __init__(self, transport): super(KW36Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKW36Z4.svd") pyocd-0.13.1/pyocd/target/target_MKL02Z32xxx4.py0000644000175000017500000001551613373511253021071 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x4604b570, 0x4616460d, 0x49302000, 0x48306008, 0xf0004448, 0x2800f8e9, 0x2001d001, 0x2000bd70, 0x4601e7fc, 0x47702000, 0x492ab510, 0x44484828, 0xf8c2f000, 0x2c004604, 0x2100d105, 0x44484824, 0xf9bef000, 0xf0004604, 0x4620f838, 0xb570bd10, 0x481f4604, 0x4b1f4448, 0x68c24621, 0xf862f000, 0x2d004605, 0x481ad107, 0x23004448, 0x68c24621, 0xf956f000, 0xf0004605, 0x4628f820, 0xb5febd70, 0x460c4605, 0x46234616, 0x46294632, 0x44484810, 0xf90af000, 0x2f004607, 0x2201d10b, 0x46339001, 0x90029200, 0x46294622, 0x44484809, 0xf99af000, 0xf0004607, 0x4638f802, 0x4807bdfe, 0x210168c0, 0x43880289, 0x49041840, 0x477060c8, 0x40048100, 0x00000004, 0x6b65666b, 0xf0003000, 0x4a102070, 0x20807010, 0xbf007010, 0x7800480d, 0x280009c0, 0x480bd0fa, 0x20207801, 0x28004008, 0x2067d001, 0x20104770, 0x28004008, 0x2068d001, 0x07c8e7f8, 0x28000fc0, 0x2069d001, 0x2000e7f2, 0x0000e7f0, 0x40020000, 0xb081b5ff, 0x460d4604, 0xf0009804, 0x4606f89f, 0xd0022e00, 0xb0054630, 0x2304bdf0, 0x46204629, 0xf0009a03, 0x4606f876, 0xd0012e00, 0xe7f24630, 0x18289803, 0x46381e47, 0xf00068e1, 0x2900f983, 0x4638d009, 0xf00068e1, 0x1c40f97d, 0x68e19000, 0x43489800, 0xe0131e47, 0x4478480c, 0x60056800, 0x490b2009, 0xf7ff71c8, 0x4606ffa7, 0x280069a0, 0x69a0d001, 0x2e004780, 0xe003d000, 0x194568e0, 0xd9e942bd, 0x4630bf00, 0x0000e7c5, 0x00000462, 0x40020000, 0x4604b570, 0x4628460d, 0xf856f000, 0x2e004606, 0x4630d001, 0x2c00bd70, 0x2004d101, 0x2044e7fa, 0x71c84902, 0xff7ef7ff, 0x0000e7f4, 0x40020000, 0x29004601, 0x2004d101, 0x482a4770, 0x010068c0, 0x00400f00, 0x447b4b28, 0x03025a18, 0xd1012a00, 0xe7f12064, 0x60082000, 0x2001604a, 0x02806088, 0x200060c8, 0x61486108, 0xbf006188, 0x4602e7e4, 0xd1012a00, 0x47702004, 0x20006191, 0xb530e7fb, 0x2c004604, 0x2004d101, 0x1e58bd30, 0x28004008, 0x1e58d103, 0x28004010, 0x2065d001, 0x6820e7f4, 0xd8054288, 0x68206865, 0x188d1940, 0xd20142a8, 0xe7e92066, 0xe7e72000, 0x480c4601, 0xd0014281, 0x4770206b, 0xe7fc2000, 0x2b004603, 0x2004d101, 0x290f4770, 0x2a04d801, 0x2004d001, 0x2000e7f8, 0x0000e7f6, 0x40048040, 0x000003c0, 0x6b65666b, 0xb081b5ff, 0x46144607, 0x2c00461d, 0x2004d102, 0xbdf0b005, 0x462a2304, 0x99024638, 0xffb7f7ff, 0x2e004606, 0x4630d001, 0xe01ce7f2, 0x44794910, 0x68099802, 0xcc016008, 0x4479490d, 0x6809390c, 0x20066048, 0x71c8490b, 0xfef4f7ff, 0x69b84606, 0xd0012800, 0x478069b8, 0xd0002e00, 0x9802e005, 0x90021d00, 0x2d001f2d, 0xbf00d1e0, 0xe7cf4630, 0x0000030a, 0x40020000, 0xb083b5ff, 0x2304460c, 0x9a054621, 0xf7ff9803, 0x9002ff82, 0x28009802, 0x9802d002, 0xbdf0b007, 0x68919a03, 0xf0006850, 0x4605f88f, 0x42684261, 0x424e4001, 0xd10042a6, 0x9f051976, 0x1b30e027, 0x98019001, 0xd90042b8, 0x98019701, 0x90000880, 0x44784811, 0x60046800, 0x49102001, 0x980071c8, 0x0e010400, 0x72c1480d, 0x9800490c, 0x98067288, 0xf7ff7248, 0x9002fea3, 0x28009802, 0x9802d001, 0x9801e7cc, 0x98011a3f, 0x19761824, 0x2f00bf00, 0x2000d1d5, 0x0000e7c2, 0x0000026e, 0x40020000, 0x4604b570, 0x2c00460d, 0x2004d101, 0x2040bd70, 0x71c84903, 0x71854608, 0xfe80f7ff, 0x0000e7f6, 0x40020000, 0xb081b5ff, 0x4617460c, 0x2d00461d, 0x2004d102, 0xbdf0b005, 0x463a2304, 0x98014621, 0xff19f7ff, 0x2e004606, 0x4630d001, 0xe022e7f2, 0x44784813, 0x60046800, 0x49122002, 0x980a71c8, 0x490f72c8, 0x39124479, 0x68096828, 0xf7ff6088, 0x4606fe55, 0xd00b2e00, 0x2800980b, 0x980bd001, 0x980c6004, 0xd0022800, 0x980c2100, 0xe0046001, 0x1d2d1f3f, 0x2f001d24, 0xbf00d1da, 0xe7c94630, 0x000001ce, 0x40020000, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, 0x2000b501, 0x46c046c0, 0x0002bd02, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000000, 0x00000000, 0x00000020, 0x40020004, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x20000049, 'pc_erase_sector' : 0x2000006F, 'pc_program_page' : 0x2000009F, 'begin_stack' : 0x20000800, 'begin_data' : 0x20000800, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) # Note: 128 pages on KL25 and KL26, 256 pages on KL46 'static_base' : 0x20000000 + 0x20 + 0x5E8, 'min_program_length' : 4, 'analyzer_supported' : False # Not enough space on KL02 and KL05 }; # @brief Flash algorithm for Kinetis L-series devices. class Flash_kl02z(Flash_Kinetis): def __init__(self, target): super(Flash_kl02z, self).__init__(target, FLASH_ALGO) class KL02Z(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffffc00, length=0x1000) ) def __init__(self, link): super(KL02Z, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKL02Z4.svd", is_local=False) pyocd-0.13.1/pyocd/target/target_RTL8195AM.py0000644000175000017500000000251213373511253020347 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging class Flash_rtl8195am(Flash): def __init__(self, target): return class RTL8195AM(CoreSightTarget): memoryMap = MemoryMap( RamRegion( start=0x00000000, length=0x400000), RamRegion( start=0x10000000, length=0x80000), RamRegion( start=0x30000000, length=0x200000), RamRegion( start=0x40000000, length=0x40000) ) def __init__(self, link): super(RTL8195AM, self).__init__(link, self.memoryMap) def init(self): logging.debug('rtl8195am init') super(RTL8195AM, self).init() pyocd-0.13.1/pyocd/target/target_STM32F103RC.py0000644000175000017500000000716613373511253020542 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) import logging DBGMCU_CR = 0xE0042004 #0111 1110 0011 1111 1111 1111 0000 0000 DBGMCU_VAL = 0x7E3FFF00 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x49384839, 0x49396041, 0x20006041, 0x49364770, 0x60c82034, 0x47702000, 0x47702000, 0xb5004a32, 0x06006910, 0xf7ffd501, 0x68d0ffeb, 0xd1fc07c0, 0xf0406910, 0x61100004, 0xf0406910, 0x61100040, 0x07c068d0, 0x6910d1fc, 0x0004f020, 0x20006110, 0x4a25bd00, 0x4603b500, 0x06006910, 0xf7ffd501, 0x68d1ffcf, 0xd1fc07c9, 0xf0406910, 0x61100002, 0x69106153, 0x0040f040, 0x68d06110, 0xd1fc07c0, 0xf0206910, 0x61100002, 0xbd002000, 0x4d16b570, 0x460e4603, 0x24006928, 0xd5010600, 0xffb0f7ff, 0x07c068e8, 0xe014d1fc, 0x0001f040, 0x88106128, 0x68e88018, 0xd1fc07c0, 0x88198810, 0xd0054288, 0xf0206928, 0x61280001, 0xbd702001, 0x1c9b1c92, 0x69281c64, 0x0f56ebb4, 0xf020d3e6, 0x61280001, 0xbd702000, 0x45670123, 0x40022000, 0xcdef89ab, 0x00000000, ], 'pc_init' : 0x2000002F, 'pc_eraseAll' : 0x2000003D, 'pc_erase_sector' : 0x20000073, 'pc_program_page' : 0x200000AD, 'static_base' : 0x20000200, 'begin_data' : 0x20001000, # Analyzer uses a max of 1 KB data (256 pages * 4 bytes / page) 'page_buffers' : [0x20001000, 0x20001800], # Enable double buffering 'begin_stack' : 0x20002800, 'min_program_length' : 2, 'analyzer_supported' : True, 'analyzer_address' : 0x20003000 # Analyzer 0x20003000..0x20003600 }; class Flash_stm32f103rc(Flash): def __init__(self, target): super(Flash_stm32f103rc, self).__init__(target, FLASH_ALGO) class STM32F103RC(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0x08000000, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x20000000, length=0x10000) ) def __init__(self, link): super(STM32F103RC, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="STMicro", filename="STM32F103xx.svd", is_local=False) def create_init_sequence(self): seq = super(STM32F103RC, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): logging.debug('stm32f103rc init') self.write_memory(DBGMCU_CR, DBGMCU_VAL) pyocd-0.13.1/pyocd/target/target_LPC54608J512ET180.py0000644000175000017500000001041713373511253021215 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, RomRegion, MemoryMap) from ..coresight import ap from ..coresight.cortex_m import CortexM FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x21002210, 0xf8c00690, 0x4a2c2630, 0xf0236813, 0x60134380, 0x1280f8c0, 0x1284f8c0, 0x68134a28, 0x4370f423, 0xf8c06013, 0x21021380, 0x20006001, 0x20004770, 0xb5104770, 0x2000210f, 0xf844f000, 0xbf182800, 0x4a1fbd10, 0xe8bd210f, 0x20004010, 0xb864f000, 0x0bc4b510, 0x46084621, 0xf834f000, 0xbf182800, 0x4a17bd10, 0xe8bd4621, 0x46084010, 0xb854f000, 0x4614b570, 0xd10e0005, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x0be861e0, 0xf0004601, 0x2800f813, 0xbd70bf18, 0x46214b06, 0xe8bd4628, 0xf44f4070, 0xf0007280, 0x0000b818, 0x40000500, 0x40000400, 0x00b71b00, 0xb08bb500, 0x92002232, 0x0101e9cd, 0x46684a39, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0xb500bd00, 0xf04fb08b, 0x92030c33, 0xc000f8cd, 0x0101e9cd, 0x707af44f, 0xf0f0fbb3, 0x4a2d9004, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x93002334, 0x0101e9cd, 0x707af44f, 0xf0f0fbb2, 0x4a229003, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x9300233b, 0x0101e9cd, 0x707af44f, 0xf0f0fbb2, 0x4a179003, 0xa9064668, 0x98064790, 0xbf182800, 0x10c4f600, 0xbd00b00b, 0xb08bb500, 0x92002235, 0x0101e9cd, 0x46684a0e, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0xb500bd00, 0x2338b08b, 0x93009203, 0x0101e9cd, 0x46684a05, 0x4790a906, 0x28009806, 0xf600bf18, 0xb00b10c4, 0x0000bd00, 0x03000205, 0x00000000 ], # Relative function addresses 'pc_init': 0x20000021, 'pc_program_page': 0x20000095, 'pc_erase_sector': 0x20000075, 'pc_eraseAll': 0x20000057, 'begin_stack' : 0x20001000, 'begin_data' : 0x20003000, 'page_buffers' : [0x20003000], 'static_base' : 0x200001dc, 'page_size' : 0x00000100, 'min_program_length' : 256, 'analyzer_supported' : False }; class Flash_lpc54608(Flash): def __init__(self, target): super(Flash_lpc54608, self).__init__(target, FLASH_ALGO) def program_page(self, flashPtr, bytes): write_size = 256 for i in range(0, 128): data = bytes[i * write_size : (i + 1) * write_size] Flash.program_page(self, flashPtr + i * write_size, data) class LPC54608(CoreSightTarget): memoryMap = MemoryMap( FlashRegion(name='flash', start=0, length=0x80000, blocksize=0x8000, is_boot_memory=True), RamRegion( name='sramx', start=0x04000000, length=0x8000), RamRegion( name='sram0', start=0x20000000, length=0x10000), RamRegion( name='sram1', start=0x20010000, length=0x10000), RamRegion( name='sram2', start=0x20020000, length=0x8000) ) def __init__(self, link): super(LPC54608, self).__init__(link, self.memoryMap) self.ignoreReset = False self._svd_location = SVDFile(vendor="NXP", filename="LPC54608.svd", is_local=False) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC54608, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40000000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MKW40Z160xxx4.py0000644000175000017500000001554313373511253021170 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .family.target_kinetis import Kinetis from .family.flash_kinetis import Flash_Kinetis from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x09032200, 0xd373428b, 0x428b0a03, 0x0b03d358, 0xd33c428b, 0x428b0c03, 0xe012d321, 0x430b4603, 0x2200d47f, 0x428b0843, 0x0903d374, 0xd35f428b, 0x428b0a03, 0x0b03d344, 0xd328428b, 0x428b0c03, 0x22ffd30d, 0xba120209, 0x428b0c03, 0x1212d302, 0xd0650209, 0x428b0b03, 0xe000d319, 0x0bc30a09, 0xd301428b, 0x1ac003cb, 0x0b834152, 0xd301428b, 0x1ac0038b, 0x0b434152, 0xd301428b, 0x1ac0034b, 0x0b034152, 0xd301428b, 0x1ac0030b, 0x0ac34152, 0xd301428b, 0x1ac002cb, 0x0a834152, 0xd301428b, 0x1ac0028b, 0x0a434152, 0xd301428b, 0x1ac0024b, 0x0a034152, 0xd301428b, 0x1ac0020b, 0xd2cd4152, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0xb510480a, 0x44484908, 0xf8f2f000, 0xd1042800, 0x21004806, 0xf0004448, 0x4a05f9bf, 0x230168d1, 0x4319029b, 0xbd1060d1, 0x6b65666b, 0x00000004, 0xf0003000, 0x4c0cb570, 0x444c4605, 0x4b0b4601, 0x68e24620, 0xf89af000, 0xd1052800, 0x46292300, 0x68e24620, 0xf964f000, 0x68ca4905, 0x029b2301, 0x60ca431a, 0x0000bd70, 0x00000004, 0x6b65666b, 0xf0003000, 0x4905b510, 0x60082000, 0x44484804, 0xf8eef000, 0xd0002800, 0xbd102001, 0x40048100, 0x00000004, 0x460cb570, 0x4606460b, 0x480d4601, 0x4615b084, 0xf0004448, 0x2800f903, 0x9001d10a, 0x21019002, 0x91004807, 0x4622462b, 0x44484631, 0xf978f000, 0x68ca4904, 0x029b2301, 0x60ca431a, 0xbd70b004, 0x00000004, 0xf0003000, 0x47702000, 0xd0082800, 0xd802290f, 0xd1042a04, 0x2913e005, 0x2a08d801, 0x2004d001, 0x20004770, 0x28004770, 0x2004d101, 0xb4104770, 0x460c1e5b, 0xd101421c, 0xd002421a, 0x2065bc10, 0x68034770, 0xd804428b, 0x18896840, 0x42881818, 0xbc10d202, 0x47702066, 0x2000bc10, 0x00004770, 0x42884903, 0x206bd001, 0x20004770, 0x00004770, 0x6b65666b, 0x2170480a, 0x21807001, 0x78017001, 0xd5fc0609, 0x06817800, 0x2067d501, 0x06c14770, 0x2068d501, 0x07c04770, 0x2069d0fc, 0x00004770, 0x40020000, 0x4605b5f8, 0x460c4616, 0xf7ff4618, 0x2800ffd7, 0x2304d12b, 0x46214632, 0xf7ff4628, 0x0007ffb2, 0x19a6d123, 0x68e91e76, 0x91004630, 0xfe36f7ff, 0xd0032900, 0x1c409e00, 0x1e764346, 0xd81342b4, 0x4478480a, 0x60046800, 0x20094909, 0xf7ff71c8, 0x4607ffbf, 0x280069a8, 0x4780d000, 0xd1032f00, 0x190468e8, 0xd9eb42b4, 0xbdf84638, 0x0000027a, 0x40020000, 0x4604b510, 0xf7ff4608, 0x2800ff9f, 0x2c00d106, 0x4904d005, 0x71c82044, 0xffa0f7ff, 0x2004bd10, 0x0000bd10, 0x40020000, 0xd00c2800, 0xd00a2a00, 0xd21a2908, 0x447b000b, 0x18db791b, 0x0705449f, 0x0d0b0907, 0x2004110f, 0x68c04770, 0x6840e00a, 0x6880e008, 0x6800e006, 0x2001e004, 0x6900e002, 0x6940e000, 0x20006010, 0x206a4770, 0x00004770, 0xd00a2800, 0x68c9490f, 0x0e094a0f, 0x447a0049, 0x03095a51, 0x2064d103, 0x20044770, 0xb4104770, 0x60032300, 0x21026041, 0x02496081, 0x490760c1, 0x158a7a0c, 0x610240a2, 0x61837ac9, 0xbc106141, 0x47704618, 0x40048040, 0x000001aa, 0x40020020, 0xd1012a00, 0x47702004, 0x461cb5ff, 0x4615b081, 0x2304460e, 0x98014622, 0xff19f7ff, 0xd1190007, 0xd0162c00, 0x4478480c, 0x600e6801, 0x6800cd02, 0x490a6041, 0x71c82006, 0xff30f7ff, 0x98014607, 0x28006980, 0x4780d000, 0xd1022f00, 0x1f241d36, 0x4638d1e8, 0xbdf0b005, 0x00000162, 0x40020000, 0xd0022800, 0x20006181, 0x20044770, 0x00004770, 0xb081b5ff, 0x460e4614, 0x23044605, 0xfee7f7ff, 0xd12a2800, 0x686868a9, 0xfd6ef7ff, 0x42719000, 0x40014240, 0x42b7424f, 0x9800d101, 0x2c00183f, 0x1bbdd01a, 0xd90042a5, 0x490d4625, 0x447908a8, 0x600e6809, 0x2201490b, 0x0a0271ca, 0x728872ca, 0x72489804, 0xfeeaf7ff, 0xd1062800, 0x1b649800, 0x183f1976, 0xd1e42c00, 0xb0052000, 0x0000bdf0, 0x000000da, 0x40020000, 0xd1012800, 0x47702004, 0x4803b510, 0x71c22240, 0xf7ff7181, 0xbd10fecf, 0x40020000, 0xd1012b00, 0x47702004, 0x461cb5f8, 0x460e4615, 0x9f082304, 0xfe99f7ff, 0xd1192800, 0xd0172d00, 0x447a4a0f, 0x60066810, 0x2102480e, 0x990671c1, 0x681172c1, 0x60886820, 0xfeaef7ff, 0xd0082800, 0x29009907, 0x600ed000, 0xd0012f00, 0x60392100, 0x1f2dbdf8, 0x1d361d24, 0xd1e12d00, 0x0000bdf8, 0x00000062, 0x40020000, 0x00040002, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00000000, 0x00000000, 0x00200000, 0x40020004, 0x00000000, ], 'pc_init' : 0x2000027D, 'pc_unInit': 0x200002E5, 'pc_program_page': 0x2000029D, 'pc_erase_sector': 0x2000023D, 'pc_eraseAll' : 0x20000209, 'static_base' : 0x20000000 + 0x00000020 + 0x00000628, 'begin_stack' : 0x20000000 + 0x00000800, 'begin_data' : 0x20000000 + 0x00000A00, 'page_buffers' : [0x20000a00, 0x20001200], # Enable double buffering 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x1ffff800 }; # @brief Flash algorithm for Kinetis KW40Z4 device. class Flash_kw40z4(Flash_Kinetis): def __init__(self, target): super(Flash_kw40z4, self).__init__(target, FLASH_ALGO) class KW40Z4(Kinetis): memoryMap = MemoryMap( FlashRegion( start=0, length=0x28000, blocksize=0x400, is_boot_memory=True), RamRegion( start=0x1ffff000, length=0x5000) ) def __init__(self, transport): super(KW40Z4, self).__init__(transport, self.memoryMap) self._svd_location = SVDFile(vendor="Freescale", filename="MKW40Z4.svd") pyocd-0.13.1/pyocd/target/target_LPC11U24FBD64_401.py0000644000175000017500000001044213373511253021267 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..flash.flash import Flash from ..core.coresight_target import (SVDFile, CoreSightTarget) from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) FLASH_ALGO = { 'load_address' : 0x10000000, 'instructions' : [ 0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2, 0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x47700b00, 0x484e494f, 0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x49496382, 0x39402002, 0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x46222607, 0x4621c261, 0x4f423114, 0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448, 0x462060e0, 0x47b89900, 0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0b044d35, 0x2032444d, 0x4629606c, 0x311460ac, 0x4e326028, 0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829, 0x68004448, 0x462860e8, 0x696847b0, 0xd0002800, 0xbdf82001, 0x0006b5f8, 0xd11e4614, 0x0180200b, 0x6bc11820, 0x42814823, 0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861, 0x184068e2, 0x188968a1, 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0b30, 0x60682132, 0x60a86029, 0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033, 0x20016028, 0x60e80280, 0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001, 0x00002ee0, 0x00000004, 0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x43218765, 0x00000000, 0x00000000 ], 'pc_init' : 0x1000003d, 'pc_eraseAll' : 0x1000006b, 'pc_erase_sector' : 0x100000ab, 'pc_program_page' : 0x100000ed, 'begin_data' : 0x100001c4, # Double buffering is not supported since there is not enough ram 'begin_stack' : 0x10001000, 'static_base' : 0x1000019c, 'min_program_length' : 256, 'analyzer_supported' : False }; class Flash_lpc11u24(Flash): def __init__(self, target): super(Flash_lpc11u24, self).__init__(target, FLASH_ALGO) # TODO - temporary until flash algo is rebuilt with 4K page program size def program_page(self, flashPtr, bytes): write_size = 1024 for i in range(0, 4): data = bytes[i * write_size : (i + 1) * write_size] Flash.program_page(self, flashPtr + i * write_size, data) class LPC11U24(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x8000, blocksize=0x1000, is_boot_memory=True), RamRegion( start=0x10000000, length=0x1000) ) def __init__(self, link): super(LPC11U24, self).__init__(link, self.memoryMap) self._svd_location = SVDFile(vendor="NXP", filename="LPC11Uxx_v7.svd", is_local=False) def reset_stop_on_reset(self, software_reset=None, map_to_user=True): super(LPC11U24, self).reset_stop_on_reset(software_reset) # Remap to use flash and set SP and SP accordingly if map_to_user: self.write_memory(0x40048000, 0x2, 32) sp = self.read_memory(0x0) pc = self.read_memory(0x4) self.write_core_register('sp', sp) self.write_core_register('pc', pc) pyocd-0.13.1/pyocd/target/target_MAX32600.py0000644000175000017500000001002013373511253020152 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, DeviceRegion, MemoryMap) import logging FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x68884972, 0x7f80f010, 0x2001d001, 0x200c4770, 0x20006048, 0x496de7fa, 0xf0106888, 0xd0017f80, 0x47702001, 0xb1486a48, 0x62482000, 0xb1286a48, 0x62482002, 0xb1086a48, 0xe7f22001, 0xf0206888, 0xf0404070, 0x60885000, 0xe7ea2000, 0x4c5fb510, 0xffe1f7ff, 0x2001b108, 0x68a0bd10, 0x407ff420, 0x402af440, 0x68a060a0, 0x0002f040, 0xbf0060a0, 0xf01068a0, 0xd1fb7f80, 0xf02068a0, 0x60a04070, 0xf0106a60, 0xd0010f02, 0xe7e52001, 0xe7e32000, 0x4605b570, 0xf7ff4c4d, 0xb108ffbe, 0xbd702001, 0xf42068a0, 0xf440407f, 0x60a040aa, 0x68a06025, 0x0004f040, 0xbf0060a0, 0xf01068a0, 0xd1fb7f80, 0xf02068a0, 0x60a04070, 0xf0106a60, 0xd0010f02, 0xe7e42001, 0xe7e22000, 0x47f0e92d, 0x468a4606, 0x4c3a4690, 0x46474655, 0x0f03f018, 0x2001d002, 0x87f0e8bd, 0xf7ff4647, 0xb108ff8e, 0xe7f72002, 0xf02068a0, 0x60a06000, 0xf04068a0, 0x60a00010, 0x6026e00d, 0x6320cf01, 0xf04068a0, 0x60a00001, 0x68a0bf00, 0x7f80f010, 0x1d36d1fb, 0x2d041f2d, 0xf016d302, 0xd1ec0f1f, 0x2d04bf00, 0x68a0d318, 0x6000f020, 0x68a060a0, 0x0010f040, 0xe00d60a0, 0xcf016026, 0x68a06320, 0x0001f040, 0xbf0060a0, 0xf01068a0, 0xd1fb7f80, 0x1f2d1d36, 0xd2ef2d04, 0x68a2b1fd, 0x6200f022, 0x68a260a2, 0x0210f042, 0xf04f60a2, 0x21ff30ff, 0x683ae005, 0x0201ea62, 0x02094010, 0x2d001e6d, 0x6026d1f7, 0x68a26320, 0x0201f042, 0xbf0060a2, 0xf01268a2, 0xd1fb7f80, 0x68a0bf00, 0x4070f020, 0x6a6060a0, 0x0f02f010, 0x2003d001, 0x2000e794, 0x0000e792, 0x400f0000, 0x00000000, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x00000000, 0x00000000, 0x00000000, ], 'pc_init' : 0x20000021, 'pc_eraseAll' : 0x2000006D, 'pc_erase_sector' : 0x200000B1, 'pc_program_page' : 0x200000F9, 'begin_data' : 0x20003000, # Analyzer uses a max of 512 B data (128 pages * 4 bytes / page) 'page_buffers' : [0x20003000, 0x20003800], # Enable double buffering 'begin_stack' : 0x20001000, 'static_base' : 0x20000230, 'min_program_length' : 4, 'analyzer_supported' : True, 'analyzer_address' : 0x20004000 # Analyzer 0x20004000..0x20004600 }; class Flash_max32600(Flash): def __init__(self, target): super(Flash_max32600mbed, self).__init__(target, FLASH_ALGO) class MAX32600(CoreSightTarget): memoryMap = MemoryMap( FlashRegion( start=0, length=0x40000, blocksize=0x800, is_boot_memory=True), RamRegion( start=0x20000000, length=0x8000), DeviceRegion( start=0x40000000, length=0x100000), DeviceRegion( start=0xe0000000, length=0x100000) ) def __init__(self, link): super(MAX32600, self).__init__(link, self.memoryMap) def dsb(self): logging.info("Triggering Destructive Security Bypass...") self.link.vendor(1) # Reconnect debugger self.link.init() def fge(self): logging.info("Triggering Factory Global Erase...") self.link.vendor(2) # Reconnect debugger self.link.init() pyocd-0.13.1/pyocd/target/target_STM32L475xx.py0000644000175000017500000001202713373511253020707 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 ..flash.flash import Flash from ..core.coresight_target import CoreSightTarget from ..core.memory_map import (FlashRegion, RamRegion, MemoryMap) from ..debug.svd import SVDFile class DBGMCU: CR = 0xE0042004 CR_VALUE = 0x7 # DBG_STANDBY | DBG_STOP | DBG_SLEEP APB1FZR1 = 0xE0042008 APB1FZR1_VALUE = 0x86e01c3f APB1FZR2 = 0xE0042008 APB1FZR2_VALUE = 0x00000022 APB2FZR = 0xE004200C APB2FZR_VALUE = 0x00072800 FLASH_ALGO = { 'load_address' : 0x20000000, 'instructions' : [ 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, 0x8f4ff3bf, 0x48584770, 0x49586800, 0x0d000500, 0xd0001840, 0x47702001, 0x6a004855, 0x0fc00280, 0xb5004770, 0xf7ff4602, 0x2801ffee, 0xf7ffd108, 0x2801fff3, 0x484fd104, 0xd3014282, 0xbd002001, 0xbd002000, 0x4602b500, 0xffddf7ff, 0xd0022801, 0x0d8002d0, 0x4948bd00, 0x40080ad0, 0xd5f90351, 0x300130ff, 0x4842bd00, 0x60814944, 0x60814944, 0x60012100, 0x61014943, 0x03c06a00, 0x4843d406, 0x60014941, 0x60412106, 0x60814941, 0x47702000, 0x49372001, 0x614807c0, 0x47702000, 0x47702001, 0x49384833, 0x13c16101, 0x69416141, 0x04122201, 0x61414311, 0x4a354937, 0x6011e000, 0x03db6903, 0x2100d4fb, 0x46086141, 0xb5104770, 0xf7ff4604, 0x4603ffa8, 0xf7ff4620, 0x4925ffb5, 0x610c4c29, 0x02d800c2, 0x43021c92, 0x6948614a, 0x04122201, 0x61484310, 0x8f4ff3bf, 0x4a244826, 0x6010e000, 0x03db690b, 0x2000d4fb, 0x69086148, 0xd0014020, 0x2001610c, 0xb5f0bd10, 0x4d151dc9, 0x4f1908c9, 0x612f00c9, 0x616b2300, 0xe0184c1a, 0x616b2301, 0x60036813, 0x60436853, 0x8f4ff3bf, 0xe0004b13, 0x692e601c, 0xd4fb03f6, 0x616b2300, 0x423b692b, 0x612fd002, 0xbdf02001, 0x39083008, 0x29003208, 0x2000d1e4, 0x0000bdf0, 0xe0042000, 0xfffffbcb, 0x40022000, 0x08040000, 0x0000037f, 0x45670123, 0xcdef89ab, 0x0000c3fa, 0x00005555, 0x40003000, 0x00000fff, 0x0000aaaa, 0x00000000 ], 'pc_init' : 0x20000087, 'pc_unInit': 0x200000b1, 'pc_program_page': 0x20000137, 'pc_erase_sector': 0x200000eb, 'pc_eraseAll' : 0x200000c1, 'static_base' : 0x20000000 + 0x00000020 + 0x00000198, 'begin_stack' : 0x20000000 + 0x00000400, 'begin_data' : 0x20001000, 'page_buffers' : [0x20001000, 0x20001800], 'min_program_length' : 8, 'analyzer_supported' : True, 'analyzer_address' : 0x20002000 }; # @brief Flash algorithm for STM32F475xx device. class Flash_stm32l475xx(Flash): def __init__(self, target): super(Flash_stm32l475xx, self).__init__(target, FLASH_ALGO) class STM32L475xx(CoreSightTarget): def create_init_sequence(self): seq = super(STM32L475xx, self).create_init_sequence() seq.insert_after('create_cores', ('setup_dbgmcu', self.setup_dbgmcu) ) return seq def setup_dbgmcu(self): self.write32(DBGMCU.CR, DBGMCU.CR_VALUE) self.write32(DBGMCU.APB1FZR1, DBGMCU.APB1FZR1_VALUE) self.write32(DBGMCU.APB1FZR2, DBGMCU.APB1FZR2_VALUE) self.write32(DBGMCU.APB2FZR, DBGMCU.APB2FZR_VALUE) class STM32L475xC(STM32L475xx): memoryMap = MemoryMap( FlashRegion(name='flash', start=0x08000000, length=0x40000, blocksize=0x800, is_boot_memory=True), RamRegion(name='sram1', start=0x20000000, length=0x18000), RamRegion(name='sram2', start=0x10000000, length=0x8000) ) def __init__(self, transport): super(STM32L475xC, self).__init__(transport, self.memoryMap) # cmsis-svd doesn't have this device's SVD file class STM32L475xE(STM32L475xx): memoryMap = MemoryMap( FlashRegion(name='flash', start=0x08000000, length=0x80000, blocksize=0x800, is_boot_memory=True), RamRegion(name='sram1', start=0x20000000, length=0x18000), RamRegion(name='sram2', start=0x10000000, length=0x8000) ) def __init__(self, transport): super(STM32L475xE, self).__init__(transport, self.memoryMap) # cmsis-svd doesn't have this device's SVD file class STM32L475xG(STM32L475xx): memoryMap = MemoryMap( FlashRegion(name='flash', start=0x08000000, length=0x100000, blocksize=0x800, is_boot_memory=True), RamRegion(name='sram1', start=0x20000000, length=0x18000), RamRegion(name='sram2', start=0x10000000, length=0x8000) ) def __init__(self, transport): super(STM32L475xG, self).__init__(transport, self.memoryMap) # cmsis-svd doesn't have this device's SVD file pyocd-0.13.1/pyocd/board/0000755000175000017500000000000013373523011015015 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/board/mbed_board.py0000644000175000017500000000425413373511253017457 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .board import Board from .board_ids import BOARD_ID_TO_INFO import logging log = logging.getLogger('mbed_board') class MbedBoard(Board): """ This class inherits from Board and is specific to mbed boards. Particularly, this class allows you to dynamically determine the type of all boards connected based on the id board """ def __init__(self, session, target=None): """ Init the board """ target = session.options.get('target_override', target) unique_id = session.probe.unique_id try: board_id = unique_id[0:4] board_info = BOARD_ID_TO_INFO[board_id] self._name = board_info.name self.native_target = board_info.target except KeyError: board_info = None self._name = "Unknown Board" self.native_target = None # Unless overridden use the native target if target is None: target = self.native_target if target is None: log.warning("Unsupported board found %s", board_id) target = "cortex_m" super(MbedBoard, self).__init__(session, target) # Set test binary if not already set. if (board_info is not None) and (self._test_binary is None): self._test_binary = board_info.binary @property def name(self): """ Return board name """ return self._name @property def description(self): """ Return info on the board """ return self.name + " [" + self.target_type + "]" pyocd-0.13.1/pyocd/board/board.py0000644000175000017500000000527013373511253016467 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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 ..target import (TARGET, FLASH) import logging import six log = logging.getLogger('board') class Board(object): """ This class associates a target and flash to create a board. """ def __init__(self, session, target=None): # As a last resort, default the target to 'cortex_m'. if target is None: target = 'cortex_m' self._session = session self._target_type = target.lower() self._test_binary = session.options.get('test_binary', None) # Create Target and Flash instances. try: log.info("Target type is %s", self._target_type) self.target = TARGET[self._target_type](session) self.flash = FLASH[self._target_type](self.target) except KeyError as exc: log.error("target '%s' not recognized", self._target_type) six.raise_from(KeyError("target '%s' not recognized" % self._target_type), exc) self.target.flash = self.flash self._inited = False ## @brief Initialize the board. def init(self): self.target.init() self._inited = True ## @brief Uninitialize the board. def uninit(self): if self._inited: log.debug("uninit board %s", self) try: resume = self.session.options.get('resume_on_disconnect', True) self.target.disconnect(resume) self._inited = False except: log.error("link exception during target disconnect:", exc_info=True) @property def session(self): return self._session @property def unique_id(self): return self.session.probe.unique_id @property def target_type(self): return self._target_type @property def test_binary(self): return self._test_binary @property def name(self): return "generic" @property def description(self): return "Generic board via " + self.session.probe.vendor_name + " " \ + self.session.probe.product_name + " [" + self.target_type + "]" pyocd-0.13.1/pyocd/board/__init__.py0000644000175000017500000000114213373511253017131 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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. """ pyocd-0.13.1/pyocd/board/board_ids.py0000644000175000017500000002005313373511253017322 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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. """ class BoardInfo(object): def __init__(self, name, target, binary): self.name = name self.target = target self.binary = binary BOARD_ID_TO_INFO = { # Note: please keep board list sorted by ID! # # Board ID Board Name Target Test Binary "0200": BoardInfo( "FRDM-KL25Z", "kl25z", "l1_kl25z.bin" ), "0201": BoardInfo( "FRDM-KW41Z", "kw41z4", "l1_kw41z4.bin" ), "0202": BoardInfo( "USB-KW41Z", "kw41z4", "l1_kw41z4.bin" ), "0203": BoardInfo( "TWR-KL28Z72M", "kl28z", "l1_kl28z.bin", ), "0204": BoardInfo( "FRDM-KL02Z", "kl02z", "l1_kl02z.bin", ), "0205": BoardInfo( "FRDM-KL28Z", "kl28z", "l1_kl28z.bin", ), "0206": BoardInfo( "TWR-KE18F", "ke18f16", "l1_ke18f16.bin", ), "0210": BoardInfo( "FRDM-KL05Z", "kl05z", "l1_kl05z.bin", ), "0213": BoardInfo( "FRDM-KE15Z", "ke15z7", "l1_ke15z7.bin", ), "0214": BoardInfo( "Hexiwear", "k64f", "l1_k64f.bin", ), "0215": BoardInfo( "FRDM-KL28ZEM", "kl28z", "l1_kl28z.bin", ), "0216": BoardInfo( "HVP-KE18F", "ke18f16", "l1_ke18f16.bin", ), "0217": BoardInfo( "FRDM-K82F", "k82f25615", "l1_k82f.bin", ), "0218": BoardInfo( "FRDM-KL82Z", "kl82z7", "l1_kl82z.bin", ), "0220": BoardInfo( "FRDM-KL46Z", "kl46z", "l1_kl46z.bin", ), "0224": BoardInfo( "FRDM-K28F", "k28f15", "l1_k28f.bin", ), "0225": BoardInfo( "FRDM-K32W042", "k32w042s", "l1_k32w042s.bin", ), "0230": BoardInfo( "FRDM-K20D50M", "k20d50m", "l1_k20d50m.bin", ), "0231": BoardInfo( "FRDM-K22F", "k22f", "l1_k22f.bin", ), "0240": BoardInfo( "FRDM-K64F", "k64f", "l1_k64f.bin", ), "0250": BoardInfo( "FRDM-KW24D512", "kw24d5", "l1_kw24d5.bin" ), "0251": BoardInfo( "FRDM-KW36", "kw36z4", "l1_kw36z.bin", ), "0260": BoardInfo( "FRDM-KL26Z", "kl26z", "l1_kl26z.bin", ), "0261": BoardInfo( "FRDM-KL27Z", "kl27z4", "l1_kl27z.bin", ), "0262": BoardInfo( "FRDM-KL43Z", "kl43z4", "l1_kl26z.bin", ), "0290": BoardInfo( "FRDM-KW40Z", "kw40z4", "l1_kw40z.bin", ), "0298": BoardInfo( "FRDM-KV10Z", "kv10z7", "l1_kl25z.bin" ), "0300": BoardInfo( "TWR-KV11Z75M", "kv11z7", "l1_kl25z.bin" ), "0311": BoardInfo( "FRDM-K66F", "k66f18", "l1_k66f.bin", ), "0320": BoardInfo( "FRDM-KW01Z9032", "kw01z4", "l1_kl26z.bin" ), "0321": BoardInfo( "USB-KW01Z", "kw01z4", "l1_kl25z.bin" ), "0324": BoardInfo( "USB-KW40Z", "kw40z4", "l1_kl25z.bin" ), "0400": BoardInfo( "MAXWSNENV", "max32600", "l1_maxwsnenv.bin", ), "0405": BoardInfo( "MAX32600MBED", "max32600", "l1_max32600mbed.bin", ), "0451": BoardInfo( "MTB MXChip EMW3166", "stm32f412xg", "mtb_mxchip_emw3166.bin",), "0459": BoardInfo( "MTB Advantech WISE-1530", "stm32f412xg", "mtb_wise-1530.bin", ), "0462": BoardInfo( "MTB USI WM-BN-BM-22", "stm32f412xg", "mtb_usi_wm-bn-bm-22.bin",), "0764": BoardInfo( "ST DISCO-L475VG-IOT01A", "stm32l475xg", "stm32l475vg_iot01a.bin",), "0824": BoardInfo( "LPCXpresso824-MAX", "lpc824", "l1_lpc824.bin", ), "0826": BoardInfo( "ST NUCLEO-F412ZG", "stm32f412xg", "nucleo_f412zg.bin", ), "1010": BoardInfo( "mbed NXP LPC1768", "lpc1768", "l1_lpc1768.bin", ), "1017": BoardInfo( "mbed HRM1017", "nrf51", "l1_nrf51.bin", ), "1018": BoardInfo( "Switch-Science-mbed-LPC824", "lpc824", "l1_lpc824.bin", ), "1019": BoardInfo( "mbed TY51822r3", "nrf51", "l1_nrf51.bin", ), "1040": BoardInfo( "mbed NXP LPC11U24", "lpc11u24", "l1_lpc11u24.bin", ), "1050": BoardInfo( "NXP LPC800-MAX", "lpc800", "l1_lpc800.bin", ), "1054": BoardInfo( "LPCXpresso54114-MAX", "lpc54114", "l1_lpc54114.bin", ), "1056": BoardInfo( "LPCXpresso54608-MAX", "lpc54608", "l1_lpc54608.bin", ), "1060": BoardInfo( "EA-LPC4088", "lpc4088qsb", "l1_lpc4088qsb.bin", ), "1062": BoardInfo( "EA-LPC4088-Display-Module", "lpc4088dm", "l1_lpc4088dm.bin", ), "1070": BoardInfo( "nRF51822-mKIT", "nrf51", "l1_nrf51.bin", ), "1080": BoardInfo( "mBuino", "lpc11u24", "l1_lpc11u24.bin", ), "1090": BoardInfo( "RedBearLab-nRF51822", "nrf51", "l1_nrf51.bin", ), "1093": BoardInfo( "RedBearLab-BLE-Nano2", "nrf52", "l1_nrf52-dk.bin", ), "1095": BoardInfo( "RedBearLab-BLE-Nano", "nrf51", "l1_nrf51.bin", ), "1100": BoardInfo( "nRF51-DK", "nrf51", "l1_nrf51-dk.bin", ), "1101": BoardInfo( "nRF52-DK", "nrf52", "l1_nrf52-dk.bin", ), "1102": BoardInfo( "nRF52840-DK", "nrf52840", "l1_nrf52840-dk.bin", ), "1114": BoardInfo( "mbed LPC1114FN28", "lpc11xx_32", "l1_mbed_LPC1114FN28.bin",), "1120": BoardInfo( "nRF51-Dongle", "nrf51", "l1_nrf51.bin", ), "1200": BoardInfo( "NCS36510-EVK", "ncs36510", "l1_ncs36510-evk.bin", ), "1234": BoardInfo( "u-blox-C027", "lpc1768", "l1_lpc1768.bin", ), "1236": BoardInfo( "u-blox EVK-ODIN-W2", "stm32f439xi", "ublox_evk_odin_w2.bin",), "1237": BoardInfo( "u-blox-EVK-NINA-B1", "nrf52", "l1_nrf52-dk.bin", ), "1600": BoardInfo( "Bambino 210", "lpc4330", "l1_lpc4330.bin", ), "1605": BoardInfo( "Bambino 210E", "lpc4330", "l1_lpc4330.bin", ), "2201": BoardInfo( "WIZwik_W7500", "w7500", "l1_w7500mbed.bin", ), "3300": BoardInfo( "CC3220SF_LaunchXL", "cc3220sf", "l1_cc3220sf.bin", ), "4600": BoardInfo( "Realtek RTL8195AM", "rtl8195am", "l1_rtl8195am.bin", ), "7402": BoardInfo( "mbed 6LoWPAN Border Router HAT", "k64f", "l1_k64f.bin", ), "9004": BoardInfo( "Arch Pro", "lpc1768", "l1_lpc1768.bin", ), "9009": BoardInfo( "Arch BLE", "nrf51", "l1_nrf51.bin", ), "9012": BoardInfo( "Seeed Tiny BLE", "nrf51", "l1_nrf51.bin", ), "9014": BoardInfo( "Seeed 96Boards Nitrogen", "nrf52", "l1_nrf52-dk.bin", ), "9900": BoardInfo( "Microbit", "nrf51", "l1_microbit.bin", ), "C004": BoardInfo( "tinyK20", "k20d50m", "l1_k20d50m.bin", ), "C006": BoardInfo( "VBLUno51", "nrf51", "l1_nrf51.bin", ), } pyocd-0.13.1/pyocd/probe/0000755000175000017500000000000013373523011015035 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/probe/debug_probe.py0000644000175000017500000001025013373511253017667 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 enum import Enum ## @brief Abstract debug probe class. class DebugProbe(object): ## @brief Debug wire protocols. class Protocol(Enum): DEFAULT = 0 SWD = 1 JTAG = 2 @classmethod def get_all_connected_probes(cls): raise NotImplementedError() @classmethod def get_probe_with_id(cls, unique_id): raise NotImplementedError() @property def description(self): return self.vendor_name + " " + self.product_name @property def vendor_name(self): raise NotImplementedError() @property def product_name(self): raise NotImplementedError() @property def supported_wire_protocols(self): raise NotImplementedError() ## @brief The unique ID of this device. # # This property will be valid before open() is called. This value can be passed to # get_probe_with_id(). @property def unique_id(self): raise NotImplementedError() ## @brief Currently selected wire protocol. # # If the probe is not connected, i.e., connect() has not been called, then this # property will be None. @property def wire_protocol(self): raise NotImplementedError() @property def is_open(self): raise NotImplementedError() ## @brief Create a board instance representing the board of which the probe is a component. # # If the probe is part of a board, then this property will be a Board instance that represents # the associated board. Usually, for an on-board debug probe, this would be the Board that # the probe physically is part of. If the probe does not have an associated board, then this # method returns None. # # @param session Session to pass to the board upon construction. def create_associated_board(self, session): return None def open(self): raise NotImplementedError() def close(self): raise NotImplementedError() # ------------------------------------------- # # Target control functions # ------------------------------------------- # def connect(self, protocol=None): """Initailize DAP IO pins for JTAG or SWD""" raise NotImplementedError() def disconnect(self): """Deinitialize the DAP I/O pins""" raise NotImplementedError() def set_clock(self, frequency): """Set the frequency for JTAG and SWD in Hz This function is safe to call before connect is called. """ raise NotImplementedError() def reset(self): """Reset the target""" raise NotImplementedError() def assert_reset(self, asserted): """Assert or de-assert target reset line""" raise NotImplementedError() def is_reset_asserted(self): """Returns True if the target reset line is asserted or False if de-asserted""" raise NotImplementedError() def flush(self): """Write out all unsent commands""" raise NotImplementedError() def read_dp(self, addr, now=True): raise NotImplementedError() def write_dp(self, addr, data): raise NotImplementedError() def read_ap(self, addr, now=True): raise NotImplementedError() def write_ap(self, addr, data): raise NotImplementedError() def read_ap_multiple(self, addr, count=1, now=True): raise NotImplementedError() def write_ap_multiple(self, addr, values): raise NotImplementedError() def get_memory_interface_for_ap(self, apsel): return None pyocd-0.13.1/pyocd/probe/aggregator.py0000644000175000017500000000303413373511253017536 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 .cmsis_dap_probe import CMSISDAPProbe from .stlink_probe import StlinkProbe PROBE_CLASSES = [ CMSISDAPProbe, StlinkProbe, ] ## @brief Simple class to enable collecting probes of all supported probe types. class DebugProbeAggregator(object): @staticmethod def get_all_connected_probes(unique_id=None): probes = [] for cls in PROBE_CLASSES: probes += cls.get_all_connected_probes() # Filter by unique ID. if unique_id is not None: unique_id = unique_id.lower() probes = [probe for probe in probes if (unique_id in probe.unique_id.lower())] return probes @classmethod def get_probe_with_id(cls, unique_id): for cls in PROBE_CLASSES: probe = cls.get_probe_with_id(unique_id) if probe is not None: return probe else: return None pyocd-0.13.1/pyocd/probe/pydapaccess/0000755000175000017500000000000013373523011017334 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/probe/pydapaccess/interface/0000755000175000017500000000000013373523011021274 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/probe/pydapaccess/interface/hidapi_backend.py0000644000175000017500000000743113373511253024565 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .interface import Interface from ..dap_access_api import DAPAccessIntf import logging import os import six log = logging.getLogger('hidapi') try: import hid except: if os.name == "posix" and os.uname()[0] == 'Darwin': log.error("cython-hidapi is required on a Mac OS X Machine") IS_AVAILABLE = False else: IS_AVAILABLE = True class HidApiUSB(Interface): """ This class provides basic functions to access a USB HID device using cython-hidapi: - write/read an endpoint """ vid = 0 pid = 0 isAvailable = IS_AVAILABLE def __init__(self): super(HidApiUSB, self).__init__() # Vendor page and usage_id = 2 self.device = None self.packet_size = 64 def open(self): try: self.device.open_path(self.device_info['path']) except IOError as exc: raise six.raise_from(DAPAccessIntf.DeviceError("Unable to open device"), exc) @staticmethod def get_all_connected_interfaces(): """ returns all the connected devices which matches HidApiUSB.vid/HidApiUSB.pid. returns an array of HidApiUSB (Interface) objects """ devices = hid.enumerate() if not devices: log.debug("No Mbed device connected") return [] boards = [] for deviceInfo in devices: product_name = deviceInfo['product_string'] if (product_name.find("CMSIS-DAP") < 0): # Skip non cmsis-dap devices continue try: dev = hid.device(vendor_id=deviceInfo['vendor_id'], product_id=deviceInfo['product_id'], path=deviceInfo['path']) except IOError: log.debug("Failed to open Mbed device") continue # Create the USB interface object for this device. new_board = HidApiUSB() new_board.vendor_name = deviceInfo['manufacturer_string'] new_board.product_name = deviceInfo['product_string'] new_board.serial_number = deviceInfo['serial_number'] new_board.vid = deviceInfo['vendor_id'] new_board.pid = deviceInfo['product_id'] new_board.device_info = deviceInfo new_board.device = dev boards.append(new_board) return boards def write(self, data): """ write data on the OUT endpoint associated to the HID interface """ for _ in range(self.packet_size - len(data)): data.append(0) #logging.debug("send: %s", data) self.device.write([0] + data) return def read(self, timeout=-1): """ read data on the IN endpoint associated to the HID interface """ return self.device.read(self.packet_size) def get_serial_number(self): return self.serial_number def close(self): """ close the interface """ log.debug("closing interface") self.device.close() def set_packet_count(self, count): # No interface level restrictions on count self.packet_count = count def set_packet_size(self, size): self.packet_size = size pyocd-0.13.1/pyocd/probe/pydapaccess/interface/pywinusb_backend.py0000644000175000017500000001340613373511253025206 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .interface import Interface from ..dap_access_api import DAPAccessIntf import logging import os import collections from time import time import six OPEN_TIMEOUT_S = 60.0 log = logging.getLogger('pywinusb') try: import pywinusb.hid as hid except: if os.name == "nt": log.error("PyWinUSB is required on a Windows Machine") IS_AVAILABLE = False else: IS_AVAILABLE = True class PyWinUSB(Interface): """ This class provides basic functions to access a USB HID device using pywinusb: - write/read an endpoint """ vid = 0 pid = 0 isAvailable = IS_AVAILABLE def __init__(self): super(PyWinUSB, self).__init__() # Vendor page and usage_id = 2 self.report = [] # deque used here instead of synchronized Queue # since read speeds are ~10-30% faster and are # comprable to a based list implmentation. self.rcv_data = collections.deque() self.device = None self.packet_size = 64 # handler called when a report is received def rx_handler(self, data): #logging.debug("rcv: %s", data[1:]) self.rcv_data.append(data[1:]) def open(self): self.device.set_raw_data_handler(self.rx_handler) # Attempt to open the device. # Note - this operation must be retried since # other instances of pyOCD listing board can prevent # opening this device with exclusive access. start = time() while True: # Attempt to open the device try: self.device.open(shared=False) break except hid.HIDError: pass # Attempt to open the device in shared mode to make # sure it is still there try: self.device.open(shared=True) self.device.close() except hid.HIDError as exc: # If the device could not be opened in read only mode # Then it either has been disconnected or is in use # by another thread/process raise six.raise_from(DAPAccessIntf.DeviceError("Unable to open device"), exc) if time() - start > OPEN_TIMEOUT_S: # If this timeout has elapsed then another process # has locked this device in shared mode. This should # not happen. assert False break @staticmethod def get_all_connected_interfaces(): """ returns all the connected CMSIS-DAP devices """ all_devices = hid.find_all_hid_devices() # find devices with good vid/pid all_mbed_devices = [] for d in all_devices: if (d.product_name.find("CMSIS-DAP") >= 0): all_mbed_devices.append(d) boards = [] for dev in all_mbed_devices: try: dev.open(shared=True) report = dev.find_output_reports() if len(report) != 1: dev.close() continue new_board = PyWinUSB() new_board.report = report[0] new_board.vendor_name = dev.vendor_name new_board.product_name = dev.product_name new_board.serial_number = dev.serial_number new_board.vid = dev.vendor_id new_board.pid = dev.product_id new_board.device = dev dev.close() boards.append(new_board) except Exception as e: if (str(e) != "Failure to get HID pre parsed data"): log.error("Receiving Exception: %s", e) dev.close() return boards def write(self, data): """ write data on the OUT endpoint associated to the HID interface """ for _ in range(self.packet_size - len(data)): data.append(0) #logging.debug("send: %s", data) self.report.send([0] + data) return def read(self, timeout=20.0): """ read data on the IN endpoint associated to the HID interface """ start = time() while len(self.rcv_data) == 0: if time() - start > timeout: # Read operations should typically take ~1-2ms. # If this exception occurs, then it could indicate # a problem in one of the following areas: # 1. Bad usb driver causing either a dropped read or write # 2. CMSIS-DAP firmware problem cause a dropped read or write # 3. CMSIS-DAP is performing a long operation or is being # halted in a debugger raise DAPAccessIntf.DeviceError("Read timed out") return self.rcv_data.popleft() def set_packet_count(self, count): # No interface level restrictions on count self.packet_count = count def set_packet_size(self, size): self.packet_size = size def get_serial_number(self): return self.serial_number def close(self): """ close the interface """ log.debug("closing interface") self.device.close() pyocd-0.13.1/pyocd/probe/pydapaccess/interface/__init__.py0000644000175000017500000000373113373511253023416 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ import os import logging from .hidapi_backend import HidApiUSB from .pyusb_backend import PyUSB from .pywinusb_backend import PyWinUSB from .ws_backend import WebSocketInterface INTERFACE = { 'hidapiusb': HidApiUSB, 'pyusb': PyUSB, 'pywinusb': PyWinUSB, 'ws': WebSocketInterface } # Allow user to override backend with an environment variable. USB_BACKEND = os.getenv('PYOCD_USB_BACKEND', "") # pylint: disable=invalid-name WS_BACKEND = "ws" # Check validity of backend env var. if USB_BACKEND and ((USB_BACKEND not in INTERFACE) or (not INTERFACE[USB_BACKEND].isAvailable)): logging.error("Invalid USB backend specified in PYOCD_USB_BACKEND: " + USB_BACKEND) USB_BACKEND = "" # Select backend based on OS and availability. if not USB_BACKEND: if os.name == "nt": # Prefer hidapi over pyWinUSB for Windows, since pyWinUSB has known bug(s) if HidApiUSB.isAvailable: USB_BACKEND = "hidapiusb" elif PyWinUSB.isAvailable: USB_BACKEND = "pywinusb" else: raise Exception("No USB backend found") elif os.name == "posix": # Select hidapi for OS X and pyUSB for Linux. if os.uname()[0] == 'Darwin': USB_BACKEND = "hidapiusb" else: USB_BACKEND = "pyusb" else: raise Exception("No USB backend found") pyocd-0.13.1/pyocd/probe/pydapaccess/interface/interface.py0000644000175000017500000000250313373511253023613 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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. """ class Interface(object): def __init__(self): self.vid = 0 self.pid = 0 self.vendor_name = "" self.product_name = "" self.packet_count = 1 def open(self): return def write(self, data): return def read(self, size=-1, timeout=-1): return def get_info(self): return self.vendor_name + " " + \ self.product_name + " (" + \ str(hex(self.vid)) + ", " + \ str(hex(self.pid)) + ")" def set_packet_count(self, count): # Unless overridden the packet count cannot be changed return def get_packet_count(self): return self.packet_count def close(self): return pyocd-0.13.1/pyocd/probe/pydapaccess/interface/pyusb_backend.py0000644000175000017500000002220613373511253024466 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .interface import Interface from ..dap_access_api import DAPAccessIntf import logging import os import threading import six log = logging.getLogger('pyusb') try: import usb.core import usb.util except: if os.name == "posix" and not os.uname()[0] == 'Darwin': log.error("PyUSB is required on a Linux Machine") IS_AVAILABLE = False else: IS_AVAILABLE = True class PyUSB(Interface): """ This class provides basic functions to access a USB HID device using pyusb: - write/read an endpoint """ isAvailable = IS_AVAILABLE def __init__(self): super(PyUSB, self).__init__() self.ep_out = None self.ep_in = None self.dev = None self.intf_number = None self.serial_number = None self.kernel_driver_was_attached = False self.closed = True self.thread = None self.rcv_data = [] self.read_sem = threading.Semaphore(0) self.packet_size = 64 def open(self): assert self.closed is True # Get device handle dev = usb.core.find(custom_match=FindDap(self.serial_number)) if dev is None: raise DAPAccessIntf.DeviceError("Device %s not found" % self.serial_number) # get active config config = dev.get_active_configuration() # Get hid interface interface = None interface_number = None for interface in config: if interface.bInterfaceClass == 0x03: interface_number = interface.bInterfaceNumber break if interface_number is None or interface is None: raise DAPAccessIntf.DeviceError("Device %s has no hid interface" % self.serial_number) # Find endpoints ep_in, ep_out = None, None for endpoint in interface: if endpoint.bEndpointAddress & 0x80: ep_in = endpoint else: ep_out = endpoint # If there is no EP for OUT then we can use CTRL EP. # The IN EP is required if not ep_in: raise DAPAccessIntf.DeviceError("Unable to open device -" " no endpoints") # Detach kernel driver kernel_driver_was_attached = False try: if dev.is_kernel_driver_active(interface_number): dev.detach_kernel_driver(interface_number) kernel_driver_was_attached = True except NotImplementedError as e: # Some implementations don't don't have kernel attach/detach log.debug('Exception detaching kernel driver: %s' % str(e)) # Explicitly claim the interface try: usb.util.claim_interface(dev, interface_number) except usb.core.USBError as exc: raise six.raise_from(DAPAccessIntf.DeviceError("Unable to open device"), exc) # Update all class variables if we made it here self.ep_out = ep_out self.ep_in = ep_in self.dev = dev self.intf_number = interface_number self.kernel_driver_was_attached = kernel_driver_was_attached # Start RX thread as the last step self.closed = False self.start_rx() def start_rx(self): # Flush the RX buffers by reading until timeout exception try: while True: self.ep_in.read(self.ep_in.wMaxPacketSize, 1) except usb.core.USBError: # USB timeout expected pass # Start RX thread self.thread = threading.Thread(target=self.rx_task) self.thread.daemon = True self.thread.start() def rx_task(self): try: while not self.closed: self.read_sem.acquire() if not self.closed: self.rcv_data.append(self.ep_in.read(self.ep_in.wMaxPacketSize, 10 * 1000)) finally: # Set last element of rcv_data to None on exit self.rcv_data.append(None) @staticmethod def get_all_connected_interfaces(): """ returns all the connected devices which matches PyUSB.vid/PyUSB.pid. returns an array of PyUSB (Interface) objects """ # find all cmsis-dap devices all_devices = usb.core.find(find_all=True, custom_match=FindDap()) # iterate on all devices found boards = [] for board in all_devices: new_board = PyUSB() new_board.vid = board.idVendor new_board.pid = board.idProduct new_board.product_name = board.product new_board.vendor_name = board.manufacturer new_board.serial_number = board.serial_number boards.append(new_board) return boards def write(self, data): """ write data on the OUT endpoint associated to the HID interface """ report_size = self.packet_size if self.ep_out: report_size = self.ep_out.wMaxPacketSize for _ in range(report_size - len(data)): data.append(0) self.read_sem.release() if not self.ep_out: bmRequestType = 0x21 #Host to device request of type Class of Recipient Interface bmRequest = 0x09 #Set_REPORT (HID class-specific request for transferring data over EP0) wValue = 0x200 #Issuing an OUT report wIndex = self.intf_number #mBed Board interface number for HID self.dev.ctrl_transfer(bmRequestType, bmRequest, wValue, wIndex, data) return #raise ValueError('EP_OUT endpoint is NULL') self.ep_out.write(data) #logging.debug('sent: %s', data) return def read(self): """ read data on the IN endpoint associated to the HID interface """ while len(self.rcv_data) == 0: pass if self.rcv_data[0] is None: raise DAPAccessIntf.DeviceError("Device %s read thread exited" % self.serial_number) return self.rcv_data.pop(0) def set_packet_count(self, count): # No interface level restrictions on count self.packet_count = count def set_packet_size(self, size): self.packet_size = size def get_serial_number(self): return self.serial_number def close(self): """ close the interface """ assert self.closed is False log.debug("closing interface") self.closed = True self.read_sem.release() self.thread.join() assert self.rcv_data[-1] is None self.rcv_data = [] usb.util.release_interface(self.dev, self.intf_number) if self.kernel_driver_was_attached: try: self.dev.attach_kernel_driver(self.intf_number) except Exception as exception: log.warning('Exception attaching kernel driver: %s', str(exception)) usb.util.dispose_resources(self.dev) self.ep_out = None self.ep_in = None self.dev = None self.intf_number = None self.kernel_driver_was_attached = False self.thread = None class FindDap(object): """CMSIS-DAP match class to be used with usb.core.find""" def __init__(self, serial=None): """Create a new FindDap object with an optional serial number""" self._serial = serial def __call__(self, dev): """Return True if this is a DAP device, False otherwise""" try: device_string = dev.product except ValueError as error: # Permission denied error gets reported as ValueError (langid) log.debug(("ValueError \"{}\" while trying to access dev.product " "for idManufacturer=0x{:04x} idProduct=0x{:04x}. " "This is probably a permission issue.").format(error, dev.idVendor, dev.idProduct)) return False except usb.core.USBError as error: log.warning("Exception getting product string: %s", error) return False except IndexError as error: log.warning("Internal pyusb error: %s", error) return False if device_string is None: return False if device_string.find("CMSIS-DAP") < 0: return False if self._serial is not None: if self._serial != dev.serial_number: return False return True pyocd-0.13.1/pyocd/probe/pydapaccess/interface/ws_backend.py0000644000175000017500000000306713373511253023761 0ustar neilneil00000000000000 from future.utils import bytes_to_native_str from future.builtins import bytes from base64 import b64encode, b64decode from websocket import create_connection from .interface import Interface class WebSocketInterface(Interface): def __init__(self, host='localhost', port=8081): super(WebSocketInterface,self).__init__() self.connected = False try: self.ws = create_connection('ws://%s:%i' % (host, port)) self.ws.settimeout(None) self.connected = True except: self.connected = False def write(self, data): self.ws.send(b64encode(bytes_to_native_str(bytes(data)))) def read(self): #It will wait on recv() until data is sent over websocket rawdata = self.ws.recv() #Data is sent in base64 string data = b64decode(rawdata) data = [ord(c) for c in data] return data def set_packet_count(self, count): self.packet_count = count def close(self): self.ws.close() def get_unique_id(self): """Get the unique id from an interface""" self.write([0x80]) raw_id = bytearray(self.read()) id_start = 2 id_size = raw_id[1] unique_id = str(raw_id[id_start:id_start + id_size]) return unique_id def get_serial_number(self): return self.get_unique_id() @staticmethod def get_all_connected_interfaces(host,port): ws = WebSocketInterface(host,port) if ws.connected: return [ws] else: return [] pyocd-0.13.1/pyocd/probe/pydapaccess/dap_access_cmsis_dap.py0000644000175000017500000010123113373511253024020 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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 re import logging import time import collections import six from .dap_settings import DAPSettings from .dap_access_api import DAPAccessIntf from .cmsis_dap_core import CMSISDAPProtocol from .interface import (INTERFACE, USB_BACKEND, WS_BACKEND) from .cmsis_dap_core import (Command, Pin, DAP_TRANSFER_OK, DAP_TRANSFER_FAULT, DAP_TRANSFER_WAIT) # CMSIS-DAP values AP_ACC = 1 << 0 DP_ACC = 0 << 0 READ = 1 << 1 WRITE = 0 << 1 VALUE_MATCH = 1 << 4 MATCH_MASK = 1 << 5 # Set to True to enable logging of packet filling logic. LOG_PACKET_BUILDS = False def _get_interfaces(): """Get the connected USB devices""" if DAPSettings.use_ws: return INTERFACE[WS_BACKEND].get_all_connected_interfaces(DAPSettings.ws_host, DAPSettings.ws_port) else: return INTERFACE[USB_BACKEND].get_all_connected_interfaces() def _get_unique_id(interface): """Get the unique id from an interface""" return interface.get_serial_number() class _Transfer(object): """ A wrapper object representing a command invoked by the layer above. The transfer class contains a logical register read or a block of reads to the same register. """ def __init__(self, daplink, dap_index, transfer_count, transfer_request, transfer_data): # Writes should not need a transfer object # since they don't have any response data assert isinstance(dap_index, six.integer_types) assert isinstance(transfer_count, six.integer_types) assert isinstance(transfer_request, six.integer_types) assert transfer_request & READ self.daplink = daplink self.dap_index = dap_index self.transfer_count = transfer_count self.transfer_request = transfer_request self.transfer_data = transfer_data self._size_bytes = 0 if transfer_request & READ: self._size_bytes = transfer_count * 4 self._result = None self._error = None def get_data_size(self): """ Get the size in bytes of the return value of this transfer """ return self._size_bytes def add_response(self, data): """ Add data read from the remote device to this object. The size of data added must match exactly the size that get_data_size returns. """ assert len(data) == self._size_bytes result = [] for i in range(0, self._size_bytes, 4): word = ((data[0 + i] << 0) | (data[1 + i] << 8) | (data[2 + i] << 16) | (data[3 + i] << 24)) result.append(word) self._result = result def add_error(self, error): """ Attach an exception to this transfer rather than data. """ assert isinstance(error, Exception) self._error = error def get_result(self): """ Get the result of this transfer. """ while self._result is None: if len(self.daplink._commands_to_read) > 0: self.daplink._read_packet() else: assert not self.daplink._crnt_cmd.get_empty() self.daplink.flush() if self._error is not None: # Pylint is confused and thinks self._error is None # since that is what it is initialized to. # Supress warnings for this. # pylint: disable=raising-bad-type raise self._error assert self._result is not None return self._result class _Command(object): """ A wrapper object representing a command send to the layer below (ex. USB). This class wraps the phyiscal commands DAP_Transfer and DAP_TransferBlock to provide a uniform way to build the command to most efficiently transfer the data supplied. Register reads and writes individually or in blocks are added to a command object until it is full. Once full, this class decides if it is more efficient to use DAP_Transfer or DAP_TransferBlock. The payload to send over the layer below is constructed with encode_data. The response to the command is decoded with decode_data. """ def __init__(self, size): self._size = size self._read_count = 0 self._write_count = 0 self._block_allowed = True self._block_request = None self._data = [] self._dap_index = None self._data_encoded = False if LOG_PACKET_BUILDS: self._logger = logging.getLogger(__name__) self._logger.debug("New _Command") def _get_free_words(self, blockAllowed, isRead): """ Return the number of words free in the transmit packet """ if blockAllowed: # DAP_TransferBlock request packet: # BYTE | BYTE *****| SHORT**********| BYTE *************| WORD *********| # > 0x06 | DAP Index | Transfer Count | Transfer Request | Transfer Data | # ******|***********|****************|*******************|+++++++++++++++| send = self._size - 5 - 4 * self._write_count # DAP_TransferBlock response packet: # BYTE | SHORT *********| BYTE *************| WORD *********| # < 0x06 | Transfer Count | Transfer Response | Transfer Data | # ******|****************|*******************|+++++++++++++++| recv = self._size - 4 - 4 * self._read_count if isRead: return recv // 4 else: return send // 4 else: # DAP_Transfer request packet: # BYTE | BYTE *****| BYTE **********| BYTE *************| WORD *********| # > 0x05 | DAP Index | Transfer Count | Transfer Request | Transfer Data | # ******|***********|****************|+++++++++++++++++++++++++++++++++++| send = self._size - 3 - 1 * self._read_count - 5 * self._write_count # DAP_Transfer response packet: # BYTE | BYTE **********| BYTE *************| WORD *********| # < 0x05 | Transfer Count | Transfer Response | Transfer Data | # ******|****************|*******************|+++++++++++++++| recv = self._size - 3 - 4 * self._read_count if isRead: # 1 request byte in request packet, 4 data bytes in response packet return min(send, recv // 4) else: # 1 request byte + 4 data bytes return send // 5 def get_request_space(self, count, request, dap_index): assert self._data_encoded is False # Must create another command if the dap index is different. if self._dap_index is not None and dap_index != self._dap_index: return 0 # Block transfers must use the same request. blockAllowed = self._block_allowed if self._block_request is not None and request != self._block_request: blockAllowed = False # Compute the portion of the request that will fit in this packet. is_read = request & READ free = self._get_free_words(blockAllowed, is_read) size = min(count, free) # Non-block transfers only have 1 byte for request count. if not blockAllowed: max_count = self._write_count + self._read_count + size delta = max_count - 255 size = min(size - delta, size) if LOG_PACKET_BUILDS: self._logger.debug("get_request_space(%d, %02x:%s)[wc=%d, rc=%d, ba=%d->%d] -> (sz=%d, free=%d, delta=%d)" % (count, request, 'r' if is_read else 'w', self._write_count, self._read_count, self._block_allowed, blockAllowed, size, free, delta)) elif LOG_PACKET_BUILDS: self._logger.debug("get_request_space(%d, %02x:%s)[wc=%d, rc=%d, ba=%d->%d] -> (sz=%d, free=%d)" % (count, request, 'r' if is_read else 'w', self._write_count, self._read_count, self._block_allowed, blockAllowed, size, free)) # We can get a negative free count if the packet already contains more data than can be # sent by a DAP_Transfer command, but the new request forces DAP_Transfer. In this case, # just return 0 to force the DAP_Transfer_Block to be sent. return max(size, 0) def get_full(self): return (self._get_free_words(self._block_allowed, True) == 0) or \ (self._get_free_words(self._block_allowed, False) == 0) def get_empty(self): """ Return True if no transfers have been added to this packet """ return len(self._data) == 0 def add(self, count, request, data, dap_index): """ Add a single or block register transfer operation to this command """ assert self._data_encoded is False if self._dap_index is None: self._dap_index = dap_index assert self._dap_index == dap_index if self._block_request is None: self._block_request = request elif request != self._block_request: self._block_allowed = False assert not self._block_allowed or self._block_request == request if request & READ: self._read_count += count else: self._write_count += count self._data.append((count, request, data)) if LOG_PACKET_BUILDS: self._logger.debug("add(%d, %02x:%s) -> [wc=%d, rc=%d, ba=%d]" % (count, request, 'r' if (request & READ) else 'w', self._write_count, self._read_count, self._block_allowed)) def _encode_transfer_data(self): """ Encode this command into a byte array that can be sent The data returned by this function is a bytearray in the format that of a DAP_Transfer CMSIS-DAP command. """ assert self.get_empty() is False buf = bytearray(self._size) transfer_count = self._read_count + self._write_count pos = 0 buf[pos] = Command.DAP_TRANSFER pos += 1 buf[pos] = self._dap_index pos += 1 buf[pos] = transfer_count pos += 1 for count, request, write_list in self._data: assert write_list is None or len(write_list) <= count write_pos = 0 for _ in range(count): buf[pos] = request pos += 1 if not request & READ: buf[pos] = (write_list[write_pos] >> (8 * 0)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 1)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 2)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 3)) & 0xff pos += 1 write_pos += 1 return buf def _decode_transfer_data(self, data): """ Take a byte array and extract the data from it Decode the response returned by a DAP_Transfer CMSIS-DAP command and return it as an array of bytes. """ assert self.get_empty() is False if data[0] != Command.DAP_TRANSFER: raise ValueError('DAP_TRANSFER response error') if data[2] != DAP_TRANSFER_OK: if data[2] == DAP_TRANSFER_FAULT: raise DAPAccessIntf.TransferFaultError() elif data[2] == DAP_TRANSFER_WAIT: raise DAPAccessIntf.TransferTimeoutError() raise DAPAccessIntf.TransferError() # Check for count mismatch after checking for DAP_TRANSFER_FAULT # This allows TransferFaultError or TransferTimeoutError to get # thrown instead of TransferFaultError if data[1] != self._read_count + self._write_count: raise DAPAccessIntf.TransferError() return data[3:3 + 4 * self._read_count] def _encode_transfer_block_data(self): """ Encode this command into a byte array that can be sent The data returned by this function is a bytearray in the format that of a DAP_TransferBlock CMSIS-DAP command. """ assert self.get_empty() is False buf = bytearray(self._size) transfer_count = self._read_count + self._write_count assert not (self._read_count != 0 and self._write_count != 0) assert self._block_request is not None pos = 0 buf[pos] = Command.DAP_TRANSFER_BLOCK pos += 1 buf[pos] = self._dap_index pos += 1 buf[pos] = transfer_count & 0xff pos += 1 buf[pos] = (transfer_count >> 8) & 0xff pos += 1 buf[pos] = self._block_request pos += 1 for count, request, write_list in self._data: assert write_list is None or len(write_list) <= count assert request == self._block_request write_pos = 0 if not request & READ: for _ in range(count): buf[pos] = (write_list[write_pos] >> (8 * 0)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 1)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 2)) & 0xff pos += 1 buf[pos] = (write_list[write_pos] >> (8 * 3)) & 0xff pos += 1 write_pos += 1 return buf def _decode_transfer_block_data(self, data): """ Take a byte array and extract the data from it Decode the response returned by a DAP_TransferBlock CMSIS-DAP command and return it as an array of bytes. """ assert self.get_empty() is False if data[0] != Command.DAP_TRANSFER_BLOCK: raise ValueError('DAP_TRANSFER_BLOCK response error') if data[3] != DAP_TRANSFER_OK: if data[3] == DAP_TRANSFER_FAULT: raise DAPAccessIntf.TransferFaultError() elif data[3] == DAP_TRANSFER_WAIT: raise DAPAccessIntf.TransferTimeoutError() raise DAPAccessIntf.TransferError() # Check for count mismatch after checking for DAP_TRANSFER_FAULT # This allows TransferFaultError or TransferTimeoutError to get # thrown instead of TransferFaultError transfer_count = data[1] | (data[2] << 8) if transfer_count != self._read_count + self._write_count: raise DAPAccessIntf.TransferError() return data[4:4 + 4 * self._read_count] def encode_data(self): """ Encode this command into a byte array that can be sent The actual command this is encoded into depends on the data that was added. """ assert self.get_empty() is False self._data_encoded = True if self._block_allowed: data = self._encode_transfer_block_data() else: data = self._encode_transfer_data() return data def decode_data(self, data): """ Decode the response data """ assert self.get_empty() is False assert self._data_encoded is True if self._block_allowed: data = self._decode_transfer_block_data(data) else: data = self._decode_transfer_data(data) return data class DAPAccessCMSISDAP(DAPAccessIntf): """ An implementation of the DAPAccessIntf layer for DAPLINK boards """ # ------------------------------------------- # # Static Functions # ------------------------------------------- # @staticmethod def get_connected_devices(): """ Return an array of all mbed boards connected """ all_daplinks = [] all_interfaces = _get_interfaces() for interface in all_interfaces: try: new_daplink = DAPAccessCMSISDAP(None, interface=interface) all_daplinks.append(new_daplink) except DAPAccessIntf.TransferError: logger = logging.getLogger(__name__) logger.error('Failed to get unique id', exc_info=True) return all_daplinks @staticmethod def get_device(device_id): assert isinstance(device_id, six.string_types) return DAPAccessCMSISDAP(device_id) @staticmethod def set_args(arg_list): # Example: arg_list =['use_ws=True', 'ws_host=localhost', 'ws_port=8081'] arg_pattern = re.compile("([^=]+)=(.*)") if arg_list: for arg in arg_list: match = arg_pattern.match(arg) # check if arguments have correct format if match: attr = match.group(1) if hasattr(DAPSettings, attr): val = match.group(2) # convert string to int or bool if val.isdigit(): val = int(val) elif val == "True": val = True elif val == "False": val = False setattr(DAPSettings, attr, val) # ------------------------------------------- # # CMSIS-DAP and Other Functions # ------------------------------------------- # def __init__(self, unique_id, interface=None): assert isinstance(unique_id, six.string_types) or (unique_id is None and interface is not None) super(DAPAccessCMSISDAP, self).__init__() if interface is not None: self._unique_id = _get_unique_id(interface) self._vendor_name = interface.vendor_name self._product_name = interface.product_name else: self._unique_id = unique_id self._vendor_name = "" self._product_name = "" self._interface = None self._deferred_transfer = False self._protocol = None # TODO, c1728p9 remove when no longer needed self._packet_count = None self._frequency = 1000000 # 1MHz default clock self._dap_port = None self._transfer_list = None self._crnt_cmd = None self._packet_size = None self._commands_to_read = None self._command_response_buf = None self._logger = logging.getLogger(__name__) @property def vendor_name(self): return self._vendor_name @property def product_name(self): return self._product_name def open(self): if self._interface is None: all_interfaces = _get_interfaces() for interface in all_interfaces: try: unique_id = _get_unique_id(interface) if self._unique_id == unique_id: # This assert could indicate that two boards # had the same ID assert self._interface is None self._interface = interface except Exception: self._logger.error('Failed to get unique id for open', exc_info=True) if self._interface is None: raise DAPAccessIntf.DeviceError("Unable to open device") self._vendor_name = self._interface.vendor_name self._product_name = self._interface.product_name self._interface.open() self._protocol = CMSISDAPProtocol(self._interface) if DAPSettings.limit_packets: self._packet_count = 1 self._logger.debug("Limiting packet count to %d", self._packet_count) else: self._packet_count = self._protocol.dap_info(self.ID.MAX_PACKET_COUNT) self._interface.set_packet_count(self._packet_count) self._packet_size = self._protocol.dap_info(self.ID.MAX_PACKET_SIZE) self._interface.set_packet_size(self._packet_size) self._init_deferred_buffers() def close(self): assert self._interface is not None self.flush() self._interface.close() def get_unique_id(self): return self._unique_id def reset(self): self.flush() self._protocol.set_swj_pins(0, Pin.nRESET) time.sleep(0.1) self._protocol.set_swj_pins(Pin.nRESET, Pin.nRESET) time.sleep(0.1) def assert_reset(self, asserted): self.flush() if asserted: self._protocol.set_swj_pins(0, Pin.nRESET) else: self._protocol.set_swj_pins(Pin.nRESET, Pin.nRESET) def is_reset_asserted(self): self.flush() pins = self._protocol.set_swj_pins(0, Pin.NONE) return (pins & Pin.nRESET) == 0 def set_clock(self, frequency): self.flush() self._protocol.set_swj_clock(frequency) self._frequency = frequency def get_swj_mode(self): return self._dap_port def set_deferred_transfer(self, enable): """ Allow transfers to be delayed and buffered By default deferred transfers are turned off. All reads and writes will be completed by the time the function returns. When enabled packets are buffered and sent all at once, which increases speed. When memory is written to, the transfer might take place immediately, or might take place on a future memory write. This means that an invalid write could cause an exception to occur on a later, unrelated write. To guarantee that previous writes are complete call the flush() function. The behaviour of read operations is determined by the modes READ_START, READ_NOW and READ_END. The option READ_NOW is the default and will cause the read to flush all previous writes, and read the data immediately. To improve performance, multiple reads can be made using READ_START and finished later with READ_NOW. This allows the reads to be buffered and sent at once. Note - All READ_ENDs must be called before a call using READ_NOW can be made. """ if self._deferred_transfer and not enable: self.flush() self._deferred_transfer = enable def flush(self): # Send current packet self._send_packet() # Read all backlogged for _ in range(len(self._commands_to_read)): self._read_packet() def identify(self, item): assert isinstance(item, DAPAccessIntf.ID) return self._protocol.dap_info(item) def vendor(self, index, data=None): if data is None: data = [] return self._protocol.vendor(index, data) # ------------------------------------------- # # Target access functions # ------------------------------------------- # def connect(self, port=DAPAccessIntf.PORT.DEFAULT): assert isinstance(port, DAPAccessIntf.PORT) actual_port = self._protocol.connect(port.value) self._dap_port = DAPAccessIntf.PORT(actual_port) # set clock frequency self._protocol.set_swj_clock(self._frequency) # configure transfer self._protocol.transfer_configure() def swj_sequence(self): if self._dap_port == DAPAccessIntf.PORT.SWD: # configure swd protocol self._protocol.swd_configure() # switch from jtag to swd self._jtag_to_swd() elif self._dap_port == DAPAccessIntf.PORT.JTAG: # configure jtag protocol self._protocol.jtag_configue(4) # Test logic reset, run test idle self._protocol.swj_sequence([0x1F]) else: assert False def disconnect(self): self.flush() self._protocol.disconnect() def write_reg(self, reg_id, value, dap_index=0): assert reg_id in self.REG assert isinstance(value, six.integer_types) assert isinstance(dap_index, six.integer_types) request = WRITE if reg_id.value < 4: request |= DP_ACC else: request |= AP_ACC request |= (reg_id.value % 4) * 4 self._write(dap_index, 1, request, [value]) def read_reg(self, reg_id, dap_index=0, now=True): assert reg_id in self.REG assert isinstance(dap_index, six.integer_types) assert isinstance(now, bool) request = READ if reg_id.value < 4: request |= DP_ACC else: request |= AP_ACC request |= (reg_id.value % 4) << 2 transfer = self._write(dap_index, 1, request, None) assert transfer is not None def read_reg_cb(): res = transfer.get_result() assert len(res) == 1 res = res[0] return res if now: return read_reg_cb() else: return read_reg_cb def reg_write_repeat(self, num_repeats, reg_id, data_array, dap_index=0): assert isinstance(num_repeats, six.integer_types) assert num_repeats == len(data_array) assert reg_id in self.REG assert isinstance(dap_index, six.integer_types) request = WRITE if reg_id.value < 4: request |= DP_ACC else: request |= AP_ACC request |= (reg_id.value % 4) * 4 self._write(dap_index, num_repeats, request, data_array) def reg_read_repeat(self, num_repeats, reg_id, dap_index=0, now=True): assert isinstance(num_repeats, six.integer_types) assert reg_id in self.REG assert isinstance(dap_index, six.integer_types) assert isinstance(now, bool) request = READ if reg_id.value < 4: request |= DP_ACC else: request |= AP_ACC request |= (reg_id.value % 4) * 4 transfer = self._write(dap_index, num_repeats, request, None) assert transfer is not None def reg_read_repeat_cb(): res = transfer.get_result() assert len(res) == num_repeats return res if now: return reg_read_repeat_cb() else: return reg_read_repeat_cb # ------------------------------------------- # # Private functions # ------------------------------------------- # def _init_deferred_buffers(self): """ Initialize or reinitalize all the deferred transfer buffers Calling this method will drop all pending transactions so use with care. """ # List of transfers that have been started, but # not completed (started by write_reg, read_reg, # reg_write_repeat and reg_read_repeat) self._transfer_list = collections.deque() # The current packet - this can contain multiple # different transfers self._crnt_cmd = _Command(self._packet_size) # Packets that have been sent but not read self._commands_to_read = collections.deque() # Buffer for data returned for completed commands. # This data will be added to transfers self._command_response_buf = bytearray() def _read_packet(self): """ Reads and decodes a single packet Reads a single packet from the device and stores the data from it in the current Command object """ # Grab command, send it and decode response cmd = self._commands_to_read.popleft() try: raw_data = self._interface.read() raw_data = bytearray(raw_data) decoded_data = cmd.decode_data(raw_data) except Exception as exception: self._abort_all_transfers(exception) raise decoded_data = bytearray(decoded_data) self._command_response_buf.extend(decoded_data) # Attach data to transfers pos = 0 while True: size_left = len(self._command_response_buf) - pos if size_left == 0: # If size left is 0 then the transfer list might # be empty, so don't try to access element 0 break transfer = self._transfer_list[0] size = transfer.get_data_size() if size > size_left: break self._transfer_list.popleft() data = self._command_response_buf[pos:pos + size] pos += size transfer.add_response(data) # Remove used data from _command_response_buf if pos > 0: self._command_response_buf = self._command_response_buf[pos:] def _send_packet(self): """ Send a single packet to the interface This function guarentees that the number of packets that are stored in daplink's buffer (the number of packets written but not read) does not exceed the number supported by the given device. """ cmd = self._crnt_cmd if cmd.get_empty(): return max_packets = self._interface.get_packet_count() if len(self._commands_to_read) >= max_packets: self._read_packet() data = cmd.encode_data() try: self._interface.write(list(data)) except Exception as exception: self._abort_all_transfers(exception) raise self._commands_to_read.append(cmd) self._crnt_cmd = _Command(self._packet_size) def _write(self, dap_index, transfer_count, transfer_request, transfer_data): """ Write one or more commands """ assert dap_index == 0 # dap index currently unsupported assert isinstance(transfer_count, six.integer_types) assert isinstance(transfer_request, six.integer_types) assert transfer_data is None or len(transfer_data) > 0 # Create transfer and add to transfer list transfer = None if transfer_request & READ: transfer = _Transfer(self, dap_index, transfer_count, transfer_request, transfer_data) self._transfer_list.append(transfer) # Build physical packet by adding it to command cmd = self._crnt_cmd is_read = transfer_request & READ size_to_transfer = transfer_count trans_data_pos = 0 while size_to_transfer > 0: # Get the size remaining in the current packet for the given request. size = cmd.get_request_space(size_to_transfer, transfer_request, dap_index) # This request doesn't fit in the packet so send it. if size == 0: if LOG_PACKET_BUILDS: self._logger.debug("_write: send packet [size==0]") self._send_packet() cmd = self._crnt_cmd continue # Add request to packet. if transfer_data is None: data = None else: data = transfer_data[trans_data_pos:trans_data_pos + size] cmd.add(size, transfer_request, data, dap_index) size_to_transfer -= size trans_data_pos += size # Packet has been filled so send it if cmd.get_full(): if LOG_PACKET_BUILDS: self._logger.debug("_write: send packet [full]") self._send_packet() cmd = self._crnt_cmd if not self._deferred_transfer: self.flush() return transfer def _jtag_to_swd(self): """ Send the command to switch from SWD to jtag """ data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self._protocol.swj_sequence(data) data = [0x9e, 0xe7] self._protocol.swj_sequence(data) data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self._protocol.swj_sequence(data) data = [0x00] self._protocol.swj_sequence(data) def _abort_all_transfers(self, exception): """ Abort any ongoing transfers and clear all buffers """ pending_reads = len(self._commands_to_read) # invalidate _transfer_list for transfer in self._transfer_list: transfer.add_error(exception) # clear all deferred buffers self._init_deferred_buffers() # finish all pending reads and ignore the data # Only do this if the error is a tranfer error. # Otherwise this could cause another exception if isinstance(exception, DAPAccessIntf.TransferError): for _ in range(pending_reads): self._interface.read() pyocd-0.13.1/pyocd/probe/pydapaccess/__init__.py0000644000175000017500000000141313373511253021451 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .dap_access_api import DAPAccessIntf from .dap_access_cmsis_dap import DAPAccessCMSISDAP # alias DAPAccessCMSISDAP as main DAPAccess class DAPAccess = DAPAccessCMSISDAP pyocd-0.13.1/pyocd/probe/pydapaccess/dap_access_api.py0000644000175000017500000001414713373511253022640 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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 enum import Enum class DAPAccessIntf(object): class PORT(Enum): """Physical access ports""" DEFAULT = 0 SWD = 1 JTAG = 2 class REG(Enum): """Register for DAP access functions""" DP_0x0 = 0 DP_0x4 = 1 DP_0x8 = 2 DP_0xC = 3 AP_0x0 = 4 AP_0x4 = 5 AP_0x8 = 6 AP_0xC = 7 class ID(Enum): """Information ID used for call to identify""" VENDOR = 1 PRODUCT = 2 SER_NUM = 3 FW_VER = 4 DEVICE_VENDOR = 5 DEVICE_NAME = 6 CAPABILITIES = 0xf0 SWO_BUFFER_SIZE = 0xfd MAX_PACKET_COUNT = 0xfe MAX_PACKET_SIZE = 0xff class Error(Exception): """Parent of all error DAPAccess can raise""" pass class DeviceError(Error): """Error communicating with device""" pass class CommandError(DeviceError): """The host debugger reported failure for the given command""" pass class TransferError(CommandError): """Error ocurred with a transfer over SWD or JTAG""" pass class TransferTimeoutError(TransferError): """A SWD or JTAG timeout occurred""" pass class TransferFaultError(TransferError): """A SWD Fault occurred""" def __init__(self, faultAddress=None): super(DAPAccessIntf.TransferFaultError, self).__init__(faultAddress) self._address = faultAddress @property def fault_address(self): return self._address @fault_address.setter def fault_address(self, addr): self._address = addr def __str__(self): desc = "SWD/JTAG Transfer Fault" if self._address is not None: desc += " @ 0x%08x" % self._address return desc class TransferProtocolError(TransferError): """A SWD protocol error occurred""" pass @staticmethod def get_connected_devices(): """Return a list of DAPAccess devices""" raise NotImplementedError() @staticmethod def get_device(device_id): """Return the DAPAccess device with the give ID""" raise NotImplementedError() @staticmethod def set_args(arg_list): """Set arguments to configure behavior""" raise NotImplementedError() @property def vendor_name(self): raise NotImplementedError() @property def product_name(self): raise NotImplementedError() # ------------------------------------------- # # Host control functions # ------------------------------------------- # def open(self): """Open device and lock it for exclusive access""" raise NotImplementedError() def close(self): """Close device and unlock it""" raise NotImplementedError() def get_unique_id(self): """Get the unique ID of this device which can be used in get_device This function is safe to call before open is called. """ raise NotImplementedError() def identify(self, item): """Return the requested information for this device""" raise NotImplementedError() # ------------------------------------------- # # Target control functions # ------------------------------------------- # def connect(self, port=None): """Initailize DAP IO pins for JTAG or SWD""" raise NotImplementedError() def swj_sequence(self): """Send seqeunce to activate JTAG or SWD on the target""" raise NotImplementedError() def disconnect(self): """Deinitialize the DAP I/O pins""" raise NotImplementedError() def set_clock(self, frequency): """Set the frequency for JTAG and SWD in Hz This function is safe to call before connect is called. """ raise NotImplementedError() def get_swj_mode(self): """Return the current port type - SWD or JTAG""" raise NotImplementedError() def reset(self): """Reset the target""" raise NotImplementedError() def assert_reset(self, asserted): """Assert or de-assert target reset line""" raise NotImplementedError() def is_reset_asserted(self): """Returns True if the target reset line is asserted or False if de-asserted""" raise NotImplementedError() def set_deferred_transfer(self, enable): """Allow reads and writes to be buffered for increased speed""" raise NotImplementedError() def flush(self): """Write out all unsent commands""" raise NotImplementedError() def vendor(self, index, data=None): """Send a vendor specific command""" raise NotImplementedError() # ------------------------------------------- # # DAP Access functions # ------------------------------------------- # def write_reg(self, reg_id, value, dap_index=0): """Write a single word to a DP or AP register""" raise NotImplementedError() def read_reg(self, reg_id, dap_index=0, now=True): """Read a single word to a DP or AP register""" raise NotImplementedError() def reg_write_repeat(self, num_repeats, reg_id, data_array, dap_index=0): """Write one or more words to the same DP or AP register""" raise NotImplementedError() def reg_read_repeat(self, num_repeats, reg_id, dap_index=0, now=True): """Read one or more words from the same DP or AP register""" raise NotImplementedError() pyocd-0.13.1/pyocd/probe/pydapaccess/cmsis_dap_core.py0000644000175000017500000002420613373511253022671 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-2013,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 array from .dap_access_api import DAPAccessIntf class Command(object): DAP_INFO = 0x00 DAP_LED = 0x01 DAP_CONNECT = 0x02 DAP_DISCONNECT = 0x03 DAP_TRANSFER_CONFIGURE = 0x04 DAP_TRANSFER = 0x05 DAP_TRANSFER_BLOCK = 0x06 DAP_TRANSFER_ABORT = 0x07 DAP_WRITE_ABORT = 0x08 DAP_DELAY = 0x09 DAP_RESET_TARGET = 0x0a DAP_SWJ_PINS = 0x10 DAP_SWJ_CLOCK = 0x11 DAP_SWJ_SEQUENCE = 0x12 DAP_SWD_CONFIGURE = 0x13 DAP_JTAG_SEQUENCE = 0x14 DAP_JTAG_CONFIGURE = 0x15 DAP_JTAG_IDCODE = 0x16 DAP_VENDOR0 = 0x80 # Start of vendor-specific command IDs. class Pin(object): NONE = 0x00 # Used to read current pin values without changing. SWCLK_TCK = (1 << 0) SWDIO_TMS = (1 << 1) TDI = (1 << 2) TDO = (1 << 3) nTRST = (1 << 5) nRESET = (1 << 7) # Info IDs that return integer values. INTEGER_INFOS = [ DAPAccessIntf.ID.CAPABILITIES, DAPAccessIntf.ID.SWO_BUFFER_SIZE, DAPAccessIntf.ID.MAX_PACKET_COUNT, DAPAccessIntf.ID.MAX_PACKET_SIZE ] DAP_DEFAULT_PORT = 0 DAP_SWD_PORT = 1 DAP_JTAG_POR = 2 DAP_LED_CONNECT = 0 DAP_LED_RUNNING = 1 DAP_OK = 0 DAP_ERROR = 0xff # Responses to DAP_Transfer and DAP_TransferBlock DAP_TRANSFER_OK = 1 DAP_TRANSFER_WAIT = 2 DAP_TRANSFER_FAULT = 4 DAP_TRANSFER_NO_ACK = 7 ## @brief This class implements the CMSIS-DAP wire protocol. class CMSISDAPProtocol(object): def __init__(self, interface): self.interface = interface def dap_info(self, id_): assert type(id_) is DAPAccessIntf.ID cmd = [] cmd.append(Command.DAP_INFO) cmd.append(id_.value) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_INFO: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] == 0: return # Integer values if id_ in INTEGER_INFOS: if resp[1] == 1: return resp[2] if resp[1] == 2: return (resp[3] << 8) | resp[2] # String values. They are sent as C strings with a terminating null char, so we strip it out. x = array.array('B', [i for i in resp[2:2 + resp[1]]]).tostring() if x[-1] == '\x00': x = x[0:-1] return x def set_led(self, type, enabled): cmd = [] cmd.append(Command.DAP_LED) cmd.append(type) cmd.append(int(enabled)) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_LED: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != 0: # Second response byte must be 0 raise DAPAccessIntf.CommandError() return resp[1] def connect(self, mode=DAP_DEFAULT_PORT): cmd = [] cmd.append(Command.DAP_CONNECT) cmd.append(mode) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_CONNECT: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] == 0: # DAP connect failed raise DAPAccessIntf.CommandError() return resp[1] def disconnect(self): cmd = [] cmd.append(Command.DAP_DISCONNECT) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_DISCONNECT: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP Disconnect failed raise DAPAccessIntf.CommandError() return resp[1] def write_abort(self, data, dap_index=0): cmd = [] cmd.append(Command.DAP_WRITE_ABORT) cmd.append(dap_index) cmd.append((data >> 0) & 0xff) cmd.append((data >> 8) & 0xff) cmd.append((data >> 16) & 0xff) cmd.append((data >> 24) & 0xff) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_WRITE_ABORT: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP Write Abort failed raise DAPAccessIntf.CommandError() return True def reset_target(self): cmd = [] cmd.append(Command.DAP_RESET_TARGET) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_RESET_TARGET: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP Reset target failed raise DAPAccessIntf.CommandError() return resp[1] def transfer_configure(self, idle_cycles=0x00, wait_retry=0x0050, match_retry=0x0000): cmd = [] cmd.append(Command.DAP_TRANSFER_CONFIGURE) cmd.append(idle_cycles) cmd.append(wait_retry & 0xff) cmd.append(wait_retry >> 8) cmd.append(match_retry & 0xff) cmd.append(match_retry >> 8) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_TRANSFER_CONFIGURE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP Transfer Configure failed raise DAPAccessIntf.CommandError() return resp[1] def set_swj_clock(self, clock=1000000): cmd = [] cmd.append(Command.DAP_SWJ_CLOCK) cmd.append(clock & 0xff) cmd.append((clock >> 8) & 0xff) cmd.append((clock >> 16) & 0xff) cmd.append((clock >> 24) & 0xff) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_SWJ_CLOCK: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP SWJ Clock failed raise DAPAccessIntf.CommandError() return resp[1] def set_swj_pins(self, output, pins, wait=0): cmd = [] cmd.append(Command.DAP_SWJ_PINS) cmd.append(output & 0xff) cmd.append(pins) cmd.append(wait & 0xff) cmd.append((wait >> 8) & 0xff) cmd.append((wait >> 16) & 0xff) cmd.append((wait >> 24) & 0xff) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_SWJ_PINS: # Response is to a different command raise DAPAccessIntf.DeviceError() return resp[1] def swd_configure(self, conf=0): cmd = [] cmd.append(Command.DAP_SWD_CONFIGURE) cmd.append(conf) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_SWD_CONFIGURE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP SWD Configure failed raise DAPAccessIntf.CommandError() return resp[1] def swj_sequence(self, data): cmd = [] cmd.append(Command.DAP_SWJ_SEQUENCE) cmd.append(len(data) * 8) for i in range(len(data)): cmd.append(data[i]) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_SWJ_SEQUENCE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP SWJ Sequence failed raise DAPAccessIntf.CommandError() return resp[1] def jtag_sequence(self, info, tdi): cmd = [] cmd.append(Command.DAP_JTAG_SEQUENCE) cmd.append(1) cmd.append(info) cmd.append(tdi) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_JTAG_SEQUENCE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP JTAG Sequence failed raise DAPAccessIntf.CommandError() return resp[2] def jtag_configue(self, irlen, dev_num=1): cmd = [] cmd.append(Command.DAP_JTAG_CONFIGURE) cmd.append(dev_num) cmd.append(irlen) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_JTAG_CONFIGURE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # DAP JTAG Configure failed raise DAPAccessIntf.CommandError() return resp[2:] def jtag_id_code(self, index=0): cmd = [] cmd.append(Command.DAP_JTAG_IDCODE) cmd.append(index) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_JTAG_IDCODE: # Response is to a different command raise DAPAccessIntf.DeviceError() if resp[1] != DAP_OK: # Operation failed raise DAPAccessIntf.CommandError() return (resp[2] << 0) | \ (resp[3] << 8) | \ (resp[4] << 16) | \ (resp[5] << 24) def vendor(self, index, data): cmd = [] cmd.append(Command.DAP_VENDOR0 + index) cmd.extend(data) self.interface.write(cmd) resp = self.interface.read() if resp[0] != Command.DAP_VENDOR0 + index: # Response is to a different command raise DAPAccessIntf.DeviceError() return resp[1:] pyocd-0.13.1/pyocd/probe/pydapaccess/dap_settings.py0000644000175000017500000000130313373511253022374 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ class DAPSettings(): use_ws = False ws_host = "localhost" ws_port = 8081 limit_packets = False pyocd-0.13.1/pyocd/probe/cmsis_dap_probe.py0000644000175000017500000003064613373511253020556 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 .debug_probe import DebugProbe from ..core import exceptions from .pydapaccess import DAPAccess from ..board.mbed_board import MbedBoard from ..board.board_ids import BOARD_ID_TO_INFO import six ## @brief Wraps a pydapaccess link as a DebugProbe. class CMSISDAPProbe(DebugProbe): # Masks for CMSIS-DAP capabilities. SWD_CAPABILITY_MASK = 1 JTAG_CAPABILITY_MASK = 2 # Map from DebugProbe protocol types to/from DAPAccess port types. PORT_MAP = { DebugProbe.Protocol.DEFAULT: DAPAccess.PORT.DEFAULT, DebugProbe.Protocol.SWD: DAPAccess.PORT.SWD, DebugProbe.Protocol.JTAG: DAPAccess.PORT.JTAG, DAPAccess.PORT.DEFAULT: DebugProbe.Protocol.DEFAULT, DAPAccess.PORT.SWD: DebugProbe.Protocol.SWD, DAPAccess.PORT.JTAG: DebugProbe.Protocol.JTAG, } # APnDP constants. DP = 0 AP = 1 # Bitmasks for AP register address fields. A32 = 0x0000000c APBANKSEL = 0x000000f0 APSEL = 0xff000000 APSEL_APBANKSEL = APSEL | APBANKSEL # Address of DP's SELECT register. DP_SELECT = 0x8 # Map from AP/DP and 2-bit register address to the enums used by pydapaccess. REG_ADDR_TO_ID_MAP = { # APnDP A32 ( 0, 0x0 ) : DAPAccess.REG.DP_0x0, ( 0, 0x4 ) : DAPAccess.REG.DP_0x4, ( 0, 0x8 ) : DAPAccess.REG.DP_0x8, ( 0, 0xC ) : DAPAccess.REG.DP_0xC, ( 1, 0x0 ) : DAPAccess.REG.AP_0x0, ( 1, 0x4 ) : DAPAccess.REG.AP_0x4, ( 1, 0x8 ) : DAPAccess.REG.AP_0x8, ( 1, 0xC ) : DAPAccess.REG.AP_0xC, } @classmethod def get_all_connected_probes(cls): try: return [cls(dev) for dev in DAPAccess.get_connected_devices()] except DAPAccess.Error as exc: six.raise_from(cls._convert_exception(exc), exc) @classmethod def get_probe_with_id(cls, unique_id): try: return cls(DAPAccess(unique_id)) except DAPAccess.Error as exc: six.raise_from(cls._convert_exception(exc), exc) def __init__(self, device): self._link = device self._supported_protocols = None self._protocol = None self._is_open = False self._dp_select = -1 @property def description(self): try: board_id = self.unique_id[0:4] board_info = BOARD_ID_TO_INFO[board_id] except KeyError: return self.vendor_name + " " + self.product_name else: return "{0} [{1}]".format(board_info.name, board_info.target) @property def vendor_name(self): return self._link.vendor_name @property def product_name(self): return self._link.product_name ## @brief Only valid after opening. @property def supported_wire_protocols(self): return self._supported_protocols @property def unique_id(self): return self._link.get_unique_id() @property def wire_protocol(self): return self._protocol @property def is_open(self): return self._is_open def create_associated_board(self, session): return MbedBoard(session) def open(self): try: self._link.open() self._is_open = True self._link.set_deferred_transfer(True) # Read CMSIS-DAP capabilities self._capabilities = self._link.identify(DAPAccess.ID.CAPABILITIES) self._supported_protocols = [DebugProbe.Protocol.DEFAULT] if self._capabilities & self.SWD_CAPABILITY_MASK: self._supported_protocols.append(DebugProbe.Protocol.SWD) if self._capabilities & self.JTAG_CAPABILITY_MASK: self._supported_protocols.append(DebugProbe.Protocol.JTAG) except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def close(self): try: self._link.close() self._is_open = False except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) # ------------------------------------------- # # Target control functions # ------------------------------------------- # def connect(self, protocol=None): """Initialize DAP IO pins for JTAG or SWD""" # Convert protocol to port enum. if protocol is not None: port = self.PORT_MAP[protocol] else: port = DAPAccess.PORT.DEFAULT try: self._link.connect(port) except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) # Read the current mode and save it. actualMode = self._link.get_swj_mode() self._protocol = self.PORT_MAP[actualMode] self._invalidate_cached_registers() # TODO remove def swj_sequence(self): """Send sequence to activate JTAG or SWD on the target""" try: self._link.swj_sequence() except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def disconnect(self): """Deinitialize the DAP I/O pins""" try: self._link.disconnect() self._protocol = None self._invalidate_cached_registers() except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def set_clock(self, frequency): """Set the frequency for JTAG and SWD in Hz This function is safe to call before connect is called. """ try: self._link.set_clock(frequency) except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def reset(self): """Reset the target""" try: self._invalidate_cached_registers() self._link.reset() except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def assert_reset(self, asserted): """Assert or de-assert target reset line""" try: self._invalidate_cached_registers() self._link.assert_reset(asserted) except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def is_reset_asserted(self): """Returns True if the target reset line is asserted or False if de-asserted""" try: return self._link.is_reset_asserted() except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) def flush(self): """Write out all unsent commands""" try: self._link.flush() except DAPAccess.Error as exc: six.raise_from(self._convert_exception(exc), exc) # ------------------------------------------- # # DAP Access functions # ------------------------------------------- # ## @brief Read a DP register. # # @param self # @param addr Integer register address being one of (0x0, 0x4, 0x8, 0xC). # @param now # # @todo Handle auto DPBANKSEL. def read_dp(self, addr, now=True): reg_id = self.REG_ADDR_TO_ID_MAP[self.DP, addr] try: result = self._link.read_reg(reg_id, now=now) except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) # Read callback returned for async reads. def read_dp_result_callback(): try: return result() except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) return result if now else read_dp_result_callback def write_dp(self, addr, data): reg_id = self.REG_ADDR_TO_ID_MAP[self.DP, addr] # Skip writing DP SELECT register if its value is not changing. if addr == self.DP_SELECT: if data == self._dp_select: return self._dp_select = data # Write the DP register. try: self._link.write_reg(reg_id, data) except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) return True def read_ap(self, addr, now=True): assert type(addr) in (six.integer_types) ap_reg = self.REG_ADDR_TO_ID_MAP[self.AP, (addr & self.A32)] try: self.write_dp(self.DP_SELECT, addr & self.APSEL_APBANKSEL) result = self._link.read_reg(ap_reg, now=now) except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) # Read callback returned for async reads. def read_ap_result_callback(): try: return result() except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) return result if now else read_ap_result_callback def write_ap(self, addr, data): assert type(addr) in (six.integer_types) ap_reg = self.REG_ADDR_TO_ID_MAP[self.AP, (addr & self.A32)] # Select the AP and bank. self.write_dp(self.DP_SELECT, addr & self.APSEL_APBANKSEL) # Perform the AP register write. try: self._link.write_reg(ap_reg, data) except DAPAccess.Error as error: self._invalidate_cached_registers() six.raise_from(self._convert_exception(error), error) return True def read_ap_multiple(self, addr, count=1, now=True): assert type(addr) in (six.integer_types) ap_reg = self.REG_ADDR_TO_ID_MAP[self.AP, (addr & self.A32)] try: # Select the AP and bank. self.write_dp(self.DP_SELECT, addr & self.APSEL_APBANKSEL) result = self._link.reg_read_repeat(count, ap_reg, dap_index=0, now=now) except DAPAccess.Error as exc: self._invalidate_cached_registers() six.raise_from(self._convert_exception(exc), exc) # Need to wrap the deferred callback to convert exceptions. def read_ap_repeat_callback(): try: return result() except DAPAccess.Error as exc: self._invalidate_cached_registers() six.raise_from(self._convert_exception(exc), exc) return result if now else read_ap_repeat_callback def write_ap_multiple(self, addr, values): assert type(addr) in (six.integer_types) ap_reg = self.REG_ADDR_TO_ID_MAP[self.AP, (addr & self.A32)] try: # Select the AP and bank. self.write_dp(self.DP_SELECT, addr & self.APSEL_APBANKSEL) return self._link.reg_write_repeat(len(values), ap_reg, values, dap_index=0) except DAPAccess.Error as exc: self._invalidate_cached_registers() six.raise_from(self._convert_exception(exc), exc) def _invalidate_cached_registers(self): # Invalidate cached DP SELECT register. self._dp_select = -1 @staticmethod def _convert_exception(exc): if isinstance(exc, DAPAccess.TransferFaultError): return exceptions.TransferFaultError() elif isinstance(exc, DAPAccess.TransferTimeoutError): return exceptions.TransferTimeoutError() elif isinstance(exc, DAPAccess.TransferError): return exceptions.TransferError() elif isinstance(exc, (DAPAccess.DeviceError, DAPAccess.CommandError)): return exceptions.ProbeError(str(exc)) elif isinstance(exc, DAPAccess.Error): return exceptions.PyOCDError(str(exc)) else: return exc pyocd-0.13.1/pyocd/probe/__init__.py0000644000175000017500000000117213373511253017154 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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. pyocd-0.13.1/pyocd/probe/stlink/0000755000175000017500000000000013373523011016341 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/probe/stlink/usb.py0000644000175000017500000001764113373511253017522 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 __future__ import absolute_import from . import STLinkException import usb.core import usb.util import logging import six import threading from collections import namedtuple # Set to True to enable debug logs of USB data transfers. LOG_USB_DATA = False log = logging.getLogger('stlink.usb') STLinkInfo = namedtuple('STLinkInfo', 'version_name out_ep in_ep swv_ep') ## # @brief Provides low-level USB enumeration and transfers for STLinkV2/3 devices. class STLinkUSBInterface(object): ## Command packet size. CMD_SIZE = 16 ## ST's USB vendor ID USB_VID = 0x0483 ## Map of USB PID to firmware version name and device endpoints. USB_PID_EP_MAP = { # PID Version OUT IN SWV 0x3748: STLinkInfo('V2', 0x02, 0x81, 0x83), 0x374b: STLinkInfo('V2-1', 0x01, 0x81, 0x82), 0x374a: STLinkInfo('V2-1', 0x01, 0x81, 0x82), # Audio 0x3742: STLinkInfo('V2-1', 0x01, 0x81, 0x82), # No MSD 0x374e: STLinkInfo('V3', 0x01, 0x81, 0x82), 0x374f: STLinkInfo('V3', 0x01, 0x81, 0x82), # Bridge 0x3753: STLinkInfo('V3', 0x01, 0x81, 0x82), # 2VCP } ## STLink devices only have one USB interface. DEBUG_INTERFACE_NUMBER = 0 @classmethod def _usb_match(cls, dev): try: # Check VID/PID. isSTLink = (dev.idVendor == cls.USB_VID) and (dev.idProduct in cls.USB_PID_EP_MAP) # Try accessing the product name, which will cause a permission error on Linux. Better # to error out here than later when building the device description. if isSTLink: dev.product return isSTLink except ValueError as error: # Permission denied error gets reported as ValueError (The device has no langid). log.debug("ValueError \"%s\" while trying to access STLink USB device fields (VID=%04x PID=%04x). " "This is probably a permission issue.", error, dev.idVendor, dev.idProduct) return False except usb.core.USBError as error: log.warning("Exception getting device info (VID=%04x PID=%04x): %s", dev.idVendor, dev.idProduct, error) return False except IndexError as error: log.warning("Internal pyusb error (VID=%04x PID=%04x): %s", dev.idVendor, dev.idProduct, error) return False except NotImplementedError as error: log.warning("Received USB unimplemented error (VID=%04x PID=%04x)", dev.idVendor, dev.idProduct) return False @classmethod def get_all_connected_devices(cls): try: devices = usb.core.find(find_all=True, custom_match=cls._usb_match) except usb.core.NoBackendError: # Print a warning if pyusb cannot find a backend, and return no probes. log.warning("STLink probes are not supported because no libusb library was found.") return [] intfList = [] for dev in devices: intf = cls(dev) intfList.append(intf) return intfList def __init__(self, dev): self._dev = dev assert dev.idVendor == self.USB_VID self._info = self.USB_PID_EP_MAP[dev.idProduct] self._ep_out = None self._ep_in = None self._ep_swv = None self._max_packet_size = 64 self._closed = True def open(self): assert self._closed # Debug interface is always interface 0, alt setting 0. config = self._dev.get_active_configuration() interface = config[(self.DEBUG_INTERFACE_NUMBER, 0)] # Look up endpoint objects. for endpoint in interface: if endpoint.bEndpointAddress == self._info.out_ep: self._ep_out = endpoint elif endpoint.bEndpointAddress == self._info.in_ep: self._ep_in = endpoint elif endpoint.bEndpointAddress == self._info.swv_ep: self._ep_swv = endpoint if not self._ep_out: raise STLinkException("Unable to find OUT endpoint") if not self._ep_in: raise STLinkException("Unable to find IN endpoint") self._max_packet_size = self._ep_in.wMaxPacketSize # Claim this interface to prevent other processes from accessing it. usb.util.claim_interface(self._dev, 0) self._flush_rx() self._closed = False def close(self): assert not self._closed self._closed = True usb.util.release_interface(self._dev, self.DEBUG_INTERFACE_NUMBER) usb.util.dispose_resources(self._dev) self._ep_out = None self._ep_in = None @property def serial_number(self): return self._dev.serial_number @property def vendor_name(self): return self._dev.manufacturer @property def product_name(self): return self._dev.product @property def version_name(self): return self._info.version_name @property def max_packet_size(self): return self._max_packet_size def _flush_rx(self): # Flush the RX buffers by reading until timeout exception try: while True: self._ep_in.read(self._max_packet_size, 1) except usb.core.USBError: # USB timeout expected pass def _read(self, size, timeout=1000): # Minimum read size is the maximum packet size. read_size = max(size, self._max_packet_size) data = self._ep_in.read(read_size, timeout) return bytearray(data)[:size] def transfer(self, cmd, writeData=None, readSize=None, timeout=1000): # Pad command to required 16 bytes. assert len(cmd) <= self.CMD_SIZE paddedCmd = bytearray(self.CMD_SIZE) paddedCmd[0:len(cmd)] = cmd try: # Command phase. if LOG_USB_DATA: log.debug(" USB CMD> %s" % ' '.join(['%02x' % i for i in paddedCmd])) count = self._ep_out.write(paddedCmd, timeout) assert count == len(paddedCmd) # Optional data out phase. if writeData is not None: if LOG_USB_DATA: log.debug(" USB OUT> %s" % ' '.join(['%02x' % i for i in writeData])) count = self._ep_out.write(writeData, timeout) assert count == len(writeData) # Optional data in phase. if readSize is not None: if LOG_USB_DATA: log.debug(" USB IN < (%d bytes)" % readSize) data = self._read(readSize) if LOG_USB_DATA: log.debug(" USB IN < %s" % ' '.join(['%02x' % i for i in data])) return data except usb.core.USBError as exc: six.raise_from(STLinkException("USB Error: %s" % exc), exc) return None def read_swv(self, size, timeout=1000): return self._ep_swv.read(size, timeout) def __repr__(self): return "<{} @ {:#x} vid={:#06x} pid={:#06x} sn={} version={}>".format( self.__class__.__name__, id(self), self._dev.idVendor, self._dev.idProduct, self.serial_number, self.version) pyocd-0.13.1/pyocd/probe/stlink/stlink.py0000644000175000017500000003231113373511253020224 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 STLinkException from .constants import (Commands, Status, SWD_FREQ_MAP, JTAG_FREQ_MAP) from ...core import exceptions from ...coresight import dap import logging import struct import six from enum import Enum log = logging.getLogger('stlink') class STLink(object): """! @brief STLink V2 and V3 command-level interface. """ class Protocol(Enum): """! @brief Protocol options to pass to STLink.enter_debug() method. """ SWD = 1 JTAG = 2 ## Maximum number of bytes to send or receive for 32- and 16- bit transfers. # # 8-bit transfers have a maximum size of the maximum USB packet size (64 bytes for full speed). MAXIMUM_TRANSFER_SIZE = 1024 ## Minimum required STLink firmware version. MIN_JTAG_VERSION = 24 ## Firmware version that adds 16-bit transfers. MIN_JTAG_VERSION_16BIT_XFER = 26 ## Firmware version that adds multiple AP support. MIN_JTAG_VERSION_MULTI_AP = 28 ## Port number to use to indicate DP registers. DP_PORT = 0xffff def __init__(self, device): self._device = device self._hw_version = 0 self._jtag_version = 0 self._version_str = None self._target_voltage = 0 self._protocol = None def open(self): self._device.open() self.get_version() self.get_target_voltage() def close(self): self.enter_idle() self._device.close() def get_version(self): # GET_VERSION response structure: # Byte 0-1: # [15:12] Major/HW version # [11:6] JTAG/SWD version # [5:0] SWIM or MSC version # Byte 2-3: ST_VID # Byte 4-5: STLINK_PID response = self._device.transfer([Commands.GET_VERSION], readSize=6) ver, = struct.unpack('>H', response[:2]) dev_ver = self._device.version_name # TODO create version bitfield constants self._hw_version = (ver >> 12) & 0xf self._jtag_version = (ver >> 6) & 0x3f self._version_str = "%s v%dJ%d" % (dev_ver, self._hw_version, self._jtag_version) # For STLinkV3 we must use the extended get version command. if self._hw_version >= 3: # GET_VERSION_EXT response structure (byte offsets): # 0: HW version # 1: SWIM version # 2: JTAG/SWD version # 3: MSC/VCP version # 4: Bridge version # 5-7: reserved # 8-9: ST_VID # 10-11: STLINK_PID response = self._device.transfer([Commands.GET_VERSION_EXT], readSize=12) hw_vers, _, self._jtag_version = struct.unpack('<3B', response[0:3]) # Check versions. if self._jtag_version == 0: raise STLinkException("%s firmware does not support JTAG/SWD. Please update" "to a firmware version that supports JTAG/SWD" % (self._version_str)) if self._jtag_version < self.MIN_JTAG_VERSION: raise STLinkException("STLink %s is using an unsupported, older firmware version. " "Please update to the latest STLink firmware. Current version is %s, must be at least version v2J%d.)" % (self.serial_number, self._version_str, self.MIN_JTAG_VERSION)) @property def vendor_name(self): return self._device.vendor_name @property def product_name(self): return self._device.product_name + self._device.version_name @property def serial_number(self): return self._device.serial_number @property def hw_version(self): return self._hw_version @property def jtag_version(self): return self._jtag_version @property def version_str(self): return self._version_str @property def target_voltage(self): return self._target_voltage def get_target_voltage(self): response = self._device.transfer([Commands.GET_TARGET_VOLTAGE], readSize=8) a0, a1 = struct.unpack('= f: response = self._device.transfer([Commands.JTAG_COMMAND, Commands.SWD_SET_FREQ, d], readSize=2) self._check_status(response) return raise STLinkException("Selected SWD frequency is too low") def set_jtag_frequency(self, freq=1120000): for f, d in JTAG_FREQ_MAP.items(): if freq >= f: response = self._device.transfer([Commands.JTAG_COMMAND, Commands.JTAG_SET_FREQ, d], readSize=2) self._check_status(response) return raise STLinkException("Selected JTAG frequency is too low") def enter_debug(self, protocol): self.enter_idle() if protocol == self.Protocol.SWD: protocolParam = Commands.JTAG_ENTER_SWD elif protocol == self.Protocol.JTAG: protocolParam = Commands.JTAG_ENTER_JTAG_NO_CORE_RESET response = self._device.transfer([Commands.JTAG_COMMAND, Commands.JTAG_ENTER2, protocolParam, 0], readSize=2) self._check_status(response) self._protocol = protocol def open_ap(self, apsel): if self._jtag_version < self.MIN_JTAG_VERSION_MULTI_AP: return cmd = [Commands.JTAG_COMMAND, Commands.JTAG_INIT_AP, apsel, Commands.JTAG_AP_NO_CORE] response = self._device.transfer(cmd, readSize=2) self._check_status(response) def close_ap(self, apsel): if self._jtag_version < self.MIN_JTAG_VERSION_MULTI_AP: return cmd = [Commands.JTAG_COMMAND, Commands.JTAG_CLOSE_AP_DBG, apsel] response = self._device.transfer(cmd, readSize=2) self._check_status(response) def target_reset(self): response = self._device.transfer([Commands.JTAG_COMMAND, Commands.JTAG_DRIVE_NRST, Commands.JTAG_DRIVE_NRST_PULSE], readSize=2) self._check_status(response) def drive_nreset(self, isAsserted): value = Commands.JTAG_DRIVE_NRST_LOW if isAsserted else Commands.JTAG_DRIVE_NRST_HIGH response = self._device.transfer([Commands.JTAG_COMMAND, Commands.JTAG_DRIVE_NRST, value], readSize=2) self._check_status(response) def _check_status(self, response): status, = struct.unpack('> 16) == 0, "register address must be 16-bit" cmd = [Commands.JTAG_COMMAND, Commands.JTAG_READ_DAP_REG] cmd.extend(six.iterbytes(struct.pack('> 16) == 0, "register address must be 16-bit" cmd = [Commands.JTAG_COMMAND, Commands.JTAG_WRITE_DAP_REG] cmd.extend(six.iterbytes(struct.pack('> self.APSEL_SHIFT result = self._link.read_dap_register(apsel, addr & 0xffff) except STLinkException as exc: six.raise_from(self._convert_exception(exc), exc) def read_ap_result_callback(): return result return result if now else read_ap_result_callback def write_ap(self, addr, data): try: apsel = (addr & self.APSEL) >> self.APSEL_SHIFT result = self._link.write_dap_register(apsel, addr & 0xffff, data) except STLinkException as exc: six.raise_from(self._convert_exception(exc), exc) def read_ap_multiple(self, addr, count=1, now=True): results = [self.read_ap(addr, now=True) for n in range(count)] def read_ap_multiple_result_callback(): return result return results if now else read_ap_multiple_result_callback def write_ap_multiple(self, addr, values): for v in values: self.write_ap(addr, v) def get_memory_interface_for_ap(self, apsel): assert self._is_connected if apsel not in self._memory_interfaces: self._link.open_ap(apsel) self._memory_interfaces[apsel] = STLinkMemoryInterface(self._link, apsel) return self._memory_interfaces[apsel] @staticmethod def _convert_exception(exc): if isinstance(exc, STLinkException): return exceptions.ProbeError(str(exc)) else: return exc ## @brief Concrete memory interface for a single AP. class STLinkMemoryInterface(MemoryInterface): def __init__(self, link, apsel): self._link = link self._apsel = apsel ## @brief Write a single memory location. # # By default the transfer size is a word. def write_memory(self, addr, data, transfer_size=32): assert transfer_size in (8, 16, 32) if transfer_size == 32: self._link.write_mem32(addr, conversion.u32le_list_to_byte_list([data]), self._apsel) elif transfer_size == 16: self._link.write_mem16(addr, conversion.u16le_list_to_byte_list([data]), self._apsel) elif transfer_size == 8: self._link.write_mem8(addr, [data], self._apsel) ## @brief Read a memory location. # # By default, a word will be read. def read_memory(self, addr, transfer_size=32, now=True): assert transfer_size in (8, 16, 32) if transfer_size == 32: result = conversion.byte_list_to_u32le_list(self._link.read_mem32(addr, 4, self._apsel))[0] elif transfer_size == 16: result = conversion.byte_list_to_u16le_list(self._link.read_mem16(addr, 2, self._apsel))[0] elif transfer_size == 8: result = self._link.read_mem8(addr, 1, self._apsel)[0] def read_callback(): return result return result if now else read_callback def write_memory_block32(self, addr, data): self._link.write_mem32(addr, conversion.u32le_list_to_byte_list(data), self._apsel) def read_memory_block32(self, addr, size): return conversion.byte_list_to_u32le_list(self._link.read_mem32(addr, size * 4, self._apsel)) pyocd-0.13.1/pyocd/utility/0000755000175000017500000000000013373523011015431 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/utility/py3_helpers.py0000644000175000017500000000374713373511253020260 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 sys import functools PY3 = sys.version_info[0] == 3 # iter_single_bytes() returns an iterator over a bytes object that produces # single-byte bytes objects for each byte in the passed in value. Normally on # py3 iterating over a bytes will give you ints for each byte, while on py3 # you'll get single-char strs. if PY3: iter_single_bytes = functools.partial(map, lambda v: bytes((v,))) # pylint: disable=invalid-name else: iter_single_bytes = iter # pylint: disable=invalid-name # to_bytes_safe() converts a unicode string to a bytes object by encoding as # latin-1. It will also accept a value that is already a bytes object and # return it unmodified. if PY3: def to_bytes_safe(v): if type(v) is str: return v.encode('latin-1') else: return v else: def to_bytes_safe(v): if type(v) is unicode: return v.encode('latin-1') else: return v # to_str_safe() converts a bytes object to a unicode string by decoding from # latin-1. It will also accept a value that is already a str object and # return it unmodified. if PY3: def to_str_safe(v): if type(v) is str: return v else: return v.decode('latin-1') else: def to_str_safe(v): if type(v) is unicode: return v.decode('latin-1') else: return v pyocd-0.13.1/pyocd/utility/progress.py0000644000175000017500000001042213373511253017653 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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 os import sys import logging log = logging.getLogger('progress') ## @brief Base progress report class. # # This base class implements the logic but no output. class ProgressReport(object): def __init__(self, file=None): self._file = file or sys.stdout self.prev_progress = 0 self.backwards_progress = False self.done = False self.last = 0 def __call__(self, progress): assert progress >= 0.0 # assert progress <= 1.0 # TODO restore this assert when the progress > 1 bug is fixed # assert (progress == 0 and self.prev_progress == 1.0) or (progress >= self.prev_progress) if progress > 1.0: log.debug("progress out of bounds: %.3f", progress) # Reset state on 0.0 if progress == 0.0: self._start() # Check for backwards progress if progress < self.prev_progress: self.backwards_progress = True self.prev_progress = progress # print progress bar if not self.done: self._update(progress) # Finish on 1.0 if progress >= 1.0: self._finish() if self.backwards_progress: log.warning("Progress went backwards!") def _start(self): self.prev_progress = 0 self.backwards_progress = False self.done = False self.last = 0 def _update(self, progress): raise NotImplemented() def _finish(self): raise NotImplemented() ## @brief Progress report subclass for TTYs. # # The progress bar is fully redrawn onscreen as progress is updated to give the # impression of animation. class ProgressReportTTY(ProgressReport): # These width constants can't be changed yet without changing the code below to match. WIDTH = 20 def _update(self, progress): self._file.write('\r') i = int(progress * self.WIDTH) self._file.write("[%-20s] %3d%%" % ('=' * i, round(progress * 100))) self._file.flush() def _finish(self): self.done = True self._file.write("\n") ## @brief Progress report subclass for non-TTY output. # # A simpler progress bar is used than for the TTY version. Only the difference between # the previous and current progress is drawn for each update, making the output suitable # for piping to a file or similar output. class ProgressReportNoTTY(ProgressReport): # These width constants can't be changed yet without changing the code below to match. WIDTH = 40 def _start(self): super(ProgressReportNoTTY, self)._start() self._file.write('[' + '---|' * 9 + '----]\n[') self._file.flush() def _update(self, progress): i = int(progress * self.WIDTH) delta = i - self.last self._file.write('=' * delta) self._file.flush() self.last = i def _finish(self): self.done = True self._file.write("]\n") self._file.flush() ## @brief Progress printer factory. # # This factory function checks whether the output file is a TTY, and instantiates the # appropriate subclass of ProgressReport. # # @param file The output file. Optional. If not provided, or if set to None, then sys.stdout # will be used automatically. def print_progress(file=None): if file is None: file = sys.stdout try: istty = os.isatty(file.fileno()) except (OSError, AttributeError): # Either the file doesn't have a fileno method, or calling it returned an # error. In either case, just assume we're not connected to a TTY. istty = False klass = ProgressReportTTY if istty else ProgressReportNoTTY return klass(file) pyocd-0.13.1/pyocd/utility/timeout.py0000644000175000017500000000414213373511253017477 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger 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. """ from time import time ## @brief Timeout helper context manager. # # The recommended way to use this class is demonstrated here. It uses an else block on a # while loop to handle the timeout. The code in the while loop must use a break statement # to exit in the successful case. # # @code # with Timeout(5) as t_o: # while t_o.check(): # or "while not t_o.did_time_out" # # Perform some operation, check, etc. # if foobar: # break # sleep(0.1) # else: # print("Timed out!") # @endcode # # Another method of using the class is to check the `did_time_out` property from within the # while loop, as shown below. # # @code # with Timeout(5) as t_o: # while perform_some_test(): # # Check for timeout. # if t_o.did_time_out: # print("Timed out!") # break # sleep(0.1) # @endcode # # You may also combine the call to check() in the while loop with other boolean expressions # related to the operation being performed. class Timeout(object): def __init__(self, timeout): self._timeout = timeout self._timed_out = False self._start = -1 def __enter__(self): self._start = time() return self def __exit__(self, exc_type, exc_val, exc_tb): pass def check(self): if (time() - self._start) > self._timeout: self._timed_out = True return not self._timed_out @property def did_time_out(self): self.check() return self._timed_out pyocd-0.13.1/pyocd/utility/notification.py0000644000175000017500000000404613373511253020502 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import logging ## # @brief Class that holds information about a notification to subscribers. class Notification(object): def __init__(self, event, source, data=None): self._event = event self._source = source self._data = data @property def event(self): return self._event @property def source(self): return self._source @property def data(self): return self._data def __repr__(self): return "" % (id(self), repr(self.event), repr(self.source), repr(self.data)) ## # @brief Mix-in class that provides notification capabilities. class Notifier(object): def __init__(self): self._subscribers = {} def subscribe(self, events, cb): if not type(events) in (list, tuple): events = [events] for event in events: if event in self._subscribers: self._subscribers[event].append(cb) else: self._subscribers[event] = [cb] def unsubscribe(self, events, cb): pass def notify(self, *notifications): for note in notifications: # This debug log is commented out because it produces too much output unless you # are specifically working on notifications. # logging.debug("Sending notification: %s", repr(note)) for cb in self._subscribers.get(note.event, []): cb(note) pyocd-0.13.1/pyocd/utility/mask.py0000644000175000017500000000440713373511253016750 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ ## @brief Returns a mask with specified bit ranges set. # # An integer mask is generated based on the bits and bit ranges specified by the # arguments. Any number of arguments can be provided. Each argument may be either # a 2-tuple of integers, a list of integers, or an individual integer. The result # is the combination of masks produced by the arguments. # # - 2-tuple: The tuple is a bit range with the first element being the MSB and the # second element the LSB. All bits from LSB up to and included MSB are set. # - list: Each bit position specified by the list elements is set. # - int: The specified bit position is set. # # @return An integer mask value computed from the logical OR'ing of masks generated # by each argument. # # Example: # @code # >>> hex(bitmask((23,17),1)) # 0xfe0002 # >>> hex(bitmask([4,0,2],(31,24)) # 0xff000015 # @endcode def bitmask(*args): mask = 0 for a in args: if type(a) is tuple: for b in range(a[1], a[0]+1): mask |= 1 << b elif type(a) is list: for b in a: mask |= 1 << b elif type(a) is int: mask |= 1 << a return mask ## @brief Return the 32-bit inverted value of the argument. def invert32(value): return 0xffffffff & ~value ## @brief Extract a value from a bitfield. def bfx(value, msb, lsb): mask = bitmask((msb, lsb)) return (value & mask) >> lsb ## @brief Change a bitfield value. def bfi(value, msb, lsb, field): mask = bitmask((msb, lsb)) value &= ~mask value |= (field << lsb) & mask return value def _msb( n ): ndx = 0 while ( 1 < n ): n = ( n >> 1 ) ndx += 1 return ndx pyocd-0.13.1/pyocd/utility/cmdline.py0000644000175000017500000000645113373511253017431 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 ..core.target import Target from ..utility.py3_helpers import to_str_safe ## @brief Split command line by whitespace, supporting quoted strings. # # Accepts def split_command_line(cmd_line): result = [] if type(cmd_line) is str: args = [cmd_line] else: args = cmd_line for cmd in args: state = 0 word = '' open_quote = '' for c in cmd: if state == 0: if c in (' ', '\t', '\r', '\n'): if word: result.append(word) word = '' elif c in ('"', "'"): open_quote = c state = 1 else: word += c elif state == 1: if c == open_quote: result.append(word) word = '' state = 0 else: word += c if word: result.append(word) return result ## Map of vector char characters to masks. VECTOR_CATCH_CHAR_MAP = { 'h': Target.CATCH_HARD_FAULT, 'b': Target.CATCH_BUS_FAULT, 'm': Target.CATCH_MEM_FAULT, 'i': Target.CATCH_INTERRUPT_ERR, 's': Target.CATCH_STATE_ERR, 'c': Target.CATCH_CHECK_ERR, 'p': Target.CATCH_COPROCESSOR_ERR, 'r': Target.CATCH_CORE_RESET, 'a': Target.CATCH_ALL, 'n': Target.CATCH_NONE, } ## @brief Convert a vector catch string to a mask. # # @exception ValueError Raised if an invalid vector catch character is encountered. def convert_vector_catch(value): # Make case insensitive. value = to_str_safe(value).lower() # Handle special vector catch options. if value == 'all': return Target.CATCH_ALL elif value == 'none': return Target.CATCH_NONE # Convert options string to mask. try: return sum([VECTOR_CATCH_CHAR_MAP[c] for c in value]) except KeyError as e: # Reraise an error with a more helpful message. raise ValueError("invalid vector catch option '{}'".format(e.args[0])) ## @brief Convert a list of session option settings to a dictionary. # # def convert_session_options(option_list): options = {} if option_list is not None: for o in option_list: if '=' in o: name, value = o.split('=') name = name.strip().lower() value = value.strip() else: name = o.strip().lower() if name.startswith('no-'): name = name[3:] value = False else: value = True options[name] = value return options pyocd-0.13.1/pyocd/utility/__init__.py0000644000175000017500000000113013373511253017542 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ pyocd-0.13.1/pyocd/utility/sequencer.py0000644000175000017500000001664013373511253020011 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 collections import (OrderedDict, Callable) import logging log = logging.getLogger("sequencer") ## @brief Call sequence manager. # # Contains an ordered sequence of tasks. Each task has a name and associated # callable. The CallSequence class itself is callable, so instances can be nested # as tasks within other CallSequences. # # When tasks within a sequence are called, they may optionally return a new CallSequence # instance. If this happens, the new sequence is executed right away, before continuing # with the next task in the original sequence. # # A CallSequence can be iterated over. It will return tuples of (task-name, callable). class CallSequence(object): ## @brief Constructor. # # The constructor accepts an arbitrary number of parameters describing an ordered # set of tasks. Each parameter must be a 2-tuple with the first element being the # task's name and the second element a callable that implements the task. If you # need to pass parameters to the callable, use a lambda. def __init__(self, *args): self._validate_tasks(args) self._calls = OrderedDict(args) def _validate_tasks(self, tasks): for i in tasks: assert len(i) == 2 assert type(i[0]) is str assert isinstance(i[1], Callable) ## @brief Returns an OrderedDict of the call sequence. # # Task names are keys. @property def sequence(self): return self._calls ## @brief Replace the entire call sequence. # # Accepts either an OrderedDict or a list of 2-tuples like the constructor. @sequence.setter def sequence(self, seq): if isinstance(seq, OrderedDict): self._calls = seq elif type(seq) is list and len(seq) and type(seq[0]) is tuple: self._calls = OrderedDict(seq) ## @brief Returns the number of tasks in the sequence. @property def count(self): return len(self._calls) ## @brief Remove all tasks from the sequence. def clear(self): self._calls = OrderedDict() ## @brief Remove a task with the given name. # @exception KeyError Raised if no task with the specified name exists. def remove_task(self, name): del self._calls[name] return self ## @brief Returns a boolean indicating presence of the named task in the sequence. def has_task(self, name): return name in self._calls ## @brief Return the callable for the named task. # @exception KeyError Raised if no task with the specified name exists. def get_task(self, name): return self._calls[name] ## @brief Change the callable associated with a task. def replace_task(self, name, replacement): assert isinstance(replacement, Callable) if name not in self._calls: raise KeyError(name) else: # OrderedDict preserves the order when changing the value of a key # that is already in the dict. self._calls[name] = replacement return self ## @brief Wrap an existing task with a new callable. # # The wrapper is expected to take a single parameter, the return value from the # original task. This allows for easy filtering of a new call sequence returned by # the original task. def wrap_task(self, name, wrapper): if name not in self._calls: raise KeyError(name) # Get original callable. orig = self._calls[name] # OrderedDict preserves the order when changing the value of a key # that is already in the dict. self._calls[name] = lambda : wrapper(orig()) return self ## @brief Append a new task or tasks to the sequence. # # Like the constructor, this method takes any number of arguments. Each must be a # 2-tuple task description. def append(self, *args): self._validate_tasks(args) # Insert iterable. self._calls.update(args) return self ## @brief Insert a task or tasks before a named task. # # @param beforeTaskName The name of an existing task. The new tasks will be inserted # prior to this task. # # After the task name parameter, any number of task description 2-tuples may be # passed. # # @exception KeyError Raised if the named task does not exist in the sequence. def insert_before(self, beforeTaskName, *args): self._validate_tasks(args) if not self.has_task(beforeTaskName): raise KeyError(beforeTaskName) seq = list(self._calls.items()) for i, v in enumerate(seq): if v[0] == beforeTaskName: for c in args: # List insert() inserts before the given index. seq.insert(i, c) i += 1 break self._calls = OrderedDict(seq) return self ## @brief Insert a task or tasks after a named task. # # @param afterTaskName The name of an existing task. The new tasks will be inserted # after this task. # # After the task name parameter, any number of task description 2-tuples may be # passed. # # @exception KeyError Raised if the named task does not exist in the sequence. def insert_after(self, afterTaskName, *args): self._validate_tasks(args) if not self.has_task(afterTaskName): raise KeyError(afterTaskName) seq = list(self._calls.items()) for i, v in enumerate(seq): if v[0] == afterTaskName: for c in args: # List insert() inserts before the given index. seq.insert(i + 1, c) i += 1 break self._calls = OrderedDict(seq) return self ## @brief Execute each task in order. # # A task may return a CallSequence, in which case the new sequence is immediately # executed. def invoke(self): for name, call in self._calls.items(): log.debug("Running task %s", name) resultSequence = call() # Invoke returned call sequence. if resultSequence is not None and isinstance(resultSequence, CallSequence): # log.debug("Invoking returned call sequence: %s", resultSequence) resultSequence.invoke() ## @brief Another way to execute the tasks. # # Supports nested CallSequences. def __call__(self, *args, **kwargs): self.invoke() ## @brief Iterate over the sequence. def __iter__(self): return iter(self._calls.items()) def __repr__(self): s = "<%s@%x: " % (self.__class__.__name__, id(self)) for name, task in self._calls.items(): s += "\n%s: %s" % (name, task) s += ">" return s pyocd-0.13.1/pyocd/utility/conversion.py0000644000175000017500000000557313373511253020207 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import struct import binascii import six def byte_list_to_u32le_list(data): """Convert a list of bytes to a list of 32-bit integers (little endian)""" res = [] for i in range(len(data) // 4): res.append(data[i * 4 + 0] | data[i * 4 + 1] << 8 | data[i * 4 + 2] << 16 | data[i * 4 + 3] << 24) return res def u32le_list_to_byte_list(data): """Convert a word array into a byte array""" res = [] for x in data: res.append((x >> 0) & 0xff) res.append((x >> 8) & 0xff) res.append((x >> 16) & 0xff) res.append((x >> 24) & 0xff) return res def u16le_list_to_byte_list(data): """Convert a halfword array into a byte array""" byteData = [] for h in data: byteData.extend([h & 0xff, (h >> 8) & 0xff]) return byteData def byte_list_to_u16le_list(byteData): """Convert a byte array into a halfword array""" data = [] for i in range(0, len(byteData), 2): data.append(byteData[i] | (byteData[i + 1] << 8)) return data def u32_to_float32(data): """Convert a 32-bit int to an IEEE754 float""" d = struct.pack(">I", data) return struct.unpack(">f", d)[0] def float32_to_u32(data): """Convert an IEEE754 float to a 32-bit int""" d = struct.pack(">f", data) return struct.unpack(">I", d)[0] def u32_to_hex8le(val): """Create 8-digit hexadecimal string from 32-bit register value""" return ''.join("%02x" % (x & 0xFF) for x in ( val, val >> 8, val >> 16, val >> 24, )) def hex8_to_u32be(data): """Build 32-bit register value from little-endian 8-digit hexadecimal string""" return int(data[6:8] + data[4:6] + data[2:4] + data[0:2], 16) def hex8_to_u32le(data): """Build 32-bit register value from little-endian 8-digit hexadecimal string""" return int(data[0:2] + data[2:4] + data[4:6] + data[6:8], 16) def byte_to_hex2(val): """Create 2-digit hexadecimal string from 8-bit value""" return "%02x" % int(val) def hex_to_byte_list(data): """Convert string of hex bytes to list of integers""" return list(six.iterbytes(binascii.unhexlify(data))) def hex_decode(cmd): return binascii.unhexlify(cmd) def hex_encode(string): return binascii.hexlify(string) pyocd-0.13.1/pyocd/flash/0000755000175000017500000000000013373523011015023 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/flash/__init__.py0000644000175000017500000000113513373511253017141 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ pyocd-0.13.1/pyocd/flash/flash.py0000644000175000017500000004010413373511253016476 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..core.target import Target import logging from struct import unpack from time import time from .flash_builder import FlashBuilder DEFAULT_PAGE_PROGRAM_WEIGHT = 0.130 DEFAULT_PAGE_ERASE_WEIGHT = 0.048 DEFAULT_CHIP_ERASE_WEIGHT = 0.174 # Program to compute the CRC of sectors. This works on cortex-m processors. # Code is relocatable and only needs to be on a 4 byte boundary. # 200 bytes of executable data below + 1024 byte crc table = 1224 bytes # Usage requirements: # -In memory reserve 0x600 for code & table # -Make sure data buffer is big enough to hold 4 bytes for each page that could be checked (ie. >= num pages * 4) analyzer = ( 0x2780b5f0, 0x25004684, 0x4e2b2401, 0x447e4a2b, 0x0023007f, 0x425b402b, 0x40130868, 0x08584043, 0x425b4023, 0x40584013, 0x40200843, 0x40104240, 0x08434058, 0x42404020, 0x40584010, 0x40200843, 0x40104240, 0x08434058, 0x42404020, 0x40584010, 0x40200843, 0x40104240, 0x08584043, 0x425b4023, 0x40434013, 0xc6083501, 0xd1d242bd, 0xd01f2900, 0x46602301, 0x469c25ff, 0x00894e11, 0x447e1841, 0x88034667, 0x409f8844, 0x2f00409c, 0x2201d012, 0x4252193f, 0x34017823, 0x402b4053, 0x599b009b, 0x405a0a12, 0xd1f542bc, 0xc00443d2, 0xd1e74281, 0xbdf02000, 0xe7f82200, 0x000000b2, 0xedb88320, 0x00000042, ) def _msb(n): ndx = 0 while (1 < n): n = (n >> 1) ndx += 1 return ndx def _same(d1, d2): if len(d1) != len(d2): return False for i in range(len(d1)): if d1[i] != d2[i]: return False return True class PageInfo(object): def __init__(self): self.base_addr = None # Start address of this page self.erase_weight = None # Time it takes to erase a page self.program_weight = None # Time it takes to program a page (Not including data transfer time) self.size = None # Size of page def __repr__(self): return "" \ % (id(self), self.base_addr, self.size, self.erase_weight, self.program_weight) class FlashInfo(object): def __init__(self): self.rom_start = None # Starting address of ROM self.erase_weight = None # Time it takes to perform a chip erase self.crc_supported = None # Is the function compute_crcs supported? def __repr__(self): return "" \ % (id(self), self.rom_start, self._erase_weight, self.crc_supported) class Flash(object): """ This class is responsible to flash a new binary in a target """ def __init__(self, target, flash_algo): self.target = target self.flash_algo = flash_algo self.flash_algo_debug = False if flash_algo is not None: self.is_valid = True self.use_analyzer = flash_algo['analyzer_supported'] self.end_flash_algo = flash_algo['load_address'] + len(flash_algo) * 4 self.begin_stack = flash_algo['begin_stack'] self.begin_data = flash_algo['begin_data'] self.static_base = flash_algo['static_base'] self.min_program_length = flash_algo.get('min_program_length', 0) # Check for double buffering support. if 'page_buffers' in flash_algo: self.page_buffers = flash_algo['page_buffers'] else: self.page_buffers = [self.begin_data] self.double_buffer_supported = len(self.page_buffers) > 1 else: self.is_valid = False self.use_analyzer = False self.end_flash_algo = None self.begin_stack = None self.begin_data = None self.static_base = None self.min_program_length = 0 self.page_buffers = [] self.double_buffer_supported = False @property def minimum_program_length(self): return self.min_program_length @property def page_buffer_count(self): return len(self.page_buffers) @property def is_double_buffering_supported(self): return self.double_buffer_supported def init(self, reset=True): """ Download the flash algorithm in RAM """ self.target.halt() if reset: self.target.set_target_state("PROGRAM") # update core register to execute the init subroutine result = self._call_function_and_wait(self.flash_algo['pc_init'], init=True) # check the return code if result != 0: logging.error('init error: %i', result) def cleanup(self): pass def compute_crcs(self, sectors): data = [] # Convert address, size pairs into commands # for the crc computation algorithm to preform for addr, size in sectors: size_val = _msb(size) addr_val = addr // size # Size must be a power of 2 assert (1 << size_val) == size # Address must be a multiple of size assert (addr % size) == 0 val = (size_val << 0) | (addr_val << 16) data.append(val) self.target.write_memory_block32(self.begin_data, data) # update core register to execute the subroutine result = self._call_function_and_wait(self.flash_algo['analyzer_address'], self.begin_data, len(data)) # Read back the CRCs for each section data = self.target.read_memory_block32(self.begin_data, len(data)) return data def erase_all(self): """ Erase all the flash """ # update core register to execute the erase_all subroutine result = self._call_function_and_wait(self.flash_algo['pc_eraseAll']) # check the return code if result != 0: logging.error('erase_all error: %i', result) def erase_page(self, flashPtr): """ Erase one page """ # update core register to execute the erase_page subroutine result = self._call_function_and_wait(self.flash_algo['pc_erase_sector'], flashPtr) # check the return code if result != 0: logging.error('erase_page(0x%x) error: %i', flashPtr, result) def program_page(self, flashPtr, bytes): """ Flash one page """ # prevent security settings from locking the device bytes = self.override_security_bits(flashPtr, bytes) # first transfer in RAM self.target.write_memory_block8(self.begin_data, bytes) # get info about this page page_info = self.get_page_info(flashPtr) # update core register to execute the program_page subroutine result = self._call_function_and_wait(self.flash_algo['pc_program_page'], flashPtr, len(bytes), self.begin_data) # check the return code if result != 0: logging.error('program_page(0x%x) error: %i', flashPtr, result) def start_program_page_with_buffer(self, bufferNumber, flashPtr): """ Flash one page """ assert bufferNumber < len(self.page_buffers), "Invalid buffer number" # get info about this page page_info = self.get_page_info(flashPtr) # update core register to execute the program_page subroutine result = self._call_function(self.flash_algo['pc_program_page'], flashPtr, page_info.size, self.page_buffers[bufferNumber]) def load_page_buffer(self, bufferNumber, flashPtr, bytes): assert bufferNumber < len(self.page_buffers), "Invalid buffer number" # prevent security settings from locking the device bytes = self.override_security_bits(flashPtr, bytes) # transfer the buffer to device RAM self.target.write_memory_block8(self.page_buffers[bufferNumber], bytes) def program_phrase(self, flashPtr, bytes): """ Flash a portion of a page. """ # Get min programming length. If one was not specified, use the page size. if self.min_program_length: min_len = self.min_program_length else: min_len = self.get_page_info(flashPtr).size # Require write address and length to be aligned to min write size. if flashPtr % min_len: raise RuntimeError("unaligned flash write address") if len(bytes) % min_len: raise RuntimeError("phrase length is unaligned or too small") # prevent security settings from locking the device bytes = self.override_security_bits(flashPtr, bytes) # first transfer in RAM self.target.write_memory_block8(self.begin_data, bytes) # update core register to execute the program_page subroutine result = self._call_function_and_wait(self.flash_algo['pc_program_page'], flashPtr, len(bytes), self.begin_data) # check the return code if result != 0: logging.error('program_phrase(0x%x) error: %i', flashPtr, result) def get_page_info(self, addr): """ Get info about the page that contains this address Override this function if variable page sizes are supported """ region = self.target.get_memory_map().get_region_for_address(addr) if not region or not region.is_flash: return None info = PageInfo() info.erase_weight = DEFAULT_PAGE_ERASE_WEIGHT info.program_weight = DEFAULT_PAGE_PROGRAM_WEIGHT info.size = region.blocksize info.base_addr = addr - (addr % info.size) return info def get_flash_info(self): """ Get info about the flash Override this function to return differnt values """ boot_region = self.target.get_memory_map().get_boot_memory() info = FlashInfo() info.rom_start = boot_region.start if boot_region else 0 info.erase_weight = DEFAULT_CHIP_ERASE_WEIGHT info.crc_supported = self.use_analyzer return info def get_flash_builder(self): return FlashBuilder(self, self.get_flash_info().rom_start) def flash_block(self, addr, data, smart_flash=True, chip_erase=None, progress_cb=None, fast_verify=False): """ Flash a block of data """ flash_start = self.get_flash_info().rom_start fb = FlashBuilder(self, flash_start) fb.add_data(addr, data) info = fb.program(chip_erase, progress_cb, smart_flash, fast_verify) return info def flash_binary(self, path_file, flashPtr=None, smart_flash=True, chip_erase=None, progress_cb=None, fast_verify=False): """ Flash a binary """ if flashPtr is None: flashPtr = self.get_flash_info().rom_start f = open(path_file, "rb") with open(path_file, "rb") as f: data = f.read() data = unpack(str(len(data)) + 'B', data) self.flash_block(flashPtr, data, smart_flash, chip_erase, progress_cb, fast_verify) def _call_function(self, pc, r0=None, r1=None, r2=None, r3=None, init=False): reg_list = [] data_list = [] if self.flash_algo_debug: # Save vector catch state for use in wait_for_completion() self._saved_vector_catch = self.target.get_vector_catch() self.target.set_vector_catch(Target.CATCH_ALL) if init: # download flash algo in RAM self.target.write_memory_block32(self.flash_algo['load_address'], self.flash_algo['instructions']) if self.use_analyzer: self.target.write_memory_block32(self.flash_algo['analyzer_address'], analyzer) reg_list.append('pc') data_list.append(pc) if r0 is not None: reg_list.append('r0') data_list.append(r0) if r1 is not None: reg_list.append('r1') data_list.append(r1) if r2 is not None: reg_list.append('r2') data_list.append(r2) if r3 is not None: reg_list.append('r3') data_list.append(r3) if init: reg_list.append('r9') data_list.append(self.static_base) if init: reg_list.append('sp') data_list.append(self.begin_stack) reg_list.append('lr') data_list.append(self.flash_algo['load_address'] + 1) self.target.write_core_registers_raw(reg_list, data_list) # resume target self.target.resume() ## @brief Wait until the breakpoint is hit. def wait_for_completion(self): while(self.target.get_state() == Target.TARGET_RUNNING): pass if self.flash_algo_debug: regs = self.target.read_core_registers_raw(list(range(19)) + [20]) logging.debug("Registers after flash algo: [%s]", " ".join("%08x" % r for r in regs)) expected_fp = self.flash_algo['static_base'] expected_sp = self.flash_algo['begin_stack'] expected_pc = self.flash_algo['load_address'] expected_flash_algo = self.flash_algo['instructions'] if self.use_analyzer: expected_analyzer = analyzer final_ipsr = self.target.read_core_register('ipsr') final_fp = self.target.read_core_register('r9') final_sp = self.target.read_core_register('sp') final_pc = self.target.read_core_register('pc') #TODO - uncomment if Read/write and zero init sections can be moved into a separate flash algo section #final_flash_algo = self.target.read_memory_block32(self.flash_algo['load_address'], len(self.flash_algo['instructions'])) #if self.use_analyzer: # final_analyzer = self.target.read_memory_block32(self.flash_algo['analyzer_address'], len(analyzer)) error = False if final_ipsr != 0: logging.error("IPSR should be 0 but is 0x%x", final_ipsr) error = True if final_fp != expected_fp: # Frame pointer should not change logging.error("Frame pointer should be 0x%x but is 0x%x" % (expected_fp, final_fp)) error = True if final_sp != expected_sp: # Stack pointer should return to original value after function call logging.error("Stack pointer should be 0x%x but is 0x%x" % (expected_sp, final_sp)) error = True if final_pc != expected_pc: # PC should be pointing to breakpoint address logging.error("PC should be 0x%x but is 0x%x" % (expected_pc, final_pc)) error = True #TODO - uncomment if Read/write and zero init sections can be moved into a separate flash algo section #if not _same(expected_flash_algo, final_flash_algo): # logging.error("Flash algorithm overwritten!") # error = True #if self.use_analyzer and not _same(expected_analyzer, final_analyzer): # logging.error("Analyzer overwritten!") # error = True assert error == False self.target.set_vector_catch(self._saved_vector_catch) return self.target.read_core_register('r0') def _call_function_and_wait(self, pc, r0=None, r1=None, r2=None, r3=None, init=False): self._call_function(pc, r0, r1, r2, r3, init) return self.wait_for_completion() def set_flash_algo_debug(self, enable): """ Turn on extra flash algorithm checking When set this will greatly slow down flash algo performance """ self.flash_algo_debug = enable def override_security_bits(self, address, data): return data pyocd-0.13.1/pyocd/flash/flash_builder.py0000644000175000017500000006061713373511253020217 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..core.target import Target from ..utility.notification import Notification import logging from struct import unpack from time import time from binascii import crc32 # Number of bytes in a page to read to quickly determine if the page has the same data PAGE_ESTIMATE_SIZE = 32 PAGE_READ_WEIGHT = 0.3 DATA_TRANSFER_B_PER_S = 40 * 1000 # ~40KB/s, depends on clock speed, theoretical limit for HID is 56,000 B/s ## @brief Exception raised when flashing fails outright. class FlashFailure(RuntimeError): pass class ProgrammingInfo(object): def __init__(self): self.program_type = None # Type of programming performed - FLASH_PAGE_ERASE or FLASH_CHIP_ERASE self.program_time = None # Total programming time self.analyze_type = None # Type of flash analysis performed - FLASH_ANALYSIS_CRC32 or FLASH_ANALYSIS_PARTIAL_PAGE_READ self.analyze_time = None # Time to analyze flash contents def _same(d1, d2): assert len(d1) == len(d2) for i in range(len(d1)): if d1[i] != d2[i]: return False return True def _erased(d): for i in range(len(d)): if d[i] != 0xFF: return False return True def _stub_progress(percent): pass class FlashPage(object): def __init__(self, addr, size, data, erase_weight, program_weight): self.addr = addr self.size = size self.data = data self.erase_weight = erase_weight self.program_weight = program_weight self.erased = None self.same = None def get_program_weight(self): """ Get time to program a page including the data transfer """ return self.program_weight + \ float(len(self.data)) / float(DATA_TRANSFER_B_PER_S) def get_erase_program_weight(self): """ Get time to erase and program a page including data transfer time """ return self.erase_weight + self.program_weight + \ float(len(self.data)) / float(DATA_TRANSFER_B_PER_S) def get_verify_weight(self): """ Get time to verify a page """ return float(self.size) / float(DATA_TRANSFER_B_PER_S) class FlashOperation(object): def __init__(self, addr, data): self.addr = addr self.data = data class FlashBuilder(object): # Type of flash operation FLASH_PAGE_ERASE = 1 FLASH_CHIP_ERASE = 2 # Type of flash analysis FLASH_ANALYSIS_CRC32 = "CRC32" FLASH_ANALYSIS_PARTIAL_PAGE_READ = "PAGE_READ" def __init__(self, flash, base_addr=0): self.flash = flash self.flash_start = base_addr self.flash_operation_list = [] self.page_list = [] self.perf = ProgrammingInfo() self.enable_double_buffering = True self.max_errors = 10 def enable_double_buffer(self, enable): self.enable_double_buffering = enable def set_max_errors(self, count): self.max_errors = count def add_data(self, addr, data): """ Add a block of data to be programmed Note - programming does not start until the method program is called. """ # Sanity check if addr < self.flash_start: raise Exception("Invalid flash address 0x%x is before flash start 0x%x" % (addr, self.flash_start)) # Add operation to list self.flash_operation_list.append(FlashOperation(addr, data)) # Keep list sorted self.flash_operation_list = sorted(self.flash_operation_list, key=lambda operation: operation.addr) # Verify this does not overlap prev_flash_operation = None for operation in self.flash_operation_list: if prev_flash_operation != None: if prev_flash_operation.addr + len(prev_flash_operation.data) > operation.addr: raise ValueError("Error adding data - Data at 0x%x..0x%x overlaps with 0x%x..0x%x" % (prev_flash_operation.addr, prev_flash_operation.addr + len(prev_flash_operation.data), operation.addr, operation.addr + len(operation.data))) prev_flash_operation = operation def program(self, chip_erase=None, progress_cb=None, smart_flash=True, fast_verify=False): """ Determine fastest method of flashing and then run flash programming. Data must have already been added with add_data """ # Send notification that we're about to program flash. self.flash.target.notify(Notification(event=Target.EVENT_PRE_FLASH_PROGRAM, source=self)) # Assumptions # 1. Page erases must be on page boundaries ( page_erase_addr % page_size == 0 ) # 2. Page erase can have a different size depending on location # 3. It is safe to program a page with less than a page of data # Examples # - lpc4330 -Non 0 base address # - nRF51 -UICR location far from flash (address 0x10001000) # - LPC1768 -Different sized pages program_start = time() if progress_cb is None: progress_cb = _stub_progress # There must be at least 1 flash operation if len(self.flash_operation_list) == 0: logging.warning("No pages were programmed") return # Convert the list of flash operations into flash pages program_byte_count = 0 flash_addr = self.flash_operation_list[0].addr info = self.flash.get_page_info(flash_addr) if info is None: raise FlashFailure("Attempt to program flash at invalid address 0x%08x" % flash_addr) page_addr = flash_addr - (flash_addr % info.size) current_page = FlashPage(page_addr, info.size, [], info.erase_weight, info.program_weight) self.page_list.append(current_page) for flash_operation in self.flash_operation_list: pos = 0 while pos < len(flash_operation.data): # Check if operation is in next page flash_addr = flash_operation.addr + pos if flash_addr >= current_page.addr + current_page.size: info = self.flash.get_page_info(flash_addr) if info is None: raise FlashFailure("Attempt to program flash at invalid address 0x%08x" % flash_addr) page_addr = flash_addr - (flash_addr % info.size) current_page = FlashPage(page_addr, info.size, [], info.erase_weight, info.program_weight) self.page_list.append(current_page) # Fill the page gap if there is one page_data_end = current_page.addr + len(current_page.data) if flash_addr != page_data_end: old_data = self.flash.target.read_memory_block8(page_data_end, flash_addr - page_data_end) current_page.data.extend(old_data) # Copy data to page and increment pos space_left_in_page = info.size - len(current_page.data) space_left_in_data = len(flash_operation.data) - pos amount = min(space_left_in_page, space_left_in_data) current_page.data.extend(flash_operation.data[pos:pos + amount]) program_byte_count += amount #increment position pos += amount # If smart flash was set to false then mark all pages # as requiring programming if not smart_flash: self._mark_all_pages_for_programming() # If the first page being programmed is not the first page # in ROM then don't use a chip erase if self.page_list[0].addr > self.flash_start: if chip_erase is None: chip_erase = False elif chip_erase is True: logging.warning('Chip erase used when flash address 0x%x is not the same as flash start 0x%x', self.page_list[0].addr, self.flash_start) self.flash.init() chip_erase_count, chip_erase_program_time = self._compute_chip_erase_pages_and_weight() page_erase_min_program_time = self._compute_page_erase_pages_weight_min() # If chip_erase hasn't been specified determine if chip erase is faster # than page erase regardless of contents if (chip_erase is None) and (chip_erase_program_time < page_erase_min_program_time): chip_erase = True # If chip erase isn't True then analyze the flash if chip_erase != True: analyze_start = time() if self.flash.get_flash_info().crc_supported: sector_erase_count, page_program_time = self._compute_page_erase_pages_and_weight_crc32(fast_verify) self.perf.analyze_type = FlashBuilder.FLASH_ANALYSIS_CRC32 else: sector_erase_count, page_program_time = self._compute_page_erase_pages_and_weight_sector_read() self.perf.analyze_type = FlashBuilder.FLASH_ANALYSIS_PARTIAL_PAGE_READ analyze_finish = time() self.perf.analyze_time = analyze_finish - analyze_start logging.debug("Analyze time: %f" % (analyze_finish - analyze_start)) # If chip erase hasn't been set then determine fastest method to program if chip_erase is None: logging.debug("Chip erase count %i, Page erase est count %i" % (chip_erase_count, sector_erase_count)) logging.debug("Chip erase weight %f, Page erase weight %f" % (chip_erase_program_time, page_program_time)) chip_erase = chip_erase_program_time < page_program_time if chip_erase: if self.flash.is_double_buffering_supported and self.enable_double_buffering: logging.debug("Using double buffer chip erase program") flash_operation = self._chip_erase_program_double_buffer(progress_cb) else: flash_operation = self._chip_erase_program(progress_cb) else: if self.flash.is_double_buffering_supported and self.enable_double_buffering: logging.debug("Using double buffer page erase program") flash_operation = self._page_erase_program_double_buffer(progress_cb) else: flash_operation = self._page_erase_program(progress_cb) self.flash.target.reset_stop_on_reset() program_finish = time() self.perf.program_time = program_finish - program_start self.perf.program_type = flash_operation logging.info("Programmed %d bytes (%d pages) at %.02f kB/s", program_byte_count, len(self.page_list), ((program_byte_count/1024) / self.perf.program_time)) # Send notification that we're done programming flash. self.flash.target.notify(Notification(event=Target.EVENT_POST_FLASH_PROGRAM, source=self)) return self.perf def get_performance(self): return self.perf def _mark_all_pages_for_programming(self): for page in self.page_list: page.erased = False page.same = False def _compute_chip_erase_pages_and_weight(self): """ Compute the number of erased pages. Determine how many pages in the new data are already erased. """ chip_erase_count = 0 chip_erase_weight = 0 chip_erase_weight += self.flash.get_flash_info().erase_weight for page in self.page_list: if page.erased is None: page.erased = _erased(page.data) if not page.erased: chip_erase_count += 1 chip_erase_weight += page.get_program_weight() self.chip_erase_count = chip_erase_count self.chip_erase_weight = chip_erase_weight return chip_erase_count, chip_erase_weight def _compute_page_erase_pages_weight_min(self): page_erase_min_weight = 0 for page in self.page_list: page_erase_min_weight += page.get_verify_weight() return page_erase_min_weight def _compute_page_erase_pages_and_weight_sector_read(self): """ Estimate how many pages are the same. Quickly estimate how many pages are the same. These estimates are used by page_erase_program so it is recommended to call this before beginning programming This is done automatically by smart_program. """ # Quickly estimate how many pages are the same page_erase_count = 0 page_erase_weight = 0 for page in self.page_list: # Analyze pages that haven't been analyzed yet if page.same is None: size = min(PAGE_ESTIMATE_SIZE, len(page.data)) data = self.flash.target.read_memory_block8(page.addr, size) page_same = _same(data, page.data[0:size]) if page_same is False: page.same = False # Put together page and time estimate for page in self.page_list: if page.same is False: page_erase_count += 1 page_erase_weight += page.get_erase_program_weight() elif page.same is None: # Page is probably the same but must be read to confirm page_erase_weight += page.get_verify_weight() elif page.same is True: # Page is confirmed to be the same so no programming weight pass self.page_erase_count = page_erase_count self.page_erase_weight = page_erase_weight return page_erase_count, page_erase_weight def _compute_page_erase_pages_and_weight_crc32(self, assume_estimate_correct=False): """ Estimate how many pages are the same. Quickly estimate how many pages are the same. These estimates are used by page_erase_program so it is recommended to call this before beginning programming This is done automatically by smart_program. If assume_estimate_correct is set to True, then pages with matching CRCs will be marked as the same. There is a small chance that the CRCs match even though the data is different, but the odds of this happing are low: ~1/(2^32) = ~2.33*10^-8%. """ # Build list of all the pages that need to be analyzed sector_list = [] page_list = [] for page in self.page_list: if page.same is None: # Add sector to compute_crcs sector_list.append((page.addr, page.size)) page_list.append(page) # Compute CRC of data (Padded with 0xFF) data = list(page.data) pad_size = page.size - len(page.data) if pad_size > 0: data.extend([0xFF] * pad_size) page.crc = crc32(bytearray(data)) & 0xFFFFFFFF # Analyze pages page_erase_count = 0 page_erase_weight = 0 if len(page_list) > 0: crc_list = self.flash.compute_crcs(sector_list) for page, crc in zip(page_list, crc_list): page_same = page.crc == crc if assume_estimate_correct: page.same = page_same elif page_same is False: page.same = False # Put together page and time estimate for page in self.page_list: if page.same is False: page_erase_count += 1 page_erase_weight += page.get_erase_program_weight() elif page.same is None: # Page is probably the same but must be read to confirm page_erase_weight += page.get_verify_weight() elif page.same is True: # Page is confirmed to be the same so no programming weight pass self.page_erase_count = page_erase_count self.page_erase_weight = page_erase_weight return page_erase_count, page_erase_weight def _chip_erase_program(self, progress_cb=_stub_progress): """ Program by first performing a chip erase. """ logging.debug("Smart chip erase") logging.debug("%i of %i pages already erased", len(self.page_list) - self.chip_erase_count, len(self.page_list)) progress_cb(0.0) progress = 0 self.flash.erase_all() progress += self.flash.get_flash_info().erase_weight for page in self.page_list: if not page.erased: self.flash.program_page(page.addr, page.data) progress += page.get_program_weight() progress_cb(float(progress) / float(self.chip_erase_weight)) progress_cb(1.0) return FlashBuilder.FLASH_CHIP_ERASE def _next_unerased_page(self, i): if i >= len(self.page_list): return None, i page = self.page_list[i] while page.erased: i += 1 if i >= len(self.page_list): return None, i page = self.page_list[i] return page, i + 1 def _chip_erase_program_double_buffer(self, progress_cb=_stub_progress): """ Program by first performing a chip erase. """ logging.debug("Smart chip erase") logging.debug("%i of %i pages already erased", len(self.page_list) - self.chip_erase_count, len(self.page_list)) progress_cb(0.0) progress = 0 self.flash.erase_all() progress += self.flash.get_flash_info().erase_weight # Set up page and buffer info. error_count = 0 current_buf = 0 next_buf = 1 page, i = self._next_unerased_page(0) assert page is not None # Load first page buffer self.flash.load_page_buffer(current_buf, page.addr, page.data) while page is not None: # Kick off this page program. current_addr = page.addr current_weight = page.get_program_weight() self.flash.start_program_page_with_buffer(current_buf, current_addr) # Get next page and load it. page, i = self._next_unerased_page(i) if page is not None: self.flash.load_page_buffer(next_buf, page.addr, page.data) # Wait for the program to complete. result = self.flash.wait_for_completion() # check the return code if result != 0: logging.error('program_page(0x%x) error: %i', current_addr, result) error_count += 1 if error_count > self.max_errors: logging.error("Too many page programming errors, aborting program operation") break # Swap buffers. temp = current_buf current_buf = next_buf next_buf = temp # Update progress. progress += current_weight progress_cb(float(progress) / float(self.chip_erase_weight)) progress_cb(1.0) return FlashBuilder.FLASH_CHIP_ERASE def _page_erase_program(self, progress_cb=_stub_progress): """ Program by performing sector erases. """ actual_page_erase_count = 0 actual_page_erase_weight = 0 progress = 0 progress_cb(0.0) for page in self.page_list: # If the page is not the same if page.same is False: progress += page.get_erase_program_weight() # Read page data if unknown - after this page.same will be True or False if page.same is None: data = self.flash.target.read_memory_block8(page.addr, len(page.data)) page.same = _same(page.data, data) progress += page.get_verify_weight() # Program page if not the same if page.same is False: self.flash.erase_page(page.addr) self.flash.program_page(page.addr, page.data) actual_page_erase_count += 1 actual_page_erase_weight += page.get_erase_program_weight() # Update progress if self.page_erase_weight > 0: progress_cb(float(progress) / float(self.page_erase_weight)) progress_cb(1.0) logging.debug("Estimated page erase count: %i", self.page_erase_count) logging.debug("Actual page erase count: %i", actual_page_erase_count) return FlashBuilder.FLASH_PAGE_ERASE def _scan_pages_for_same(self, progress_cb=_stub_progress): """ Program by performing sector erases. """ progress = 0 count = 0 same_count = 0 for page in self.page_list: # Read page data if unknown - after this page.same will be True or False if page.same is None: data = self.flash.target.read_memory_block8(page.addr, len(page.data)) page.same = _same(page.data, data) progress += page.get_verify_weight() count += 1 if page.same: same_count += 1 # Update progress progress_cb(float(progress) / float(self.page_erase_weight)) return progress def _next_nonsame_page(self, i): if i >= len(self.page_list): return None, i page = self.page_list[i] while page.same: i += 1 if i >= len(self.page_list): return None, i page = self.page_list[i] return page, i + 1 def _page_erase_program_double_buffer(self, progress_cb=_stub_progress): """ Program by performing sector erases. """ actual_page_erase_count = 0 actual_page_erase_weight = 0 progress = 0 progress_cb(0.0) # Fill in same flag for all pages. This is done up front so we're not trying # to read from flash while simultaneously programming it. progress = self._scan_pages_for_same(progress_cb) # Set up page and buffer info. error_count = 0 current_buf = 0 next_buf = 1 page, i = self._next_nonsame_page(0) # Make sure there are actually pages to program differently from current flash contents. if page is not None: # Load first page buffer self.flash.load_page_buffer(current_buf, page.addr, page.data) while page is not None: assert page.same is not None # Kick off this page program. current_addr = page.addr current_weight = page.get_erase_program_weight() self.flash.erase_page(current_addr) self.flash.start_program_page_with_buffer(current_buf, current_addr) #, erase_page=True) actual_page_erase_count += 1 actual_page_erase_weight += page.get_erase_program_weight() # Get next page and load it. page, i = self._next_nonsame_page(i) if page is not None: self.flash.load_page_buffer(next_buf, page.addr, page.data) # Wait for the program to complete. result = self.flash.wait_for_completion() # check the return code if result != 0: logging.error('program_page(0x%x) error: %i', current_addr, result) error_count += 1 if error_count > self.max_errors: logging.error("Too many page programming errors, aborting program operation") break # Swap buffers. temp = current_buf current_buf = next_buf next_buf = temp # Update progress progress += current_weight if self.page_erase_weight > 0: progress_cb(float(progress) / float(self.page_erase_weight)) progress_cb(1.0) logging.debug("Estimated page erase count: %i", self.page_erase_count) logging.debug("Actual page erase count: %i", actual_page_erase_count) return FlashBuilder.FLASH_PAGE_ERASE pyocd-0.13.1/pyocd/_version.py0000644000175000017500000000016513373523011016126 0ustar neilneil00000000000000# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control version = '0.13.1' pyocd-0.13.1/pyocd/__init__.py0000644000175000017500000000146613373511253016053 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 . import board from . import core from . import debug from . import flash from . import gdbserver from . import target from . import utility from . import coresight from ._version import version as __version__ pyocd-0.13.1/pyocd/rtos/0000755000175000017500000000000013373523011014715 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/rtos/zephyr.py0000644000175000017500000003305413373511253016622 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .provider import (TargetThread, ThreadProvider) from .common import (read_c_string, HandlerModeThread) from ..core import exceptions from ..core.target import Target from ..debug.context import DebugContext from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index) import logging # Create a logger for this module. log = logging.getLogger("zephyr") class TargetList(object): def __init__(self, context, ptr, next_offset): self._context = context self._list = ptr self._list_node_next_offset = next_offset def __iter__(self): node = self._context.read32(self._list) while (node != 0): try: yield node # Read next list node pointer. node = self._context.read32(node + self._list_node_next_offset) except exceptions.TransferError: log.warning("TransferError while reading list elements (list=0x%08x, node=0x%08x), terminating list", self._list, node) node = 0 ## @brief class ZephyrThreadContext(DebugContext): STACK_FRAME_OFFSETS = { 0: 0, # r0 1: 4, # r1 2: 8, # r2 3: 12, # r3 12: 16, # r12 14: 20, # lr 15: 24, # pc 16: 28, # xpsr } CALLEE_SAVED_OFFSETS = { 4: -32, # r4 5: -28, # r5 6: -24, # r6 7: -20, # r7 8: -16, # r8 9: -12, # r9 10: -8, # r10 11: -4, # r11 13: 0, # r13/sp } def __init__(self, parentContext, thread): super(ZephyrThreadContext, self).__init__(parentContext.core) self._parent = parentContext self._thread = thread self._has_fpu = parentContext.core.has_fpu def read_core_registers_raw(self, reg_list): reg_list = [register_name_to_index(reg) for reg in reg_list] reg_vals = [] inException = self._parent.read_core_register('ipsr') > 0 isCurrent = self._thread.is_current # If this is the current thread and we're not in an exception, just read the live registers. if isCurrent and not inException: log.debug("Reading live registers") return self._parent.read_core_registers_raw(reg_list) sp = self._thread.get_stack_pointer() exceptionFrame = 0x20 for reg in reg_list: # If this is a stack pointer register, add an offset to account for the exception stack frame if reg == 13 or reg == 18: val = sp + exceptionFrame log.debug("Reading register %d = 0x%x", reg, val) reg_vals.append(val) continue # If this is a callee-saved register, read it from the thread structure calleeOffset = self.CALLEE_SAVED_OFFSETS.get(reg, None) if calleeOffset is not None: try: addr = self._thread._base + self._thread._offsets["t_stack_ptr"] + calleeOffset val = self._parent.read32(addr) reg_vals.append(val) log.debug("Reading callee-saved register %d at 0x%08x = 0x%x", reg, addr, val) except exceptions.TransferError: reg_vals.append(0) continue # If this is a exception stack frame register, read it from the stack stackFrameOffset = self.STACK_FRAME_OFFSETS.get(reg, None) if stackFrameOffset is not None: try: addr = sp + stackFrameOffset val = self._parent.read32(addr) reg_vals.append(val) log.debug("Reading stack frame register %d at 0x%08x = 0x%x", reg, addr, val) except exceptions.TransferError: reg_vals.append(0) continue # If we get here, this is a register not in any of the dictionaries val = self._parent.read_core_register(reg) log.debug("Reading live register %d = 0x%x", reg, val) reg_vals.append(val) continue return reg_vals def write_core_registers_raw(self, reg_list, data_list): self._parent.write_core_registers_raw(reg_list, data_list) ## @brief A Zephyr task. class ZephyrThread(TargetThread): READY = 0 PENDING = 1 << 1 PRESTART = 1 << 2 DEAD = 1 << 3 SUSPENDED = 1 << 4 POLLING = 1 << 5 RUNNING = 1 << 6 STATE_NAMES = { READY : "Ready", PENDING : "Pending", PRESTART : "Prestart", DEAD : "Dead", SUSPENDED : "Suspended", POLLING : "Polling", RUNNING : "Running", } def __init__(self, targetContext, provider, base, offsets): super(ZephyrThread, self).__init__() self._target_context = targetContext self._provider = provider self._base = base self._thread_context = ZephyrThreadContext(self._target_context, self) self._offsets = offsets self._state = ZephyrThread.READY self._priority = 0 self._name = "Unnamed" try: self.update_info() except exceptions.TransferError: log.debug("Transfer error while reading thread info") def get_stack_pointer(self): if self.is_current: # Read live process stack. sp = self._target_context.read_core_register('psp') else: # Get stack pointer saved in thread struct. addr = self._base + self._offsets["t_stack_ptr"] try: sp = self._target_context.read32(addr) except exceptions.TransferError: log.debug("Transfer error while reading thread's stack pointer @ 0x%08x", addr) return sp def update_info(self): try: self._priority = self._target_context.read8(self._base + self._offsets["t_prio"]) self._state = self._target_context.read8(self._base + self._offsets["t_state"]) if self._provider.version > 0: addr = self._target_context.read32(self._base + self._offsets["t_name"]) if addr != 0: self._name = read_c_string(self._target_context, addr) else: self._name = "Unnamed" except exceptions.TransferError: log.debug("Transfer error while reading thread info") @property def state(self): return self._state @state.setter def state(self, value): self._state = value @property def priority(self): return self._priority @property def unique_id(self): return self._base @property def name(self): return self._name @property def description(self): return "%s; Priority %d" % (self.STATE_NAMES[self.state], self.priority) @property def is_current(self): return self._provider.get_actual_current_thread_id() == self.unique_id @property def context(self): return self._thread_context def __str__(self): return "" % (id(self), self.unique_id, self.name) def __repr__(self): return str(self) ## @brief Thread provider for Zephyr. class ZephyrThreadProvider(ThreadProvider): ## Required Zephyr symbols. ZEPHYR_SYMBOLS = [ "_kernel", "_kernel_openocd_offsets", "_kernel_openocd_size_t_size", ] ZEPHYR_OFFSETS = [ 'version', 'k_curr_thread', 'k_threads', 't_entry', 't_next_thread', 't_state', 't_user_options', 't_prio', 't_stack_ptr', 't_name', ] def __init__(self, target): super(ZephyrThreadProvider, self).__init__(target) self._symbols = None self._offsets = None self._version = None self._all_threads = None self._curr_thread = None self._threads = {} def init(self, symbolProvider): # Lookup required symbols. self._symbols = self._lookup_symbols(self.ZEPHYR_SYMBOLS, symbolProvider) if self._symbols is None: return False self._update() self._target.root_target.subscribe(Target.EVENT_POST_FLASH_PROGRAM, self.event_handler) self._target.subscribe(Target.EVENT_POST_RESET, self.event_handler) return True def _get_offsets(self): # Read the kernel and thread structure member offsets size = self._target_context.read8(self._symbols["_kernel_openocd_size_t_size"]) log.debug("_kernel_openocd_size_t_size = %d", size) if size != 4: log.error("Unsupported _kernel_openocd_size_t_size") return None offsets = {} for index, name in enumerate(self.ZEPHYR_OFFSETS): offset = self._symbols["_kernel_openocd_offsets"] + index * size offsets[name] = self._target_context.read32(offset) log.debug("%s = 0x%04x", name, offsets[name]) return offsets def _update(self): self._offsets = self._get_offsets() if self._offsets is None: self._version = None self._all_threads = None self._curr_thread = None log.debug("_offsets, _all_threads, and _curr_thread are invalid") else: self._version = self._offsets["version"] self._all_threads = self._symbols["_kernel"] + self._offsets["k_threads"] self._curr_thread = self._symbols["_kernel"] + self._offsets["k_curr_thread"] log.debug("version = %d, _all_threads = 0x%08x, _curr_thread = 0x%08x", self._version, self._all_threads, self._curr_thread) def invalidate(self): self._threads = {} def event_handler(self, notification): if notification.event == Target.EVENT_POST_RESET: log.debug("Invalidating threads list: %s" % (repr(notification))) self.invalidate(); elif notification.event == Target.EVENT_POST_FLASH_PROGRAM: self._update() def _build_thread_list(self): allThreads = TargetList(self._target_context, self._all_threads, self._offsets["t_next_thread"]) newThreads = {} currentThread = self._target_context.read32(self._curr_thread) log.debug("currentThread = 0x%08x", currentThread) for threadBase in allThreads: try: # Reuse existing thread objects. if threadBase in self._threads: t = self._threads[threadBase] # Ask the thread object to update its state and priority. t.update_info() else: t = ZephyrThread(self._target_context, self, threadBase, self._offsets) # Set thread state. if threadBase == currentThread: t.state = ZephyrThread.RUNNING log.debug("Thread 0x%08x (%s)", threadBase, t.name) newThreads[t.unique_id] = t except exceptions.TransferError: log.debug("TransferError while examining thread 0x%08x", threadBase) # Create fake handler mode thread. if self._target_context.read_core_register('ipsr') > 0: log.debug("creating handler mode thread") t = HandlerModeThread(self._target_context, self) newThreads[t.unique_id] = t self._threads = newThreads def get_threads(self): if not self.is_enabled: return [] self.update_threads() return list(self._threads.values()) def get_thread(self, threadId): if not self.is_enabled: return None self.update_threads() return self._threads.get(threadId, None) @property def is_enabled(self): return self._symbols is not None and self.get_is_running() @property def current_thread(self): if not self.is_enabled: return None self.update_threads() id = self.get_current_thread_id() try: return self._threads[id] except KeyError: return None def is_valid_thread_id(self, threadId): if not self.is_enabled: return False self.update_threads() return threadId in self._threads def get_current_thread_id(self): if not self.is_enabled: return None if self._target_context.read_core_register('ipsr') > 0: return HandlerModeThread.UNIQUE_ID return self.get_actual_current_thread_id() def get_actual_current_thread_id(self): if not self.is_enabled: return None return self._target_context.read32(self._curr_thread) def get_is_running(self): if self._symbols is None or self._offsets is None: return False # TODO return True @property def version(self): return self._version pyocd-0.13.1/pyocd/rtos/provider.py0000644000175000017500000000630113373511253017126 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import logging ## @brief Base class representing a thread on the target. class TargetThread(object): def __init__(self): pass @property def unique_id(self): raise NotImplementedError() @property def name(self): raise NotImplementedError() @property def description(self): raise NotImplementedError() @property def is_current(self): raise NotImplementedError() @property def context(self): raise NotImplementedError() ## @brief Base class for RTOS support plugins. class ThreadProvider(object): def __init__(self, target): self._target = target self._target_context = self._target.get_target_context() self._last_run_token = -1 self._read_from_target = False def _lookup_symbols(self, symbolList, symbolProvider): syms = {} for name in symbolList: addr = symbolProvider.get_symbol_value(name) logging.debug("Value for symbol %s = %s", name, hex(addr) if addr is not None else "") if addr is None: return None syms[name] = addr return syms ## # @retval True The provider was successfully initialzed. # @retval False The provider could not be initialized successfully. def init(self, symbolProvider): raise NotImplementedError() def _build_thread_list(self): raise NotImplementedError() def _is_thread_list_dirty(self): token = self._target.run_token if token == self._last_run_token: # Target hasn't run since we last updated threads, so there is nothing to do. return False self._last_run_token = token return True def update_threads(self): if self._is_thread_list_dirty() and self._read_from_target: self._build_thread_list() def get_threads(self): raise NotImplementedError() def get_thread(self, threadId): raise NotImplementedError() def invalidate(self): raise NotImplementedError() @property def read_from_target(self): return self._read_from_target @read_from_target.setter def read_from_target(self, value): if value != self._read_from_target: self.invalidate() self._read_from_target = value @property def is_enabled(self): raise NotImplementedError() @property def current_thread(self): raise NotImplementedError() def is_valid_thread_id(self, threadId): raise NotImplementedError() def get_current_thread_id(self): raise NotImplementedError() pyocd-0.13.1/pyocd/rtos/rtx5.py0000644000175000017500000003410013373511253016174 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .provider import (TargetThread, ThreadProvider) from .common import (read_c_string, HandlerModeThread) from ..core import exceptions from ..core.target import Target from ..debug.context import DebugContext from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index) import logging # Create a logger for this module. log = logging.getLogger("rtx5") class TargetList(object): def __init__(self, context, ptr, nextOffset): self._context = context self._list = ptr self._offset = nextOffset def __iter__(self): # Read first item on list. node = self._context.read32(self._list) while node != 0: # Return previously read item. yield node try: # Read the next item in the list. node = self._context.read32(node + self._offset) except exceptions.TransferError as exc: log.warning("TransferError while reading list elements (list=0x%08x, node=0x%08x), terminating list: %s", self._list, node, exc) break ## @brief class RTXThreadContext(DebugContext): # SP/PSP are handled specially, so it is not in these dicts. NOFPU_REGISTER_OFFSETS = { 4: 0, # r4 5: 4, # r5 6: 8, # r6 7: 12, # r7 8: 16, # r8 9: 20, # r9 10: 24, # r10 11: 28, # r11 0: 32, # r0 1: 36, # r1 2: 40, # r2 3: 44, # r3 12: 48, # r12 14: 52, # lr 15: 56, # pc 16: 60, # xpsr } FPU_REGISTER_OFFSETS = { 0x50: 0, # s16 0x51: 4, # s17 0x52: 8, # s18 0x53: 12, # s19 0x54: 16, # s20 0x55: 20, # s21 0x56: 24, # s22 0x57: 28, # s23 0x58: 32, # s24 0x59: 36, # s25 0x5a: 40, # s26 0x5b: 44, # s27 0x5c: 48, # s28 0x5d: 52, # s29 0x5e: 56, # s30 0x5f: 60, # s31 4: 64, # r4 5: 68, # r5 6: 72, # r6 7: 76, # r7 8: 80, # r8 9: 84, # r9 10: 88, # r10 11: 92, # r11 0: 96, # r0 1: 100, # r1 2: 104, # r2 3: 108, # r3 12: 112, # r12 14: 116, # lr 15: 120, # pc 16: 124, # xpsr 0x40: 128, # s0 0x41: 132, # s1 0x42: 136, # s2 0x43: 140, # s3 0x44: 144, # s4 0x45: 148, # s5 0x46: 152, # s6 0x47: 156, # s7 0x48: 160, # s8 0x49: 164, # s9 0x4a: 168, # s10 0x4b: 172, # s11 0x4c: 176, # s12 0x4d: 180, # s13 0x4e: 184, # s14 0x4f: 188, # s15 33: 192, # fpscr # (reserved word: 196) } # Registers that are not available on the stack for exceptions. EXCEPTION_UNAVAILABLE_REGS = (4, 5, 6, 7, 8, 9, 10, 11) def __init__(self, parentContext, thread): super(RTXThreadContext, self).__init__(parentContext.core) self._parent = parentContext self._thread = thread self._has_fpu = parentContext.core.has_fpu def read_core_registers_raw(self, reg_list): reg_list = [register_name_to_index(reg) for reg in reg_list] reg_vals = [] inException = self._parent.read_core_register('ipsr') > 0 isCurrent = self._thread.is_current # If this is the current thread and we're not in an exception, just read the live registers. if isCurrent and not inException: return self._parent.read_core_registers_raw(reg_list) sp = self._thread.get_stack_pointer() # Determine which register offset table to use and the offsets past the saved state. realSpOffset = 0x40 realSpExceptionOffset = 0x20 table = self.NOFPU_REGISTER_OFFSETS if self._has_fpu: try: # Read stacked exception return LR. exceptionLR = self._thread.get_stack_frame() # Check bit 4 of the saved exception LR to determine if FPU registers were stacked. if (exceptionLR & (1 << 4)) == 0: table = self.FPU_REGISTER_OFFSETS realSpOffset = 0xc8 realSpExceptionOffset = 0x68 except exceptions.TransferError: log.debug("Transfer error while reading thread's saved LR") for reg in reg_list: # Check for regs we can't access. if isCurrent and inException: if reg in self.EXCEPTION_UNAVAILABLE_REGS: reg_vals.append(0) continue if reg == 18 or reg == 13: # PSP reg_vals.append(sp + realSpExceptionOffset) continue # Must handle stack pointer specially. if reg == 13: reg_vals.append(sp + realSpOffset) continue # Look up offset for this register on the stack. spOffset = table.get(reg, None) if spOffset is None: reg_vals.append(self._parent.read_core_register(reg)) continue if isCurrent and inException: spOffset -= realSpExceptionOffset #0x20 try: reg_vals.append(self._parent.read32(sp + spOffset)) except exceptions.TransferError: reg_vals.append(0) return reg_vals def write_core_registers_raw(self, reg_list, data_list): self._parent.write_core_registers_raw(reg_list, data_list) ## @brief Base class representing a thread on the target. class RTXTargetThread(TargetThread): STATE_OFFSET = 1 NAME_OFFSET = 4 STACKFRAME_OFFSET = 34 SP_OFFSET = 56 STATES = { 0x00: "Inactive", 0x01: "Ready", 0x02: "Running", 0x03: "Blocked", 0x04: "Terminated", 0x13: "Waiting[Delay]", 0x23: "Waiting[Join]", 0x33: "Waiting[ThrFlg]", 0x43: "Waiting[EvtFlg]", 0x53: "Waiting[Mutex]", 0x63: "Waiting[Sem]", 0x73: "Waiting[MemPool]", 0x83: "Waiting[MsgGet]", 0x93: "Waiting[MsgPut]", } def __init__(self, targetContext, provider, base): super(RTXTargetThread, self).__init__() self._target_context = targetContext self._provider = provider self._base = base self._state = 0 self._thread_context = RTXThreadContext(self._target_context, self) self._has_fpu = self._thread_context.core.has_fpu try: name_ptr = self._target_context.read32(self._base + RTXTargetThread.NAME_OFFSET) self._name = read_c_string(self._target_context, name_ptr) self.update_state() except exceptions.TransferError as exc: log.debug("Transfer error while reading thread %x name: %s", self._base, exc) self._name = "?" log.debug('RTXTargetThread 0x%x' % base) def update_state(self): try: state = self._target_context.read8(self._base + RTXTargetThread.STATE_OFFSET) except exceptions.TransferError as exc: log.debug("Transfer error while reading thread %x state: %s", self._base, exc) else: self._state = state @property def unique_id(self): # There is no other meaningful ID than base address return self._base @property def context(self): return self._thread_context @property def description(self): return self.STATES[self._state] + '; 0x%x' % self._base @property def name(self): return self._name @property def is_current(self): return self._provider.get_current_thread_id() == self._base def get_stack_pointer(self): if self.is_current: # Read live process stack. sp = self._target_context.read_core_register('psp') else: # Get stack pointer saved in thread struct. try: sp = self._target_context.read32(self._base + RTXTargetThread.SP_OFFSET) except exceptions.TransferError: log.debug("Transfer error while reading thread's stack pointer @ 0x%08x", self._base + RTXTargetThread.SP_OFFSET) return sp def get_stack_frame(self): return self._target_context.read8(self._base + RTXTargetThread.STACKFRAME_OFFSET) ## @brief Thread provider for RTX5 RTOS. class RTX5ThreadProvider(ThreadProvider): # Offsets in osRtxInfo_t KERNEL_STATE_OFFSET = 8 CURRENT_OFFSET = 20 THREADLIST_OFFSET = 36 DELAYLIST_OFFSET = 44 WAITLIST_OFFSET = 48 # Offset in osRtxThread_t THREADNEXT_OFFSET = 8 DELAYNEXT_OFFSET = 16 def __init__(self, target): super(RTX5ThreadProvider, self).__init__(target) def init(self, symbolProvider): # Lookup required symbols. self._os_rtx_info = symbolProvider.get_symbol_value('osRtxInfo') if self._os_rtx_info is None: return False log.debug('osRtxInfo = 0x%08x', self._os_rtx_info) self._readylist = self._os_rtx_info + RTX5ThreadProvider.THREADLIST_OFFSET self._delaylist = self._os_rtx_info + RTX5ThreadProvider.DELAYLIST_OFFSET self._waitlist = self._os_rtx_info + RTX5ThreadProvider.WAITLIST_OFFSET self._threads = {} self._current = None self._current_id = None self._target.root_target.subscribe(Target.EVENT_POST_FLASH_PROGRAM, self.event_handler) self._target.subscribe(Target.EVENT_POST_RESET, self.event_handler) return True def get_threads(self): if not self.is_enabled: return [] return list(self._threads.values()) def invalidate(self): self._threads = {} def event_handler(self, notification): # Invalidate threads list if flash is reprogrammed. self.invalidate(); def _build_thread_list(self): newThreads = {} def create_or_update(thread): # Check for and reuse existing thread. if thread in self._threads: # Thread already exists, update its state. t = self._threads[thread] t.update_state() else: # Create a new thread. t = RTXTargetThread(self._target_context, self, thread) newThreads[t.unique_id] = t # Currently running Thread thread = self._target_context.read32(self._os_rtx_info + RTX5ThreadProvider.CURRENT_OFFSET) if thread: create_or_update(thread) self._current_id = thread self._current = newThreads[thread] else: self._current_id = None self._current = None # List of target thread lists to examine. threadLists = [ TargetList(self._target_context, self._readylist, RTX5ThreadProvider.THREADNEXT_OFFSET), TargetList(self._target_context, self._delaylist, RTX5ThreadProvider.DELAYNEXT_OFFSET), TargetList(self._target_context, self._waitlist, RTX5ThreadProvider.DELAYNEXT_OFFSET), ] # Scan thread lists. for theList in threadLists: for thread in theList: create_or_update(thread) # Create fake handler mode thread. if self._target_context.read_core_register('ipsr') > 0: newThreads[HandlerModeThread.UNIQUE_ID] = HandlerModeThread(self._target_context, self) self._threads = newThreads def get_thread(self, threadId): if not self.is_enabled: return None self.update_threads() return self._threads.get(threadId, None) @property def is_enabled(self): return self.get_is_active() @property def current_thread(self): if not self.is_enabled: return None self.update_threads() id = self.get_current_thread_id() try: return self._threads[id] except KeyError: log.debug("key error getting current thread id=%s; self._threads = %s", ("%x" % id) if (id is not None) else id, repr(self._threads)) return None def is_valid_thread_id(self, threadId): if not self.is_enabled: return False self.update_threads() return threadId in self._threads def get_current_thread_id(self): if not self.is_enabled: return None if self._target_context.read_core_register('ipsr') > 0: return HandlerModeThread.UNIQUE_ID self.update_threads() return self._current_id def get_is_active(self): if self._os_rtx_info is None: return False try: state = self._target_context.read8(self._os_rtx_info + RTX5ThreadProvider.KERNEL_STATE_OFFSET) except exceptions.TransferError as exc: log.debug("Transfer error reading kernel state: %s", exc) return False else: return state != 0 pyocd-0.13.1/pyocd/rtos/common.py0000644000175000017500000000562413373511253016573 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .provider import (TargetThread, ThreadProvider) from ..debug.context import DebugContext from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index) from ..core import exceptions import logging LIST_NODE_NEXT_OFFSET = 0 LIST_NODE_OBJ_OFFSET= 8 ## @brief Reads a null-terminated C string from the target. def read_c_string(context, ptr): if ptr == 0: return "" s = "" done = False count = 0 badCount = 0 try: while not done and count < 256: data = context.read_memory_block8(ptr, 16) ptr += 16 count += 16 for c in data: if c == 0: done = True break elif c > 127: # Replace non-ASCII characters. If there is a run of invalid characters longer # than 4, then terminate the string early. badCount += 1 if badCount > 4: done = True break s += '?' else: s += chr(c) badCount = 0 except exceptions.TransferError: logging.debug("TransferError while trying to read 16 bytes at 0x%08x", ptr) return s ## @brief Class representing the handler mode. class HandlerModeThread(TargetThread): UNIQUE_ID = 2 def __init__(self, targetContext, provider): super(HandlerModeThread, self).__init__() self._target_context = targetContext self._provider = provider def get_stack_pointer(self): return self._target_context.read_core_register('msp') @property def priority(self): return 0 @property def unique_id(self): return self.UNIQUE_ID @property def name(self): return "Handler mode" @property def description(self): ipsr = self._target_context.read_core_register('ipsr'); return self._target_context.core.exception_number_to_name(ipsr) @property def is_current(self): return self._target_context.read_core_register('ipsr') > 0 @property def context(self): return self._target_context def __str__(self): return "" % (id(self)) def __repr__(self): return str(self) pyocd-0.13.1/pyocd/rtos/__init__.py0000644000175000017500000000167113373511253017040 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .argon import ArgonThreadProvider from .freertos import FreeRTOSThreadProvider from .zephyr import ZephyrThreadProvider from .rtx5 import RTX5ThreadProvider RTOS = { 'Argon' : ArgonThreadProvider, 'FreeRTOS' : FreeRTOSThreadProvider, 'Zephyr' : ZephyrThreadProvider, 'RTX5' : RTX5ThreadProvider, } pyocd-0.13.1/pyocd/rtos/freertos.py0000644000175000017500000004414613373511253017136 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .provider import (TargetThread, ThreadProvider) from .common import (read_c_string, HandlerModeThread) from ..core import exceptions from ..core.target import Target from ..debug.context import DebugContext from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index) import logging FREERTOS_MAX_PRIORITIES = 63 LIST_SIZE = 20 LIST_INDEX_OFFSET = 16 LIST_NODE_NEXT_OFFSET = 8 # 4? LIST_NODE_OBJECT_OFFSET = 12 THREAD_STACK_POINTER_OFFSET = 0 THREAD_PRIORITY_OFFSET = 44 THREAD_NAME_OFFSET = 52 # Create a logger for this module. log = logging.getLogger("freertos") class TargetList(object): def __init__(self, context, ptr): self._context = context self._list = ptr def __iter__(self): prev = -1 found = 0 count = self._context.read32(self._list) if count == 0: return node = self._context.read32(self._list + LIST_INDEX_OFFSET) while (node != 0) and (node != prev) and (found < count): try: # Read the object from the node. obj = self._context.read32(node + LIST_NODE_OBJECT_OFFSET) yield obj found += 1 # Read next list node pointer. prev = node node = self._context.read32(node + LIST_NODE_NEXT_OFFSET) except exceptions.TransferError: log.warning("TransferError while reading list elements (list=0x%08x, node=0x%08x), terminating list", self._list, node) node = 0 ## @brief class FreeRTOSThreadContext(DebugContext): # SP/PSP are handled specially, so it is not in these dicts. COMMON_REGISTER_OFFSETS = { 4: 0, # r4 5: 4, # r5 6: 8, # r6 7: 12, # r7 8: 16, # r8 9: 20, # r9 10: 24, # r10 11: 28, # r11 } NOFPU_REGISTER_OFFSETS = { 0: 32, # r0 1: 36, # r1 2: 40, # r2 3: 44, # r3 12: 48, # r12 14: 52, # lr 15: 56, # pc 16: 60, # xpsr } NOFPU_REGISTER_OFFSETS.update(COMMON_REGISTER_OFFSETS) FPU_BASIC_REGISTER_OFFSETS = { -1: 32, # exception LR 0: 36, # r0 1: 40, # r1 2: 44, # r2 3: 48, # r3 12: 42, # r12 14: 56, # lr 15: 60, # pc 16: 64, # xpsr } FPU_BASIC_REGISTER_OFFSETS.update(COMMON_REGISTER_OFFSETS) FPU_EXTENDED_REGISTER_OFFSETS = { -1: 32, # exception LR 0x50: 36, # s16 0x51: 40, # s17 0x52: 44, # s18 0x53: 48, # s19 0x54: 52, # s20 0x55: 56, # s21 0x56: 60, # s22 0x57: 64, # s23 0x58: 68, # s24 0x59: 72, # s25 0x5a: 76, # s26 0x5b: 80, # s27 0x5c: 84, # s28 0x5d: 88, # s29 0x5e: 92, # s30 0x5f: 96, # s31 0: 100, # r0 1: 104, # r1 2: 108, # r2 3: 112, # r3 12: 116, # r12 14: 120, # lr 15: 124, # pc 16: 128, # xpsr 0x40: 132, # s0 0x41: 136, # s1 0x42: 140, # s2 0x43: 144, # s3 0x44: 148, # s4 0x45: 152, # s5 0x46: 156, # s6 0x47: 160, # s7 0x48: 164, # s8 0x49: 168, # s9 0x4a: 172, # s10 0x4b: 176, # s11 0x4c: 180, # s12 0x4d: 184, # s13 0x4e: 188, # s14 0x4f: 192, # s15 33: 196, # fpscr # (reserved word: 200) } FPU_EXTENDED_REGISTER_OFFSETS.update(COMMON_REGISTER_OFFSETS) # Registers that are not available on the stack for exceptions. EXCEPTION_UNAVAILABLE_REGS = (4, 5, 6, 7, 8, 9, 10, 11) def __init__(self, parentContext, thread): super(FreeRTOSThreadContext, self).__init__(parentContext.core) self._parent = parentContext self._thread = thread self._has_fpu = parentContext.core.has_fpu def read_core_registers_raw(self, reg_list): reg_list = [register_name_to_index(reg) for reg in reg_list] reg_vals = [] inException = self._parent.read_core_register('ipsr') > 0 isCurrent = self._thread.is_current # If this is the current thread and we're not in an exception, just read the live registers. if isCurrent and not inException: return self._parent.read_core_registers_raw(reg_list) sp = self._thread.get_stack_pointer() # Determine which register offset table to use and the offsets past the saved state. realSpOffset = 0x40 realSpExceptionOffset = 0x20 table = self.NOFPU_REGISTER_OFFSETS if self._has_fpu: try: # Read stacked exception return LR. offset = self.FPU_BASIC_REGISTER_OFFSETS[-1] exceptionLR = self._parent.read32(sp + offset) # Check bit 4 of the saved exception LR to determine if FPU registers were stacked. if (exceptionLR & (1 << 4)) != 0: table = self.FPU_BASIC_REGISTER_OFFSETS realSpOffset = 0x44 else: table = self.FPU_EXTENDED_REGISTER_OFFSETS realSpOffset = 0xcc realSpExceptionOffset = 0x6c except exceptions.TransferError: log.debug("Transfer error while reading thread's saved LR") for reg in reg_list: # Check for regs we can't access. if isCurrent and inException: if reg in self.EXCEPTION_UNAVAILABLE_REGS: reg_vals.append(0) continue if reg == 18 or reg == 13: # PSP reg_vals.append(sp + realSpExceptionOffset) continue # Must handle stack pointer specially. if reg == 13: reg_vals.append(sp + realSpOffset) continue # Look up offset for this register on the stack. spOffset = table.get(reg, None) if spOffset is None: reg_vals.append(self._parent.read_core_register(reg)) continue if isCurrent and inException: spOffset -= realSpExceptionOffset #0x20 try: reg_vals.append(self._parent.read32(sp + spOffset)) except exceptions.TransferError: reg_vals.append(0) return reg_vals def write_core_registers_raw(self, reg_list, data_list): self._parent.write_core_registers_raw(reg_list, data_list) ## @brief A FreeRTOS task. class FreeRTOSThread(TargetThread): RUNNING = 1 READY = 2 BLOCKED = 3 SUSPENDED = 4 DELETED = 5 STATE_NAMES = { RUNNING : "Running", READY : "Ready", BLOCKED : "Blocked", SUSPENDED : "Suspended", DELETED : "Deleted", } def __init__(self, targetContext, provider, base): super(FreeRTOSThread, self).__init__() self._target_context = targetContext self._provider = provider self._base = base self._state = FreeRTOSThread.READY self._thread_context = FreeRTOSThreadContext(self._target_context, self) self._priority = self._target_context.read32(self._base + THREAD_PRIORITY_OFFSET) self._name = read_c_string(self._target_context, self._base + THREAD_NAME_OFFSET) if len(self._name) == 0: self._name = "Unnamed" def get_stack_pointer(self): if self.is_current: # Read live process stack. sp = self._target_context.read_core_register('psp') else: # Get stack pointer saved in thread struct. try: sp = self._target_context.read32(self._base + THREAD_STACK_POINTER_OFFSET) except exceptions.TransferError: log.debug("Transfer error while reading thread's stack pointer @ 0x%08x", self._base + THREAD_STACK_POINTER_OFFSET) return sp @property def state(self): return self._state @state.setter def state(self, value): self._state = value @property def priority(self): return self._priority @property def unique_id(self): return self._base @property def name(self): return self._name @property def description(self): return "%s; Priority %d" % (self.STATE_NAMES[self.state], self.priority) @property def is_current(self): return self._provider.get_actual_current_thread_id() == self.unique_id @property def context(self): return self._thread_context def __str__(self): return "" % (id(self), self.unique_id, self.name) def __repr__(self): return str(self) ## @brief Thread provider for FreeRTOS. class FreeRTOSThreadProvider(ThreadProvider): ## Required FreeRTOS symbols. FREERTOS_SYMBOLS = [ "uxCurrentNumberOfTasks", "pxCurrentTCB", "pxReadyTasksLists", "xDelayedTaskList1", "xDelayedTaskList2", "xPendingReadyList", "uxTopReadyPriority", "xSchedulerRunning", ] def __init__(self, target): super(FreeRTOSThreadProvider, self).__init__(target) self._symbols = None self._total_priorities = 0 self._threads = {} def init(self, symbolProvider): # Lookup required symbols. self._symbols = self._lookup_symbols(self.FREERTOS_SYMBOLS, symbolProvider) if self._symbols is None: return False # Look up optional xSuspendedTaskList, controlled by INCLUDE_vTaskSuspend suspendedTaskListSym = self._lookup_symbols(["xSuspendedTaskList"], symbolProvider) if suspendedTaskListSym is not None: self._symbols['xSuspendedTaskList'] = suspendedTaskListSym['xSuspendedTaskList'] # Look up optional xTasksWaitingTermination, controlled by INCLUDE_vTaskDelete tasksWaitingTerminationSym = self._lookup_symbols(["xTasksWaitingTermination"], symbolProvider) if tasksWaitingTerminationSym is not None: self._symbols['xTasksWaitingTermination'] = tasksWaitingTerminationSym['xTasksWaitingTermination'] # Look up vPortEnableVFP() to determine if the FreeRTOS port supports the FPU. vPortEnableVFP = self._lookup_symbols(["vPortEnableVFP"], symbolProvider) self._fpu_port = vPortEnableVFP is not None # Check for the expected list size. These two symbols are each a single list and xDelayedTaskList2 # immediately follows xDelayedTaskList1, so we can just subtract their addresses to get the # size of a single list. delta = self._symbols['xDelayedTaskList2'] - self._symbols['xDelayedTaskList1'] if delta != LIST_SIZE: log.warning("FreeRTOS: list size is unexpected, maybe an unsupported configuration of FreeRTOS") return False # xDelayedTaskList1 immediately follows pxReadyTasksLists, so subtracting their addresses gives # us the total size of the pxReadyTaskLists array. delta = self._symbols['xDelayedTaskList1'] - self._symbols['pxReadyTasksLists'] if delta % LIST_SIZE: log.warning("FreeRTOS: pxReadyTasksLists size is unexpected, maybe an unsupported version of FreeRTOS") return False self._total_priorities = delta // LIST_SIZE if self._total_priorities > FREERTOS_MAX_PRIORITIES: log.warning("FreeRTOS: number of priorities is too large (%d)", self._total_priorities) return False log.debug("FreeRTOS: number of priorities is %d", self._total_priorities) self._target.root_target.subscribe(Target.EVENT_POST_FLASH_PROGRAM, self.event_handler) self._target.subscribe(Target.EVENT_POST_RESET, self.event_handler) return True def invalidate(self): self._threads = {} def event_handler(self, notification): # Invalidate threads list if flash is reprogrammed. log.debug("FreeRTOS: invalidating threads list: %s" % (repr(notification))) self.invalidate(); def _build_thread_list(self): newThreads = {} # Read the number of threads. threadCount = self._target_context.read32(self._symbols['uxCurrentNumberOfTasks']) # Read the current thread. currentThread = self._target_context.read32(self._symbols['pxCurrentTCB']) # We should only be building the thread list if the scheduler is running, so a zero thread # count or a null current thread means something is bizarrely wrong. if threadCount == 0 or currentThread == 0: log.warning("FreeRTOS: no threads even though the scheduler is running") return # Read the top ready priority. topPriority = self._target_context.read32(self._symbols['uxTopReadyPriority']) # Handle an uxTopReadyPriority value larger than the number of lists. This is most likely # caused by the configUSE_PORT_OPTIMISED_TASK_SELECTION option being enabled, which treats # uxTopReadyPriority as a bitmap instead of integer. This is ok because uxTopReadyPriority # in optimised mode will always be >= the actual top priority. if topPriority > self._total_priorities: topPriority = self._total_priorities # Build up list of all the thread lists we need to scan. listsToRead = [] for i in range(topPriority + 1): listsToRead.append((self._symbols['pxReadyTasksLists'] + i * LIST_SIZE, FreeRTOSThread.READY)) listsToRead.append((self._symbols['xDelayedTaskList1'], FreeRTOSThread.BLOCKED)) listsToRead.append((self._symbols['xDelayedTaskList2'], FreeRTOSThread.BLOCKED)) listsToRead.append((self._symbols['xPendingReadyList'], FreeRTOSThread.READY)) if 'xSuspendedTaskList' in self._symbols: listsToRead.append((self._symbols['xSuspendedTaskList'], FreeRTOSThread.SUSPENDED)) if 'xTasksWaitingTermination' in self._symbols: listsToRead.append((self._symbols['xTasksWaitingTermination'], FreeRTOSThread.DELETED)) for listPtr, state in listsToRead: for threadBase in TargetList(self._target_context, listPtr): try: # Don't try adding more threads than the number of threads that FreeRTOS says there are. if len(newThreads) >= threadCount: break # Reuse existing thread objects. if threadBase in self._threads: t = self._threads[threadBase] else: t = FreeRTOSThread(self._target_context, self, threadBase) # Set thread state. if threadBase == currentThread: t.state = FreeRTOSThread.RUNNING else: t.state = state log.debug("Thread 0x%08x (%s)", threadBase, t.name) newThreads[t.unique_id] = t except exceptions.TransferError: log.debug("TransferError while examining thread 0x%08x", threadBase) if len(newThreads) != threadCount: log.warning("FreeRTOS: thread count mismatch") # Create fake handler mode thread. if self._target_context.read_core_register('ipsr') > 0: log.debug("FreeRTOS: creating handler mode thread") t = HandlerModeThread(self._target_context, self) newThreads[t.unique_id] = t self._threads = newThreads def get_threads(self): if not self.is_enabled: return [] self.update_threads() return list(self._threads.values()) def get_thread(self, threadId): if not self.is_enabled: return None self.update_threads() return self._threads.get(threadId, None) @property def is_enabled(self): return self._symbols is not None and self.get_is_running() @property def current_thread(self): if not self.is_enabled: return None self.update_threads() id = self.get_current_thread_id() try: return self._threads[id] except KeyError: return None def is_valid_thread_id(self, threadId): if not self.is_enabled: return False self.update_threads() return threadId in self._threads def get_current_thread_id(self): if not self.is_enabled: return None if self._target_context.read_core_register('ipsr') > 0: return HandlerModeThread.UNIQUE_ID return self.get_actual_current_thread_id() def get_actual_current_thread_id(self): if not self.is_enabled: return None return self._target_context.read32(self._symbols['pxCurrentTCB']) def get_is_running(self): if self._symbols is None: return False return self._target_context.read32(self._symbols['xSchedulerRunning']) != 0 pyocd-0.13.1/pyocd/rtos/argon.py0000644000175000017500000003402713373511253016410 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .provider import (TargetThread, ThreadProvider) from .common import (read_c_string, HandlerModeThread) from ..core import exceptions from ..core.target import Target from ..debug.context import DebugContext from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index) import logging IS_RUNNING_OFFSET = 0x54 ALL_OBJECTS_THREADS_OFFSET = 0 THREAD_STACK_POINTER_OFFSET = 0 THREAD_EXTENDED_FRAME_OFFSET = 4 THREAD_NAME_OFFSET = 8 THREAD_STACK_BOTTOM_OFFSET = 12 THREAD_PRIORITY_OFFSET = 16 THREAD_STATE_OFFSET = 17 THREAD_CREATED_NODE_OFFSET = 36 LIST_NODE_NEXT_OFFSET = 0 LIST_NODE_OBJ_OFFSET= 8 # Create a logger for this module. log = logging.getLogger("argon") class TargetList(object): def __init__(self, context, ptr): self._context = context self._list = ptr def __iter__(self): next = 0 head = self._context.read32(self._list) node = head is_valid = head != 0 while is_valid and next != head: try: # Read the object from the node. obj = self._context.read32(node + LIST_NODE_OBJ_OFFSET) yield obj next = self._context.read32(node + LIST_NODE_NEXT_OFFSET) node = next except exceptions.TransferError: log.warning("TransferError while reading list elements (list=0x%08x, node=0x%08x), terminating list", self._list, node) is_valid = False ## @brief class ArgonThreadContext(DebugContext): # SP is handled specially, so it is not in these dicts. CORE_REGISTER_OFFSETS = { # Software stacked 4: 0, # r4 5: 4, # r5 6: 8, # r6 7: 12, # r7 8: 16, # r8 9: 20, # r9 10: 24, # r10 11: 28, # r11 # Hardware stacked 0: 32, # r0 1: 36, # r1 2: 40, # r2 3: 44, # r3 12: 48, # r12 14: 52, # lr 15: 56, # pc 16: 60, # xpsr } FPU_EXTENDED_REGISTER_OFFSETS = { # Software stacked 4: 0, # r4 5: 4, # r5 6: 8, # r6 7: 12, # r7 8: 16, # r8 9: 20, # r9 10: 24, # r10 11: 28, # r11 0x50: 32, # s16 0x51: 36, # s17 0x52: 40, # s18 0x53: 44, # s19 0x54: 48, # s20 0x55: 52, # s21 0x56: 56, # s22 0x57: 60, # s23 0x58: 64, # s24 0x59: 68, # s25 0x5a: 72, # s26 0x5b: 76, # s27 0x5c: 80, # s28 0x5d: 84, # s29 0x5e: 88, # s30 0x5f: 92, # s31 # Hardware stacked 0: 96, # r0 1: 100, # r1 2: 104, # r2 3: 108, # r3 12: 112, # r12 14: 116, # lr 15: 120, # pc 16: 124, # xpsr 0x40: 128, # s0 0x41: 132, # s1 0x42: 136, # s2 0x43: 140, # s3 0x44: 144, # s4 0x45: 148, # s5 0x46: 152, # s6 0x47: 156, # s7 0x48: 160, # s8 0x49: 164, # s9 0x4a: 168, # s10 0x4b: 172, # s11 0x4c: 176, # s12 0x4d: 180, # s13 0x4e: 184, # s14 0x4f: 188, # s15 33: 192, # fpscr # (reserved word: 196) } # Registers that are not available on the stack for exceptions. EXCEPTION_UNAVAILABLE_REGS = (4, 5, 6, 7, 8, 9, 10, 11) def __init__(self, parentContext, thread): super(ArgonThreadContext, self).__init__(parentContext.core) self._parent = parentContext self._thread = thread def read_core_registers_raw(self, reg_list): reg_list = [register_name_to_index(reg) for reg in reg_list] reg_vals = [] inException = self._parent.read_core_register('ipsr') > 0 isCurrent = self._thread.is_current # If this is the current thread and we're not in an exception, just read the live registers. if isCurrent and not inException: return self._parent.read_core_registers_raw(reg_list) sp = self._thread.get_stack_pointer() # Determine which register offset table to use and the offsets past the saved state. realSpOffset = 0x40 realSpExceptionOffset = 0x20 table = self.CORE_REGISTER_OFFSETS if self._thread.has_extended_frame: table = self.FPU_EXTENDED_REGISTER_OFFSETS realSpOffset = 0xc8 realSpExceptionOffset = 0x68 for reg in reg_list: # Check for regs we can't access. if isCurrent and inException: if reg in self.EXCEPTION_UNAVAILABLE_REGS: reg_vals.append(0) continue if reg == 18 or reg == 13: # PSP log.debug("psp = 0x%08x", sp + realSpExceptionOffset) reg_vals.append(sp + realSpExceptionOffset) continue # Must handle stack pointer specially. if reg == 13: reg_vals.append(sp + realSpOffset) continue # Look up offset for this register on the stack. spOffset = table.get(reg, None) if spOffset is None: reg_vals.append(self._parent.read_core_register(reg)) continue if isCurrent and inException: spOffset -= realSpExceptionOffset #0x20 try: reg_vals.append(self._parent.read32(sp + spOffset)) except exceptions.TransferError: reg_vals.append(0) return reg_vals def write_core_registers_raw(self, reg_list, data_list): self._parent.write_core_registers_raw(reg_list, data_list) ## @brief Base class representing a thread on the target. class ArgonThread(TargetThread): UNKNOWN = 0 SUSPENDED = 1 READY = 2 RUNNING = 3 BLOCKED = 4 SLEEPING = 5 DONE = 6 STATE_NAMES = { UNKNOWN : "Unknown", SUSPENDED : "Suspended", READY : "Ready", RUNNING : "Running", BLOCKED : "Blocked", SLEEPING : "Sleeping", DONE : "Done", } def __init__(self, targetContext, provider, base): super(ArgonThread, self).__init__() self._target_context = targetContext self._provider = provider self._base = base self._thread_context = ArgonThreadContext(self._target_context, self) self._has_fpu = self._thread_context.core.has_fpu self._priority = 0 self._state = self.UNKNOWN self._name = "?" try: self.update_info() ptr = self._target_context.read32(self._base + THREAD_NAME_OFFSET) self._name = read_c_string(self._target_context, ptr) log.debug("Thread@%x name=%x '%s'", self._base, ptr, self._name) except exceptions.TransferError: log.debug("Transfer error while reading thread info") def get_stack_pointer(self): sp = 0 if self.is_current: # Read live process stack. sp = self._target_context.read_core_register('psp') else: # Get stack pointer saved in thread struct. try: sp = self._target_context.read32(self._base + THREAD_STACK_POINTER_OFFSET) except exceptions.TransferError: log.debug("Transfer error while reading thread's stack pointer @ 0x%08x", self._base + THREAD_STACK_POINTER_OFFSET) return sp def update_info(self): try: self._priority = self._target_context.read8(self._base + THREAD_PRIORITY_OFFSET) self._state = self._target_context.read8(self._base + THREAD_STATE_OFFSET) if self._state > self.DONE: self._state = self.UNKNOWN except exceptions.TransferError: log.debug("Transfer error while reading thread info") @property def state(self): return self._state @property def priority(self): return self._priority @property def unique_id(self): return self._base @property def name(self): return self._name @property def description(self): return "%s; Priority %d" % (self.STATE_NAMES[self.state], self.priority) @property def is_current(self): return self._provider.get_actual_current_thread_id() == self.unique_id @property def context(self): return self._thread_context @property def has_extended_frame(self): if not self._has_fpu: return False try: flag = self._target_context.read8(self._base + THREAD_EXTENDED_FRAME_OFFSET) return flag != 0 except exceptions.TransferError: log.debug("Transfer error while reading thread's extended frame flag @ 0x%08x", self._base + THREAD_EXTENDED_FRAME_OFFSET) return False def __str__(self): return "" % (id(self), self.unique_id, self.name) def __repr__(self): return str(self) ## @brief Base class for RTOS support plugins. class ArgonThreadProvider(ThreadProvider): def __init__(self, target): super(ArgonThreadProvider, self).__init__(target) self.g_ar = None self.g_ar_objects = None self._all_threads = None self._threads = {} def init(self, symbolProvider): self.g_ar = symbolProvider.get_symbol_value("g_ar") if self.g_ar is None: return False log.debug("Argon: g_ar = 0x%08x", self.g_ar) self.g_ar_objects = symbolProvider.get_symbol_value("g_ar_objects") if self.g_ar_objects is None: return False log.debug("Argon: g_ar_objects = 0x%08x", self.g_ar_objects) self._all_threads = self.g_ar_objects + ALL_OBJECTS_THREADS_OFFSET self._target.root_target.subscribe(Target.EVENT_POST_FLASH_PROGRAM, self.event_handler) self._target.subscribe(Target.EVENT_POST_RESET, self.event_handler) return True def invalidate(self): self._threads = {} def event_handler(self, notification): # Invalidate threads list if flash is reprogrammed. log.debug("Argon: invalidating threads list: %s" % (repr(notification))) self.invalidate(); def _build_thread_list(self): allThreads = TargetList(self._target_context, self._all_threads) newThreads = {} for threadBase in allThreads: try: # Reuse existing thread objects if possible. if threadBase in self._threads: t = self._threads[threadBase] # Ask the thread object to update its state and priority. t.update_info() else: t = ArgonThread(self._target_context, self, threadBase) log.debug("Thread 0x%08x (%s)", threadBase, t.name) newThreads[t.unique_id] = t except exceptions.TransferError: log.debug("TransferError while examining thread 0x%08x", threadBase) # Create fake handler mode thread. if self._target_context.read_core_register('ipsr') > 0: log.debug("creating handler mode thread") t = HandlerModeThread(self._target_context, self) newThreads[t.unique_id] = t self._threads = newThreads def get_threads(self): if not self.is_enabled: return [] self.update_threads() return list(self._threads.values()) def get_thread(self, threadId): if not self.is_enabled: return None self.update_threads() return self._threads.get(threadId, None) @property def is_enabled(self): return self.g_ar is not None and self.get_is_running() @property def current_thread(self): if not self.is_enabled: return None self.update_threads() id = self.get_current_thread_id() try: return self._threads[id] except KeyError: log.debug("key error getting current thread id=%s; self._threads = %s", ("%x" % id) if (id is not None) else id, repr(self._threads)) return None def is_valid_thread_id(self, threadId): if not self.is_enabled: return False self.update_threads() return threadId in self._threads def get_current_thread_id(self): if not self.is_enabled: return None if self._target_context.read_core_register('ipsr') > 0: return HandlerModeThread.UNIQUE_ID return self.get_actual_current_thread_id() def get_actual_current_thread_id(self): if not self.is_enabled: return None return self._target_context.read32(self.g_ar) def get_is_running(self): if self.g_ar is None: return False flag = self._target_context.read8(self.g_ar + IS_RUNNING_OFFSET) return flag != 0 pyocd-0.13.1/pyocd/debug/0000755000175000017500000000000013373523011015014 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/debug/elf/0000755000175000017500000000000013373523011015562 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/debug/elf/flash_reader.py0000644000175000017500000000704213373511253020563 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 ..context import DebugContext from ...utility import conversion import logging from intervaltree import (Interval, IntervalTree) ## @brief Reads flash memory regions from an ELF file instead of the target. class FlashReaderContext(DebugContext): def __init__(self, parentContext, elf): super(FlashReaderContext, self).__init__(parentContext.core) self._parent = parentContext self._elf = elf self._log = logging.getLogger('flashreadercontext') self._build_regions() def _build_regions(self): self._tree = IntervalTree() for sect in [s for s in self._elf.sections if (s.region and s.region.is_flash)]: start = sect.start length = sect.length sect.data # Go ahead and read the data from the file. self._tree.addi(start, start + length, sect) self._log.debug("created flash section [%x:%x] for section %s", start, start + length, sect.name) def read_memory(self, addr, transfer_size=32, now=True): length = transfer_size // 8 matches = self._tree.search(addr, addr + length) # Must match only one interval (ELF section). if len(matches) != 1: return self._parent.read_memory(addr, transfer_size, now) section = matches.pop().data addr -= section.start def read_memory_cb(): self._log.debug("read flash data [%x:%x] from section %s", section.start + addr, section.start + addr + length, section.name) data = section.data[addr:addr + length] if transfer_size == 8: return data[0] elif transfer_size == 16: return conversion.byte_list_to_u16le_list(data)[0] elif transfer_size == 32: return conversion.byte_list_to_u32le_list(data)[0] else: raise ValueError("invalid transfer_size (%d)" % transfer_size) if now: return read_memory_cb() else: return read_memory_cb def read_memory_block8(self, addr, size): matches = self._tree.search(addr, addr + size) # Must match only one interval (ELF section). if len(matches) != 1: return self._parent.read_memory_block8(addr, size) section = matches.pop().data addr -= section.start data = section.data[addr:addr + size] self._log.debug("read flash data [%x:%x]", section.start + addr, section.start + addr + size) return list(data) def read_memory_block32(self, addr, size): return conversion.byte_list_to_u32le_list(self.read_memory_block8(addr, size)) def write_memory(self, addr, value, transfer_size=32): return self._parent.write_memory(addr, value, transfer_size) def write_memory_block8(self, addr, value): return self._parent.write_memory_block8(addr, value) def write_memory_block32(self, addr, data): return self._parent.write_memory_block32(addr, data) pyocd-0.13.1/pyocd/debug/elf/decoder.py0000644000175000017500000002060113373511253017545 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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 os from elftools.elf.elffile import ELFFile from elftools.dwarf.constants import DW_LNE_set_address from intervaltree import IntervalTree from collections import namedtuple from itertools import islice import logging FunctionInfo = namedtuple('FunctionInfo', 'name subprogram low_pc high_pc') LineInfo = namedtuple('LineInfo', 'cu filename dirname line') SymbolInfo = namedtuple('SymbolInfo', 'name address size type') class ElfSymbolDecoder(object): def __init__(self, elf): assert isinstance(elf, ELFFile) self.elffile = elf self.symtab = self.elffile.get_section_by_name('.symtab') self.symcount = self.symtab.num_symbols() self.symbol_dict = {} self.symbol_tree = None # Build indices. self._build_symbol_search_tree() self._process_arm_type_symbols() def get_elf(self): return self.elffile def get_symbol_for_address(self, addr): try: return sorted(self.symbol_tree[addr])[0].data except IndexError: return None def get_symbol_for_name(self, name): try: return self.symbol_dict[name] except KeyError: return None def _build_symbol_search_tree(self): self.symbol_tree = IntervalTree() symbols = self.symtab.iter_symbols() for symbol in symbols: # Only look for functions and objects. sym_type = symbol.entry['st_info']['type'] if sym_type not in ['STT_FUNC', 'STT_OBJECT']: continue sym_value = symbol.entry['st_value'] sym_size = symbol.entry['st_size'] # Cannot put an empty interval into the tree, so ensure symbols have # at least a size of 1. real_sym_size = sym_size if sym_size == 0: sym_size = 1 syminfo = SymbolInfo(name=symbol.name, address=sym_value, size=real_sym_size, type=sym_type) # Add to symbol dict. self.symbol_dict[symbol.name] = syminfo # Add to symbol tree. self.symbol_tree.addi(sym_value, sym_value+sym_size, syminfo) def _process_arm_type_symbols(self): type_symbols = self._get_arm_type_symbol_iter() # map(print, imap(lambda x:"%s : 0x%x" % (x.name, x['st_value']), type_symbols)) def _get_arm_type_symbol_iter(self): # Scan until we find $m symbol. i = 1 while i < self.symcount: symbol = self.symtab.get_symbol(i) if symbol.name == '$m': break i += 1 if i >= self.symcount: return n = symbol['st_value'] return islice(self.symtab.iter_symbols(), i, n) class DwarfAddressDecoder(object): def __init__(self, elf): assert isinstance(elf, ELFFile) self.elffile = elf if not self.elffile.has_dwarf_info(): raise Exception("No DWARF debug info available") self.dwarfinfo = self.elffile.get_dwarf_info() self.subprograms = None self.function_tree = None self.line_tree = None # Build indices. self._get_subprograms() self._build_function_search_tree() self._build_line_search_tree() def get_function_for_address(self, addr): try: return sorted(self.function_tree[addr])[0].data except IndexError: return None def get_line_for_address(self, addr): try: return sorted(self.line_tree[addr])[0].data except IndexError: return None def _get_subprograms(self): self.subprograms = [] for CU in self.dwarfinfo.iter_CUs(): self.subprograms.extend([d for d in CU.iter_DIEs() if d.tag == 'DW_TAG_subprogram']) def _build_function_search_tree(self): self.function_tree = IntervalTree() for prog in self.subprograms: try: name = prog.attributes['DW_AT_name'].value low_pc = prog.attributes['DW_AT_low_pc'].value high_pc = prog.attributes['DW_AT_high_pc'].value # Skip subprograms excluded from the link. if low_pc == 0: continue # If high_pc is not explicitly an address, then it's an offset from the # low_pc value. if prog.attributes['DW_AT_high_pc'].form != 'DW_FORM_addr': high_pc = low_pc + high_pc fninfo = FunctionInfo(name=name, subprogram=prog, low_pc=low_pc, high_pc=high_pc) self.function_tree.addi(low_pc, high_pc, fninfo) except KeyError: pass def _build_line_search_tree(self): self.line_tree = IntervalTree() for cu in self.dwarfinfo.iter_CUs(): lineprog = self.dwarfinfo.line_program_for_CU(cu) prevstate = None skipThisSequence = False for entry in lineprog.get_entries(): # Look for a DW_LNE_set_address command with a 0 address. This indicates # code that is not actually included in the link. # # TODO: find a better way to determine the code is really not present and # doesn't have a real address of 0 if entry.is_extended and entry.command == DW_LNE_set_address \ and len(entry.args) == 1 and entry.args[0] == 0: skipThisSequence = True # We're interested in those entries where a new state is assigned if entry.state is None: continue # Looking for a range of addresses in two consecutive states. if prevstate and not skipThisSequence: fileinfo = lineprog['file_entry'][prevstate.file - 1] filename = fileinfo.name dirname = lineprog['include_directory'][fileinfo.dir_index - 1] info = LineInfo(cu=cu, filename=filename, dirname=dirname, line=prevstate.line) fromAddr = prevstate.address toAddr = entry.state.address try: if fromAddr != 0 and toAddr != 0: if fromAddr == toAddr: toAddr += 1 self.line_tree.addi(fromAddr, toAddr, info) except: logging.debug("Problematic lineprog:") self._dump_lineprog(lineprog) raise if entry.state.end_sequence: prevstate = None skipThisSequence = False else: prevstate = entry.state def _dump_lineprog(self, lineprog): for i, e in enumerate(lineprog.get_entries()): s = e.state if s is None: logging.debug("%d: cmd=%d ext=%d args=%s", i, e.command, int(e.is_extended), repr(e.args)) else: logging.debug("%d: %06x %4d stmt=%1d block=%1d end=%d file=[%d]%s", i, s.address, s.line, s.is_stmt, int(s.basic_block), int(s.end_sequence), s.file, lineprog['file_entry'][s.file-1].name) def dump_subprograms(self): for prog in self.subprograms: name = prog.attributes['DW_AT_name'].value try: low_pc = prog.attributes['DW_AT_low_pc'].value except KeyError: low_pc = 0 try: high_pc = prog.attributes['DW_AT_high_pc'].value except KeyError: high_pc = 0xffffffff filename = os.path.basename(prog._parent.attributes['DW_AT_name'].value.replace('\\', '/')) logging.debug("%s%s%08x %08x %s", name, (' ' * (50-len(name))), low_pc, high_pc, filename) pyocd-0.13.1/pyocd/debug/elf/__init__.py0000644000175000017500000000113013373511253017673 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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. """ pyocd-0.13.1/pyocd/debug/elf/symbols.py0000644000175000017500000000174113373511253017634 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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 ..symbols import SymbolProvider ## @brief Get symbol information from an ELF file. class ELFSymbolProvider(SymbolProvider): def __init__(self, elf): self._symbols = elf.symbol_decoder def get_symbol_value(self, name): sym = self._symbols.get_symbol_for_name(name) if sym is not None: return sym.address else: return None pyocd-0.13.1/pyocd/debug/elf/elf.py0000644000175000017500000001671713373511253016723 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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 __future__ import print_function from ...core.memory_map import (MemoryRange, MemoryMap) from .decoder import (ElfSymbolDecoder, DwarfAddressDecoder) from elftools.elf.elffile import ELFFile from elftools.elf.constants import SH_FLAGS import logging import six ## # @brief Memory range for a section of an ELF file. # # Objects of this class represent sections of an ELF file. See the ELFBinaryFile class documentation # for details of how sections are selected and how to get instances of this class. # # If a region in the target's memory map can be found that contains the section, it will be # accessible via the instance's _region_ attribute. Otherwise _region_ will be `None`. A maximum of # one associated memory region is supported, even if the section spans multiple regions. # # The contents of the ELF section can be read via the `data` property as a `bytearray`. The data is # read from the file only once and cached. class ELFSection(MemoryRange): def __init__(self, elf, sect): self._elf = elf self._section = sect self._name = self._section.name self._data = None # Look up the corresponding memory region. start = self._section['sh_addr'] length = self._section['sh_size'] regions = self._elf._memory_map.get_intersecting_regions(start=start, length=length) region = regions[0] if len(regions) else None super(ELFSection, self).__init__(start=start, length=length, region=region) @property def name(self): return self._name @property def type(self): return self._section['sh_type'] @property def flags(self): return self._section['sh_flags'] @property def data(self): if self._data is None: self._data = bytearray(self._section.data()) return self._data @property def flags_description(self): flags = self.flags flagsDesc = "" if flags & SH_FLAGS.SHF_WRITE: flagsDesc += "WRITE|" if flags & SH_FLAGS.SHF_ALLOC: flagsDesc += "ALLOC|" if flags & SH_FLAGS.SHF_EXECINSTR: flagsDesc += "EXECINSTR" if flagsDesc[-1] == '|': flagsDesc = flagsDesc[:-1] return flagsDesc def __repr__(self): return "".format( id(self), self.name, self.type, self.flags_description, hex(self.start), hex(self.length)) ## # @brief An ELF binary executable file. # # Examines the ELF and provides several lists of useful data: section objects, and both used # and unused ranges of memory. # # An ELFSection object is created for each of the sections of the file that are loadable code or # data, or otherwise occupy memory. These are normally the .text, .rodata, .data, and .bss # sections. More specifically, the list of sections contains any section with a type of # `SHT_PROGBITS` or `SHT_NOBITS`. Also, at least one of the `SHF_WRITE`, `SHF_ALLOC`, or # `SHF_EXECINSTR` flags must be set. # # The set of sections is compared with the target's memory map to produce a lists of the used # (occupied) and unused (unoccupied) ranges of memory. Note that if the executable uses ranges # of memory not mapped with a section of the ELF file, those ranges will not be considered in # the used/unused lists. Also, only ranges completely contained within a region of the memory # map are considered. class ELFBinaryFile(object): def __init__(self, elf, memory_map): if isinstance(elf, six.string_types): self._file = open(elf, 'rb') self._owns_file = True else: self._file = elf self._owns_file = False self._elf = ELFFile(self._file) self._memory_map = memory_map or MemoryMap() self._symbol_decoder = None self._address_decoder = None self._extract_sections() self._compute_regions() ## @brief Close the ELF file if it is owned by this instance. def __del__(self): if self._owns_file: self.close() def _extract_sections(self): # Get list of interesting sections. self._sections = [] sections = self._elf.iter_sections() for s in sections: # Skip sections not of these types. if s['sh_type'] not in ('SHT_PROGBITS', 'SHT_NOBITS'): continue # Skip sections that don't have one of these flags set. if s['sh_flags'] & (SH_FLAGS.SHF_WRITE | SH_FLAGS.SHF_ALLOC | SH_FLAGS.SHF_EXECINSTR) == 0: continue self._sections.append(ELFSection(self, s)) self._sections.sort(key=lambda x: x.start) def _dump_sections(self): for s in self._sections: print("{0:<20} {1:<25} {2:<10} {3:<10}".format( s.name, s.flags_description, hex(s.start), hex(s.length))) def _compute_regions(self): used = [] unused = [] for region in self._memory_map: current = region.start for sect in self._sections: start = sect.start length = sect.length # Skip if this section isn't within this memory region. if not region.contains_range(start, length=length): continue # Add this section as used. used.append(MemoryRange(start=start, length=length, region=region)) # Add unused segment. if start > current: unused.append(MemoryRange(start=current, length=(start - current), region=region)) current = start + length # Add a final unused segment of the region. if region.end > current: unused.append(MemoryRange(start=current, end=region.end, region=region)) self._used = used self._unused = unused def close(self): self._file.close() self._owns_file = False ## # @brief Access the list of sections in the ELF file. # @return A list of ELFSection objects sorted by start address. @property def sections(self): return self._sections ## # @brief Access the list of used ranges of memory in the ELF file. # @return A list of MemoryRange objects sorted by start address. @property def used_ranges(self): return self._used ## # @brief Access the list of unused ranges of memory in the ELF file. # @return A list of MemoryRange objects sorted by start address. @property def unused_ranges(self): return self._unused @property def symbol_decoder(self): if self._symbol_decoder is None: self._symbol_decoder = ElfSymbolDecoder(self._elf) return self._symbol_decoder @property def address_decoder(self): if self._address_decoder is None: self._address_decoder = DwarfAddressDecoder(self._elf) return self._address_decoder pyocd-0.13.1/pyocd/debug/semihost.py0000644000175000017500000006062113373511253017233 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import os import sys import io import logging import time import datetime import threading import socket import traceback import six import pyocd from ..gdbserver.gdb_socket import GDBSocket from ..gdbserver.gdb_websocket import GDBWebSocket from ..core import exceptions # Debug logging options LOG_SEMIHOST = True ## bkpt #0xab instruction BKPT_INSTR = 0xbeab # ARM semihosting request numbers. TARGET_SYS_OPEN = 0x01 TARGET_SYS_CLOSE = 0x02 TARGET_SYS_WRITEC = 0x03 TARGET_SYS_WRITE0 = 0x04 TARGET_SYS_WRITE = 0x05 TARGET_SYS_READ = 0x06 TARGET_SYS_READC = 0x07 TARGET_SYS_ISERROR = 0x08 TARGET_SYS_ISTTY = 0x09 TARGET_SYS_SEEK = 0x0a TARGET_SYS_FLEN = 0x0c TARGET_SYS_TMPNAM = 0x0d TARGET_SYS_REMOVE = 0x0e TARGET_SYS_RENAME = 0x0f TARGET_SYS_CLOCK = 0x10 TARGET_SYS_TIME = 0x11 TARGET_SYS_SYSTEM = 0x12 TARGET_SYS_ERRNO = 0x13 TARGET_SYS_GET_CMDLINE = 0x15 TARGET_SYS_HEAPINFO = 0x16 angel_SWIreason_EnterSVC = 0x17 # pylint: disable=invalid-name TARGET_SYS_EXIT = 0x18 # Also called angel_SWIreason_ReportException TARGET_SYS_ELAPSED = 0x30 TARGET_SYS_TICKFREQ = 0x31 # Pseudo-file descriptor numbers. The fds must be non-zero according to the # ARM semihosting spec. STDIN_FD = 1 STDOUT_FD = 2 STDERR_FD = 3 ## Maximum length of a null-terminated string we'll attempt to read from target memory. # # The length is limited in case the string isn't terminated. # # @see SemihostAgent::_get_string() MAX_STRING_LENGTH = 2048 ## # @brief Interface for semihosting file I/O handlers. # # This class is also used as the default I/O handler if none is provided to SemihostAgent. # In this case, all file I/O requests are rejected. class SemihostIOHandler(object): def __init__(self): self.agent = None self._errno = 0 def cleanup(self): pass @property def errno(self): return self._errno ## @brief Helper for standard I/O open requests. # # In the ARM semihosting spec, standard I/O files are opened using a filename of ":tt" # with the open mode specifying which standard I/O file to open. This method takes care # of these special open requests, and is intended to be used by concrete I/O handler # subclasses. # # @return A 2-tuple of the file descriptor and filename. The filename is returned so it # only has to be read from target memory once if the request is not for standard I/O. # The returned file descriptor may be one of 0, 1, or 2 for the standard I/O files, # -1 if an invalid combination was requested, or None if the request was not for # a standard I/O file (i.e., the filename was not ":tt"). If None is returned for the # file descriptor, the caller must handle the open request. def _std_open(self, fnptr, fnlen, mode): filename = self.agent._get_string(fnptr, fnlen) logging.debug("Semihost: open '%s' mode %s", filename, mode) # Handle standard I/O. if filename == ':tt': if mode == 'r': fd = STDIN_FD elif mode == 'w': fd = STDOUT_FD elif mode == 'a': fd = STDERR_FD else: logging.warning("Unrecognized semihosting console open file combination: mode=%s", mode) return -1, filename return fd, filename return None, filename def open(self, fnptr, fnlen, mode): raise NotImplementedError() def close(self, fd): raise NotImplementedError() def write(self, fd, ptr, length): raise NotImplementedError() def read(self, fd, ptr, length): raise NotImplementedError() def readc(self): raise NotImplementedError() def istty(self, fd): raise NotImplementedError() def seek(self, fd, pos): raise NotImplementedError() def flen(self, fd): raise NotImplementedError() def remove(self, ptr, length): raise NotImplementedError() def rename(self, oldptr, oldlength, newptr, newlength): raise NotImplementedError() ## # @brief Implements semihosting requests directly in the Python process. # # This class maintains its own list of pseudo-file descriptors for files opened by the # debug target. By default, this class uses the system stdin, stdout, and stderr file objects # for file desscriptors 1, 2, and 3. class InternalSemihostIOHandler(SemihostIOHandler): def __init__(self): super(InternalSemihostIOHandler, self).__init__() self.next_fd = STDERR_FD + 1 # Go ahead and connect standard I/O. self.open_files = { STDIN_FD : sys.stdin, STDOUT_FD : sys.stdout, STDERR_FD : sys.stderr } def _is_valid_fd(self, fd): return fd in self.open_files and self.open_files[fd] is not None def cleanup(self): for f in (self.open_files[k] for k in self.open_files if k > STDERR_FD): f.close() def open(self, fnptr, fnlen, mode): fd, filename = self._std_open(fnptr, fnlen, mode) if fd is not None: return fd try: fd = self.next_fd self.next_fd += 1 f = io.open(filename, mode) self.open_files[fd] = f return fd except IOError as e: self._errno = e.errno logging.error("Semihost: failed to open file '%s'", filename) traceback.print_exc() return -1 def close(self, fd): if fd > STDERR_FD: if not self._is_valid_fd(fd): return -1 f = self.open_files.pop(fd) try: f.close() except OSError: # Ignore errors closing files. pass return 0 def write(self, fd, ptr, length): if not self._is_valid_fd(fd): # Return byte count not written. return length data = self.agent._get_string(ptr, length) try: f = self.open_files[fd] if 'b' not in f.mode: data = six.text_type(data) f.write(data) f.flush() return 0 except IOError as e: self._errno = e.errno logging.debug("Semihost: exception: %s", e) return -1 def read(self, fd, ptr, length): if not self._is_valid_fd(fd): # Return byte count not read. return length try: f = self.open_files[fd] data = f.read(length) if 'b' not in f.mode: data = data.encode() except IOError as e: self._errno = e.errno logging.debug("Semihost: exception: %s", e) return -1 data = bytearray(data) self.agent.context.write_memory_block8(ptr, data) return length - len(data) def readc(self): try: f = self.open_files[STDIN_FD] if f is not None: data = f.read(1) if 'b' not in f.mode: data = data.encode() return data else: return 0 except OSError as e: self._errno = e.errno return 0 def istty(self, fd): if not self._is_valid_fd(fd): return -1 # Just assume that stdio is a terminal and other files aren't. return int(not fd > STDERR_FD) def seek(self, fd, pos): if not self._is_valid_fd(fd): return -1 try: self.open_files[fd].seek(pos) return 0 except IOError as e: self._errno = e.errno return -1 def flen(self, fd): if not self._is_valid_fd(fd): return -1 try: info = os.fstat(self.open_files[fd].fileno()) return info.st_size except OSError as e: self._errno = e.errno return -1 ## # @brief Serves a telnet connection for semihosting. # # Not all semihost requests are support. This class is meant to be used only for the # debug console. Pass an instance for the @i console parameter of the SemihostAgent # constructor. # # The server thread will automatically be started by the constructor. To shut down the # server and its thread, call the stop() method. class TelnetSemihostIOHandler(SemihostIOHandler): def __init__(self, port_or_url, serve_local_only=True): super(TelnetSemihostIOHandler, self).__init__() self._abstract_socket = None self._wss_server = None self._port = 0 if isinstance(port_or_url, str) == True: self._wss_server = port_or_url self._abstract_socket = GDBWebSocket(self._wss_server) else: self._port = port_or_url self._abstract_socket = GDBSocket(self._port, 4096) if serve_local_only: self._abstract_socket.host = 'localhost' self._buffer = bytearray() self._buffer_lock = threading.Lock() self.connected = None self._shutdown_event = threading.Event() self._thread = threading.Thread(target=self._server, name="semihost-telnet") self._thread.daemon = True self._thread.start() def stop(self): self._shutdown_event.set() self._thread.join() def _server(self): logging.info("Telnet: server started on port %s", str(self._port)) self.connected = None try: while not self._shutdown_event.is_set(): # Wait for a client to connect. # TODO support multiple client connections while not self._shutdown_event.is_set(): self.connected = self._abstract_socket.connect() if self.connected is not None: logging.debug("Telnet: client connected") break if self._shutdown_event.is_set(): break # Set timeout on new connection. self._abstract_socket.set_timeout(0.1) # Keep reading from the client until we either get a shutdown event, or # the client disconnects. The incoming data is appended to our read buffer. while not self._shutdown_event.is_set(): try: data = self._abstract_socket.read() if len(data) == 0: # Client disconnected. self._abstract_socket.close() self.connected = None break self._buffer_lock.acquire() self._buffer += bytearray(data) self._buffer_lock.release() except socket.timeout: pass finally: self._abstract_socket.close() logging.info("Telnet: server stopped") def write(self, fd, ptr, length): # If nobody is connected, act like all data was written anyway. if self.connected is None: return 0 data = self.agent._get_string(ptr, length) remaining = len(data) while remaining: count = self._abstract_socket.write(data) remaining -= count if remaining: data = data[count:] return 0 ## @brief Extract requested amount of data from the read buffer. def _get_input(self, length): self._buffer_lock.acquire() try: actualLength = min(length, len(self._buffer)) if actualLength: data = self._buffer[:actualLength] self._buffer = self._buffer[actualLength:] else: data = bytearray() return data finally: self._buffer_lock.release() def read(self, fd, ptr, length): if self.connected is None: return -1 # Extract requested amount of data from the read buffer. data = self._get_input(length) # Stuff data into provided buffer. if data: self.agent.context.write_memory_block8(ptr, data) result = length - len(data) if not data: self._errno = 5 return -1 return result def readc(self): if self.connected is None: return -1 data = self._get_input(1) if data: return data[0] else: return -1 ## # @brief Handler for ARM semihosting requests. # # Semihosting requests are made by the target by executing a 'bkpt #0xab' instruction. The # requested operation is specified by R0 and any arguments by R1. Many requests use a block # of word-sized arguments pointed to by R1. The return value is passed back to the target # in R0. # # This class does not handle any file-related requests by itself. It uses I/O handler objects # passed in to the constructor. The requests handled directly by this class are #TARGET_SYS_CLOCK # and #TARGET_SYS_TIME. # # There are two types of I/O handlers used by this class. The main I/O handler, set # with the constructor's @i io_handler parameter, is used for most file operations. # You may optionally pass another I/O handler for the @i console constructor parameter. The # console handler is used solely for standard I/O and debug console I/O requests. If no console # handler is provided, the main handler is used instead. TARGET_SYS_OPEN requests are not # passed to the console handler in any event, they are always passed to the main handler. # # If no main I/O handler is provided, the class will use SemihostIOHandler, which causes all # file I/O requests to be rejected as an error. # # The SemihostAgent assumes standard I/O file descriptor numbers are #STDIN_FD, #STDOUT_FD, # and #STDERR_FD. When it receives a read or write request for one of these descriptors, it # passes the request to the console handler. This means the main handler must return these # numbers for standard I/O open requests (those with a file name of ":tt"). # # Not all semihosting requests are supported. Those that are not implemented are: # - TARGET_SYS_TMPNAM # - TARGET_SYS_SYSTEM # - TARGET_SYS_GET_CMDLINE # - TARGET_SYS_HEAPINFO # - TARGET_SYS_EXIT # - TARGET_SYS_ELAPSED # - TARGET_SYS_TICKFREQ class SemihostAgent(object): ## Index into this array is the file open mode argument to TARGET_SYS_OPEN. OPEN_MODES = ['r', 'rb', 'r+', 'r+b', 'w', 'wb', 'w+', 'w+b', 'a', 'ab', 'a+', 'a+b'] EPOCH = datetime.datetime(1970, 1, 1) def __init__(self, context, io_handler=None, console=None): self.context = context self.start_time = time.time() self.io_handler = io_handler or SemihostIOHandler() self.io_handler.agent = self self.console = console or self.io_handler self.console.agent = self self.request_map = { TARGET_SYS_OPEN : self.handle_sys_open, TARGET_SYS_CLOSE : self.handle_sys_close, TARGET_SYS_WRITEC : self.handle_sys_writec, TARGET_SYS_WRITE0 : self.handle_sys_write0, TARGET_SYS_WRITE : self.handle_sys_write, TARGET_SYS_READ : self.handle_sys_read, TARGET_SYS_READC : self.handle_sys_readc, TARGET_SYS_ISERROR : self.handle_sys_iserror, TARGET_SYS_ISTTY : self.handle_sys_istty, TARGET_SYS_SEEK : self.handle_sys_seek, TARGET_SYS_FLEN : self.handle_sys_flen, TARGET_SYS_TMPNAM : self.handle_sys_tmpnam, TARGET_SYS_REMOVE : self.handle_sys_remove, TARGET_SYS_RENAME : self.handle_sys_rename, TARGET_SYS_CLOCK : self.handle_sys_clock, TARGET_SYS_TIME : self.handle_sys_time, TARGET_SYS_SYSTEM : self.handle_sys_system, TARGET_SYS_ERRNO : self.handle_sys_errno, TARGET_SYS_GET_CMDLINE : self.handle_sys_get_cmdline, TARGET_SYS_HEAPINFO : self.handle_sys_heapinfo, TARGET_SYS_EXIT : self.handle_sys_exit, TARGET_SYS_ELAPSED : self.handle_sys_elapsed, TARGET_SYS_TICKFREQ : self.handle_sys_tickfreq } ## @brief Handle a semihosting request. # # This method should be called after the target has halted, to check if the halt was # due to a semihosting request. It first checks to see if the target halted because # of a breakpoint. If so, it reads the instruction at PC to make sure it is a 'bkpt #0xAB' # instruction. If so, the target is making a semihosting request. If not, nothing more is done. # # After the request is handled, the PC is advanced to the next instruction after the 'bkpt'. # A boolean is return indicating whether a semihosting request was handled. If True, the # caller should resume the target immediately. # # @retval True A semihosting request was handled. # @retval False The target halted for a reason other than semihosting, i.e. a user-installed # debugging breakpoint. def check_and_handle_semihost_request(self): # Nothing to do if this is not a bkpt. if (self.context.read32(pyocd.coresight.cortex_m.CortexM.DFSR) & pyocd.coresight.cortex_m.CortexM.DFSR_BKPT) == 0: return False pc = self.context.read_core_register('pc') # Are we stopped due to one of our own breakpoints? bp = self.context.core.find_breakpoint(pc) if bp: return False # Get the instruction at the breakpoint. instr = self.context.read16(pc) # Check for semihost bkpt. if instr != BKPT_INSTR: return False # Advance PC beyond the bkpt instruction. self.context.write_core_register('pc', pc + 2) # Get args op = self.context.read_core_register('r0') args = self.context.read_core_register('r1') # Handle request handler = self.request_map.get(op, None) if handler: try: result = handler(args) except NotImplementedError: logging.warning("Semihost: unimplemented request pc=%x r0=%x r1=%x", pc, op, args) result = -1 except Exception as e: logging.warning("Exception while handling semihost request: %s", e) traceback.print_exc(e) result = -1 else: result = -1 # Set return value. self.context.write_core_register('r0', result) return True ## @brief Clean up any resources allocated by semihost requests. # # @note May be called more than once. def cleanup(self): self.io_handler.cleanup() if self.console is not self.io_handler: self.console.cleanup() def _get_args(self, args, count): args = self.context.read_memory_block32(args, count) if count == 1: return args[0] else: return args def _get_string(self, ptr, length=None): if length is not None: data = self.context.read_memory_block8(ptr, length) return str(bytearray(data)) target_str = '' # TODO - use memory map to make sure we don't try to read off the end of memory # Limit string size in case it isn't terminated. while len(target_str) < MAX_STRING_LENGTH: try: # Read 32 bytes at a time for efficiency. data = self.context.read_memory_block8(ptr, 32) terminator = data.index(0) # Found a null terminator, append data up to but not including the null # and then exit the loop. target_str += str(bytearray(data[:terminator])) break except exceptions.TransferError: # Failed to read some or all of the string. break except ValueError: # No null terminator was found. Append all of data. target_str += str(bytearray(data)) ptr += 32 return target_str def handle_sys_open(self, args): fnptr, mode, fnlen = self._get_args(args, 3) if mode >= len(self.OPEN_MODES): return -1 mode = self.OPEN_MODES[mode] if LOG_SEMIHOST: logging.debug("Semihost: open %x/%x, mode %s", fnptr, fnlen, mode) return self.io_handler.open(fnptr, fnlen, mode) def handle_sys_close(self, args): fd = self._get_args(args, 1) if LOG_SEMIHOST: logging.debug("Semihost: close fd=%d", fd) return self.io_handler.close(fd) def handle_sys_writec(self, args): if LOG_SEMIHOST: logging.debug("Semihost: writec %x", args) return self.console.write(STDOUT_FD, args, 1) def handle_sys_write0(self, args): msg = self._get_string(args) if LOG_SEMIHOST: logging.debug("Semihost: write0 msg='%s'", msg) return self.console.write(STDOUT_FD, args, len(msg)) def handle_sys_write(self, args): fd, data_ptr, length = self._get_args(args, 3) if LOG_SEMIHOST: logging.debug("Semihost: write fd=%d ptr=%x len=%d", fd, data_ptr, length) if fd in (STDOUT_FD, STDERR_FD): return self.console.write(fd, data_ptr, length) else: return self.io_handler.write(fd, data_ptr, length) def handle_sys_read(self, args): fd, ptr, length = self._get_args(args, 3) if LOG_SEMIHOST: logging.debug("Semihost: read fd=%d ptr=%x len=%d", fd, ptr, length) if fd == STDIN_FD: return self.console.read(fd, ptr, length) else: return self.io_handler.read(fd, ptr, length) def handle_sys_readc(self, args): if LOG_SEMIHOST: logging.debug("Semihost: readc") return self.console.readc() def handle_sys_iserror(self, args): raise NotImplementedError() def handle_sys_istty(self, args): fd = self._get_args(args, 1) if LOG_SEMIHOST: logging.debug("Semihost: istty fd=%d", fd) return self.io_handler.istty(fd) def handle_sys_seek(self, args): fd, pos = self._get_args(args, 2) if LOG_SEMIHOST: logging.debug("Semihost: seek fd=%d pos=%d", fd, pos) return self.io_handler.seek(fd, pos) def handle_sys_flen(self, args): fd = self._get_args(args, 1) if LOG_SEMIHOST: logging.debug("Semihost: flen fd=%d", fd) return self.io_handler.flen(fd) def handle_sys_tmpnam(self, args): raise NotImplementedError() def handle_sys_remove(self, args): ptr, length = self._get_args(args, 2) return self.io_handler.remove(ptr, length) def handle_sys_rename(self, args): oldptr, oldlength, newptr, newlength = self._get_args(args, 4) return self.io_handler.rename(oldptr, oldlength, newptr, newlength) def handle_sys_clock(self, args): now = time.time() delta = now - self.start_time return int(delta * 100) def handle_sys_time(self, args): now = datetime.datetime.now() delta = now - self.EPOCH seconds = (delta.days * 86400) + delta.seconds return seconds def handle_sys_system(self, args): raise NotImplementedError() def handle_sys_errno(self, args): return self.io_handler.errno def handle_sys_get_cmdline(self, args): raise NotImplementedError() def handle_sys_heapinfo(self, args): raise NotImplementedError() def handle_sys_exit(self, args): raise NotImplementedError() def handle_sys_elapsed(self, args): raise NotImplementedError() def handle_sys_tickfreq(self, args): raise NotImplementedError() pyocd-0.13.1/pyocd/debug/__init__.py0000644000175000017500000000112713373511253017133 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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. """ pyocd-0.13.1/pyocd/debug/svd.py0000644000175000017500000000421613373511253016172 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import threading import logging # Make cmsis_svd optional. try: from cmsis_svd.parser import SVDParser IS_CMSIS_SVD_AVAILABLE = True except ImportError: IS_CMSIS_SVD_AVAILABLE = False class SVDFile(object): def __init__(self, filename=None, vendor=None, is_local=False): self.filename = filename self.vendor = vendor self.is_local = is_local self.device = None def load(self): if not IS_CMSIS_SVD_AVAILABLE: return if self.is_local: self.device = SVDParser.for_xml_file(self.filename).get_device() else: self.device = SVDParser.for_packaged_svd(self.vendor, self.filename).get_device() ## @brief Thread to read an SVD file in the background. class SVDLoader(threading.Thread): def __init__(self, svdFile, completionCallback): super(SVDLoader, self).__init__(name='load-svd') self.daemon = True self._svd_location = svdFile self._svd_device = None self._callback = completionCallback @property def device(self): if not self._svd_device: self.join() return self._svd_device def load(self): if not self._svd_device and self._svd_location: self.start() def run(self): try: self._svd_location.load() self._svd_device = self._svd_location.device if self._callback: self._callback(self._svd_device) except IOError: logging.warning("Failed to load SVD file %s", self._svd_location.filename) pyocd-0.13.1/pyocd/debug/cache.py0000644000175000017500000004671713373511253016455 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 .context import DebugContext from ..coresight.cortex_m import ( CORE_REGISTER, register_name_to_index, is_fpu_register, is_cfbp_subregister, is_psr_subregister, sysm_to_psr_mask ) from ..utility import conversion from intervaltree import (Interval, IntervalTree) import logging ## @brief Generic failure to access memory. class MemoryAccessError(RuntimeError): pass ## @brief Holds hit ratio metrics for the caches. class CacheMetrics(object): def __init__(self): self.hits = 0 self.misses = 0 self.reads = 0 self.writes = 0 @property def total(self): return self.hits + self.misses @property def percent_hit(self): if self.total > 0: return self.hits * 100.0 / self.total else: return 0 @property def percent_miss(self): if self.total > 0: return self.misses * 100.0 / self.total else: return 0 ## @brief Cache of a core's register values. # # The only interesting part of this cache is how it handles the special registers: CONTROL, # FAULTMASK, BASEPRI, PRIMASK, and CFBP. The values of the first four registers are read and written # all at once as the CFBP register through the hardware DCRSR register. On reads of any of these # registers, or the combined CFBP, the cache will ask the underlying context to read CFBP. It will # then update the cache entries for all five registers. Writes to any of these registers just # invalidate all five. # # Same logic applies for XPSR submasks. class RegisterCache(object): CFBP_REGS = [ CORE_REGISTER['cfbp'], CORE_REGISTER['control'], CORE_REGISTER['faultmask'], CORE_REGISTER['basepri'], CORE_REGISTER['primask'], ] XPSR_REGS = [ CORE_REGISTER['xpsr'], CORE_REGISTER['apsr'], CORE_REGISTER['iapsr'], CORE_REGISTER['eapsr'], CORE_REGISTER['ipsr'], CORE_REGISTER['epsr'], CORE_REGISTER['iepsr'], ] def __init__(self, parentContext): self._context = parentContext self._run_token = -1 self._log = logging.getLogger('regcache') self._reset_cache() def _reset_cache(self): self._cache = {} self._metrics = CacheMetrics() def _dump_metrics(self): if self._metrics.total > 0: self._log.debug("%d reads [%d%% hits, %d regs]", self._metrics.total, self._metrics.percent_hit, self._metrics.hits) else: self._log.debug("no accesses") def _check_cache(self): if self._context.core.is_running(): self._log.debug("core is running; invalidating cache") self._reset_cache() elif self._run_token != self._context.core.run_token: self._dump_metrics() self._log.debug("out of date run token; invalidating cache") self._reset_cache() self._run_token = self._context.core.run_token def _convert_and_check_registers(self, reg_list): # convert to index only reg_list = [register_name_to_index(reg) for reg in reg_list] # Sanity check register values for reg in reg_list: if reg not in CORE_REGISTER.values(): raise ValueError("unknown reg: %d" % reg) elif is_fpu_register(reg) and (not self._context.core.has_fpu): raise ValueError("attempt to read FPU register without FPU") return reg_list def read_core_registers_raw(self, reg_list): self._check_cache() reg_list = self._convert_and_check_registers(reg_list) reg_set = set(reg_list) # Get list of values we have cached. cached_set = set(r for r in reg_list if r in self._cache) self._metrics.hits += len(cached_set) # Read uncached registers from the target. read_list = list(reg_set.difference(cached_set)) reading_cfbp = any(r for r in read_list if r in self.CFBP_REGS) reading_xpsr = any(r for r in read_list if r in self.XPSR_REGS) if reading_cfbp: if not CORE_REGISTER['cfbp'] in read_list: read_list.append(CORE_REGISTER['cfbp']) cfbp_index = read_list.index(CORE_REGISTER['cfbp']) if reading_xpsr: if not CORE_REGISTER['xpsr'] in read_list: read_list.append(CORE_REGISTER['xpsr']) xpsr_index = read_list.index(CORE_REGISTER['xpsr']) self._metrics.misses += len(read_list) values = self._context.read_core_registers_raw(read_list) # Update all CFBP based registers. if reading_cfbp: v = values[cfbp_index] self._cache[CORE_REGISTER['cfbp']] = v for r in self.CFBP_REGS: if r == CORE_REGISTER['cfbp']: continue self._cache[r] = (v >> ((-r - 1) * 8)) & 0xff # Update all XPSR based registers. if reading_xpsr: v = values[xpsr_index] self._cache[CORE_REGISTER['xpsr']] = v for r in self.XPSR_REGS: if r == CORE_REGISTER['xpsr']: continue self._cache[r] = v & sysm_to_psr_mask(r) # Build the results list in the same order as requested registers. results = [] for r in reg_list: if r in cached_set: results.append(self._cache[r]) else: i = read_list.index(r) v = values[i] results.append(v) self._cache[r] = v return results # TODO only write dirty registers to target right before running. def write_core_registers_raw(self, reg_list, data_list): self._check_cache() reg_list = self._convert_and_check_registers(reg_list) self._metrics.writes += len(reg_list) writing_cfbp = any(r for r in reg_list if r in self.CFBP_REGS) writing_xpsr = any(r for r in reg_list if r in self.XPSR_REGS) # Update cached register values. for i, r in enumerate(reg_list): v = data_list[i] self._cache[r] = v # Just remove all cached CFBP and XPSR based register values. if writing_cfbp: for r in self.CFBP_REGS: self._cache.pop(r, None) if writing_xpsr: for r in self.XPSR_REGS: self._cache.pop(r, None) # Write new register values to target. self._context.write_core_registers_raw(reg_list, data_list) def invalidate(self): self._reset_cache() ## @brief Memory cache. # # Maintains a cache of target memory. The constructor is passed a backing DebugContext object that # will be used to fill the cache. # # The cache is invalidated whenever the target has run since the last cache operation (based on run # tokens). If the target is currently running, all accesses cause the cache to be invalidated. # # The target's memory map is referenced. All memory accesses must be fully contained within a single # memory region, or a MemoryAccessError will be raised. However, if an access is outside of all regions, # the access is passed to the underlying context unmodified. When an access is within a region, that # region's cacheability flag is honoured. class MemoryCache(object): def __init__(self, context): self._context = context self._run_token = -1 self._log = logging.getLogger('memcache') self._reset_cache() def _reset_cache(self): self._cache = IntervalTree() self._metrics = CacheMetrics() ## # @brief Invalidates the cache if appropriate. def _check_cache(self): if self._context.core.is_running(): self._log.debug("core is running; invalidating cache") self._reset_cache() elif self._run_token != self._context.core.run_token: self._dump_metrics() self._log.debug("out of date run token; invalidating cache") self._reset_cache() self._run_token = self._context.core.run_token ## # @brief Splits a memory address range into cached and uncached subranges. # @return Returns a 2-tuple with the first element being a set of Interval objects for each # of the cached subranges. The second element is a set of Interval objects for each of the # non-cached subranges. def _get_ranges(self, addr, count): cached = self._cache.search(addr, addr + count) uncached = {Interval(addr, addr + count)} for cachedIv in cached: newUncachedSet = set() for uncachedIv in uncached: # No overlap. if cachedIv.end < uncachedIv.begin or cachedIv.begin > uncachedIv.end: newUncachedSet.add(uncachedIv) continue # Begin segment. if cachedIv.begin - uncachedIv.begin > 0: newUncachedSet.add(Interval(uncachedIv.begin, cachedIv.begin)) # End segment. if uncachedIv.end - cachedIv.end > 0: newUncachedSet.add(Interval(cachedIv.end, uncachedIv.end)) uncached = newUncachedSet return cached, uncached ## # @brief Reads uncached memory ranges and updates the cache. # @return A list of Interval objects is returned. Each Interval has its @a data attribute set # to a bytearray of the data read from target memory. def _read_uncached(self, uncached): uncachedData = [] for uncachedIv in uncached: data = self._context.read_memory_block8(uncachedIv.begin, uncachedIv.end - uncachedIv.begin) iv = Interval(uncachedIv.begin, uncachedIv.end, bytearray(data)) self._cache.add(iv) # TODO merge contiguous cached intervals uncachedData.append(iv) return uncachedData def _update_metrics(self, cached, uncached, addr, size): cachedSize = 0 for iv in cached: begin = iv.begin end = iv.end if iv.begin < addr: begin = addr if iv.end > addr + size: end = addr + size cachedSize += end - begin uncachedSize = sum((iv.end - iv.begin) for iv in uncached) self._metrics.reads += 1 self._metrics.hits += cachedSize self._metrics.misses += uncachedSize def _dump_metrics(self): if self._metrics.total > 0: self._log.debug("%d reads, %d bytes [%d%% hits, %d bytes]; %d bytes written", self._metrics.reads, self._metrics.total, self._metrics.percent_hit, self._metrics.hits, self._metrics.writes) else: self._log.debug("no reads") ## # @brief Performs a cached read operation of an address range. # @return A list of Interval objects sorted by address. def _read(self, addr, size): # Get the cached and uncached subranges of the requested read. cached, uncached = self._get_ranges(addr, size) self._update_metrics(cached, uncached, addr, size) # Read any uncached ranges. uncachedData = self._read_uncached(uncached) # Merged cached with data we just read combined = list(cached) + uncachedData combined.sort(key=lambda x: x.begin) return combined ## # @brief Extracts data from the intersection of an address range across a list of interval objects. # # The range represented by @a addr and @a size are assumed to overlap the intervals. The first # and last interval in the list may have ragged edges not fully contained in the address range, in # which case the correct slice of those intervals is extracted. # # @param self # @param combined List of Interval objects forming a contiguous range. The @a data attribute of # each interval must be a bytearray. # @param addr Start address. Must be within the range of the first interval. # @param size Number of bytes. (@a addr + @a size) must be within the range of the last interval. # @return A single bytearray object with all data from the intervals that intersects the address # range. def _merge_data(self, combined, addr, size): result = bytearray() resultAppend = bytearray() # Take slice of leading ragged edge. if len(combined) and combined[0].begin < addr: offset = addr - combined[0].begin result += combined[0].data[offset:] combined = combined[1:] # Take slice of trailing ragged edge. if len(combined) and combined[-1].end > addr + size: offset = addr + size - combined[-1].begin resultAppend = combined[-1].data[:offset] combined = combined[:-1] # Merge. for iv in combined: result += iv.data result += resultAppend return result ## # @brief def _update_contiguous(self, cached, addr, value): size = len(value) end = addr + size leadBegin = addr leadData = bytearray() trailData = bytearray() trailEnd = end if cached[0].begin < addr and cached[0].end > addr: offset = addr - cached[0].begin leadData = cached[0].data[:offset] leadBegin = cached[0].begin if cached[-1].begin < end and cached[-1].end > end: offset = end - cached[-1].begin trailData = cached[-1].data[offset:] trailEnd = cached[-1].end self._cache.remove_overlap(addr, end) data = leadData + value + trailData self._cache.addi(leadBegin, trailEnd, data) ## # @return A bool indicating whether the given address range is fully contained within # one known memory region, and that region is cacheable. # @exception MemoryAccessError Raised if the access is not entirely contained within a single region. def _check_regions(self, addr, count): regions = self._context.core.memory_map.get_intersecting_regions(addr, length=count) # If no regions matched, then allow an uncached operation. if len(regions) == 0: return False # Raise if not fully contained within one region. if len(regions) > 1 or not regions[0].contains_range(addr, length=count): raise MemoryAccessError("individual memory accesses must not cross memory region boundaries") # Otherwise return whether the region is cacheable. return regions[0].is_cacheable def read_memory(self, addr, transfer_size=32, now=True): # TODO use more optimal underlying read_memory call if transfer_size == 8: data = self.read_memory_block8(addr, 1)[0] elif transfer_size == 16: data = conversion.byte_list_to_u16le_list(self.read_memory_block8(addr, 2))[0] elif transfer_size == 32: data = conversion.byte_list_to_u32le_list(self.read_memory_block8(addr, 4))[0] if now: return data else: def read_cb(): return data return read_cb def read_memory_block8(self, addr, size): if size <= 0: return [] self._check_cache() # Validate memory regions. if not self._check_regions(addr, size): self._log.debug("range [%x:%x] is not cacheable", addr, addr+size) return self._context.read_memory_block8(addr, size) # Get the cached and uncached subranges of the requested read. combined = self._read(addr, size) # Extract data out of combined intervals. result = list(self._merge_data(combined, addr, size)) return result def read_memory_block32(self, addr, size): return conversion.byte_list_to_u32le_list(self.read_memory_block8(addr, size*4)) def write_memory(self, addr, value, transfer_size=32): if transfer_size == 8: return self.write_memory_block8(addr, [value]) elif transfer_size == 16: return self.write_memory_block8(addr, conversion.u16le_list_to_byte_list([value])) elif transfer_size == 32: return self.write_memory_block8(addr, conversion.u32le_list_to_byte_list([value])) def write_memory_block8(self, addr, value): if len(value) <= 0: return self._check_cache() # Validate memory regions. cacheable = self._check_regions(addr, len(value)) # Write to the target first, so if it fails we don't update the cache. result = self._context.write_memory_block8(addr, value) if cacheable: size = len(value) end = addr + size cached = sorted(self._cache.search(addr, end), key=lambda x:x.begin) self._metrics.writes += size if len(cached): # Write data is entirely within cached data. if addr >= cached[0].begin and end <= cached[0].end: beginOffset = addr - cached[0].begin endOffset = end - cached[0].end cached[0].data[beginOffset:endOffset] = value else: self._update_contiguous(cached, addr, bytearray(value)) else: # No cached data in this range, so just add the entire interval. self._cache.addi(addr, end, bytearray(value)) return result def write_memory_block32(self, addr, data): return self.write_memory_block8(addr, conversion.u32le_list_to_byte_list(data)) def invalidate(self): self._reset_cache() ## @brief Debug context combining register and memory caches. class CachingDebugContext(DebugContext): def __init__(self, parentContext): super(CachingDebugContext, self).__init__(parentContext.core) self._regcache = RegisterCache(parentContext) self._memcache = MemoryCache(parentContext) def write_memory(self, addr, value, transfer_size=32): return self._memcache.write_memory(addr, value, transfer_size) def read_memory(self, addr, transfer_size=32, now=True): return self._memcache.read_memory(addr, transfer_size, now) def write_memory_block8(self, addr, value): return self._memcache.write_memory_block8(addr, value) def write_memory_block32(self, addr, data): return self._memcache.write_memory_block32(addr, data) def read_memory_block8(self, addr, size): return self._memcache.read_memory_block8(addr, size) def read_memory_block32(self, addr, size): return self._memcache.read_memory_block32(addr, size) def read_core_registers_raw(self, reg_list): return self._regcache.read_core_registers_raw(reg_list) def write_core_registers_raw(self, reg_list, data_list): return self._regcache.write_core_registers_raw(reg_list, data_list) def invalidate(self): self._regcache.invalidate() self._memcache.invalidate() pyocd-0.13.1/pyocd/debug/breakpoints/0000755000175000017500000000000013373523011017335 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/debug/breakpoints/provider.py0000644000175000017500000000316013373511253021546 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-2017 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 ...core.target import Target class Breakpoint(object): def __init__(self, provider): self.type = Target.BREAKPOINT_HW self.enabled = False self.addr = 0 self.original_instr = 0 self.provider = provider def __repr__(self): return "<%s@0x%08x type=%d addr=0x%08x>" % (self.__class__.__name__, id(self), self.type, self.addr) ## @brief Abstract base class for breakpoint providers. class BreakpointProvider(object): def init(self): raise NotImplementedError() def bp_type(self): return 0 @property def do_filter_memory(self): return False def available_breakpoints(self): raise NotImplementedError() def find_breakpoint(self, addr): raise NotImplementedError() def set_breakpoint(self, addr): raise NotImplementedError() def remove_breakpoint(self, bp): raise NotImplementedError() def filter_memory(self, addr, size, data): return data def flush(self): pass pyocd-0.13.1/pyocd/debug/breakpoints/__init__.py0000644000175000017500000000113013373511253021446 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ pyocd-0.13.1/pyocd/debug/breakpoints/software.py0000644000175000017500000000633513373511253021555 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-2017 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 .provider import (Breakpoint, BreakpointProvider) from ...core import exceptions from ...core.target import Target import logging class SoftwareBreakpoint(Breakpoint): def __init__(self, provider): super(SoftwareBreakpoint, self).__init__(provider) self.type = Target.BREAKPOINT_SW class SoftwareBreakpointProvider(BreakpointProvider): ## BKPT #0 instruction. BKPT_INSTR = 0xbe00 def __init__(self, core): super(SoftwareBreakpointProvider, self).__init__() self._core = core self._breakpoints = {} def init(self): pass def bp_type(self): return Target.BREAKPOINT_SW @property def do_filter_memory(self): return True def available_breakpoints(self): return -1 def find_breakpoint(self, addr): return self._breakpoints.get(addr, None) def set_breakpoint(self, addr): assert self._core.memory_map.get_region_for_address(addr).is_ram assert (addr & 1) == 0 try: # Read original instruction. instr = self._core.read16(addr) # Insert BKPT #0 instruction. self._core.write16(addr, self.BKPT_INSTR) # Create bp object. bp = SoftwareBreakpoint(self) bp.enabled = True bp.addr = addr bp.original_instr = instr # Save this breakpoint. self._breakpoints[addr] = bp return bp except exceptions.TransferError: logging.debug("Failed to set sw bp at 0x%x" % addr) return None def remove_breakpoint(self, bp): assert bp is not None and isinstance(bp, Breakpoint) try: # Restore original instruction. self._core.write16(bp.addr, bp.original_instr) # Remove from our list. del self._breakpoints[bp.addr] except exceptions.TransferError: logging.debug("Failed to remove sw bp at 0x%x" % bp.addr) def filter_memory(self, addr, size, data): for bp in self._breakpoints.values(): if size == 8: if bp.addr == addr: data = bp.original_instr & 0xff elif bp.addr + 1 == addr: data = bp.original_instr >> 8 elif size == 16: if bp.addr == addr: data = bp.original_instr elif size == 32: if bp.addr == addr: data = (data & 0xffff0000) | bp.original_instr elif bp.addr == addr + 2: data = (data & 0xffff) | (bp.original_instr << 16) return data pyocd-0.13.1/pyocd/debug/breakpoints/manager.py0000644000175000017500000001443313373511253021333 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-2017 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 ...core.target import Target import logging ## # @brief class BreakpointManager(object): ## Number of hardware breakpoints to try to keep available. MIN_HW_BREAKPOINTS = 0 def __init__(self, core): self._breakpoints = {} self._core = core self._fpb = None self._providers = {} def add_provider(self, provider, type): self._providers[type] = provider if type == Target.BREAKPOINT_HW: self._fpb = provider ## @brief Return a list of all breakpoint addresses. def get_breakpoints(self): return self._breakpoints.keys() def find_breakpoint(self, addr): return self._breakpoints.get(addr, None) ## @brief Set a hardware or software breakpoint at a specific location in memory. # # @retval True Breakpoint was set. # @retval False Breakpoint could not be set. def set_breakpoint(self, addr, type=Target.BREAKPOINT_AUTO): logging.debug("set bkpt type %d at 0x%x", type, addr) # Clear Thumb bit in case it is set. addr = addr & ~1 in_hw_bkpt_range = addr < 0x20000000 fbp_available = ((self._fpb is not None) and (self._fpb.available_breakpoints() > 0)) fbp_below_min = ((self._fpb is None) or (self._fpb.available_breakpoints() <= self.MIN_HW_BREAKPOINTS)) # Check for an existing breakpoint at this address. bp = self.find_breakpoint(addr) if bp is not None: return True if self._core.memory_map is None: # No memory map - fallback to hardware breakpoints. type = Target.BREAKPOINT_HW is_flash = False is_ram = False else: # Look up the memory type for the requested address. region = self._core.memory_map.get_region_for_address(addr) if region is not None: is_flash = region.is_flash is_ram = region.is_ram else: # No memory region - fallback to hardware breakpoints. type = Target.BREAKPOINT_HW is_flash = False is_ram = False # Determine best type to use if auto. if type == Target.BREAKPOINT_AUTO: # Use sw breaks for: # 1. Addresses outside the supported FPBv1 range of 0-0x1fffffff # 2. RAM regions by default. # 3. Number of remaining hw breaks are at or less than the minimum we want to keep. # # Otherwise use hw. if not in_hw_bkpt_range or is_ram or fbp_below_min: type = Target.BREAKPOINT_SW else: type = Target.BREAKPOINT_HW logging.debug("using type %d for auto bp", type) # Revert to sw bp if out of hardware breakpoint range. if (type == Target.BREAKPOINT_HW) and not in_hw_bkpt_range: if is_ram: logging.debug("using sw bp instead because of unsupported addr") type = Target.BREAKPOINT_SW else: logging.debug("could not fallback to software breakpoint") return False # Revert to hw bp if region is flash. if is_flash: if in_hw_bkpt_range and fbp_available: logging.debug("using hw bp instead because addr is flash") type = Target.BREAKPOINT_HW else: logging.debug("could not fallback to hardware breakpoint") return False # Set the bp. try: provider = self._providers[type] bp = provider.set_breakpoint(addr) except KeyError: raise RuntimeError("Unknown breakpoint type %d" % type) if bp is None: return False # Save the bp. self._breakpoints[addr] = bp return True ## @brief Remove a breakpoint at a specific location. def remove_breakpoint(self, addr): try: logging.debug("remove bkpt at 0x%x", addr) # Clear Thumb bit in case it is set. addr = addr & ~1 # Get bp and remove from dict. bp = self._breakpoints.pop(addr) assert bp.provider is not None bp.provider.remove_breakpoint(bp) except KeyError: logging.debug("Tried to remove breakpoint 0x%08x that wasn't set" % addr) def get_breakpoint_type(self, addr): bp = self.find_breakpoint(addr) return bp.type if (bp is not None) else None def filter_memory(self, addr, size, data): for provider in [p for p in self._providers.values() if p.do_filter_memory]: data = provider.filter_memory(addr, size, data) return data def filter_memory_unaligned_8(self, addr, size, data): for provider in [p for p in self._providers.values() if p.do_filter_memory]: for i, d in enumerate(data): data[i] = provider.filter_memory(addr + i, 8, d) return data def filter_memory_aligned_32(self, addr, size, data): for provider in [p for p in self._providers.values() if p.do_filter_memory]: for i, d in enumerate(data): data[i] = provider.filter_memory(addr + i, 32, d) return data def remove_all_breakpoints(self): for bp in self._breakpoints.values(): bp.provider.remove_breakpoint(bp) self._breakpoints = {} self._flush_all() def _flush_all(self): # Flush all providers. for provider in self._providers.values(): provider.flush() def flush(self): try: # Flush all providers. self._flush_all() finally: pass pyocd-0.13.1/pyocd/debug/context.py0000644000175000017500000000725413373511253017067 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 ..core.memory_interface import MemoryInterface from ..coresight.cortex_m import (CORE_REGISTER, register_name_to_index, is_float_register) from ..utility import conversion import logging ## @brief Viewport for inspecting the system being debugged. # # A debug context is used to access registers and other target information. It enables these # accesses to be redirected to different locations. For instance, if you want to read registers # from a call frame that is not the topmost, then a context would redirect those reads to # locations on the stack. # # A context always has a specific core associated with it, which cannot be changed after the # context is created. class DebugContext(MemoryInterface): def __init__(self, core): self._core = core @property def core(self): return self._core def write_memory(self, addr, value, transfer_size=32): return self._core.write_memory(addr, value, transfer_size) def read_memory(self, addr, transfer_size=32, now=True): return self._core.read_memory(addr, transfer_size, now) def write_memory_block8(self, addr, value): return self._core.write_memory_block8(addr, value) def write_memory_block32(self, addr, data): return self._core.write_memory_block32(addr, data) def read_memory_block8(self, addr, size): return self._core.read_memory_block8(addr, size) def read_memory_block32(self, addr, size): return self._core.read_memory_block32(addr, size) def read_core_register(self, reg): """ read CPU register Unpack floating point register values """ regIndex = register_name_to_index(reg) regValue = self.read_core_register(regIndex) # Convert int to float. if is_float_register(regIndex): regValue = conversion.u32_to_float32(regValue) return regValue def read_core_register(self, reg): """ read a core register (r0 .. r16). If reg is a string, find the number associated to this register in the lookup table CORE_REGISTER """ vals = self.read_core_registers_raw([reg]) return vals[0] def read_core_registers_raw(self, reg_list): return self._core.read_core_registers_raw(reg_list) def write_core_register(self, reg, data): """ write a CPU register. Will need to pack floating point register values before writing. """ regIndex = register_name_to_index(reg) # Convert float to int. if is_float_register(regIndex): data = conversion.float32_to_u32(data) self.write_core_register(regIndex, data) def write_core_register(self, reg, data): """ write a core register (r0 .. r16) If reg is a string, find the number associated to this register in the lookup table CORE_REGISTER """ self.write_core_registers_raw([reg], [data]) def write_core_registers_raw(self, reg_list, data_list): self._core.write_core_registers_raw(reg_list, data_list) def flush(self): self._core.flush() pyocd-0.13.1/pyocd/debug/symbols.py0000644000175000017500000000142713373511253017067 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ ## @brief Abstract class for getting information about symbols in the target program. class SymbolProvider(object): def get_symbol_value(self, name): raise NotImplementedError() pyocd-0.13.1/pyocd/tools/0000755000175000017500000000000013373523011015066 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/tools/pyocd.py0000755000175000017500000015640513373511253016601 0ustar neilneil00000000000000#!/usr/bin/env python """ mbed CMSIS-DAP debugger Copyright (c) 2015-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 __future__ import print_function import argparse import logging import os import sys import optparse from optparse import make_option import traceback import six # Attempt to import readline. try: import readline except ImportError: pass from .. import __version__ from .. import (utility, coresight) from ..core.helpers import ConnectHelper from ..core import exceptions from ..target.family import target_kinetis from ..probe.pydapaccess import DAPAccess from ..probe.debug_probe import DebugProbe from ..core.target import Target from ..utility import mask from ..utility.cmdline import convert_session_options # Make disasm optional. try: import capstone isCapstoneAvailable = True # pylint: disable=invalid-name except ImportError: isCapstoneAvailable = False # pylint: disable=invalid-name LEVELS = { 'debug':logging.DEBUG, 'info':logging.INFO, 'warning':logging.WARNING, 'error':logging.ERROR, 'critical':logging.CRITICAL } CORE_STATUS_DESC = { Target.TARGET_HALTED : "Halted", Target.TARGET_RUNNING : "Running", Target.TARGET_RESET : "Reset", Target.TARGET_SLEEPING : "Sleeping", Target.TARGET_LOCKUP : "Lockup", } VC_NAMES_MAP = { Target.CATCH_HARD_FAULT : "hard fault", Target.CATCH_BUS_FAULT : "bus fault", Target.CATCH_MEM_FAULT : "memory fault", Target.CATCH_INTERRUPT_ERR : "interrupt error", Target.CATCH_STATE_ERR : "state error", Target.CATCH_CHECK_ERR : "check error", Target.CATCH_COPROCESSOR_ERR : "coprocessor error", Target.CATCH_CORE_RESET : "core reset", } ## Default SWD clock in kHz. DEFAULT_CLOCK_FREQ_KHZ = 1000 ## Command info and help. COMMAND_INFO = { 'list' : { 'aliases' : [], 'args' : "", 'help' : "Show available targets" }, 'erase' : { 'aliases' : [], 'args' : "ADDR [COUNT]", 'help' : "Erase internal flash sectors" }, 'unlock' : { 'aliases' : [], 'args' : "", 'help' : "Unlock security on the target" }, 'status' : { 'aliases' : ['stat'], 'args' : "", 'help' : "Show the target's current state" }, 'reg' : { 'aliases' : [], 'args' : "[-f] [REG]", 'help' : "Print all or one register" }, 'wreg' : { 'aliases' : [], 'args' : "REG VALUE", 'help' : "Set the value of a register" }, 'reset' : { 'aliases' : [], 'args' : "[-h/--halt]", 'help' : "Reset the target" }, 'savemem' : { 'aliases' : [], 'args' : "ADDR LEN FILENAME", "help" : "Save a range of memory to a binary file" }, 'loadmem' : { 'aliases' : [], 'args' : "ADDR FILENAME", "help" : "Load a binary file to an address in memory" }, 'read8' : { 'aliases' : ['read', 'r', 'rb'], 'args' : "ADDR [LEN]", 'help' : "Read 8-bit bytes" }, 'read16' : { 'aliases' : ['r16', 'rh'], 'args' : "ADDR [LEN]", 'help' : "Read 16-bit halfwords" }, 'read32' : { 'aliases' : ['r32', 'rw'], 'args' : "ADDR [LEN]", 'help' : "Read 32-bit words" }, 'write8' : { 'aliases' : ['write', 'w', 'wb'], 'args' : "ADDR DATA...", 'help' : "Write 8-bit bytes" }, 'write16' : { 'aliases' : ['w16', 'wh'], 'args' : "ADDR DATA...", 'help' : "Write 16-bit halfwords" }, 'write32' : { 'aliases' : ['w32', 'ww'], 'args' : "ADDR DATA...", 'help' : "Write 32-bit words" }, 'go' : { 'aliases' : ['g'], 'args' : "", 'help' : "Resume execution of the target" }, 'step' : { 'aliases' : ['s'], 'args' : "", 'help' : "Step one instruction" }, 'halt' : { 'aliases' : ['h'], 'args' : "", 'help' : "Halt the target" }, 'break' : { 'aliases' : [], 'args' : "ADDR", 'help' : "Set a breakpoint address" }, 'rmbreak' : { 'aliases' : [], 'args' : "ADDR", 'help' : "Remove a breakpoint" }, 'lsbreak' : { 'aliases' : [], 'args' : "", 'help' : "List breakpoints" }, 'help' : { 'aliases' : ['?'], 'args' : "[CMD]", 'help' : "Show help for commands" }, 'disasm' : { 'aliases' : ['d'], 'args' : "[-c/--center] ADDR [LEN]", 'help' : "Disassemble instructions at an address", 'extra_help' : "Only available if the capstone library is installed." }, 'exit' : { 'aliases' : ['quit'], 'args' : "", 'help' : "Quit pyocd-tool" }, 'core' : { 'aliases' : [], 'args' : "[NUM]", 'help' : "Select CPU core by number or print selected core" }, 'readdp' : { 'aliases' : ['rdp'], 'args' : "ADDR", 'help' : "Read DP register" }, 'writedp' : { 'aliases' : ['wdp'], 'args' : "ADDR DATA", 'help' : "Read DP register" }, 'readap' : { 'aliases' : ['rap'], 'args' : "[APSEL] ADDR", 'help' : "Read AP register" }, 'writeap' : { 'aliases' : ['wap'], 'args' : "[APSEL] ADDR DATA", 'help' : "Read AP register" }, 'reinit' : { 'aliases' : [], 'args' : "", 'help' : "Reinitialize the target object" }, 'show' : { 'aliases' : [], 'args' : "INFO", 'help' : "Report info about the target", }, 'set' : { 'aliases' : [], 'args' : "NAME VALUE", 'help' : "Set an option value", 'extra_help' : "Available info names: vc, vectorcatch.", }, 'initdp' : { 'aliases' : [], 'args' : "", 'help' : "Init DP and power up debug.", }, 'makeap' : { 'aliases' : [], 'args' : "APSEL", 'help' : "Creates a new AP object for the given APSEL.", 'extra_help' : "The type of AP, MEM-AP or generic, is autodetected.", }, 'where' : { 'aliases' : [], 'args' : "[ADDR]", 'help' : "Show symbol, file, and line for address.", 'extra_help' : "The symbol name, source file path, and line number are displayed for the specified address. If no address is given then current PC is used. An ELF file must have been specified with the --elf option.", }, 'symbol' : { 'aliases' : [], 'args' : "NAME", 'help' : "Show a symbol's value.", 'extra_help' : "An ELF file must have been specified with the --elf option.", }, } INFO_HELP = { 'map' : { 'aliases' : [], 'help' : "Target memory map.", }, 'peripherals' : { 'aliases' : [], 'help' : "List of target peripheral instances.", }, 'uid' : { 'aliases' : [], 'help' : "Target's unique ID", }, 'cores' : { 'aliases' : [], 'help' : "Information about CPU cores in the target.", }, 'target' : { 'aliases' : [], 'help' : "General target information.", }, 'fault' : { 'aliases' : [], 'help' : "Fault status information.", 'extra_help' : "By default, only asserted fields are shown. Add -a to command to show all fields.", }, 'vector-catch' : { 'aliases' : ['vc'], 'help' : "Show current vector catch settings.", }, 'step-into-interrupt' : { 'aliases' : ['si'], 'help' : "Display whether interrupts are enabled when single stepping." }, 'nreset' : { 'aliases' : [], 'help' : "Current nRESET signal state.", }, } OPTION_HELP = { 'vector-catch' : { 'aliases' : ['vc'], 'help' : "Control enabled vector catch sources.", 'extra_help' : "Value is a concatenation of one letter per enabled source in any order, or 'all' or 'none'. (h=hard fault, b=bus fault, m=mem fault, i=irq err, s=state err, c=check err, p=nocp, r=reset, a=all, n=none).", }, 'step-into-interrupt' : { 'aliases' : ['si'], 'help' : "Set whether to enable or disable interrupts when single stepping. Set to 1 to enable." }, 'nreset' : { 'aliases' : [], 'help' : "Set nRESET signal state. Accepts a value of 0 or 1." }, 'log' : { 'aliases' : [], 'help' : "Set log level to one of debug, info, warning, error, critical" }, 'clock' : { 'aliases' : [], 'help' : "Set SWD or JTAG clock frequency in kilohertz." }, } def hex_width(value, width): if width == 8: return "%02x" % value elif width == 16: return "%04x" % value elif width == 32: return "%08x" % value else: raise ToolError("unrecognized register width (%d)" % width) def dump_hex_data(data, startAddress=0, width=8): i = 0 while i < len(data): print("%08x: " % (startAddress + (i * (width // 8))), end=' ') while i < len(data): d = data[i] i += 1 if width == 8: print("%02x" % d, end=' ') if i % 4 == 0: print("", end=' ') if i % 16 == 0: break elif width == 16: print("%04x" % d, end=' ') if i % 8 == 0: break elif width == 32: print("%08x" % d, end=' ') if i % 4 == 0: break print() class ToolError(Exception): pass class ToolExitException(Exception): pass def cmdoptions(opts): def process_opts(fn): parser = optparse.OptionParser(add_help_option=False) for opt in opts: parser.add_option(opt) def foo(inst, args): namespace, other_args = parser.parse_args(args) return fn(inst, namespace, other_args) return foo return process_opts class PyOCDConsole(object): PROMPT = '>>> ' def __init__(self, tool): self.tool = tool self.last_command = '' def run(self): try: while True: try: line = six.moves.input(self.PROMPT) line = line.strip() if line: self.process_command_line(line) self.last_command = line elif self.last_command: self.process_command(self.last_command) except KeyboardInterrupt: print() except EOFError: # Print a newline when we get a Ctrl-D on a Posix system. # Windows exits with a Ctrl-Z+Return, so there is no need for this. if os.name != "nt": print() def process_command_line(self, line): for cmd in line.split(';'): self.process_command(cmd) def process_command(self, cmd): try: firstChar = (cmd.strip())[0] if firstChar in '$!': cmd = cmd[1:].strip() if firstChar == '$': self.tool.handle_python(cmd) elif firstChar == '!': os.system(cmd) return args = utility.cmdline.split_command_line(cmd) cmd = args[0].lower() args = args[1:] # Handle register name as command. if cmd in coresight.cortex_m.CORE_REGISTER: self.tool.handle_reg([cmd]) return # Check for valid command. if cmd not in self.tool.command_list: print("Error: unrecognized command '%s'" % cmd) return # Run command. handler = self.tool.command_list[cmd] handler(args) except ValueError: print("Error: invalid argument") traceback.print_exc() except exceptions.TransferError as e: print("Error:", e) traceback.print_exc() except ToolError as e: print("Error:", e) except ToolExitException: raise except Exception as e: print("Unexpected exception:", e) traceback.print_exc() class PyOCDTool(object): def __init__(self): self.session = None self.board = None self.exit_code = 0 self.step_into_interrupt = False self.command_list = { 'list' : self.handle_list, 'erase' : self.handle_erase, 'unlock' : self.handle_unlock, 'status' : self.handle_status, 'stat' : self.handle_status, 'reg' : self.handle_reg, 'wreg' : self.handle_write_reg, 'reset' : self.handle_reset, 'savemem' : self.handle_savemem, 'loadmem' : self.handle_loadmem, 'read' : self.handle_read8, 'read8' : self.handle_read8, 'read16' : self.handle_read16, 'read32' : self.handle_read32, 'r' : self.handle_read8, 'rb' : self.handle_read8, 'r16' : self.handle_read16, 'rh' : self.handle_read16, 'r32' : self.handle_read32, 'rw' : self.handle_read32, 'write' : self.handle_write8, 'write8' : self.handle_write8, 'write16' : self.handle_write16, 'write32' : self.handle_write32, 'w' : self.handle_write8, 'wb' : self.handle_write8, 'w16' : self.handle_write16, 'wh' : self.handle_write16, 'w32' : self.handle_write32, 'ww' : self.handle_write32, 'go' : self.handle_go, 'g' : self.handle_go, 'step' : self.handle_step, 's' : self.handle_step, 'halt' : self.handle_halt, 'h' : self.handle_halt, 'break' : self.handle_breakpoint, 'rmbreak' : self.handle_remove_breakpoint, 'lsbreak' : self.handle_list_breakpoints, 'disasm' : self.handle_disasm, 'd' : self.handle_disasm, 'exit' : self.handle_exit, 'quit' : self.handle_exit, 'core' : self.handle_core, 'readdp' : self.handle_readdp, 'writedp' : self.handle_writedp, 'readap' : self.handle_readap, 'writeap' : self.handle_writeap, 'rdp' : self.handle_readdp, 'wdp' : self.handle_writedp, 'rap' : self.handle_readap, 'wap' : self.handle_writeap, 'reinit' : self.handle_reinit, 'show' : self.handle_show, 'set' : self.handle_set, 'help' : self.handle_help, 'where' : self.handle_where, '?' : self.handle_help, 'initdp' : self.handle_initdp, 'makeap' : self.handle_makeap, 'symbol' : self.handle_symbol, } self.info_list = { 'map' : self.handle_show_map, 'peripherals' : self.handle_show_peripherals, 'uid' : self.handle_show_unique_id, 'cores' : self.handle_show_cores, 'target' : self.handle_show_target, 'fault' : self.handle_show_fault, 'vector-catch' : self.handle_show_vectorcatch, 'vc' : self.handle_show_vectorcatch, 'step-into-interrupt' : self.handle_show_step_interrupts, 'si' : self.handle_show_step_interrupts, 'nreset' : self.handle_show_nreset, } self.option_list = { 'vector-catch' : self.handle_set_vectorcatch, 'vc' : self.handle_set_vectorcatch, 'step-into-interrupt' : self.handle_set_step_interrupts, 'si' : self.handle_set_step_interrupts, 'nreset' : self.handle_set_nreset, 'log' : self.handle_set_log, 'clock' : self.handle_set_clock, } def get_args(self): debug_levels = list(LEVELS.keys()) epi = "Available commands:\n" + ', '.join(sorted(self.command_list.keys())) parser = argparse.ArgumentParser(description='Target inspection utility', epilog=epi) parser.add_argument('--version', action='version', version=__version__) parser.add_argument('--config', metavar="PATH", default=None, help="Use a YAML config file.") parser.add_argument("-H", "--halt", action="store_true", help="Halt core upon connect.") parser.add_argument("-N", "--no-init", action="store_true", help="Do not init debug system.") parser.add_argument('-k', "--clock", metavar='KHZ', default=DEFAULT_CLOCK_FREQ_KHZ, type=int, help="Set SWD speed in kHz. (Default 1 MHz.)") parser.add_argument('-b', "--board", action='store', metavar='ID', help="Use the specified board. Only a unique part of the board ID needs to be provided.") parser.add_argument('-t', "--target", action='store', metavar='TARGET', help="Override target.") parser.add_argument('-e', "--elf", metavar="PATH", help="Optionally specify ELF file being debugged.") parser.add_argument("-d", "--debug", dest="debug_level", choices=debug_levels, default='warning', help="Set the level of system logging output. Supported choices are: " + ", ".join(debug_levels), metavar="LEVEL") parser.add_argument("cmd", nargs='?', default=None, help="Command") parser.add_argument("args", nargs='*', help="Arguments for the command.") parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") parser.add_argument("-O", "--option", metavar="OPTION", action="append", help="Set session option of form 'OPTION=VALUE'.") return parser.parse_args() def configure_logging(self): level = LEVELS.get(self.args.debug_level, logging.WARNING) logging.basicConfig(level=level) def run(self): try: # Read command-line arguments. self.args = self.get_args() self.cmd = self.args.cmd if self.cmd: self.cmd = self.cmd.lower() # Set logging level self.configure_logging() DAPAccess.set_args(self.args.daparg) # Check for a valid command. if self.cmd and self.cmd not in self.command_list: print("Error: unrecognized command '%s'" % self.cmd) return 1 # Handle certain commands without connecting. if self.cmd == 'list': self.handle_list([]) return 0 elif self.cmd == 'help': self.handle_help(self.args.args) return 0 if self.args.clock != DEFAULT_CLOCK_FREQ_KHZ: print("Setting SWD clock to %d kHz" % self.args.clock) # Connect to board. self.session = ConnectHelper.session_with_chosen_probe( config_file=self.args.config, board_id=self.args.board, target_override=self.args.target, init_board=False, auto_unlock=False, halt_on_connect=self.args.halt, resume_on_disconnect=False, frequency=(self.args.clock * 1000), **convert_session_options(self.args.option)) if self.session is None: return 1 self.board = self.session.board try: if not self.args.no_init: self.session.open() except exceptions.TransferFaultError as e: if not self.board.target.is_locked(): print("Transfer fault while initing board: %s" % e) traceback.print_exc() self.exit_code = 1 return self.exit_code except Exception as e: print("Exception while initing board: %s" % e) traceback.print_exc() self.exit_code = 1 return self.exit_code self.target = self.board.target self.probe = self.session.probe self.flash = self.board.flash # Set elf file if provided. if self.args.elf: self.target.elf = self.args.elf self.elf = self.target.elf else: self.elf = None self._peripherals = {} self._loaded_peripherals = False # Handle a device with flash security enabled. self.did_erase = False if not self.args.no_init and self.target.is_locked() and self.cmd != 'unlock': print("Warning: Target is locked, limited operations available. Use unlock command to mass erase and unlock.") # If no command, enter interactive mode. if not self.cmd: if not self.args.no_init: try: # If the target is locked, we can't read the CPU state. if self.target.is_locked(): status = "locked" else: status = CORE_STATUS_DESC[self.target.get_state()] # Say what we're connected to. print("Connected to %s [%s]: %s" % (self.target.part_number, status, self.board.unique_id)) except exceptions.TransferFaultError: pass # Run the command line. console = PyOCDConsole(self) console.run() else: # Invoke action handler. result = self.command_list[self.cmd](self.args.args) if result is not None: self.exit_code = result except ToolExitException: self.exit_code = 0 except ValueError: print("Error: invalid argument") traceback.print_exc() except exceptions.TransferError: print("Error: transfer failed") traceback.print_exc() self.exit_code = 2 except ToolError as e: print("Error:", e) self.exit_code = 1 finally: if self.session != None: # Pass false to prevent target resume. self.session.close() return self.exit_code @property def peripherals(self): if self.target.svd_device and not self._loaded_peripherals: for p in self.target.svd_device.peripherals: self._peripherals[p.name.lower()] = p self._loaded_peripherals = True return self._peripherals def handle_list(self, args): ConnectHelper.list_connected_probes() def handle_status(self, args): if self.target.is_locked(): print("Security: Locked") else: print("Security: Unlocked") if isinstance(self.target, target_kinetis.Kinetis): print("MDM-AP Status: 0x%08x" % self.target.mdm_ap.read_reg(target_kinetis.MDM_STATUS)) if not self.target.is_locked(): for i, c in enumerate(self.target.cores): core = self.target.cores[c] print("Core %d status: %s" % (i, CORE_STATUS_DESC[core.get_state()])) def handle_reg(self, args): # If there are no args, print all register values. if len(args) < 1: self.dump_registers() return if len(args) == 2 and args[0].lower() == '-f': del args[0] show_fields = True else: show_fields = False reg = args[0].lower() if reg in coresight.cortex_m.CORE_REGISTER: value = self.target.read_core_register(reg) if type(value) in six.integer_types: print("%s = 0x%08x (%d)" % (reg, value, value)) elif type(value) is float: print("%s = %g" % (reg, value)) else: raise ToolError("Unknown register value type") else: subargs = reg.split('.') if subargs[0] in self.peripherals: p = self.peripherals[subargs[0]] if len(subargs) > 1: r = [x for x in p.registers if x.name.lower() == subargs[1]] if len(r): self._dump_peripheral_register(p, r[0], True) else: raise ToolError("invalid register '%s' for %s" % (subargs[1], p.name)) else: for r in p.registers: self._dump_peripheral_register(p, r, show_fields) else: raise ToolError("invalid peripheral '%s'" % (subargs[0])) def handle_write_reg(self, args): if len(args) < 1: raise ToolError("No register specified") if len(args) < 2: raise ToolError("No value specified") reg = args[0].lower() if reg in coresight.cortex_m.CORE_REGISTER: if reg.startswith('s') and reg != 'sp': value = float(args[1]) else: value = self.convert_value(args[1]) self.target.write_core_register(reg, value) else: value = self.convert_value(args[1]) subargs = reg.split('.') if len(subargs) < 2: raise ToolError("no register specified") if subargs[0] in self.peripherals: p = self.peripherals[subargs[0]] r = [x for x in p.registers if x.name.lower() == subargs[1]] if len(r): r = r[0] addr = p.base_address + r.address_offset if len(subargs) == 2: print("writing 0x%x to 0x%x:%d (%s)" % (value, addr, r.size, r.name)) self.target.write_memory(addr, value, r.size) elif len(subargs) == 3: f = [x for x in r.fields if x.name.lower() == subargs[2]] if len(f): f = f[0] msb = f.bit_offset + f.bit_width - 1 lsb = f.bit_offset originalValue = self.target.read_memory(addr, r.size) value = mask.bfi(originalValue, msb, lsb, value) print("writing 0x%x to 0x%x[%d:%d]:%d (%s.%s)" % (value, addr, msb, lsb, r.size, r.name, f.name)) self.target.write_memory(addr, value, r.size) else: raise ToolError("too many dots") self._dump_peripheral_register(p, r, True) else: raise ToolError("invalid register '%s' for %s" % (subargs[1], p.name)) else: raise ToolError("invalid peripheral '%s'" % (subargs[0])) @cmdoptions([make_option('-h', "--halt", action="store_true")]) def handle_reset(self, args, other): print("Resetting target") if args.halt: self.target.reset_stop_on_reset() status = self.target.get_state() if status != Target.TARGET_HALTED: print("Failed to halt device on reset") else: print("Successfully halted device on reset") else: self.target.reset() def handle_set_nreset(self, args): if len(args) != 1: print("Missing reset state") return state = int(args[0], base=0) print("nRESET = %d" % (state)) self.probe.assert_reset((state == 0)) @cmdoptions([make_option('-c', "--center", action="store_true")]) def handle_disasm(self, args, other): if len(other) == 0: print("Error: no address specified") return 1 addr = self.convert_value(other[0]) if len(other) < 2: count = 6 else: count = self.convert_value(other[1]) if args.center: addr -= count // 2 # Since we're disassembling, make sure the Thumb bit is cleared. addr &= ~1 # Print disasm of data. data = self.target.read_memory_block8(addr, count) self.print_disasm(bytes(bytearray(data)), addr) def handle_read8(self, args): return self.do_read(args, 8) def handle_read16(self, args): return self.do_read(args, 16) def handle_read32(self, args): return self.do_read(args, 32) def handle_write8(self, args): return self.do_write(args, 8) def handle_write16(self, args): return self.do_write(args, 16) def handle_write32(self, args): return self.do_write(args, 32) def handle_savemem(self, args): if len(args) < 3: print("Error: missing argument") return 1 addr = self.convert_value(args[0]) count = self.convert_value(args[1]) filename = args[2] data = bytearray(self.target.read_memory_block8(addr, count)) with open(filename, 'wb') as f: f.write(data) print("Saved %d bytes to %s" % (count, filename)) def handle_loadmem(self, args): if len(args) < 2: print("Error: missing argument") return 1 addr = self.convert_value(args[0]) filename = args[1] with open(filename, 'rb') as f: data = bytearray(f.read()) self.target.write_memory_block8(addr, data) print("Loaded %d bytes to 0x%08x" % (len(data), addr)) def do_read(self, args, width): if len(args) == 0: print("Error: no address specified") return 1 addr = self.convert_value(args[0]) if len(args) < 2: count = width // 8 else: count = self.convert_value(args[1]) if width == 8: data = self.target.read_memory_block8(addr, count) byteData = data elif width == 16: byteData = self.target.read_memory_block8(addr, count) data = utility.conversion.byte_list_to_u16le_list(byteData) elif width == 32: byteData = self.target.read_memory_block8(addr, count) data = utility.conversion.byte_list_to_u32le_list(byteData) # Print hex dump of output. dump_hex_data(data, addr, width=width) def do_write(self, args, width): if len(args) == 0: print("Error: no address specified") return 1 addr = self.convert_value(args[0]) if len(args) <= 1: print("Error: no data for write") return 1 else: data = [self.convert_value(d) for d in args[1:]] if width == 8: pass elif width == 16: data = utility.conversion.u16le_list_to_byte_list(data) elif width == 32: data = utility.conversion.u32le_list_to_byte_list(data) if self.is_flash_write(addr, width, data): self.target.flash.init() self.target.flash.program_phrase(addr, data) else: self.target.write_memory_block8(addr, data) self.target.flush() def handle_erase(self, args): if len(args) < 1: raise ToolError("invalid arguments") addr = self.convert_value(args[0]) if len(args) < 2: count = 1 else: count = self.convert_value(args[1]) self.flash.init() while count: info = self.flash.get_page_info(addr) self.flash.erase_page(info.base_addr) print("Erased page 0x%08x" % info.base_addr) count -= 1 addr += info.size def handle_unlock(self, args): # Currently the same as erase. if not self.did_erase: self.target.mass_erase() def handle_go(self, args): self.target.resume() status = self.target.get_state() if status == Target.TARGET_RUNNING: print("Successfully resumed device") else: print("Failed to resume device") def handle_step(self, args): self.target.step(disable_interrupts=not self.step_into_interrupt) addr = self.target.read_core_register('pc') if isCapstoneAvailable: addr &= ~1 data = self.target.read_memory_block8(addr, 4) self.print_disasm(bytes(bytearray(data)), addr, maxInstructions=1) else: print("PC = 0x%08x" % (addr)) def handle_halt(self, args): self.target.halt() status = self.target.get_state() if status != Target.TARGET_HALTED: print("Failed to halt device") return 1 else: print("Successfully halted device") def handle_breakpoint(self, args): if len(args) < 1: raise ToolError("no breakpoint address provided") addr = self.convert_value(args[0]) if self.target.set_breakpoint(addr): self.target.selected_core.bp_manager.flush() print("Set breakpoint at 0x%08x" % addr) else: print("Failed to set breakpoint at 0x%08x" % addr) def handle_remove_breakpoint(self, args): if len(args) < 1: raise ToolError("no breakpoint address provided") addr = self.convert_value(args[0]) try: type = self.target.get_breakpoint_type(addr) self.target.remove_breakpoint(addr) self.target.selected_core.bp_manager.flush() print("Removed breakpoint at 0x%08x" % addr) except: print("Failed to remove breakpoint at 0x%08x" % addr) def handle_list_breakpoints(self, args): availableBpCount = self.target.selected_core.available_breakpoint_count print("%d hardware breakpoints available" % availableBpCount) bps = self.target.selected_core.bp_manager.get_breakpoints() if not len(bps): print("No breakpoints installed") else: for i, addr in enumerate(bps): print("%d: 0x%08x" % (i, addr)) def handle_set_log(self, args): if len(args) < 1: print("Error: no log level provided") return 1 if args[0].lower() not in LEVELS: print("Error: log level must be one of {%s}" % ','.join(LEVELS.keys())) return 1 logging.getLogger().setLevel(LEVELS[args[0].lower()]) def handle_set_clock(self, args): if len(args) < 1: print("Error: no clock frequency provided") return 1 try: freq_Hz = self.convert_value(args[0]) * 1000 except: print("Error: invalid frequency") return 1 self.probe.set_clock(freq_Hz) if self.probe.wire_protocol == DebugProbe.Protocol.SWD: swd_jtag = 'SWD' elif self.probe.wire_protocol == DebugProbe.Protocol.JTAG: swd_jtag = 'JTAG' else: swd_jtag = '??' if freq_Hz >= 1000000: nice_freq = "%.2f MHz" % (freq_Hz / 1000000) elif freq_Hz > 1000: nice_freq = "%.2f kHz" % (freq_Hz / 1000) else: nice_freq = "%d Hz" % freq_Hz print("Changed %s frequency to %s" % (swd_jtag, nice_freq)) def handle_exit(self, args): raise ToolExitException() def handle_python(self, args): try: env = { 'session' : self.session, 'board' : self.board, 'target' : self.target, 'probe' : self.probe, 'link' : self.probe, # Old name 'flash' : self.flash, 'dp' : self.target.dp, 'aps' : self.target.dp.aps, 'elf' : self.elf, } result = eval(args, globals(), env) if result is not None: if type(result) in six.integer_types: print("0x%08x (%d)" % (result, result)) else: print(result) except Exception as e: print("Exception while executing expression:", e) traceback.print_exc() def handle_core(self, args): if len(args) < 1: print("Core %d is selected" % self.target.selected_core.core_number) return core = int(args[0], base=0) self.target.select_core(core) print("Selected core %d" % core) def handle_readdp(self, args): if len(args) < 1: print("Missing DP address") return addr = self.convert_value(args[0]) result = self.target.dp.read_reg(addr) print("DP register 0x%x = 0x%08x" % (addr, result)) def handle_writedp(self, args): if len(args) < 1: print("Missing DP address") return if len(args) < 2: print("Missing value") return addr = self.convert_value(args[0]) data = self.convert_value(args[1]) self.target.dp.write_reg(addr, data) def handle_readap(self, args): if len(args) < 1: print("Missing AP address") return if len(args) == 1: addr = self.convert_value(args[0]) elif len(args) == 2: addr = (self.convert_value(args[0]) << 24) | self.convert_value(args[1]) result = self.target.dp.read_ap(addr) print("AP register 0x%x = 0x%08x" % (addr, result)) def handle_writeap(self, args): if len(args) < 1: print("Missing AP address") return if len(args) < 2: print("Missing value") return if len(args) == 2: addr = self.convert_value(args[0]) data_arg = 1 elif len(args) == 3: addr = (self.convert_value(args[0]) << 24) | self.convert_value(args[1]) data_arg = 2 data = self.convert_value(args[data_arg]) self.target.dp.write_ap(addr, data) def handle_initdp(self, args): self.target.dp.init() self.target.dp.power_up_debug() def handle_makeap(self, args): if len(args) < 1: print("Missing APSEL") return apsel = self.convert_value(args[0]) if apsel in self.target.aps: print("AP with APSEL=%d already exists" % apsel) return exists = coresight.ap.AccessPort.probe(self.target.dp, apsel) if not exists: print("Error: no AP with APSEL={} exists".format(apsel)) return ap = coresight.ap.AccessPort.create(self.target.dp, apsel) self.target.dp.aps[apsel] = ap def handle_where(self, args): if self.elf is None: print("No ELF available") return if len(args) >= 1: addr = self.convert_value(args[0]) else: addr = self.target.read_core_register('pc') lineInfo = self.elf.address_decoder.get_line_for_address(addr) if lineInfo is not None: path = os.path.join(lineInfo.dirname, lineInfo.filename).decode() line = lineInfo.line pathline = "{}:{}".format(path, line) else: pathline = "" fnInfo = self.elf.address_decoder.get_function_for_address(addr) if fnInfo is not None: name = fnInfo.name.decode() else: name = "" print("{addr:#10x} : {fn} : {pathline}".format(addr=addr, fn=name, pathline=pathline)) def handle_symbol(self, args): if self.elf is None: print("No ELF available") return if len(args) < 1: raise ToolError("missing symbol name argument") name = args[0] sym = self.elf.symbol_decoder.get_symbol_for_name(name) if sym is not None: if sym.type == 'STT_FUNC': name += "()" print("{name}: {addr:#10x} {sz:#x}".format(name=name, addr=sym.address, sz=sym.size)) else: print("No symbol named '{}' was found".format(name)) def handle_reinit(self, args): self.target.init() def handle_show(self, args): if len(args) < 1: raise ToolError("missing info name argument") infoName = args[0] try: self.info_list[infoName](args[1:]) except KeyError: raise ToolError("unknown info name '%s'" % infoName) def handle_show_unique_id(self, args): print("Unique ID: %s" % self.board.unique_id) def handle_show_target(self, args): print("Target: %s" % self.target.part_number) print("DAP IDCODE: 0x%08x" % self.target.dp.dpidr) def handle_show_cores(self, args): if self.target.is_locked(): print("Target is locked") else: print("Cores: %d" % len(self.target.cores)) for i, c in enumerate(self.target.cores): core = self.target.cores[c] print("Core %d type: %s" % (i, coresight.cortex_m.CORE_TYPE_NAME[core.core_type])) def handle_show_map(self, args): print("Region Start End Size Blocksize") for region in self.target.get_memory_map(): print("{:<15} {:#010x} {:#010x} {:#10x} {}".format(region.name, region.start, region.end, region.length, region.blocksize if region.is_flash else '-')) def handle_show_peripherals(self, args): for periph in sorted(self.peripherals.values(), key=lambda x:x.base_address): print("0x%08x: %s" % (periph.base_address, periph.name)) def handle_show_fault(self, args): showAll = ('-a' in args) CFSR = 0xe000ed28 HFSR = 0xe000ed2c DFSR = 0xe000ed30 MMFAR = 0xe000ed34 BFAR = 0xe000ed38 AFSR = 0xe000ed3c MMFSR_fields = [ ('IACCVIOL', 0), ('DACCVIOL', 1), ('MUNSTKERR', 3), ('MSTKERR', 4), # ('MMARVALID', 7), ] BFSR_fields = [ ('IBUSERR', 0), ('PRECISERR', 1), ('IMPRECISERR', 2), ('UNSTKERR', 3), ('STKERR', 4), ('LSPERR', 5), # ('BFARVALID', 7), ] UFSR_fields = [ ('UNDEFINSTR', 0), ('INVSTATE', 1), ('INVPC', 2), ('NOCP', 3), ('STKOF', 4), ('UNALIGNED', 8), ('DIVBYZERO', 9), ] HFSR_fields = [ ('VECTTBL', 1), ('FORCED', 30), ('DEBUGEVT', 31), ] DFSR_fields = [ ('HALTED', 0), ('BKPT', 1), ('DWTTRAP', 2), ('VCATCH', 3), ('EXTERNAL', 4), ] def print_fields(regname, value, fields, showAll): if value == 0 and not showAll: return print(" %s = 0x%08x" % (regname, value)) for name, bitpos in fields: bit = (value >> bitpos) & 1 if showAll or bit != 0: print(" %s = 0x%x" % (name, bit)) cfsr = self.target.read32(CFSR) mmfsr = cfsr & 0xff bfsr = (cfsr >> 8) & 0xff ufsr = (cfsr >> 16) & 0xffff hfsr = self.target.read32(HFSR) dfsr = self.target.read32(DFSR) mmfar = self.target.read32(MMFAR) bfar = self.target.read32(BFAR) print_fields('MMFSR', mmfsr, MMFSR_fields, showAll) if showAll or mmfsr & (1 << 7): # MMFARVALID print(" MMFAR = 0x%08x" % (mmfar)) print_fields('BFSR', bfsr, BFSR_fields, showAll) if showAll or bfsr & (1 << 7): # BFARVALID print(" BFAR = 0x%08x" % (bfar)) print_fields('UFSR', ufsr, UFSR_fields, showAll) print_fields('HFSR', hfsr, HFSR_fields, showAll) print_fields('DFSR', dfsr, DFSR_fields, showAll) def handle_show_nreset(self, args): rst = int(not self.probe.is_reset_asserted()) print("nRESET = {}".format(rst)) def handle_set(self, args): if len(args) < 1: raise ToolError("missing option name argument") name = args[0] try: self.option_list[name](args[1:]) except KeyError: raise ToolError("unkown option name '%s'" % name) def handle_show_vectorcatch(self, args): catch = self.target.get_vector_catch() print("Vector catch:") for mask in sorted(VC_NAMES_MAP.keys()): name = VC_NAMES_MAP[mask] s = "ON" if (catch & mask) else "OFF" print(" {:3} {}".format(s, name)) def handle_set_vectorcatch(self, args): if len(args) == 0: print("Missing vector catch setting") return try: self.target.set_vector_catch(utility.cmdline.convert_vector_catch(args[0])) except ValueError as e: print(e) def handle_show_step_interrupts(self, args): print("Interrupts while stepping:", ("enabled" if self.step_into_interrupt else "disabled")) def handle_set_step_interrupts(self, args): if len(args) == 0: print("Missing argument") return self.step_into_interrupt = (args[0] in ('1', 'true', 'yes', 'on')) def handle_help(self, args): if not args: self._list_commands("Commands", COMMAND_INFO, "{cmd:<25} {args:<20} {help}") print(""" All register names are also available as commands that print the register's value. Any ADDR or LEN argument will accept a register name. Prefix line with $ to execute a Python expression. Prefix line with ! to execute a shell command.""") print() self._list_commands("Info", INFO_HELP, "{cmd:<25} {help}") print() self._list_commands("Options", OPTION_HELP, "{cmd:<25} {help}") else: cmd = args[0].lower() try: subcmd = args[1].lower() except IndexError: subcmd = None def print_help(cmd, commandList, usageFormat): for name, info in commandList.items(): if cmd == name or cmd in info['aliases']: print(("Usage: " + usageFormat).format(cmd=name, **info)) if len(info['aliases']): print("Aliases:", ", ".join(info['aliases'])) print(info['help']) if 'extra_help' in info: print(info['extra_help']) if subcmd is None: print_help(cmd, COMMAND_INFO, "{cmd} {args}") if cmd == "show": print() self._list_commands("Info", INFO_HELP, "{cmd:<25} {help}") elif cmd == "set": print() self._list_commands("Options", OPTION_HELP, "{cmd:<25} {help}") elif cmd == 'show': print_help(subcmd, INFO_HELP, "show {cmd}") elif cmd == 'set': print_help(subcmd, OPTION_HELP, "set {cmd} VALUE") else: print("Error: invalid arguments") def _list_commands(self, title, commandList, helpFormat): print(title + ":\n" + ("-" * len(title))) for cmd in sorted(commandList.keys()): info = commandList[cmd] aliases = ', '.join(sorted([cmd] + info['aliases'])) print(helpFormat.format(cmd=aliases, **info)) def is_flash_write(self, addr, width, data): mem_map = self.board.target.get_memory_map() region = mem_map.get_region_for_address(addr) if (region is None) or (not region.is_flash): return False if width == 8: l = len(data) elif width == 16: l = len(data) * 2 elif width == 32: l = len(data) * 4 return region.contains_range(addr, length=l) ## @brief Convert an argument to a 32-bit integer. # # Handles the usual decimal, binary, and hex numbers with the appropriate prefix. # Also recognizes register names and address dereferencing. Dereferencing using the # ARM assembler syntax. To dereference, put the value in brackets, i.e. '[r0]' or # '[0x1040]'. You can also use put an offset in the brackets after a comma, such as # '[r3,8]'. The offset can be positive or negative, and any supported base. def convert_value(self, arg): deref = (arg[0] == '[') if deref: arg = arg[1:-1] offset = 0 if ',' in arg: arg, offset = arg.split(',') arg = arg.strip() offset = int(offset.strip(), base=0) value = None if arg.lower() in coresight.cortex_m.CORE_REGISTER: value = self.target.read_core_register(arg.lower()) print("%s = 0x%08x" % (arg.lower(), value)) else: subargs = arg.lower().split('.') if subargs[0] in self.peripherals and len(subargs) > 1: p = self.peripherals[subargs[0]] r = [x for x in p.registers if x.name.lower() == subargs[1]] if len(r): value = p.base_address + r[0].address_offset else: raise ToolError("invalid register '%s' for %s" % (subargs[1], p.name)) elif self.elf is not None: sym = self.elf.symbol_decoder.get_symbol_for_name(arg) if sym is not None: value = sym.address if value is None: arg = arg.lower().replace('_', '') value = int(arg, base=0) if deref: value = utility.conversion.byte_list_to_u32le_list(self.target.read_memory_block8(value + offset, 4))[0] print("[%s,%d] = 0x%08x" % (arg, offset, value)) return value def dump_registers(self): # Registers organized into columns for display. regs = ['r0', 'r6', 'r12', 'r1', 'r7', 'sp', 'r2', 'r8', 'lr', 'r3', 'r9', 'pc', 'r4', 'r10', 'xpsr', 'r5', 'r11', 'primask'] for i, reg in enumerate(regs): regValue = self.target.read_core_register(reg) print("{:>8} {:#010x} ".format(reg + ':', regValue), end=' ') if i % 3 == 2: print() def _dump_peripheral_register(self, periph, reg, show_fields): addr = periph.base_address + reg.address_offset value = self.target.read_memory(addr, reg.size) value_str = hex_width(value, reg.size) print("%s.%s @ %08x = %s" % (periph.name, reg.name, addr, value_str)) if show_fields: for f in reg.fields: if f.is_reserved: continue msb = f.bit_offset + f.bit_width - 1 lsb = f.bit_offset f_value = mask.bfx(value, msb, lsb) v_enum = None if f.enumerated_values: for v in f.enumerated_values: if v.value == f_value: v_enum = v break if f.bit_width == 1: bits_str = "%d" % lsb else: bits_str = "%d:%d" % (msb, lsb) f_value_str = "%x" % f_value digits = (f.bit_width + 3) // 4 f_value_str = "0" * (digits - len(f_value_str)) + f_value_str f_value_bin_str = bin(f_value)[2:] f_value_bin_str = "0" * (f.bit_width - len(f_value_bin_str)) + f_value_bin_str if v_enum: f_value_enum_str = " %s: %s" % (v.name, v_enum.description) else: f_value_enum_str = "" print(" %s[%s] = %s (%s)%s" % (f.name, bits_str, f_value_str, f_value_bin_str, f_value_enum_str)) def print_disasm(self, code, startAddr, maxInstructions=None): if not isCapstoneAvailable: print("Warning: Disassembly is not available because the Capstone library is not installed") return pc = self.target.read_core_register('pc') & ~1 md = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB) addrLine = 0 text = '' n = 0 for i in md.disasm(code, startAddr): hexBytes = '' for b in i.bytes: hexBytes += '%02x' % b pc_marker = '*' if (pc == i.address) else ' ' text += "{addr:#010x}:{pc_marker} {bytes:<10}{mnemonic:<8}{args}\n".format(addr=i.address, pc_marker=pc_marker, bytes=hexBytes, mnemonic=i.mnemonic, args=i.op_str) n += 1 if (maxInstructions is not None) and (n >= maxInstructions): break print(text) def main(): sys.exit(PyOCDTool().run()) if __name__ == '__main__': main() pyocd-0.13.1/pyocd/tools/gdb_server.py0000644000175000017500000003637013373511253017600 0ustar neilneil00000000000000#!/usr/bin/env python """ mbed CMSIS-DAP debugger Copyright (c) 2006-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 __future__ import print_function import sys import os import logging import traceback import argparse import json import pkg_resources from .. import __version__ from .. import target from ..core.session import Session from ..core.helpers import ConnectHelper from ..debug.svd import IS_CMSIS_SVD_AVAILABLE from ..gdbserver import GDBServer from ..utility.cmdline import (split_command_line, VECTOR_CATCH_CHAR_MAP, convert_vector_catch, convert_session_options) from ..probe.cmsis_dap_probe import CMSISDAPProbe from ..probe.pydapaccess import DAPAccess from ..core.session import Session LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } SUPPORTED_TARGETS = list(sorted(target.TARGET.keys())) DEBUG_LEVELS = list(LEVELS.keys()) class InvalidArgumentError(RuntimeError): pass ## @brief Argparse type function to validate the supplied target device name. # # If the target name is valid, it is returned unmodified to become the --target option's # attribute value. def validate_target(value): if value.lower() not in SUPPORTED_TARGETS: raise InvalidArgumentError("invalid target option '{}'".format(value)) return value class GDBServerTool(object): def __init__(self): self.args = None self.gdb_server_settings = None self.echo_msg = None def build_parser(self): # Build epilog with list of targets. epilog = "Available targets for use with --target option: " + ", ".join(SUPPORTED_TARGETS) # Keep args in snyc with flash_tool.py when possible parser = argparse.ArgumentParser(description='PyOCD GDB Server', epilog=epilog) parser.add_argument('--version', action='version', version=__version__) parser.add_argument('--config', metavar="PATH", default=None, help="Use a YAML config file.") parser.add_argument("-p", "--port", dest="port_number", type=int, default=3333, help="Set the port number that GDB server will open (default 3333).") parser.add_argument("-sc", "--semihost-console", dest="semihost_console_type", default="telnet", choices=('telnet', 'stdx'), help="Console for semihosting.") parser.add_argument("-T", "--telnet-port", dest="telnet_port", type=int, default=4444, help="Specify the telnet port for semihosting (default 4444).") parser.add_argument("--allow-remote", dest="serve_local_only", default=True, action="store_false", help="Allow remote TCP/IP connections (default is no).") parser.add_argument("-b", "--board", dest="board_id", default=None, help="Connect to board by board ID. Use -l to list all connected boards. Only a unique part of the board ID needs to be provided.") parser.add_argument("-l", "--list", action="store_true", dest="list_all", default=False, help="List all connected boards.") parser.add_argument("--list-targets", action="store_true", dest="list_targets", default=False, help="List all available targets.") parser.add_argument("--json", action="store_true", dest="output_json", default=False, help="Output lists in JSON format. Only applies to --list and --list-targets.") parser.add_argument("-d", "--debug", dest="debug_level", choices=DEBUG_LEVELS, default='info', help="Set the level of system logging output. Supported choices are: " + ", ".join(DEBUG_LEVELS), metavar="LEVEL") parser.add_argument("-t", "--target", dest="target_override", default=None, help="Override target to debug.", metavar="TARGET", type=validate_target) parser.add_argument("-n", "--nobreak", dest="no_break_at_hardfault", action="store_true", help="Disable halt at hardfault handler. (Deprecated)") parser.add_argument("-r", "--reset-break", dest="break_on_reset", action="store_true", help="Halt the target when reset. (Deprecated)") parser.add_argument("-C", "--vector-catch", default='h', help="Enable vector catch sources, one letter per enabled source in any order, or 'all' or 'none'. (h=hard fault, b=bus fault, m=mem fault, i=irq err, s=state err, c=check err, p=nocp, r=reset, a=all, n=none). (Default is hard fault.)") parser.add_argument("-s", "--step-int", dest="step_into_interrupt", default=False, action="store_true", help="Allow single stepping to step into interrupts.") parser.add_argument("-f", "--frequency", dest="frequency", default=1000000, type=int, help="Set the SWD clock frequency in Hz.") parser.add_argument("-o", "--persist", dest="persist", default=False, action="store_true", help="Keep GDB server running even after remote has detached.") parser.add_argument("-bh", "--soft-bkpt-as-hard", dest="soft_bkpt_as_hard", default=False, action="store_true", help="Replace software breakpoints with hardware breakpoints.") group = parser.add_mutually_exclusive_group() group.add_argument("-ce", "--chip_erase", action="store_true", help="Use chip erase when programming.") group.add_argument("-se", "--sector_erase", action="store_true", help="Use sector erase when programming.") # -Currently "--unlock" does nothing since kinetis parts will automatically get unlocked parser.add_argument("-u", "--unlock", action="store_true", default=False, help="Unlock the device.") # reserved: "-a", "--address" # reserved: "-s", "--skip" parser.add_argument("-hp", "--hide_progress", action="store_true", help="Don't display programming progress.") parser.add_argument("-fp", "--fast_program", action="store_true", help="Use only the CRC of each page to determine if it already has the same data.") parser.add_argument("-S", "--semihosting", dest="enable_semihosting", action="store_true", help="Enable semihosting.") parser.add_argument("-G", "--gdb-syscall", dest="semihost_use_syscalls", action="store_true", help="Use GDB syscalls for semihosting file I/O.") parser.add_argument("-c", "--command", dest="commands", metavar="CMD", action='append', nargs='+', help="Run command (OpenOCD compatibility).") parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") parser.add_argument("--elf", metavar="PATH", help="Optionally specify ELF file being debugged.") parser.add_argument("-O", "--option", metavar="OPTION", action="append", help="Set session option of form 'OPTION=VALUE'.") self.parser = parser return parser def get_chip_erase(self, args): # Determine programming mode chip_erase = None if args.chip_erase: chip_erase = True elif args.sector_erase: chip_erase = False return chip_erase def get_vector_catch(self, args): vector_catch = args.vector_catch.lower() # Handle deprecated options. if args.break_on_reset: vector_catch += 'r' if args.no_break_at_hardfault: # Must handle all case specially since we can't just filter 'h'. if vector_catch == 'all' or 'a' in vector_catch: vector_catch = 'bmiscpr' # Does not include 'h'. else: vector_catch = vector_catch.replace('h', '') try: return convert_vector_catch(vector_catch) except ValueError as e: # Reraise as an invalid argument error. raise InvalidArgumentError(e.message) def get_gdb_server_settings(self, args): # Set gdb server settings return { 'step_into_interrupt' : args.step_into_interrupt, 'persist' : args.persist, 'soft_bkpt_as_hard' : args.soft_bkpt_as_hard, 'chip_erase': self.get_chip_erase(args), 'hide_programming_progress' : args.hide_progress, 'fast_program' : args.fast_program, 'server_listening_callback' : self.server_listening, 'enable_semihosting' : args.enable_semihosting, 'semihost_console_type' : args.semihost_console_type, 'telnet_port' : args.telnet_port, 'semihost_use_syscalls' : args.semihost_use_syscalls, 'serve_local_only' : args.serve_local_only, 'vector_catch' : self.get_vector_catch(args), } def setup_logging(self, args): format = "%(relativeCreated)07d:%(levelname)s:%(module)s:%(message)s" level = LEVELS.get(args.debug_level, logging.NOTSET) logging.basicConfig(level=level, format=format) ## @brief Handle OpenOCD commands for compatibility. def process_commands(self, commands): if commands is None: return for cmd_list in commands: try: cmd_list = split_command_line(cmd_list) cmd = cmd_list[0] if cmd == 'gdb_port': if len(cmd_list) < 2: print("Missing port argument") else: self.args.port_number = int(cmd_list[1], base=0) elif cmd == 'telnet_port': if len(cmd_list) < 2: print("Missing port argument") else: self.gdb_server_settings['telnet_port'] = int(cmd_list[1], base=0) elif cmd == 'echo': self.echo_msg = ' '.join(cmd_list[1:]) else: print("Unsupported command: %s" % ' '.join(cmd_list)) except IndexError: pass def server_listening(self, server): if self.echo_msg is not None: print(self.echo_msg, file=sys.stderr) sys.stderr.flush() def disable_logging(self): logging.getLogger().setLevel(logging.FATAL) def list_boards(self): self.disable_logging() if not self.args.output_json: ConnectHelper.list_connected_probes() else: try: all_mbeds = ConnectHelper.get_sessions_for_all_connected_probes(blocking=False) status = 0 error = "" except Exception as e: all_mbeds = [] status = 1 error = str(e) if not self.args.output_json: raise boards = [] obj = { 'pyocd_version' : __version__, 'version' : { 'major' : 1, 'minor' : 0 }, 'status' : status, 'boards' : boards, } if status != 0: obj['error'] = error for mbed in all_mbeds: d = { 'unique_id' : mbed.probe.unique_id, 'info' : mbed.board.description, 'board_name' : mbed.board.name, 'target' : mbed.board.target_type, 'vendor_name' : mbed.probe.vendor_name, 'product_name' : mbed.probe.product_name, } boards.append(d) print(json.dumps(obj, indent=4)) def list_targets(self): self.disable_logging() if self.args.output_json: targets = [] obj = { 'pyocd_version' : __version__, 'version' : { 'major' : 1, 'minor' : 0 }, 'status' : 0, 'targets' : targets } for name in SUPPORTED_TARGETS: s = Session(None) # Create empty session t = target.TARGET[name](s) d = { 'name' : name, 'part_number' : t.part_number, } if t._svd_location is not None and IS_CMSIS_SVD_AVAILABLE: if t._svd_location.is_local: svdPath = t._svd_location.filename else: resource = "data/{vendor}/{filename}".format( vendor=t._svd_location.vendor, filename=t._svd_location.filename ) svdPath = pkg_resources.resource_filename("cmsis_svd", resource) if os.path.exists(svdPath): d['svd_path'] = svdPath targets.append(d) print(json.dumps(obj, indent=4)) else: for t in SUPPORTED_TARGETS: print(t) def run(self, args=None): try: self.args = self.build_parser().parse_args(args) self.gdb_server_settings = self.get_gdb_server_settings(self.args) self.setup_logging(self.args) DAPAccess.set_args(self.args.daparg) self.process_commands(self.args.commands) gdb = None gdbs = [] if self.args.list_all == True: self.list_boards() elif self.args.list_targets == True: self.list_targets() else: try: session = ConnectHelper.session_with_chosen_probe( config_file=self.args.config, board_id=self.args.board_id, target_override=self.args.target_override, frequency=self.args.frequency, **convert_session_options(self.args.option)) if session is None: print("No board selected") return 1 with session: # Set ELF if provided. if self.args.elf: session.board.target.elf = self.args.elf baseTelnetPort = self.gdb_server_settings['telnet_port'] for core_number, core in session.board.target.cores.items(): self.gdb_server_settings['telnet_port'] = baseTelnetPort + core_number gdb = GDBServer(session.board, self.args.port_number + core_number, self.gdb_server_settings, core=core_number) gdbs.append(gdb) gdb = gdbs[0] while gdb.isAlive(): gdb.join(timeout=0.5) except KeyboardInterrupt: for gdb in gdbs: gdb.stop() except Exception as e: print("uncaught exception: %s" % e) traceback.print_exc() for gdb in gdbs: gdb.stop() return 1 # Successful exit. return 0 except InvalidArgumentError as e: self.parser.error(e) return 1 def main(): sys.exit(GDBServerTool().run()) if __name__ == '__main__': main() pyocd-0.13.1/pyocd/tools/__init__.py0000644000175000017500000000113413373511253017203 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ pyocd-0.13.1/pyocd/tools/flash_tool.py0000755000175000017500000002576413373511253017620 0ustar neilneil00000000000000#!/usr/bin/env python """ mbed CMSIS-DAP debugger Copyright (c) 2006-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 __future__ import print_function import argparse import os import sys import logging import itertools from struct import unpack try: from intelhex import IntelHex intelhex_available = True except ImportError: intelhex_available = False from .. import __version__ from .. import target from ..core.helpers import ConnectHelper from ..probe.pydapaccess import DAPAccess from ..utility.progress import print_progress from ..utility.cmdline import convert_session_options from ..debug.elf.elf import (ELFBinaryFile, SH_FLAGS) LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } # pylint: disable=invalid-name board = None supported_formats = ['bin', 'hex', 'elf'] supported_targets = list(target.TARGET.keys()) supported_targets.remove('cortex_m') # No generic programming DEBUG_LEVELS = list(LEVELS.keys()) def int_base_0(x): return int(x, base=0) epi = """--chip_erase and --sector_erase can be used alone as individual commands, or they can be used in conjunction with flashing a binary or hex file. For the former, only the erase option will be performed. With a file, the erase options specify whether to erase the entire chip before flashing the file, or just to erase only those sectors occupied by the file. For a standalone sector erase, the --address and --count options are used to specify the start address of the sector to erase and the number of sectors to erase. """ # Keep args in snyc with gdb_server.py when possible parser = argparse.ArgumentParser(description='Flash utility', epilog=epi) parser.add_argument("file", nargs='?', default=None, help="File to program") parser.add_argument("format", nargs='?', choices=supported_formats, default=None, help="File format. Default is to use the file extension (.bin, .hex, .elf, .afx)") parser.add_argument('--version', action='version', version=__version__) # reserved: "-p", "--port" # reserved: "-c", "--cmd-port" parser.add_argument('--config', metavar="PATH", default=None, help="Use a YAML config file.") parser.add_argument("-b", "--board", dest="board_id", default=None, help="Connect to board by board ID. Use -l to list all connected boards. Only a unique part of the board ID needs to be provided.") parser.add_argument("-l", "--list", action="store_true", dest="list_all", default=False, help="List all connected boards.") parser.add_argument("-d", "--debug", dest="debug_level", choices=DEBUG_LEVELS, default='info', help="Set the level of system logging output. Supported choices are: " + ", ".join(DEBUG_LEVELS), metavar="LEVEL") parser.add_argument("-t", "--target", dest="target_override", choices=supported_targets, default=None, help="Override target to debug. Supported targets are: " + ", ".join(supported_targets), metavar="TARGET") # reserved: "-n", "--nobreak" # reserved: "-r", "--reset-break" # reserved: "-s", "--step-int" parser.add_argument("-f", "--frequency", dest="frequency", default=1000000, type=int, help="Set the SWD clock frequency in Hz.") # reserved: "-o", "--persist" # reserved: "-k", "--soft-bkpt-as-hard" group = parser.add_mutually_exclusive_group() group.add_argument("-ce", "--chip_erase", action="store_true", help="Use chip erase when programming.") group.add_argument("-se", "--sector_erase", action="store_true", help="Use sector erase when programming.") parser.add_argument("-u", "--unlock", action="store_true", default=False, help="Unlock the device.") parser.add_argument("-a", "--address", default=None, type=int_base_0, help="Address. Used for the sector address with sector erase, and for the address where to flash a binary.") parser.add_argument("-n", "--count", default=1, type=int_base_0, help="Number of sectors to erase. Only applies to sector erase. Default is 1.") parser.add_argument("-s", "--skip", default=0, type=int_base_0, help="Skip programming the first N bytes. This can only be used with binary files") parser.add_argument("-hp", "--hide_progress", action="store_true", help="Don't display programming progress.") parser.add_argument("-fp", "--fast_program", action="store_true", help="Use only the CRC of each page to determine if it already has the same data.") parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") parser.add_argument("--mass-erase", action="store_true", help="Mass erase the target device.") parser.add_argument("-O", "--option", metavar="OPTION", action="append", help="Set session option of form 'OPTION=VALUE'.") # pylint: enable=invalid-name # Notes # -Currently "--unlock" does nothing since kinetis parts will automatically get unlocked def setup_logging(args): # Set logging level level = LEVELS.get(args.debug_level, logging.NOTSET) logging.basicConfig(level=level) def ranges(i): for a, b in itertools.groupby(enumerate(i), lambda x: x[1] - x[0]): b = list(b) yield b[0][1], b[-1][1] def main(): args = parser.parse_args() setup_logging(args) DAPAccess.set_args(args.daparg) # Sanity checks before attaching to board if args.format == 'hex' and not intelhex_available: print("Unable to program hex file") print("Module 'intelhex' must be installed first") exit() if args.list_all: ConnectHelper.list_connected_probes() else: session = ConnectHelper.session_with_chosen_probe( config_file=args.config, board_id=args.board_id, target_override=args.target_override, frequency=args.frequency, blocking=False, **convert_session_options(args.option)) if session is None: print("Error: There is no debug probe connected.") sys.exit(1) with session: board = session.board flash = board.flash progress = print_progress() if args.hide_progress: progress = None has_file = args.file is not None chip_erase = None if args.chip_erase: chip_erase = True elif args.sector_erase: chip_erase = False if args.mass_erase: print("Mass erasing device...") if board.target.mass_erase(): print("Successfully erased.") else: print("Failed.") return if not has_file: if chip_erase: print("Erasing chip...") flash.init() flash.erase_all() print("Done") elif args.sector_erase and args.address is not None: flash.init() page_addr = args.address for i in range(args.count): page_info = flash.get_page_info(page_addr) if not page_info: break # Align page address on first time through. if i == 0: delta = page_addr % page_info.size if delta: print("Warning: sector address 0x%08x is unaligned" % page_addr) page_addr -= delta print("Erasing sector 0x%08x" % page_addr) flash.erase_page(page_addr) page_addr += page_info.size else: print("No operation performed") return # If no format provided, use the file's extension. if not args.format: args.format = os.path.splitext(args.file)[1][1:] if args.format == 'axf': args.format = 'elf' # Binary file format if args.format == 'bin': # If no address is specified use the start of rom if args.address is None: args.address = board.flash.get_flash_info().rom_start with open(args.file, "rb") as f: f.seek(args.skip, 0) data = f.read() args.address += args.skip data = unpack(str(len(data)) + 'B', data) flash.flash_block(args.address, data, chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) # Intel hex file format elif args.format == 'hex': hexfile = IntelHex(args.file) addresses = hexfile.addresses() addresses.sort() flash_builder = flash.get_flash_builder() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hexfile.tobinarray(start=start, size=size)) flash_builder.add_data(start, data) flash_builder.program(chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) # ELF format elif args.format == 'elf': flash_builder = flash.get_flash_builder() with open(args.file, "rb") as f: elf = ELFBinaryFile(f, board.target.memory_map) for section in elf.sections: if ((section.type == 'SHT_PROGBITS') and ((section.flags & (SH_FLAGS.SHF_ALLOC | SH_FLAGS.SHF_WRITE)) == SH_FLAGS.SHF_ALLOC) and (section.length > 0) and (section.region.is_flash)): logging.debug("Writing section %s", repr(section)) flash_builder.add_data(section.start, section.data) else: logging.debug("Skipping section %s", repr(section)) flash_builder.program(chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) else: print("Unknown file format '%s'" % args.format) if __name__ == '__main__': main() pyocd-0.13.1/pyocd/gdbserver/0000755000175000017500000000000013373523011015711 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/gdbserver/gdb_socket.py0000644000175000017500000000351413373511253020377 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ import socket, select class GDBSocket(object): def __init__(self, port, packet_size): self.packet_size = packet_size self.s = None self.conn = None self.port = port self.host = '' def init(self): if self.s is None: self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.s.bind((self.host, self.port)) self.s.listen(5) def connect(self): self.conn = None self.init() rr, _, _ = select.select([self.s], [], [], 0.5) if rr: self.conn, _ = self.s.accept() return self.conn def read(self): return self.conn.recv(self.packet_size) def write(self, data): return self.conn.send(data) def close(self): if self.conn is not None: self.conn.close() self.conn = None return_value = None if self.s is not None: return_value = self.s.close() self.s = None return return_value def set_blocking(self, blocking): self.conn.setblocking(blocking) def set_timeout(self, timeout): self.conn.settimeout(timeout) pyocd-0.13.1/pyocd/gdbserver/gdbserver.py0000644000175000017500000014147613373511253020270 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 ..core import exceptions from ..core.target import Target from ..utility.cmdline import convert_vector_catch from ..utility.conversion import (hex_to_byte_list, hex_encode, hex_decode, hex8_to_u32le) from ..utility.progress import print_progress from ..utility.py3_helpers import (iter_single_bytes, to_bytes_safe) from .gdb_socket import GDBSocket from .gdb_websocket import GDBWebSocket from .syscall import GDBSyscallIOHandler from ..debug import semihost from ..debug.cache import MemoryAccessError from .context_facade import GDBDebugContextFacade from .symbols import GDBSymbolProvider from ..rtos import RTOS from . import signals import logging, threading, socket from struct import unpack from time import (sleep, time) import sys import traceback import six from six.moves import queue from xml.etree.ElementTree import (Element, SubElement, tostring) CTRL_C = b'\x03' # Logging options. Set to True to enable. LOG_MEM = False # Log memory accesses. LOG_ACK = False # Log ack or nak. LOG_PACKETS = False # Log all packets sent and received. def checksum(data): return ("%02x" % (sum(six.iterbytes(data)) % 256)).encode() ## @brief De-escapes binary data from Gdb. # # @param data Bytes-like object with possibly escaped values. # @return List of integers in the range 0-255, with all escaped bytes de-escaped. def unescape(data): data_idx = 0 # unpack the data into binary array str_unpack = str(len(data)) + 'B' data = unpack(str_unpack, data) data = list(data) # check for escaped characters while data_idx < len(data): if data[data_idx] == 0x7d: data.pop(data_idx) data[data_idx] = data[data_idx] ^ 0x20 data_idx += 1 return data ## @brief Escape binary data to be sent to Gdb. # # @param data Bytes-like object containing raw binary. # @return Bytes object with the characters in '#$}*' escaped as required by Gdb. def escape(data): result = b'' for c in iter_single_bytes(data): if c in b'#$}*': result += b'}' + six.int2byte(six.byte2int(c) ^ 0x20) else: result += c return result ## @brief Exception used to signal the GDB server connection closed. class ConnectionClosedException(Exception): pass ## @brief Packet I/O thread. # # This class is a thread used by the GDBServer class to perform all RSP packet I/O. It # handles verifying checksums, acking, and receiving Ctrl-C interrupts. There is a queue # for received packets. The interface to this queue is the receive() method. The send() # method writes outgoing packets to the socket immediately. class GDBServerPacketIOThread(threading.Thread): def __init__(self, abstract_socket): super(GDBServerPacketIOThread, self).__init__(name="gdb-packet-thread") self.log = logging.getLogger('gdbpacket.%d' % abstract_socket.port) self._abstract_socket = abstract_socket self._receive_queue = queue.Queue() self._shutdown_event = threading.Event() self.interrupt_event = threading.Event() self.send_acks = True self._clear_send_acks = False self._buffer = b'' self._expecting_ack = False self.drop_reply = False self._last_packet = b'' self._closed = False self.setDaemon(True) self.start() def set_send_acks(self, ack): if ack: self.send_acks = True else: self._clear_send_acks = True def stop(self): self._shutdown_event.set() def send(self, packet): if self._closed or not packet: return if not self.drop_reply: self._last_packet = packet self._write_packet(packet) else: self.drop_reply = False self.log.debug("GDB dropped reply %s", packet) def receive(self, block=True): if self._closed: raise ConnectionClosedException() while True: try: # If block is false, we'll get an Empty exception immediately if there # are no packets in the queue. Same if block is true and it times out # waiting on an empty queue. return self._receive_queue.get(block, 0.1) except queue.Empty: # Only exit the loop if block is false or connection closed. if not block: return None if self._closed: raise ConnectionClosedException() def run(self): self._abstract_socket.set_timeout(0.01) while not self._shutdown_event.is_set(): try: data = self._abstract_socket.read() # Handle closed connection if len(data) == 0: self.log.debug("GDB packet thread: other side closed connection") self._closed = True break if LOG_PACKETS: self.log.debug('-->>>>>>>>>>>> GDB read %d bytes: %s', len(data), data) self._buffer += data except socket.error: pass if self._shutdown_event.is_set(): break self._process_data() self.log.debug("GDB packet thread stopping") def _write_packet(self, packet): if LOG_PACKETS: self.log.debug('--<<<<<<<<<<<< GDB send %d bytes: %s', len(packet), packet) # Make sure the entire packet is sent. remaining = len(packet) while remaining: written = self._abstract_socket.write(packet) remaining -= written if remaining: packet = packet[written:] if self.send_acks: self._expecting_ack = True def _check_expected_ack(self): # Handle expected ack. c = self._buffer[0:1] if c in (b'+', b'-'): self._buffer = self._buffer[1:] if LOG_ACK: self.log.debug('got ack: %s', c) if c == '-': # Handle nack from gdb self._write_packet(self._last_packet) return # Handle disabling of acks. if self._clear_send_acks: self.send_acks = False self._clear_send_acks = False else: self.log.debug("GDB: expected n/ack but got '%s'", c) def _process_data(self): # Process all incoming data until there are no more complete packets. while len(self._buffer): if self._expecting_ack: self._expecting_ack = False self._check_expected_ack() # Check for a ctrl-c. if len(self._buffer) and self._buffer[0:1] == CTRL_C: self.interrupt_event.set() self._buffer = self._buffer[1:] try: # Look for complete packet and extract from buffer. pkt_begin = self._buffer.index(b"$") pkt_end = self._buffer.index(b"#") + 2 if pkt_begin >= 0 and pkt_end < len(self._buffer): pkt = self._buffer[pkt_begin:pkt_end + 1] self._buffer = self._buffer[pkt_end + 1:] self._handling_incoming_packet(pkt) else: break except ValueError: # No complete packet received yet. break def _handling_incoming_packet(self, packet): # Compute checksum data, cksum = packet[1:].split(b'#') computedCksum = checksum(data) goodPacket = (computedCksum.lower() == cksum.lower()) if self.send_acks: ack = b'+' if goodPacket else b'-' self._abstract_socket.write(ack) if LOG_ACK: self.log.debug(ack) if goodPacket: self._receive_queue.put(packet) class GDBServer(threading.Thread): """ This class start a GDB server listening a gdb connection on a specific port. It implements the RSP (Remote Serial Protocol). """ def __init__(self, board, port_urlWSS, options={}, core=None): threading.Thread.__init__(self) self.board = board if core is None: self.core = 0 self.target = board.target else: self.core = core self.target = board.target.cores[core] self.log = logging.getLogger('gdbserver') self.flash = board.flash self.abstract_socket = None self.wss_server = None self.port = 0 if isinstance(port_urlWSS, str) == True: self.wss_server = port_urlWSS else: self.port = port_urlWSS self.vector_catch = options.get('vector_catch', Target.CATCH_HARD_FAULT) self.target.set_vector_catch(self.vector_catch) self.step_into_interrupt = options.get('step_into_interrupt', False) self.persist = options.get('persist', False) self.soft_bkpt_as_hard = options.get('soft_bkpt_as_hard', False) self.chip_erase = options.get('chip_erase', None) self.hide_programming_progress = options.get('hide_programming_progress', False) self.fast_program = options.get('fast_program', False) self.enable_semihosting = options.get('enable_semihosting', False) self.semihost_console_type = options.get('semihost_console_type', 'telnet') self.telnet_port = options.get('telnet_port', 4444) self.semihost_use_syscalls = options.get('semihost_use_syscalls', False) self.server_listening_callback = options.get('server_listening_callback', None) self.serve_local_only = options.get('serve_local_only', True) self.packet_size = 2048 self.packet_io = None self.gdb_features = [] self.non_stop = False self.is_target_running = (self.target.get_state() == Target.TARGET_RUNNING) self.flash_builder = None self.lock = threading.Lock() self.shutdown_event = threading.Event() self.detach_event = threading.Event() if core is None: self.target_context = self.board.target.get_target_context() else: self.target_context = self.board.target.get_target_context(core=core) self.target_facade = GDBDebugContextFacade(self.target_context) self.thread_provider = None self.did_init_thread_providers = False self.current_thread_id = 0 self.first_run_after_reset_or_flash = True if self.wss_server == None: self.abstract_socket = GDBSocket(self.port, self.packet_size) if self.serve_local_only: self.abstract_socket.host = 'localhost' else: self.abstract_socket = GDBWebSocket(self.wss_server) self.target.subscribe(Target.EVENT_POST_RESET, self.event_handler) # Init semihosting and telnet console. if self.semihost_use_syscalls: semihost_io_handler = GDBSyscallIOHandler(self) else: # Use internal IO handler. semihost_io_handler = semihost.InternalSemihostIOHandler() if self.semihost_console_type == 'telnet': self.telnet_console = semihost.TelnetSemihostIOHandler(self.telnet_port, self.serve_local_only) semihost_console = self.telnet_console else: self.log.info("Semihosting will be output to console") self.telnet_console = None semihost_console = semihost_io_handler self.semihost = semihost.SemihostAgent(self.target_context, io_handler=semihost_io_handler, console=semihost_console) # pylint: disable=invalid-name # Command handler table. # # The dict keys are the first character of the incoming command from gdb. Values are a # bi-tuple. The first element is the handler method, and the second element is the start # offset of the command string passed to the handler. # # Start offset values: # 0 - Special case: handler method does not take any parameters. # 1 - Strip off leading "$" from command. # 2 - Strip leading "$" plus character matched through this table. # 3+ - Supported, but not very useful. # self.COMMANDS = { # CMD HANDLER START DESCRIPTION b'?' : (self.stop_reason_query, 0 ), # Stop reason query. b'c' : (self.resume, 1 ), # Continue (at addr) b'C' : (self.resume, 1 ), # Continue with signal. b'D' : (self.detach, 1 ), # Detach. b'g' : (self.get_registers, 0 ), # Read general registers. b'G' : (self.set_registers, 2 ), # Write general registers. b'H' : (self.set_thread, 2 ), # Set thread for subsequent operations. b'k' : (self.kill, 0 ), # Kill. b'm' : (self.get_memory, 2 ), # Read memory. b'M' : (self.write_memory_hex, 2 ), # Write memory (hex). b'p' : (self.read_register, 2 ), # Read register. b'P' : (self.write_register, 2 ), # Write register. b'q' : (self.handle_query, 2 ), # General query. b'Q' : (self.handle_general_set, 2 ), # General set. b's' : (self.step, 1 ), # Single step. b'S' : (self.step, 1 ), # Step with signal. b'T' : (self.is_thread_alive, 1 ), # Thread liveness query. b'v' : (self.v_command, 2 ), # v command. b'X' : (self.write_memory, 2 ), # Write memory (binary). b'z' : (self.breakpoint, 1 ), # Insert breakpoint/watchpoint. b'Z' : (self.breakpoint, 1 ), # Remove breakpoint/watchpoint. } # Commands that kill the connection to gdb. self.DETACH_COMMANDS = (b'D', b'k') # pylint: enable=invalid-name self.setDaemon(True) self.start() def restart(self): if self.isAlive(): self.detach_event.set() def stop(self): if self.isAlive(): self.shutdown_event.set() while self.isAlive(): pass self.log.info("GDB server thread killed") self.board.uninit() def set_board(self, board, stop=True): self.lock.acquire() if stop: self.restart() self.board = board self.target = board.target self.flash = board.flash self.lock.release() return def _cleanup(self): self.log.debug("GDB server cleaning up") if self.packet_io: self.packet_io.stop() self.packet_io = None if self.semihost: self.semihost.cleanup() self.semihost = None if self.telnet_console: self.telnet_console.stop() self.telnet_console = None def _cleanup_for_next_connection(self): self.non_stop = False self.thread_provider = None self.did_init_thread_providers = False self.current_thread_id = 0 def run(self): self.log.info('GDB server started at port:%d', self.port) while True: try: self.detach_event.clear() # Inform callback that the server is running. if self.server_listening_callback: self.server_listening_callback(self) while not self.shutdown_event.isSet() and not self.detach_event.isSet(): connected = self.abstract_socket.connect() if connected != None: self.packet_io = GDBServerPacketIOThread(self.abstract_socket) break if self.shutdown_event.isSet(): self._cleanup() return if self.detach_event.isSet(): continue self.log.info("One client connected!") self._run_connection() except Exception as e: self.log.error("Unexpected exception: %s", e) traceback.print_exc() def _run_connection(self): while True: try: if self.shutdown_event.isSet(): self._cleanup() return if self.detach_event.isSet(): break if self.packet_io.interrupt_event.isSet(): if self.non_stop: self.target.halt() self.is_target_running = False self.send_stop_notification() else: self.log.error("Got unexpected ctrl-c, ignoring") self.packet_io.interrupt_event.clear() if self.non_stop and self.is_target_running: try: if self.target.get_state() == Target.TARGET_HALTED: self.log.debug("state halted") self.is_target_running = False self.send_stop_notification() except Exception as e: self.log.error("Unexpected exception: %s", e) traceback.print_exc() # read command try: packet = self.packet_io.receive(block=not self.non_stop) except ConnectionClosedException: break if self.shutdown_event.isSet(): self._cleanup() return if self.detach_event.isSet(): break if self.non_stop and packet is None: sleep(0.1) continue self.lock.acquire() if len(packet) != 0: # decode and prepare resp resp, detach = self.handle_message(packet) if resp is not None: # send resp self.packet_io.send(resp) if detach: self.abstract_socket.close() self.packet_io.stop() self.packet_io = None self.lock.release() if self.persist: self._cleanup_for_next_connection() break else: self.shutdown_event.set() return self.lock.release() except Exception as e: self.log.error("Unexpected exception: %s", e) traceback.print_exc() def handle_message(self, msg): try: assert msg[0:1] == b'$', "invalid first char of message != $" try: handler, msgStart = self.COMMANDS[msg[1:2]] except (KeyError, IndexError): self.log.error("Unknown RSP packet: %s", msg) return self.create_rsp_packet(b""), 0 if msgStart == 0: reply = handler() else: reply = handler(msg[msgStart:]) detach = 1 if msg[1:2] in self.DETACH_COMMANDS else 0 return reply, detach except Exception as e: self.log.error("Unhandled exception in handle_message: %s", e) traceback.print_exc() return self.create_rsp_packet(b"E01"), 0 def detach(self, data): self.log.info("Client detached") resp = b"OK" return self.create_rsp_packet(resp) def kill(self): self.log.debug("GDB kill") # Keep target halted and leave vector catches if in persistent mode. if not self.persist: self.board.target.set_vector_catch(Target.CATCH_NONE) self.board.target.resume() return self.create_rsp_packet(b"") def breakpoint(self, data): # handle breakpoint/watchpoint commands split = data.split(b'#')[0].split(b',') addr = int(split[1], 16) self.log.debug("GDB breakpoint %s%d @ %x" % (data[0:1], int(data[1:2]), addr)) # handle software breakpoint Z0/z0 if data[1:2] == b'0' and not self.soft_bkpt_as_hard: if data[0:1] == b'Z': if not self.target.set_breakpoint(addr, Target.BREAKPOINT_SW): return self.create_rsp_packet(b'E01') #EPERM else: self.target.remove_breakpoint(addr) return self.create_rsp_packet(b"OK") # handle hardware breakpoint Z1/z1 if data[1:2] == b'1' or (self.soft_bkpt_as_hard and data[1:2] == b'0'): if data[0:1] == b'Z': if self.target.set_breakpoint(addr, Target.BREAKPOINT_HW) == False: return self.create_rsp_packet(b'E01') #EPERM else: self.target.remove_breakpoint(addr) return self.create_rsp_packet(b"OK") # handle hardware watchpoint Z2/z2/Z3/z3/Z4/z4 if data[1:2] == b'2': # Write-only watch watchpoint_type = Target.WATCHPOINT_WRITE elif data[1:2] == b'3': # Read-only watch watchpoint_type = Target.WATCHPOINT_READ elif data[1:2] == b'4': # Read-Write watch watchpoint_type = Target.WATCHPOINT_READ_WRITE else: return self.create_rsp_packet(b'E01') #EPERM size = int(split[2], 16) if data[0:1] == b'Z': if self.target.set_watchpoint(addr, size, watchpoint_type) == False: return self.create_rsp_packet(b'E01') #EPERM else: self.target.remove_watchpoint(addr, size, watchpoint_type) return self.create_rsp_packet(b"OK") def set_thread(self, data): if not self.is_threading_enabled(): return self.create_rsp_packet(b'OK') self.log.debug("set_thread:%s", data) op = data[0:1] thread_id = int(data[1:-3], 16) if not (thread_id in (0, -1) or self.thread_provider.is_valid_thread_id(thread_id)): return self.create_rsp_packet(b'E01') if op == b'c': pass elif op == b'g': if thread_id == -1: self.target_facade.set_context(self.target_context) else: if thread_id == 0: thread = self.thread_provider.current_thread thread_id = thread.unique_id else: thread = self.thread_provider.get_thread(thread_id) self.target_facade.set_context(thread.context) else: return self.create_rsp_packet(b'E01') self.current_thread_id = thread_id return self.create_rsp_packet(b'OK') def is_thread_alive(self, data): threadId = int(data[1:-3], 16) if self.is_threading_enabled(): isAlive = self.thread_provider.is_valid_thread_id(threadId) else: isAlive = (threadId == 1) if isAlive: return self.create_rsp_packet(b'OK') else: self.validate_debug_context() return self.create_rsp_packet(b'E00') def validate_debug_context(self): if self.is_threading_enabled(): currentThread = self.thread_provider.current_thread if self.current_thread_id != currentThread.unique_id: self.target_facade.set_context(currentThread.context) self.current_thread_id = currentThread.unique_id else: if self.current_thread_id != 1: self.log.debug("Current thread %x is no longer valid, switching context to target", self.current_thread_id) self.target_facade.set_context(self.target_context) self.current_thread_id = 1 def stop_reason_query(self): # In non-stop mode, if no threads are stopped we need to reply with OK. if self.non_stop and self.is_target_running: return self.create_rsp_packet(b"OK") return self.create_rsp_packet(self.get_t_response()) def _get_resume_step_addr(self, data): if data is None: return None data = data.split(b'#')[0] if b';' not in data: return None # c[;addr] if data[0:1] in (b'c', b's'): addr = int(data[2:], base=16) # Csig[;addr] elif data[0:1] in (b'C', b'S'): addr = int(data[1:].split(b';')[1], base=16) return addr def resume(self, data): addr = self._get_resume_step_addr(data) self.target.resume() self.log.debug("target resumed") if self.first_run_after_reset_or_flash: self.first_run_after_reset_or_flash = False if self.thread_provider is not None: self.thread_provider.read_from_target = True val = b'' while True: if self.shutdown_event.isSet(): self.packet_io.interrupt_event.clear() return self.create_rsp_packet(val) # Wait for a ctrl-c to be received. if self.packet_io.interrupt_event.wait(0.01): self.log.debug("receive CTRL-C") self.packet_io.interrupt_event.clear() self.target.halt() val = self.get_t_response(forceSignal=signals.SIGINT) break try: if self.target.get_state() == Target.TARGET_HALTED: # Handle semihosting if self.enable_semihosting: was_semihost = self.semihost.check_and_handle_semihost_request() if was_semihost: self.target.resume() continue pc = self.target_context.read_core_register('pc') self.log.debug("state halted; pc=0x%08x", pc) val = self.get_t_response() break except Exception as e: try: self.target.halt() except: pass traceback.print_exc() self.log.debug('Target is unavailable temporarily.') val = ('S%02x' % self.target_facade.get_signal_value()).encode() break return self.create_rsp_packet(val) def step(self, data): addr = self._get_resume_step_addr(data) self.log.debug("GDB step: %s", data) self.target.step(not self.step_into_interrupt) return self.create_rsp_packet(self.get_t_response()) def halt(self): self.target.halt() return self.create_rsp_packet(self.get_t_response()) def send_stop_notification(self, forceSignal=None): data = self.get_t_response(forceSignal=forceSignal) packet = b'%Stop:' + data + b'#' + checksum(data) self.packet_io.send(packet) def v_command(self, data): cmd = data.split(b'#')[0] # Flash command. if cmd.startswith(b'Flash'): return self.flash_op(data) # v_cont capabilities query. elif b'Cont?' == cmd: return self.create_rsp_packet(b"v_cont;c;C;s;S;t") # v_cont, thread action command. elif cmd.startswith(b'Cont'): return self.v_cont(cmd) # vStopped, part of thread stop state notification sequence. elif b'Stopped' in cmd: # Because we only support one thread for now, we can just reply OK to vStopped. return self.create_rsp_packet(b"OK") return self.create_rsp_packet(b"") # Example: $v_cont;s:1;c#c1 def v_cont(self, cmd): ops = cmd.split(b';')[1:] # split and remove 'Cont' from list if not ops: return self.create_rsp_packet(b"OK") if self.is_threading_enabled(): thread_actions = {} threads = self.thread_provider.get_threads() for k in threads: thread_actions[k.unique_id] = None currentThread = self.thread_provider.get_current_thread_id() else: thread_actions = { 1 : None } # our only thread currentThread = 1 default_action = None for op in ops: args = op.split(b':') action = args[0] if len(args) > 1: thread_id = int(args[1], 16) if thread_id == -1 or thread_id == 0: thread_id = currentThread thread_actions[thread_id] = action else: default_action = action self.log.debug("thread_actions=%s; default_action=%s", repr(thread_actions), default_action) # Only the current thread is supported at the moment. if thread_actions[currentThread] is None: if default_action is None: return self.create_rsp_packet(b'E01') thread_actions[currentThread] = default_action if thread_actions[currentThread][0:1] in (b'c', b'C'): if self.non_stop: self.target.resume() self.is_target_running = True return self.create_rsp_packet(b"OK") else: return self.resume(None) elif thread_actions[currentThread][0:1] in (b's', b'S'): if self.non_stop: self.target.step(not self.step_into_interrupt) self.packet_io.send(self.create_rsp_packet(b"OK")) self.send_stop_notification() return None else: return self.step(None) elif thread_actions[currentThread] == b't': # Must ignore t command in all-stop mode. if not self.non_stop: return self.create_rsp_packet(b"") self.packet_io.send(self.create_rsp_packet(b"OK")) self.target.halt() self.is_target_running = False self.send_stop_notification(forceSignal=0) else: self.log.error("Unsupported v_cont action '%s'" % thread_actions[1:2]) def flash_op(self, data): ops = data.split(b':')[0] self.log.debug("flash op: %s", ops) if ops == b'FlashErase': return self.create_rsp_packet(b"OK") elif ops == b'FlashWrite': write_addr = int(data.split(b':')[1], 16) self.log.debug("flash write addr: 0x%x", write_addr) # search for second ':' (beginning of data encoded in the message) second_colon = 0 idx_begin = 0 while second_colon != 2: if data[idx_begin:idx_begin+1] == b':': second_colon += 1 idx_begin += 1 # Get flash builder if there isn't one already if self.flash_builder is None: self.flash_builder = self.flash.get_flash_builder() # Add data to flash builder self.flash_builder.add_data(write_addr, unescape(data[idx_begin:len(data) - 3])) return self.create_rsp_packet(b"OK") # we need to flash everything elif b'FlashDone' in ops : # Only program if we received data. if self.flash_builder is not None: if self.hide_programming_progress: progress_cb = None else: progress_cb = print_progress() self.flash_builder.program(chip_erase=self.chip_erase, progress_cb=progress_cb, fast_verify=self.fast_program) # Set flash builder to None so that on the next flash command a new # object is used. self.flash_builder = None self.first_run_after_reset_or_flash = True if self.thread_provider is not None: self.thread_provider.read_from_target = False return self.create_rsp_packet(b"OK") return None def get_memory(self, data): split = data.split(b',') addr = int(split[0], 16) length = split[1].split(b'#')[0] length = int(length, 16) if LOG_MEM: self.log.debug("GDB getMem: addr=%x len=%x", addr, length) try: val = b'' mem = self.target_context.read_memory_block8(addr, length) # Flush so an exception is thrown now if invalid memory was accesses self.target_context.flush() for x in mem: if x >= 0x10: val += six.b(hex(x)[2:4]) else: val += b'0' + six.b(hex(x)[2:3]) except exceptions.TransferError: self.log.debug("get_memory failed at 0x%x" % addr) val = b'E01' #EPERM except MemoryAccessError as e: logging.debug("get_memory failed at 0x%x: %s", addr, str(e)) val = b'E01' #EPERM return self.create_rsp_packet(val) def write_memory_hex(self, data): split = data.split(b',') addr = int(split[0], 16) split = split[1].split(b':') length = int(split[0], 16) split = split[1].split(b'#') data = hex_to_byte_list(split[0]) if LOG_MEM: self.log.debug("GDB writeMemHex: addr=%x len=%x", addr, length) try: if length > 0: self.target_context.write_memory_block8(addr, data) # Flush so an exception is thrown now if invalid memory was accessed self.target_context.flush() resp = b"OK" except exceptions.TransferError: self.log.debug("write_memory failed at 0x%x" % addr) resp = b'E01' #EPERM except MemoryAccessError as e: logging.debug("get_memory failed at 0x%x: %s", addr, str(e)) val = b'E01' #EPERM return self.create_rsp_packet(resp) def write_memory(self, data): split = data.split(b',') addr = int(split[0], 16) length = int(split[1].split(b':')[0], 16) if LOG_MEM: self.log.debug("GDB writeMem: addr=%x len=%x", addr, length) idx_begin = data.index(b':') + 1 data = data[idx_begin:len(data) - 3] data = unescape(data) try: if length > 0: self.target_context.write_memory_block8(addr, data) # Flush so an exception is thrown now if invalid memory was accessed self.target_context.flush() resp = b"OK" except exceptions.TransferError: self.log.debug("write_memory failed at 0x%x" % addr) resp = b'E01' #EPERM except MemoryAccessError as e: logging.debug("get_memory failed at 0x%x: %s", addr, str(e)) val = b'E01' #EPERM return self.create_rsp_packet(resp) def read_register(self, which): return self.create_rsp_packet(self.target_facade.gdb_get_register(which)) def write_register(self, data): reg = int(data.split(b'=')[0], 16) val = data.split(b'=')[1].split(b'#')[0] self.target_facade.set_register(reg, val) return self.create_rsp_packet(b"OK") def get_registers(self): return self.create_rsp_packet(self.target_facade.get_register_context()) def set_registers(self, data): self.target_facade.set_register_context(data) return self.create_rsp_packet(b"OK") def handle_query(self, msg): query = msg.split(b':') self.log.debug('GDB received query: %s', query) if query is None: self.log.error('GDB received query packet malformed') return None if query[0] == b'Supported': # Save features sent by gdb. self.gdb_features = query[1].split(b';') # Build our list of features. features = [b'qXfer:features:read+', b'QStartNoAckMode+', b'qXfer:threads:read+', b'QNonStop+'] features.append(b'PacketSize=' + six.b(hex(self.packet_size))[2:]) if self.target_facade.get_memory_map_xml() is not None: features.append(b'qXfer:memory-map:read+') resp = b';'.join(features) return self.create_rsp_packet(resp) elif query[0] == b'Xfer': if query[1] == b'features' and query[2] == b'read' and \ query[3] == b'target.xml': data = query[4].split(b',') resp = self.handle_query_xml(b'read_feature', int(data[0], 16), int(data[1].split(b'#')[0], 16)) return self.create_rsp_packet(resp) elif query[1] == b'memory-map' and query[2] == b'read': data = query[4].split(b',') resp = self.handle_query_xml(b'memory_map', int(data[0], 16), int(data[1].split(b'#')[0], 16)) return self.create_rsp_packet(resp) elif query[1] == b'threads' and query[2] == b'read': data = query[4].split(b',') resp = self.handle_query_xml(b'threads', int(data[0], 16), int(data[1].split(b'#')[0], 16)) return self.create_rsp_packet(resp) else: self.log.debug("Unsupported qXfer request: %s:%s:%s:%s", query[1], query[2], query[3], query[4]) return None elif query[0].startswith(b'C'): if not self.is_threading_enabled(): return self.create_rsp_packet(b"QC1") else: self.validate_debug_context() return self.create_rsp_packet(("QC%x" % self.current_thread_id).encode()) elif query[0].find(b'Attached') != -1: return self.create_rsp_packet(b"1") elif query[0].find(b'TStatus') != -1: return self.create_rsp_packet(b"") elif query[0].find(b'Tf') != -1: return self.create_rsp_packet(b"") elif b'Offsets' in query[0]: resp = b"Text=0;Data=0;Bss=0" return self.create_rsp_packet(resp) elif b'Symbol' in query[0]: if self.did_init_thread_providers: return self.create_rsp_packet(b"OK") return self.init_thread_providers() elif query[0].startswith(b'Rcmd,'): cmd = hex_decode(query[0][5:].split(b'#')[0]) return self.handle_remote_command(cmd) else: return self.create_rsp_packet(b"") def init_thread_providers(self): symbol_provider = GDBSymbolProvider(self) for rtosName, rtosClass in RTOS.items(): try: self.log.info("Attempting to load %s", rtosName) rtos = rtosClass(self.target) if rtos.init(symbol_provider): self.log.info("%s loaded successfully", rtosName) self.thread_provider = rtos break except RuntimeError as e: self.log.error("Error during symbol lookup: " + str(e)) traceback.print_exc() self.did_init_thread_providers = True # Done with symbol processing. return self.create_rsp_packet(b"OK") def get_symbol(self, name): # Send the symbol request. request = self.create_rsp_packet(b'qSymbol:' + hex_encode(name)) self.packet_io.send(request) # Read a packet. packet = self.packet_io.receive() # Parse symbol value reply packet. packet = packet[1:-3] if not packet.startswith(b'qSymbol:'): raise RuntimeError("Got unexpected response from gdb when asking for symbol value") packet = packet[8:] symValue, symName = packet.split(b':') symName = hex_decode(symName) if symName != name: raise RuntimeError("Symbol value reply from gdb has unexpected symbol name") if symValue: symValue = hex8_to_u32le(symValue) else: return None return symValue # TODO rewrite the remote command handler def handle_remote_command(self, cmd): self.log.debug('Remote command: %s', cmd) safecmd = { b'init' : [b'Init reset sequence', 0x1], b'reset' : [b'Reset and halt the target', 0x2], b'halt' : [b'Halt target', 0x4], # 'resume': ['Resume target', 0x8], b'help' : [b'Display this help', 0x80], } cmdList = cmd.split() resp = b'OK' if cmd == b'help': resp = b''.join([b'%s\t%s\n' % (k, v[0]) for k, v in safecmd.items()]) resp = hex_encode(resp) elif cmd.startswith(b'arm semihosting'): self.enable_semihosting = b'enable' in cmd self.log.info("Semihosting %s", ('enabled' if self.enable_semihosting else 'disabled')) elif cmdList[0] == b'set': if len(cmdList) < 3: resp = hex_encode("Error: invalid set command") elif cmdList[1] == b'vector-catch': try: self.target.set_vector_catch(convert_vector_catch(cmdList[2])) except ValueError as e: resp = hex_encode("Error: " + str(e)) elif cmdList[1] == b'step-into-interrupt': self.step_into_interrupt = (cmdList[2].lower() in (b"true", b"on", b"yes", b"1")) else: resp = hex_encode("Error: invalid set option") elif cmd == b"flush threads": if self.thread_provider is not None: self.thread_provider.invalidate() else: resultMask = 0x00 if cmdList[0] == b'help': # a 'help' is only valid as the first cmd, and only # gives info on the second cmd if it is valid resultMask |= 0x80 del cmdList[0] for cmd_sub in cmdList: if cmd_sub not in safecmd: self.log.warning("Invalid mon command '%s'", cmd_sub) resp = ('Invalid Command: "%s"\n' % cmd_sub).encode() resp = hex_encode(resp) return self.create_rsp_packet(resp) elif resultMask == 0x80: # if the first command was a 'help', we only need # to return info about the first cmd after it resp = hex_encode(safecmd[cmd_sub][0]+b'\n') return self.create_rsp_packet(resp) resultMask |= safecmd[cmd_sub][1] # Run cmds in proper order if resultMask & 0x1: pass if (resultMask & 0x6) == 0x6: if self.core == 0: self.target.reset_stop_on_reset() else: self.log.debug("Ignoring reset request for core #%d", self.core) elif resultMask & 0x2: # on 'reset' still do a reset halt if self.core == 0: self.target.reset_stop_on_reset() else: self.log.debug("Ignoring reset request for core #%d", self.core) # self.target.reset() elif resultMask & 0x4: self.target.halt() # if resultMask & 0x8: # self.target.resume() return self.create_rsp_packet(resp) def handle_general_set(self, msg): feature = msg.split(b'#')[0] self.log.debug("GDB general set: %s", feature) if feature == b'StartNoAckMode': # Disable acks after the reply and ack. self.packet_io.set_send_acks(False) return self.create_rsp_packet(b"OK") elif feature.startswith(b'NonStop'): enable = feature.split(b':')[1] self.non_stop = (enable == b'1') return self.create_rsp_packet(b"OK") else: return self.create_rsp_packet(b"") def handle_query_xml(self, query, offset, size): self.log.debug('GDB query %s: offset: %s, size: %s', query, offset, size) xml = '' if query == b'memory_map': xml = self.target_facade.get_memory_map_xml() elif query == b'read_feature': xml = self.target.get_target_xml() elif query == b'threads': xml = self.get_threads_xml() else: raise RuntimeError("Invalid XML query (%s)" % query) size_xml = len(xml) prefix = b'm' if offset > size_xml: self.log.error('GDB: xml offset > size for %s!', query) return if size > (self.packet_size - 4): size = self.packet_size - 4 nbBytesAvailable = size_xml - offset if size > nbBytesAvailable: prefix = b'l' size = nbBytesAvailable resp = prefix + escape(xml[offset:offset + size]) return resp def create_rsp_packet(self, data): resp = b'$' + data + b'#' + checksum(data) return resp def syscall(self, op): op = to_bytes_safe(op) self.log.debug("GDB server syscall: %s", op) request = self.create_rsp_packet(b'F' + op) self.packet_io.send(request) while not self.packet_io.interrupt_event.is_set(): # Read a packet. packet = self.packet_io.receive(False) if packet is None: sleep(0.1) continue # Check for file I/O response. if packet[0:1] == b'$' and packet[1:2] == b'F': self.log.debug("Syscall: got syscall response " + packet) args = packet[2:packet.index(b'#')].split(b',') result = int(args[0], base=16) errno = int(args[1], base=16) if len(args) > 1 else 0 ctrl_c = args[2] if len(args) > 2 else b'' if ctrl_c == b'C': self.packet_io.interrupt_event.set() self.packet_io.drop_reply = True return result, errno # decode and prepare resp resp, detach = self.handle_message(packet) if resp is not None: # send resp self.packet_io.send(resp) if detach: self.detach_event.set() self.log.warning("GDB server received detach request while waiting for file I/O completion") break return -1, 0 def get_t_response(self, forceSignal=None): self.validate_debug_context() response = self.target_facade.get_t_response(forceSignal) # Append thread and core if not self.is_threading_enabled(): response += b"thread:1;core:0;" else: if self.current_thread_id in (-1, 0, 1): response += ("thread:%x;core:0;" % self.thread_provider.current_thread.unique_id).encode() else: response += ("thread:%x;core:0;" % self.current_thread_id).encode() self.log.debug("Tresponse=%s", response) return response def get_threads_xml(self): root = Element('threads') if not self.is_threading_enabled(): t = SubElement(root, 'thread', id="1", core=str(self.core)) if self.is_target_in_reset(): t.text = "Reset" else: t.text = self.exception_name() else: threads = self.thread_provider.get_threads() for thread in threads: hexId = "%x" % thread.unique_id t = SubElement(root, 'thread', id=hexId, core="0", name=thread.name, handle=hexId) desc = thread.description if desc: desc = thread.name + "; " + desc else: desc = thread.name t.text = desc return b'' + tostring(root) def is_threading_enabled(self): return (self.thread_provider is not None) and self.thread_provider.is_enabled \ and (self.thread_provider.current_thread is not None) def is_target_in_reset(self): return self.target.get_state() == Target.TARGET_RESET def exception_name(self): try: ipsr = self.target_context.read_core_register('ipsr') return self.target_context.core.exception_number_to_name(ipsr) except: return None def event_handler(self, notification): if notification.event == Target.EVENT_POST_RESET: # Invalidate threads list if flash is reprogrammed. self.log.debug("Received EVENT_POST_RESET event") self.first_run_after_reset_or_flash = True if self.thread_provider is not None: self.thread_provider.read_from_target = False pyocd-0.13.1/pyocd/gdbserver/syscall.py0000644000175000017500000001013013373511253017735 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import os import logging from ..debug.semihost import SemihostIOHandler # Open mode flags O_RDONLY = 0x0 O_WRONLY = 0x1 O_RDWR = 0x2 O_APPEND = 0x8 O_CREAT = 0x200 O_TRUNC = 0x400 O_EXCL = 0x800 # Offset added to file descriptor numbers returned from gdb. This offset is to make # sure we don't overlap with the standard I/O file descriptors 1, 2, and 3 (fds must be # non-zero for semihosting). FD_OFFSET = 4 ## # @brief Semihosting file I/O handler that performs GDB syscalls. class GDBSyscallIOHandler(SemihostIOHandler): def __init__(self, server): super(GDBSyscallIOHandler, self).__init__() self._server = server def open(self, fnptr, fnlen, mode): # Handle standard I/O. fd, _ = self._std_open(fnptr, fnlen, mode) if fd is not None: return fd # Convert mode string to flags. modeval = 0 hasplus = '+' in mode if 'r' in mode: if hasplus: modeval |= O_RDWR else: modeval |= O_RDONLY elif 'w' in mode: if hasplus: modeval |= O_RDWR | O_CREAT | O_TRUNC else: modeval |= O_WRONLY | O_CREAT | O_TRUNC elif 'a' in mode: if hasplus: modeval |= O_RDWR | O_APPEND | O_CREAT else: modeval |= O_WRONLY | O_APPEND | O_CREAT result, self._errno = self._server.syscall('open,%x/%x,%x,%x' % (fnptr, fnlen + 1, modeval, 0o777)) if result != -1: result += FD_OFFSET return result def close(self, fd): fd -= FD_OFFSET result, self._errno = self._server.syscall('close,%x' % (fd)) return result # syscall return: number of bytes written # semihost return: 0 is success, or number of bytes not written def write(self, fd, ptr, length): fd -= FD_OFFSET result, self._errno = self._server.syscall('write,%x,%x,%x' % (fd, ptr, length)) return length - result # syscall return: number of bytes read # semihost return: 0 is success, length is EOF, number of bytes not read def read(self, fd, ptr, length): fd -= FD_OFFSET result, self._errno = self._server.syscall('read,%x,%x,%x' % (fd, ptr, length)) return length - result def readc(self): ptr = self.agent.target.read_core_register('sp') - 4 result, self._errno = self._server.syscall('read,0,%x,1' % (ptr)) if result != -1: result = self.agent.target.read8(ptr) return result def istty(self, fd): fd -= FD_OFFSET result, self._errno = self._server.syscall('isatty,%x' % (fd)) return result def seek(self, fd, pos): fd -= FD_OFFSET result, self._errno = self._server.syscall('lseek,%x,%x,0' % (fd, pos)) return 0 if result is not -1 else -1 def flen(self, fd): fd -= FD_OFFSET ptr = self.agent.target.read_core_register('sp') - 64 result, self._errno = self._server.syscall('fstat,%x,%x' % (fd, ptr)) if result != -1: # Fields in stat struct are big endian as written by gdb. size = self.agent.target.read_memory_block8(ptr, 8) result = (size[0] << 56) \ | (size[1] << 48) \ | (size[2] << 40) \ | (size[3] << 32) \ | (size[4] << 24) \ | (size[5] << 16) \ | (size[6] << 8) \ | (size[7]) return result pyocd-0.13.1/pyocd/gdbserver/context_facade.py0000644000175000017500000001240013373511253021234 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 ..utility import conversion from . import signals import logging import six # Maps the fault code found in the IPSR to a GDB signal value. FAULT = [ signals.SIGSTOP, signals.SIGSTOP, # Reset signals.SIGINT, # NMI signals.SIGSEGV, # HardFault signals.SIGSEGV, # MemManage signals.SIGBUS, # BusFault signals.SIGILL, # UsageFault # The rest are not faults ] ## @brief Provides GDB specific transformations to a DebugContext. class GDBDebugContextFacade(object): def __init__(self, context): self._context = context self._register_list = self._context.core.register_list @property def context(self): return self._context def set_context(self, newContext): self._context = newContext def get_register_context(self): """ return hexadecimal dump of registers as expected by GDB """ logging.debug("GDB getting register context") resp = b'' reg_num_list = [reg.reg_num for reg in self._register_list] vals = self._context.read_core_registers_raw(reg_num_list) #print("Vals: %s" % vals) for reg, regValue in zip(self._register_list, vals): resp += six.b(conversion.u32_to_hex8le(regValue)) logging.debug("GDB reg: %s = 0x%X", reg.name, regValue) return resp def set_register_context(self, data): """ Set registers from GDB hexadecimal string. """ logging.debug("GDB setting register context") reg_num_list = [] reg_data_list = [] for reg in self._register_list: regValue = conversion.hex8_to_u32be(data) reg_num_list.append(reg.reg_num) reg_data_list.append(regValue) logging.debug("GDB reg: %s = 0x%X", reg.name, regValue) data = data[8:] self._context.write_core_registers_raw(reg_num_list, reg_data_list) def set_register(self, reg, data): """ Set single register from GDB hexadecimal string. reg parameter is the index of register in targetXML sent to GDB. """ if reg < 0: return elif reg < len(self._register_list): regName = self._register_list[reg].name value = conversion.hex8_to_u32be(data) logging.debug("GDB: write reg %s: 0x%X", regName, value) self._context.write_core_register(regName, value) def gdb_get_register(self, reg): resp = '' if reg < len(self._register_list): regName = self._register_list[reg].name regValue = self._context.read_core_register(regName) resp = six.b(conversion.u32_to_hex8le(regValue)) logging.debug("GDB reg: %s = 0x%X", regName, regValue) return resp def get_t_response(self, forceSignal=None): """ Returns a GDB T response string. This includes: The signal encountered. The current value of the important registers (sp, lr, pc). """ if forceSignal is not None: response = six.b('T' + conversion.byte_to_hex2(forceSignal)) else: response = six.b('T' + conversion.byte_to_hex2(self.get_signal_value())) # Append fp(r7), sp(r13), lr(r14), pc(r15) response += self.get_reg_index_value_pairs([7, 13, 14, 15]) return response def get_signal_value(self): if self._context.core.is_debug_trap(): return signals.SIGTRAP fault = self._context.read_core_register('ipsr') try: signal = FAULT[fault] except: # If not a fault then default to SIGSTOP signal = signals.SIGSTOP logging.debug("GDB lastSignal: %d", signal) return signal def get_reg_index_value_pairs(self, regIndexList): """ Returns a string like NN:MMMMMMMM;NN:MMMMMMMM;... for the T response string. NN is the index of the register to follow MMMMMMMM is the value of the register. """ str = b'' regList = self._context.read_core_registers_raw(regIndexList) for regIndex, reg in zip(regIndexList, regList): str += six.b(conversion.byte_to_hex2(regIndex) + ':' + conversion.u32_to_hex8le(reg) + ';') return str def get_memory_map_xml(self): if self._context.core.memory_map: return self._context.core.memory_map.get_xml() else: return None def get_target_xml(self): return self._context.core.get_target_xml() def flush(self): self._context.core.flush() pyocd-0.13.1/pyocd/gdbserver/__init__.py0000644000175000017500000000117613373511253020034 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .gdbserver import GDBServer pyocd-0.13.1/pyocd/gdbserver/signals.py0000644000175000017500000000124413373511253017731 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ SIGINT = 2 SIGSEGV = 11 SIGILL = 4 SIGSTOP = 17 SIGTRAP = 5 SIGBUS = 10 pyocd-0.13.1/pyocd/gdbserver/gdb_websocket.py0000644000175000017500000000251413373511253021074 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ try: from websocket import create_connection except: pass class GDBWebSocket(object): def __init__(self, url): self.url = url self.wss = None return def connect(self): self.wss = None try: self.wss = create_connection(self.url) except: pass return self.wss def read(self): return self.wss.recv() def write(self, data): return self.wss.send(data) def close(self): return self.wss.close() def set_blocking(self, blocking): if blocking != 0: self.wss.settimeout(None) else: self.wss.settimeout(0) def set_timeout(self, timeout): self.wss.settimeout(timeout) pyocd-0.13.1/pyocd/gdbserver/symbols.py0000644000175000017500000000167613373511253017772 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ from ..debug.symbols import SymbolProvider from ..utility.py3_helpers import to_bytes_safe ## @brief Request symbol information from gdb. class GDBSymbolProvider(SymbolProvider): def __init__(self, gdbserver): self._gdbserver = gdbserver def get_symbol_value(self, name): return self._gdbserver.get_symbol(to_bytes_safe(name)) pyocd-0.13.1/pyocd/test/0000755000175000017500000000000013373523011014705 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/test/test_regcache.py0000644000175000017500000002131313373511253020064 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 pyocd.debug.cache import RegisterCache from pyocd.debug.context import DebugContext from pyocd.coresight.cortex_m import ( CortexM, CORE_REGISTER, register_name_to_index, is_psr_subregister, sysm_to_psr_mask ) from pyocd.core import memory_map from pyocd.utility import conversion from pyocd.utility import mask import pytest import logging @pytest.fixture(scope='function') def regcache(mockcore): return RegisterCache(DebugContext(mockcore)) # Copy of the register list without composite registers. CORE_REGS_NO_COMPOSITES = CORE_REGISTER.copy() CORE_REGS_NO_COMPOSITES.pop('cfbp') CORE_REGS_NO_COMPOSITES.pop('xpsr') CORE_REGS_NO_COMPOSITES.pop('iapsr') CORE_REGS_NO_COMPOSITES.pop('eapsr') CORE_REGS_NO_COMPOSITES.pop('iepsr') # Appropriate modifiers for masked registers - others modified by adding 7 REG_MODIFIER = { 'apsr': 0x30010000, 'epsr': 0x01000C00, } def get_modifier(r): return REG_MODIFIER.get(r, 7) def get_expected_reg_value(r): i = register_name_to_index(r) if is_psr_subregister(i): return 0x55555555 & sysm_to_psr_mask(i) if i < 0: i += 100 return i + 1 def get_expected_cfbp(): return ((get_expected_reg_value('control') << 24) | (get_expected_reg_value('faultmask') << 16) | (get_expected_reg_value('basepri') << 8) | get_expected_reg_value('primask')) def get_expected_xpsr(): return (get_expected_reg_value('apsr') | get_expected_reg_value('ipsr') | get_expected_reg_value('epsr')) class TestRegisterCache: def set_core_regs(self, mockcore, modify=False): for r in CORE_REGS_NO_COMPOSITES: if modify: modifier = get_modifier(r) else: modifier = 0 mockcore.write_core_registers_raw([r], [get_expected_reg_value(r) + modifier]) assert mockcore.read_core_registers_raw([r]) == [get_expected_reg_value(r) + modifier] def test_r_1(self, mockcore, regcache): assert regcache.read_core_registers_raw(['r0']) == [0] # cache initial value of 0 mockcore.write_core_registers_raw(['r0'], [1234]) # modify reg behind the cache's back assert mockcore.read_core_registers_raw(['r0']) == [1234] # verify modified reg assert regcache.read_core_registers_raw(['r0']) == [0] # should return cached 0 value regcache.invalidate() # explicitly invalidate cache assert mockcore.read_core_registers_raw(['r0']) == [1234] # verify modified reg assert regcache.read_core_registers_raw(['r0']) == [1234] # now should return updated 1234 value def test_run_token(self, mockcore, regcache): assert regcache.read_core_registers_raw(['r0']) == [0] # cache initial value of 0 mockcore.write_core_registers_raw(['r0'], [1234]) # modify reg behind the cache's back assert mockcore.read_core_registers_raw(['r0']) == [1234] # verify modified reg assert regcache.read_core_registers_raw(['r0']) == [0] # should return cached 0 value mockcore.run_token += 1 # bump run token to cause cache to invalidate assert regcache.read_core_registers_raw(['r0']) == [1234] # now should return updated 1234 value def test_reading_from_core(self, mockcore, regcache): self.set_core_regs(mockcore) for r in CORE_REGS_NO_COMPOSITES: assert regcache.read_core_registers_raw([r]) == [get_expected_reg_value(r)] def test_read_cached(self, mockcore, regcache): self.set_core_regs(mockcore) # cache all regs regcache.read_core_registers_raw(CORE_REGS_NO_COMPOSITES.values()) # modify regs in mock core self.set_core_regs(mockcore, True) # cache should return original unmodified values for r in CORE_REGS_NO_COMPOSITES: assert regcache.read_core_registers_raw([r]) == [get_expected_reg_value(r)] def test_read_cfbp(self, mockcore, regcache): self.set_core_regs(mockcore) assert regcache.read_core_registers_raw(['cfbp', 'control', 'faultmask']) == [ get_expected_cfbp(), get_expected_reg_value('control'), get_expected_reg_value('faultmask') ] def test_read_xpsr(self, mockcore, regcache): self.set_core_regs(mockcore) assert regcache.read_core_registers_raw(['xpsr', 'ipsr', 'apsr', 'eapsr']) == [ get_expected_xpsr(), get_expected_reg_value('ipsr'), get_expected_reg_value('apsr'), get_expected_reg_value('eapsr') ] def test_read_cached_cfbp(self, mockcore, regcache): self.set_core_regs(mockcore) # cache it regcache.read_core_registers_raw(['cfbp']) # modify behind the cache's back mockcore.write_core_registers_raw(['control', 'primask'], [0x55, 0xaa]) # cache should return original value assert regcache.read_core_registers_raw(['cfbp']) == [get_expected_cfbp()] def test_read_cached_xpsr(self, mockcore, regcache): self.set_core_regs(mockcore) # cache it regcache.read_core_registers_raw(['xpsr']) # modify behind the cache's back mockcore.write_core_registers_raw(['ipsr', 'apsr'], [0x22, 0x10000000]) # cache should return original value assert regcache.read_core_registers_raw(['xpsr']) == [get_expected_xpsr()] def test_write_1(self, mockcore, regcache): self.set_core_regs(mockcore) assert mockcore.read_core_registers_raw(['r0']) == [get_expected_reg_value('r0')] assert regcache.read_core_registers_raw(['r0']) == [get_expected_reg_value('r0')] regcache.write_core_registers_raw(['r0'], [1234]) assert mockcore.read_core_registers_raw(['r0']) == [1234] assert regcache.read_core_registers_raw(['r0']) == [1234] def test_write_regs(self, mockcore, regcache): self.set_core_regs(mockcore) for r in CORE_REGS_NO_COMPOSITES: regcache.write_core_registers_raw([r], [get_expected_reg_value(r) + get_modifier(r)]) for r in CORE_REGS_NO_COMPOSITES: assert mockcore.read_core_registers_raw([r]) == [get_expected_reg_value(r) + get_modifier(r)] def test_write_cfbp(self, mockcore, regcache): self.set_core_regs(mockcore) assert mockcore.read_core_registers_raw(['cfbp']) == [get_expected_cfbp()] regcache.write_core_registers_raw(['control', 'primask'], [3, 19]) assert mockcore.read_core_registers_raw(['control', 'primask', 'cfbp']) == [ 3, 19, ((3 << 24) | (get_expected_reg_value('faultmask') << 16) | (get_expected_reg_value('basepri') << 8) | 19) ] def test_write_xpsr(self, mockcore, regcache): self.set_core_regs(mockcore) assert mockcore.read_core_registers_raw(['xpsr']) == [get_expected_xpsr()] regcache.write_core_registers_raw(['iapsr'], [0x10000022]) assert mockcore.read_core_registers_raw(['ipsr', 'apsr', 'iapsr', 'xpsr']) == [ 0x22, 0x10000000, 0x10000022, 0x10000022 | get_expected_reg_value('epsr') ] def test_write_full_xpsr(self, mockcore, regcache): self.set_core_regs(mockcore) assert mockcore.read_core_registers_raw(['xpsr']) == [get_expected_xpsr()] regcache.write_core_registers_raw(['xpsr'], [0xffffffff]) assert mockcore.read_core_registers_raw(['ipsr', 'apsr', 'epsr', 'xpsr']) == [ CortexM.IPSR_MASK, CortexM.APSR_MASK, CortexM.EPSR_MASK, 0xffffffff ] def test_invalid_reg_r(self, regcache): with pytest.raises(ValueError): regcache.read_core_registers_raw([132423]) def test_invalid_reg_w(self, regcache): with pytest.raises(ValueError): regcache.write_core_registers_raw([132423], [1234]) def test_invalid_fpu_reg_r(self, mockcore, regcache): mockcore.has_fpu = False with pytest.raises(ValueError): regcache.read_core_registers_raw(['s1']) def test_invalid_fpu_reg_w(self, mockcore, regcache): mockcore.has_fpu = False with pytest.raises(ValueError): regcache.write_core_registers_raw(['s1'], [1.234]) pyocd-0.13.1/pyocd/test/test_mockcore.py0000644000175000017500000000715313373511253020133 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 pyocd.core import memory_map from pyocd.coresight.cortex_m import CORE_REGISTER from pyocd.utility import conversion from pyocd.utility import mask import pytest import logging from .mockcore import MockCore # @pytest.fixture(scope='function') # def mockcore(): # return MockCore() # Basic tests of MockCore memory simulation. class TestMockCoreMem: def test_read8_flash(self, mockcore): assert mockcore.read_memory_block8(0, 4) == [0xff, 0xff, 0xff, 0xff] def test_read8_ram(self, mockcore): assert mockcore.read_memory_block8(0x20000000, 4) == [0, 0, 0, 0] def test_read32_flash(self, mockcore): assert mockcore.read_memory_block32(0, 1) == [0xffffffff] def test_read32_ram(self, mockcore): assert mockcore.read_memory_block32(0x20000000, 1) == [0x00000000] def test_write8_flash(self, mockcore): mockcore.write_memory_block8(0x100, [0xaa, 0xbb, 0xcc, 0xdd]) assert mockcore.read_memory_block8(0xfe, 8) == [0xff, 0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xff, 0xff] def test_write32_flash(self, mockcore): mockcore.write_memory_block32(0x100, [0xaabbccdd]) assert mockcore.read_memory_block32(0xfc, 3) == [0xffffffff, 0xaabbccdd, 0xffffffff] def test_write8_ram(self, mockcore): mockcore.write_memory_block8(0x20000100, [0xaa, 0xbb, 0xcc, 0xdd]) assert mockcore.read_memory_block8(0x200000fe, 8) == [0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x00, 0x00] def test_write32_ram(self, mockcore): mockcore.write_memory_block32(0x20000100, [0xaabbccdd]) assert mockcore.read_memory_block32(0x200000fc, 3) == [0x00000000, 0xaabbccdd, 0x00000000] # Basic tests of MockCore register simulation. class TestMockCoreReg: def test_rw_r0_r15(self, mockcore): for r in range(0, 16): mockcore.write_core_registers_raw([r], [1+r]) for r in range(0, 16): assert mockcore.read_core_registers_raw([r]) == [1+r] def test_rw_cfbp(self, mockcore): mockcore.write_core_registers_raw([CORE_REGISTER['cfbp']], [0x01020304]) assert mockcore.read_core_registers_raw([CORE_REGISTER['control'], CORE_REGISTER['faultmask'], CORE_REGISTER['basepri'], CORE_REGISTER['primask']]) == [0x01, 0x02, 0x03, 0x04] def test_w_control(self, mockcore): mockcore.write_core_registers_raw([CORE_REGISTER['control']], [0xaa]) assert mockcore.read_core_registers_raw([CORE_REGISTER['cfbp']]) == [0xaa000000] def test_w_faultmask(self, mockcore): mockcore.write_core_registers_raw([CORE_REGISTER['faultmask']], [0xaa]) mockcore.read_core_registers_raw([CORE_REGISTER['cfbp']]) == [0x00aa0000] def test_w_basepri(self, mockcore): mockcore.write_core_registers_raw([CORE_REGISTER['basepri']], [0xaa]) mockcore.read_core_registers_raw([CORE_REGISTER['cfbp']]) == [0x0000aa00] def test_w_primask(self, mockcore): mockcore.write_core_registers_raw([CORE_REGISTER['primask']], [0xaa]) mockcore.read_core_registers_raw([CORE_REGISTER['cfbp']]) == [0x000000aa] pyocd-0.13.1/pyocd/test/test_cmdline.py0000644000175000017500000000467313373511253017750 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015,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 pyocd.utility.cmdline import ( split_command_line, convert_vector_catch, VECTOR_CATCH_CHAR_MAP ) from pyocd.core.target import Target import pytest import six class TestSplitCommandLine(object): def test_split(self): assert split_command_line('foo') == ['foo'] assert split_command_line(['foo']) == ['foo'] assert split_command_line('foo bar') == ['foo', 'bar'] assert split_command_line(['foo bar']) == ['foo', 'bar'] def test_split_strings(self): assert split_command_line('"foo"') == ['foo'] assert split_command_line('"foo bar"') == ['foo bar'] assert split_command_line(['"foo"']) == ['foo'] assert split_command_line('a "b c" d') == ['a', "b c", 'd'] assert split_command_line("'foo bar'") == ['foo bar'] def test_split_whitespace(self): assert split_command_line('a b') == ['a', 'b'] assert split_command_line('a\tb') == ['a', 'b'] assert split_command_line('a\rb') == ['a', 'b'] assert split_command_line('a\nb') == ['a', 'b'] assert split_command_line('a \tb') == ['a', 'b'] class TestConvertVectorCatch(object): def test_none_str(self): assert convert_vector_catch('none') == 0 def test_all_str(self): assert convert_vector_catch('all') == Target.CATCH_ALL def test_none_b(self): assert convert_vector_catch(b'none') == 0 def test_all_b(self): assert convert_vector_catch(b'all') == Target.CATCH_ALL @pytest.mark.parametrize(("vc", "msk"), list(VECTOR_CATCH_CHAR_MAP.items())) def test_vc_str(self, vc, msk): assert convert_vector_catch(vc) == msk @pytest.mark.parametrize(("vc", "msk"), [(six.b(x), y) for x,y in VECTOR_CATCH_CHAR_MAP.items()]) def test_vc_b(self, vc, msk): assert convert_vector_catch(vc) == msk pyocd-0.13.1/pyocd/test/__init__.py0000644000175000017500000000113513373511253017023 0ustar neilneil00000000000000# mbed CMSIS-DAP debugger # Copyright (c) 2017 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. pyocd-0.13.1/pyocd/test/test_sequencer.py0000644000175000017500000002124713373511253020323 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 pyocd.utility.sequencer import CallSequence import pytest import six class TestCallSequence: def test_empty(self): cs = CallSequence() assert cs.count == 0 def test_a(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.invoke() assert results == ['a ran', 'b ran'] def test_append_1(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ) assert cs.count == 1 cs.append( ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.invoke() assert results == ['a ran', 'b ran'] def test_append_2(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ) assert cs.count == 1 cs.append( ('b', lambda : results.append('b ran')), ('c', lambda : results.append('c ran')), ) assert cs.count == 3 cs.invoke() assert results == ['a ran', 'b ran', 'c ran'] def test_remove_1(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.remove_task('b') assert cs.count == 1 cs.invoke() assert results == ['a ran'] def test_callable(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs() assert results == ['a ran', 'b ran'] def test_nested(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs2 = CallSequence( ('c', cs), ) assert cs2.count == 1 cs2.invoke() assert results == ['a ran', 'b ran'] def test_clear(self): cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.clear() assert cs.count == 0 def test_iter(self): results = [] def task_a(): results.append('a ran') def task_b(): results.append('b ran') cs = CallSequence( ('a', task_a), ('b', task_b), ) assert cs.count == 2 it = iter(cs) print("it=",repr(it),dir(it)) assert six.next(it) == ('a', task_a) assert six.next(it) == ('b', task_b) with pytest.raises(StopIteration): six.next(it) def test_get(self): results = [] def task_a(): results.append('a ran') cs = CallSequence( ('a', task_a), ) assert cs.count == 1 assert cs.get_task('a') == task_a with pytest.raises(KeyError): cs.get_task('foo') def test_has(self): cs = CallSequence( ('a', lambda : results.append('a ran')), ) assert cs.count == 1 assert cs.has_task('a') assert not cs.has_task('foo') def test_replace(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.replace_task('b', lambda : results.append('wheee')) cs() assert results == ['a ran', 'wheee'] def test_wrap(self): results = [] def task_b(): results.append('b ran') return "task b result" cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', task_b), ) assert cs.count == 2 def wrapper(t): assert t == "task b result" results.append('wrapper ran') cs.wrap_task('b', wrapper) cs() assert results == ['a ran', 'b ran', 'wrapper ran'] def test_returned_seq(self): results = [] def task_b(): results.append('b ran') cs2 = CallSequence( ('x', lambda : results.append('x ran')), ('y', lambda : results.append('y ran')), ) assert cs2.count == 2 return cs2 cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', task_b), ('c', lambda : results.append('c ran')), ) assert cs.count == 3 cs() assert results == ['a ran', 'b ran', 'x ran', 'y ran', 'c ran'] def test_insert_before_1(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_before('b', ('c', lambda : results.append('c ran'))) assert cs.count == 3 cs() assert results == ['a ran', 'c ran', 'b ran'] def test_insert_before_2(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_before('a', ('c', lambda : results.append('c ran'))) assert cs.count == 3 cs() assert results == ['c ran', 'a ran', 'b ran'] def test_insert_before_3(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_before('a', ('c', lambda : results.append('c ran')), ('d', lambda : results.append('d ran'))) assert cs.count == 4 cs() assert results == ['c ran', 'd ran', 'a ran', 'b ran'] def test_insert_before_4(self): cs = CallSequence() with pytest.raises(KeyError): cs.insert_before('z', ('c', lambda : results.append('c ran'))) def test_insert_after_1(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_after('b', ('c', lambda : results.append('c ran'))) assert cs.count == 3 cs() assert results == ['a ran', 'b ran', 'c ran'] def test_insert_after_2(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_after('a', ('c', lambda : results.append('c ran'))) assert cs.count == 3 cs() assert results == ['a ran', 'c ran', 'b ran'] def test_insert_after_3(self): results = [] cs = CallSequence( ('a', lambda : results.append('a ran')), ('b', lambda : results.append('b ran')), ) assert cs.count == 2 cs.insert_after('a', ('c', lambda : results.append('c ran')), ('d', lambda : results.append('d ran'))) assert cs.count == 4 cs() assert results == ['a ran', 'c ran', 'd ran', 'b ran'] def test_insert_after_4(self): cs = CallSequence() with pytest.raises(KeyError): cs.insert_after('z', ('c', lambda : results.append('c ran'))) pyocd-0.13.1/pyocd/test/conftest.py0000644000175000017500000000150213373511253017107 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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. """ import pytest import logging from .mockcore import MockCore @pytest.fixture(scope='function') def mockcore(): return MockCore() # Ignore semihosting test that currently crashes on Travis collect_ignore = ["test_semihosting.py"] pyocd-0.13.1/pyocd/test/test_conversion.py0000644000175000017500000001060013373511253020505 0ustar neilneil00000000000000# mbed CMSIS-DAP debugger # Copyright (c) 2015 Paul Osborne # Copyright (c) 2018 Arm Ltd # # 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 pyocd.utility.conversion import ( byte_list_to_u32le_list, u32le_list_to_byte_list, u16le_list_to_byte_list, byte_list_to_u16le_list, u32_to_float32, float32_to_u32, u32_to_hex8le, hex8_to_u32be, byte_to_hex2, hex_to_byte_list, hex_decode, hex_encode, ) from pyocd.gdbserver.gdbserver import ( escape, unescape, ) import pytest import six # pylint: disable=invalid-name class TestConversionUtilities(object): def test_byteListToU32leList(self): data = range(32) assert byte_list_to_u32le_list(data) == [ 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918, 0x1F1E1D1C, ] def test_u32leListToByteList(self): data = [ 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918, 0x1F1E1D1C, ] assert u32le_list_to_byte_list(data) == list(range(32)) def test_u16leListToByteList(self): data = [0x3412, 0xFEAB] assert u16le_list_to_byte_list(data) == [ 0x12, 0x34, 0xAB, 0xFE ] def test_byteListToU16leList(self): data = [0x01, 0x00, 0xAB, 0xCD, ] assert byte_list_to_u16le_list(data) == [ 0x0001, 0xCDAB, ] def test_u32BEToFloat32BE(self): assert u32_to_float32(0x012345678) == 5.690456613903524e-28 def test_float32beToU32be(self): assert float32_to_u32(5.690456613903524e-28) == 0x012345678 def test_u32beToHex8le(self): assert u32_to_hex8le(0x0102ABCD) == "cdab0201" def test_hex8leToU32be(self): assert hex8_to_u32be("0102ABCD") == 0xCDAB0201 def test_byteToHex2(self): assert byte_to_hex2(0xC3) == "c3" def test_hexToByteList(self): assert hex_to_byte_list("ABCDEF1234") == [0xAB, 0xCD, 0xEF, 0x12, 0x34] def test_hexDecode(self): assert hex_decode('ABCDEF1234') == b'\xab\xcd\xef\x12\x34' def test_hexEncode(self): assert hex_encode(b'\xab\xcd\xef\x12\x34') == b'abcdef1234' # Characters that must be escaped. ESCAPEES = (0x23, 0x24, 0x2a, 0x7d) # == ('#', '$', '}', '*') # Test the gdbserver binary data escape/unescape routines. class TestGdbEscape(object): # Verify all chars that shouldn't be escaped pass through unmodified. @pytest.mark.parametrize("data", [six.int2byte(x) for x in range(256) if (x not in ESCAPEES)]) def test_escape_passthrough(self, data): assert escape(data) == data @pytest.mark.parametrize(("data", "expected"), [ (b'#', b'}\x03'), (b'$', b'}\x04'), (b'}', b'}]'), (b'*', b'}\x0a') ]) def test_escape_1(self, data, expected): assert escape(data) == expected def test_escape_2(self): assert escape(b'1234#09*xyz') == b'1234}\x0309}\x0axyz' # Verify all chars that shouldn't be escaped pass through unmodified. @pytest.mark.parametrize("data", [six.int2byte(x) for x in range(256) if (x not in ESCAPEES)]) def test_unescape_passthrough(self, data): assert unescape(data) == [six.byte2int(data)] @pytest.mark.parametrize(("expected", "data"), [ (0x23, b'}\x03'), (0x24, b'}\x04'), (0x7d, b'}]'), (0x2a, b'}\x0a') ]) def test_unescape_1(self, data, expected): assert unescape(data) == [expected] def test_unescape_2(self): assert unescape(b'1234}\x0309}\x0axyz') == \ [0x31, 0x32, 0x33, 0x34, 0x23, 0x30, 0x39, 0x2a, 0x78, 0x79, 0x7a] pyocd-0.13.1/pyocd/test/test_memory_map.py0000644000175000017500000002016413373511253020473 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 pyocd.core.memory_map import (check_range, MemoryMap, FlashRegion, RomRegion, RamRegion) import pytest import logging @pytest.fixture(scope='function') def flash(): return FlashRegion(start=0, length=1*1024, blocksize=0x100, name='flash', is_boot_memory=True) @pytest.fixture(scope='function') def rom(): return RomRegion(start=0x1c000000, length=16*1024, name='rom') @pytest.fixture(scope='function') def ram1(): return RamRegion(start=0x20000000, length=1*1024, name='ram') @pytest.fixture(scope='function') def ram2(): return RamRegion(start=0x20000400, length=1*1024, name='ram2', is_cacheable=False) @pytest.fixture(scope='function') def memmap(flash, rom, ram1, ram2): return MemoryMap(flash, rom, ram1, ram2) class TestCheckRange: def test_1(self): assert check_range(0, end=0x1ff) == (0, 0x1ff) def test_2(self): assert check_range(0, length=0x200) == (0, 0x1ff) def test_3(self): with pytest.raises(AssertionError): check_range(None, end=100) def test_4(self): with pytest.raises(AssertionError): check_range(0x100, end=None) def test_5(self): with pytest.raises(AssertionError): check_range(0x100, length=None) # MemoryRegion test cases. class TestMemoryRegion: def test_flash_attrs(self, flash): assert flash.start == 0 assert flash.end == 0x3ff assert flash.length == 0x400 assert flash.blocksize == 0x100 assert flash.name == 'flash' assert flash.is_flash assert not flash.is_ram assert not flash.is_rom assert flash.is_boot_memory assert flash.is_cacheable assert flash.is_powered_on_boot def test_rom_attrs(self, rom): assert rom.start == 0x1c000000 assert rom.end == 0x1c003fff assert rom.length == 0x4000 assert rom.blocksize == 0 assert rom.name == 'rom' assert not rom.is_flash assert not rom.is_ram assert rom.is_rom assert not rom.is_boot_memory assert rom.is_cacheable assert rom.is_powered_on_boot def test_ram1_attrs(self, ram1): assert ram1.start == 0x20000000 assert ram1.end == 0x200003ff assert ram1.length == 0x400 assert ram1.blocksize == 0 assert ram1.name == 'ram' assert not ram1.is_flash assert ram1.is_ram assert not ram1.is_rom assert not ram1.is_boot_memory assert ram1.is_cacheable assert ram1.is_powered_on_boot def test_ram2_attrs(self, ram2): assert ram2.start == 0x20000400 assert ram2.end == 0x200007ff assert ram2.length == 0x400 assert ram2.blocksize == 0 assert ram2.name == 'ram2' assert not ram2.is_flash assert ram2.is_ram assert not ram2.is_rom assert not ram2.is_boot_memory assert not ram2.is_cacheable assert ram2.is_powered_on_boot def test_flash_range(self, flash): assert flash.contains_address(0) assert flash.contains_address(0x3ff) assert not flash.contains_address(0x400) assert flash.contains_range(0, length=0x400) assert flash.contains_range(0, end=0x3ff) assert flash.contains_range(0x100, length=0x100) assert not flash.contains_range(0x300, end=0x720) assert flash.intersects_range(0, length=0x100) assert flash.intersects_range(0x300, end=0x720) def test_intersects(self, ram1): assert not ram1.intersects_range(0, length=10) assert not ram1.intersects_range(0xf0000000, end=0xffffffff) assert ram1.intersects_range(0x100000, end=0x20000010) assert ram1.intersects_range(0x20000010, end=0x30000000) assert ram1.intersects_range(0x20000040, length=0x1000) assert ram1.intersects_range(0x20000020, end=0x20000030) assert ram1.intersects_range(0x20000020, length=0x10) assert ram1.intersects_range(0x1fff0000, end=0x20001000) assert ram1.intersects_range(0x1ffff000, length=0x40000) # MemoryMap test cases. class TestMemoryMap: def test_empty_map(self): memmap = MemoryMap() assert memmap.region_count == 0 assert memmap.regions == [] assert memmap.get_boot_memory() is None assert memmap.get_region_for_address(0x1000) is None assert not memmap.is_valid_address(0x2000) assert memmap.get_contained_regions(0, end=0xffffffff) == [] assert memmap.get_intersecting_regions(0, end=0xffffffff) == [] def test_regions(self, memmap): rgns = memmap.regions # Count assert len(rgns) == 4 assert memmap.region_count == 4 # Sorted order assert rgns[0].start < rgns[1].start and rgns[1].start < rgns[2].start and rgns[2].start < rgns[3].start def test_boot_mem(self, memmap): bootmem = memmap.get_boot_memory() assert bootmem is not None assert bootmem.name == 'flash' assert bootmem.start == 0 assert bootmem.end == 0x3ff assert bootmem.is_boot_memory == True def test_rgn_for_addr(self, memmap): assert memmap.get_region_for_address(0).name == 'flash' assert memmap.get_region_for_address(0x20000000).name == 'ram' assert memmap.get_region_for_address(0x20000500).name == 'ram2' def test_valid(self, memmap): assert memmap.is_valid_address(0) assert memmap.is_valid_address(0x200) assert memmap.is_valid_address(0x3ff) assert not memmap.is_valid_address(0x400) assert not memmap.is_valid_address(0x1bffffff) assert memmap.is_valid_address(0x1c000000) assert not memmap.is_valid_address(0x1fffffff) assert memmap.is_valid_address(0x20000000) assert memmap.is_valid_address(0x20000001) assert memmap.is_valid_address(0x200003ff) assert memmap.is_valid_address(0x20000400) assert memmap.is_valid_address(0x200007ff) assert not memmap.is_valid_address(0x20000800) def test_contained_1(self, memmap): rgns = memmap.get_contained_regions(0, 0x100) assert len(rgns) == 0 def test_contained_2(self, memmap): rgns = memmap.get_contained_regions(0x20000000, 0x20000600) assert len(rgns) == 1 def test_intersect_1(self, memmap): rgns = memmap.get_intersecting_regions(0, 0x100) assert len(rgns) == 1 def test_intersect_2(self, memmap): rgns = memmap.get_intersecting_regions(0x20000200, end=0x20000700) assert len(rgns) == 2 def test_x(self): ramrgn = RamRegion(name='core0 ram', start=0x1fffa000, length=0x18000) assert ramrgn.contains_range(0x1fffc9f8, end=0x1fffc9fc) assert ramrgn.intersects_range(0x1fffc9f8, end=0x1fffc9fc) dualMap = MemoryMap( FlashRegion(name='flash', start=0, length=0x80000, blocksize=0x800, is_boot_memory=True), RomRegion(name='core1 imem alias', start=0x1d200000, length=0x40000), ramrgn, RomRegion(name='core1 imem', start=0x2d200000, length=0x40000), RamRegion(name='core1 dmem', start=0x2d300000, length=0x8000), RamRegion(name='usb ram', start=0x40100000, length=0x800) ) rgns = dualMap.get_intersecting_regions(0x1fffc9f8, end=0x1fffc9fc) assert len(rgns) > 0 def test_get_type_iter(self, memmap, flash, rom, ram1, ram2): assert list(memmap.get_regions_of_type('flash')) == [flash] assert list(memmap.get_regions_of_type('rom')) == [rom] assert list(memmap.get_regions_of_type('ram')) == [ram1, ram2] pyocd-0.13.1/pyocd/test/test_semihosting.py0000644000175000017500000004712013373511253020660 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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. """ import pytest import os import sys import logging from pyocd.core.helpers import ConnectHelper from pyocd.core.target import Target from pyocd.debug import semihost from elapsedtimer import ElapsedTimer import telnetlib @pytest.fixture(scope='module') def tgt(request): board = None try: session = ConnectHelper.session_with_chosen_probe(blocking=False, return_first=True) except Exception as error: logging.error("Exception during session_with_chosen_probe", exc_info=error) if session is None: pytest.skip("No probe present") return board = session.board session.options['resume_on_disconnect'] = False board.target.reset_stop_on_reset() def cleanup(): board.uninit() request.addfinalizer(cleanup) return board.target @pytest.fixture(scope='module') def ctx(tgt): return tgt.get_target_context() @pytest.fixture(scope='function') def semihostagent(ctx, request): io_handler = semihost.InternalSemihostIOHandler() agent = semihost.SemihostAgent(ctx, io_handler) def cleanup(): agent.cleanup() request.addfinalizer(cleanup) return agent @pytest.fixture(scope='module') def ramrgn(tgt): map = tgt.get_memory_map() for rgn in map: if rgn.is_ram: return rgn pytest.skip("No RAM available to load test") class TimeoutError(RuntimeError): pass def run_til_halt(tgt, semihostagent): with ElapsedTimer('run_til_halt', logger=logging.getLogger('root'), loglevel=logging.INFO) as t: logging.info("Resuming target") tgt.resume() try: while True: if t.elapsed >= 2.0: raise TimeoutError() if tgt.get_state() == Target.TARGET_HALTED: logging.info("Target halted") didHandle = semihostagent.check_and_handle_semihost_request() if didHandle: logging.info("Semihost request handled") else: logging.info("Non-semihost break") return didHandle except TimeoutError: tgt.halt() return False finally: assert tgt.get_state() == Target.TARGET_HALTED NOP = 0x46c0 BKPT_00 = 0xbe00 BKPT_AB = 0xbeab ## @brief Semihost IO handler that records output. # # This handler is only meant to be used for console I/O since it doesn't implement # open() or close(). class RecordingSemihostIOHandler(semihost.SemihostIOHandler): def __init__(self): self._out_data = {} self._in_data = {} def set_input_data(self, fd, data): self._in_data[fd] = data def get_output_data(self, fd): if fd in self._out_data: return self._out_data[fd] else: return None def write(self, fd, ptr, length): if fd not in self._out_data: self._out_data[fd] = '' s = self.agent._get_string(ptr, length) self._out_data[fd] += s return 0 def read(self, fd, ptr, length): if fd not in self._in_data: return length d = self._in_data[fd][:length] self._in_data[fd] = self._in_data[fd][length:] self.agent.context.write_memory_block8(ptr, bytearray(d)) return length - len(d) def readc(self): if semihost.STDIN_FD not in self._in_data: return -1 d = self._in_data[semihost.STDIN_FD][:1] self._in_data[semihost.STDIN_FD] = self._in_data[semihost.STDIN_FD][1:] if len(d): return ord(d[0]) else: return -1 ## @brief Utility to build code and set registers to perform a semihost request. class SemihostRequestBuilder: def __init__(self, tgt, semihostagent, ramrgn): self.tgt = tgt self.ctx = tgt.get_target_context() self.semihostagent = semihostagent self.ramrgn = ramrgn def set_agent(self, agent): self.semihostagent = agent def setup_semihost_request(self, rqnum): assert self.tgt.get_state() == Target.TARGET_HALTED self.ctx.write16(self.ramrgn.start, NOP) self.ctx.write16(self.ramrgn.start + 2, BKPT_AB) self.ctx.write16(self.ramrgn.start + 4, BKPT_00) self.ctx.write_core_register('pc', self.ramrgn.start) self.ctx.write_core_register('sp', self.ramrgn.start + 0x100) self.ctx.write_core_register('r0', rqnum) self.ctx.write_core_register('r1', self.ramrgn.start + 0x200) self.ctx.flush() return self.ramrgn.start + 0x200 def do_open(self, filename, mode): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_OPEN) # Write filename filename = bytearray(filename + '\x00') self.ctx.write_memory_block8(argsptr + 12, filename) self.ctx.write32(argsptr, argsptr + 12) # null terminated filename self.ctx.write32(argsptr + 4, semihost.SemihostAgent.OPEN_MODES.index(mode)) # mode self.ctx.write32(argsptr + 8, len(filename) - 1) # filename length minus null terminator was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_close(self, fd): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_CLOSE) self.ctx.write32(argsptr, fd) was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_write(self, fd, data): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_WRITE) # Write data self.ctx.write_memory_block8(argsptr + 12, bytearray(data)) self.ctx.write32(argsptr, fd) # fd self.ctx.write32(argsptr + 4, argsptr + 12) # data self.ctx.write32(argsptr + 8, len(data)) # data length self.ctx.flush() was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_writec(self, c): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_WRITEC) self.ctx.write8(argsptr, ord(c)) was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_write0(self, s): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_WRITE0) s = bytearray(s + '\x00') self.ctx.write_memory_block8(argsptr, s) was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_read(self, fd, length): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_READ) # Clear read buffer. self.ctx.write_memory_block8(argsptr + 12, bytearray('\x00') * length) self.ctx.write32(argsptr, fd) # fd self.ctx.write32(argsptr + 4, argsptr + 12) # ptr self.ctx.write32(argsptr + 8, length) # data length self.ctx.flush() was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') # Read data put into read buffer. data = str(bytearray(self.tgt.read_memory_block8(argsptr + 12, length - result))) return result, data def do_seek(self, fd, pos): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_SEEK) self.ctx.write32(argsptr, fd) # fd self.ctx.write32(argsptr + 4, pos) # pos self.ctx.flush() was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_flen(self, fd): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_FLEN) self.ctx.write32(argsptr, fd) # fd self.ctx.flush() was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_istty(self, fd): argsptr = self.setup_semihost_request(semihost.TARGET_SYS_ISTTY) self.ctx.write32(argsptr, fd) # fd self.ctx.flush() was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result def do_no_args_call(self, rq): argsptr = self.setup_semihost_request(rq) self.ctx.write_core_register('r1', 0) # r1 must be zero on entry was_semihost = run_til_halt(self.tgt, self.semihostagent) assert was_semihost result = self.ctx.read_core_register('r0') return result @pytest.fixture(scope='function') def semihost_builder(tgt, semihostagent, ramrgn): return SemihostRequestBuilder(tgt, semihostagent, ramrgn) @pytest.fixture(scope='function') def console_semihost_builder(semihost_builder): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) return semihost_builder @pytest.fixture def delete_testfile(request): def delete_it(): try: os.remove("testfile") except IOError: pass request.addfinalizer(delete_it) ## @brief Tests for semihost requests. class TestSemihosting: def test_open_stdio(self, semihost_builder): fd = semihost_builder.do_open(":tt", 'r') # stdin assert fd == 1 fd = semihost_builder.do_open(":tt", 'w') # stdout assert fd == 2 fd = semihost_builder.do_open(":tt", 'a') # stderr assert fd == 3 def test_open_close_file(self, semihost_builder, delete_testfile): fd = semihost_builder.do_open("testfile", 'w+b') assert fd != 0 and fd > 3 result = semihost_builder.do_close(fd) assert result == 0 @pytest.mark.parametrize(("writeData", "pos", "readLen", "readResult"), [ ("12345678", 0, 8, 0), ("hi", 0, 2, 0), ("hello", 2, 3, 0), ("", 0, 4, 4), ("abcd", -1, 0, 0) ]) def test_file_write_read(self, semihost_builder, delete_testfile, writeData, pos, readLen, readResult): fd = semihost_builder.do_open("testfile", 'w+b') assert fd != 0 and fd > 3 if len(writeData): result = semihost_builder.do_write(fd, writeData) assert result == 0 result = semihost_builder.do_flen(fd) assert result == len(writeData) if pos != -1: result = semihost_builder.do_seek(fd, pos) assert result == 0 result, data = semihost_builder.do_read(fd, readLen) assert result == readResult assert data == writeData[pos:pos + readLen] result = semihost_builder.do_close(fd) assert result == 0 def test_console_write(self, semihost_builder): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) result = semihost_builder.do_write(semihost.STDOUT_FD, 'hello world') assert result == 0 assert console.get_output_data(semihost.STDOUT_FD) == 'hello world' def test_console_writec(self, semihost_builder): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) for c in 'abcdef': result = semihost_builder.do_writec(c) assert result == 0 assert console.get_output_data(semihost.STDOUT_FD) == 'abcdef' def test_console_write0(self, semihost_builder): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) result = semihost_builder.do_write0('this is a string') assert result == 0 assert console.get_output_data(semihost.STDOUT_FD) == 'this is a string' @pytest.mark.parametrize(("data", "readlen"), [ ("12345678", 8), ("hi", 2), ("hello", 3), ("", 4), ("abcd", 0) ]) def test_console_read(self, semihost_builder, data, readlen): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) console.set_input_data(semihost.STDIN_FD, data) result, resultData = semihost_builder.do_read(semihost.STDIN_FD, readlen) assert result == (readlen - min(readlen, len(data))) expectedData = data[:min(len(data), readlen)] assert resultData == expectedData def test_console_readc(self, semihost_builder): console = RecordingSemihostIOHandler() agent = semihost.SemihostAgent(semihost_builder.ctx, console=console) semihost_builder.set_agent(agent) console.set_input_data(semihost.STDIN_FD, 'x') result = semihost_builder.do_no_args_call(semihost.TARGET_SYS_READC) assert chr(result) == 'x' def test_clock(self, semihost_builder): result = semihost_builder.do_no_args_call(semihost.TARGET_SYS_CLOCK) assert result != -1 assert result != 0 logging.info("clock = %d cs", result) result2 = semihost_builder.do_no_args_call(semihost.TARGET_SYS_CLOCK) assert result2 != -1 assert result2 != 0 assert result2 > result logging.info("clock = %d cs", result2) def test_time(self, semihost_builder): result = semihost_builder.do_no_args_call(semihost.TARGET_SYS_TIME) assert result != 0 logging.info("time = %d sec", result) def test_errno_no_err(self, semihost_builder): result = semihost_builder.do_no_args_call(semihost.TARGET_SYS_ERRNO) assert result == 0 @pytest.mark.parametrize(("fd"), [ (semihost.STDIN_FD), (semihost.STDOUT_FD), (semihost.STDERR_FD), ]) def test_istty_stdio(self, semihost_builder, fd): result = semihost_builder.do_istty(fd) assert result == 1 def test_istty_non_stdio(self, semihost_builder, delete_testfile): fd = semihost_builder.do_open("testfile", 'w+b') assert fd != 0 and fd > 3 result = semihost_builder.do_istty(fd) assert result == 0 result = semihost_builder.do_close(fd) assert result == 0 @pytest.fixture(scope='function') def telnet(request): telnet = semihost.TelnetSemihostIOHandler(4444) def stopit(): telnet.stop() request.addfinalizer(stopit) return telnet @pytest.fixture(scope='function') def semihost_telnet_agent(ctx, telnet, request): agent = semihost.SemihostAgent(ctx, console=telnet) def cleanup(): agent.cleanup() request.addfinalizer(cleanup) return agent @pytest.fixture(scope='function') def semihost_telnet_builder(tgt, semihost_telnet_agent, ramrgn): return SemihostRequestBuilder(tgt, semihost_telnet_agent, ramrgn) @pytest.fixture(scope='function') def telnet_conn(request): from time import sleep # Sleep for a bit to ensure the semihost telnet server has started up in its own thread. sleep(0.25) telnet = telnetlib.Telnet('localhost', 4444, 10.0) def cleanup(): telnet.close() request.addfinalizer(cleanup) return telnet class TestSemihostingTelnet: def test_connect(self, semihost_telnet_builder, telnet_conn): result = semihost_telnet_builder.do_no_args_call(semihost.TARGET_SYS_ERRNO) assert result == 0 def test_write(self, semihost_telnet_builder, telnet_conn): result = semihost_telnet_builder.do_write(semihost.STDOUT_FD, 'hello world') assert result == 0 index, _, text = telnet_conn.expect(['hello world']) assert index != -1 assert text == 'hello world' def test_writec(self, semihost_telnet_builder, telnet_conn): for c in 'xyzzy': result = semihost_telnet_builder.do_writec(c) assert result == 0 index, _, text = telnet_conn.expect([c]) assert index != -1 assert text == c def test_write0(self, semihost_telnet_builder, telnet_conn): result = semihost_telnet_builder.do_write0('hello world') assert result == 0 index, _, text = telnet_conn.expect(['hello world']) assert index != -1 assert text == 'hello world' def test_read(self, semihost_telnet_builder, telnet_conn): telnet_conn.write('hello world') result, data = semihost_telnet_builder.do_read(semihost.STDIN_FD, 11) assert result == 0 assert data == 'hello world' def test_readc(self, semihost_telnet_builder, telnet_conn): telnet_conn.write('xyz') for c in 'xyz': rc = semihost_telnet_builder.do_no_args_call(semihost.TARGET_SYS_READC) assert chr(rc) == c class TestSemihostAgent: def test_no_io_handler(self, ctx): a = semihost.SemihostAgent(ctx, io_handler=None, console=None) assert type(a.io_handler) is semihost.SemihostIOHandler assert type(a.console) is semihost.SemihostIOHandler assert a.console is a.io_handler def test_only_io_handler(self, ctx): c = RecordingSemihostIOHandler() a = semihost.SemihostAgent(ctx, io_handler=c, console=None) assert a.io_handler is c assert a.console is c def test_only_console(self, ctx): c = RecordingSemihostIOHandler() a = semihost.SemihostAgent(ctx, io_handler=None, console=c) assert type(a.io_handler) is semihost.SemihostIOHandler assert a.console is c @pytest.fixture def ioh(ctx): handler = semihost.SemihostIOHandler() agent = semihost.SemihostAgent(ctx, io_handler=handler) return handler, agent class TestSemihostIOHandlerBase: @pytest.mark.parametrize(("filename", "mode", "expectedFd"), [ (":tt", 'r', semihost.STDIN_FD), (":tt", 'w', semihost.STDOUT_FD), (":tt", 'a', semihost.STDERR_FD), (":tt", 'r+b', -1), ("somefile", 'r+b', None), ]) def test_std_open(self, ctx, ramrgn, ioh, filename, mode, expectedFd): handler, agent = ioh ctx.write_memory_block8(ramrgn.start, bytearray(filename) + bytearray('\x00')) assert handler._std_open(ramrgn.start, len(filename), mode) == (expectedFd, filename) @pytest.mark.parametrize(("op", "args"), [ ('open', (0, 0, 'r')), ('close', (1,)), ('write', (1, 0, 0)), ('read', (1, 0, 0)), ('readc', tuple()), ('istty', (1,)), ('seek', (1, 0)), ('flen', (1,)), ('remove', (0, 0)), ('rename', (0, 0, 0, 0)), ]) def test_unimplemented(self, op, args): handler = semihost.SemihostIOHandler() with pytest.raises(NotImplementedError): handler.__getattribute__(op)(*args) pyocd-0.13.1/pyocd/test/mockcore.py0000644000175000017500000001103513373511253017066 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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 pyocd.debug.cache import MemoryCache from pyocd.debug.context import DebugContext from pyocd.coresight.cortex_m import ( CORE_REGISTER, register_name_to_index, is_cfbp_subregister, is_psr_subregister, sysm_to_psr_mask ) from pyocd.core import memory_map from pyocd.utility import conversion from pyocd.utility import mask import pytest import logging class MockCore(object): def __init__(self): self.run_token = 1 self.flash_region = memory_map.FlashRegion(start=0, length=1*1024, blocksize=1024, name='flash') self.ram_region = memory_map.RamRegion(start=0x20000000, length=1*1024, name='ram') self.ram2_region = memory_map.RamRegion(start=0x20000400, length=1*1024, name='ram2', is_cacheable=False) self.memory_map = memory_map.MemoryMap( self.flash_region, self.ram_region, self.ram2_region ) self.ram = bytearray(1024) self.ram2 = bytearray(1024) self.flash = bytearray([0xff]) * 1024 self.regions = [(self.flash_region, self.flash), (self.ram_region, self.ram), (self.ram2_region, self.ram2)] self.has_fpu = True self.clear_all_regs() def clear_all_regs(self): self.regs = {i:0 for i in range(0, 19)} # r0-15, xpsr, msp, psp self.regs[CORE_REGISTER['cfbp']] = 0 def is_running(self): return False def read_core_registers_raw(self, reg_list): reg_list = [register_name_to_index(reg) for reg in reg_list] results = [] for r in reg_list: if is_cfbp_subregister(r): v = self.regs[CORE_REGISTER['cfbp']] v = (v >> ((-r - 1) * 8)) & 0xff elif is_psr_subregister(r): v = self.regs[CORE_REGISTER['xpsr']] v &= sysm_to_psr_mask(r) else: if r not in self.regs: self.regs[r] = 0 v = self.regs[r] results.append(v) # logging.info("mockcore[%x]:read(%s)=%s", id(self), reg_list, results) return results def write_core_registers_raw(self, reg, data): reg = [register_name_to_index(r) for r in reg] # logging.info("mockcore[%x]:write(%s, %s)", id(self), reg, data) for r, v in zip(reg, data): if is_cfbp_subregister(r): shift = (-r - 1) * 8 mask = 0xffffffff ^ (0xff << shift) data = (self.regs[CORE_REGISTER['cfbp']] & mask) | ((v & 0xff) << shift) self.regs[CORE_REGISTER['cfbp']] = data elif is_psr_subregister(r): mask = sysm_to_psr_mask(r) data = (self.regs[CORE_REGISTER['xpsr']] & (0xffffffff ^ mask)) | (v & mask) self.regs[CORE_REGISTER['xpsr']] = data else: self.regs[r] = v def read_memory(self, addr, transfer_size=32, now=True): if transfer_size == 8: return 0x12 elif transfer_size == 16: return 0x1234 elif transfer_size == 32: return 0x12345678 def read_memory_block8(self, addr, size): for r, m in self.regions: if r.contains_range(addr, length=size): addr -= r.start return list(m[addr:addr+size]) return [0x55] * size def read_memory_block32(self, addr, size): return conversion.byte_list_to_u32le_list(self.read_memory_block8(addr, size*4)) def write_memory(self, addr, value, transfer_size=32): return True def write_memory_block8(self, addr, value): for r, m in self.regions: if r.contains_range(addr, length=len(value)): addr -= r.start m[addr:addr+len(value)] = value return True return False def write_memory_block32(self, addr, data): return self.write_memory_block8(addr, conversion.u32le_list_to_byte_list(data)) pyocd-0.13.1/pyocd/test/test_timeout.py0000644000175000017500000000356213373511253020017 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger 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. """ from pyocd.utility.timeout import Timeout from time import (time, sleep) import pytest class TestTimeout: def test_no_timeout(self): with Timeout(0.05) as to: cnt = 0 while to.check(): sleep(0.01) cnt += 1 if cnt == 4: break else: assert False assert not to.did_time_out def test_timeout_a(self): s = time() with Timeout(0.05) as to: while to.check(): sleep(0.01) assert to.did_time_out assert (time() - s) >= 0.05 def test_timeout_b(self): timedout = False s = time() with Timeout(0.05) as to: cnt = 0 while cnt < 10: if to.did_time_out: timedout = True sleep(0.02) cnt += 1 assert timedout assert to.did_time_out assert (time() - s) >= 0.05 def test_timeout_c(self): timedout = False with Timeout(0.05) as to: cnt = 0 while cnt < 10: if to.did_time_out: timedout = True cnt += 1 assert not timedout assert not to.did_time_out pyocd-0.13.1/pyocd/test/test_memcache.py0000644000175000017500000001432613373511253020073 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 pyocd.debug.cache import MemoryCache from pyocd.debug.context import DebugContext from pyocd.core import memory_map from pyocd.utility import conversion from pyocd.utility import mask import pytest import logging @pytest.fixture(scope='function') def memcache(mockcore): return MemoryCache(DebugContext(mockcore)) class TestMemoryCache: def test_1(self, mockcore, memcache): memcache.write_memory_block8(0, [0x10, 0x12, 0x14, 0x16]) assert memcache.read_memory_block8(0, 4) == [0x10, 0x12, 0x14, 0x16] def test_2(self, mockcore, memcache): memcache.write_memory_block8(0, [0x10, 0x12, 0x14, 0x16]) assert memcache.read_memory_block8(0, 4) == [0x10, 0x12, 0x14, 0x16] assert memcache.read_memory_block8(2, 4) == [0x14, 0x16, 0xff, 0xff] def test_3(self, mockcore, memcache): memcache.write_memory_block32(0, [0x10121416]) assert memcache.read_memory_block32(0, 1) == [0x10121416] assert memcache.read_memory_block8(2, 4) == [0x12, 0x10, 0xff, 0xff] def test_4(self, mockcore, memcache): mockcore.write_memory_block8(0, [1, 2, 3, 4]) assert memcache.read_memory_block8(0, 8) == [1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff] assert memcache.read_memory_block8(4, 4) == [0xff] * 4 mockcore.write_memory_block8(10, [50, 51]) assert memcache.read_memory_block8(6, 6) == [0xff, 0xff, 0xff, 0xff, 50, 51] def test_5(self, mockcore, memcache): memcache.write_memory_block8(0, [1, 2]) memcache.write_memory_block8(4, [3, 4]) assert memcache.read_memory_block8(0, 8) == [1, 2, 0xff, 0xff, 3, 4, 0xff, 0xff] def test_6_middle_cached(self, mockcore, memcache): mockcore.write_memory_block8(0, [50, 51, 52, 53, 54, 55, 56, 57]) memcache.write_memory_block8(4, [3, 4]) assert memcache.read_memory_block8(0, 8) == [50, 51, 52, 53, 3, 4, 56, 57] def test_7_odd_cached(self, mockcore, memcache): mockcore.write_memory_block8(0, [50, 51, 52, 53, 54, 55, 56, 57]) memcache.write_memory_block8(1, [1]) memcache.write_memory_block8(3, [2]) memcache.write_memory_block8(5, [3]) memcache.write_memory_block8(7, [4]) assert memcache.read_memory_block8(0, 8) == [50, 1, 52, 2, 54, 3, 56, 4] def test_8_no_overlap(self, mockcore, memcache): memcache.write_memory_block8(0, [1, 2, 3, 4]) assert memcache.read_memory_block8(8, 4) == [0xff] * 4 def test_9_begin_overlap(self, mockcore, memcache): memcache.write_memory_block8(4, range(8)) assert memcache.read_memory_block8(0, 8) == [0xff, 0xff, 0xff, 0xff, 0, 1, 2, 3] def test_10_end_overlap(self, mockcore, memcache): memcache.write_memory_block8(0, range(8)) assert memcache.read_memory_block8(4, 8) == [4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff] def test_11_full_overlap(self, mockcore, memcache): memcache.write_memory_block8(0, range(8)) assert memcache.read_memory_block8(0, 8) == list(range(8)) def test_12_begin(self, mockcore, memcache): memcache.write_memory_block8(8, [1, 2, 3, 4]) assert memcache.read_memory_block8(7, 1) == [0xff] assert memcache.read_memory_block8(8, 1) == [1] def test_13_end(self, mockcore, memcache): memcache.write_memory_block8(0, [1, 2, 3, 4]) assert memcache.read_memory_block8(3, 1) == [4] assert memcache.read_memory_block8(4, 1) == [0xff] def test_14_write_begin_ragged_cached(self, mockcore, memcache): memcache.write_memory_block8(4, [1, 2, 3, 4]) mockcore.write_memory_block8(8, [90, 91, 92, 93]) memcache.write_memory_block8(6, [55, 56, 57, 58]) assert memcache.read_memory_block8(4, 8) == [1, 2, 55, 56, 57, 58, 92, 93] def test_15_write_end_ragged_cached(self, mockcore, memcache): memcache.write_memory_block8(4, [1, 2, 3, 4]) mockcore.write_memory_block8(0, [90, 91, 92, 93]) memcache.write_memory_block8(2, [55, 56, 57, 58]) assert memcache.read_memory_block8(0, 8) == [90, 91, 55, 56, 57, 58, 3, 4] def test_16_no_mem_region(self, mockcore, memcache): assert memcache.read_memory_block8(0x30000000, 4) == [0x55] * 4 # Make sure we didn't cache anything. assert memcache._cache.search(0x30000000, 0x30000004) == set() def test_17_noncacheable_region_read(self, mockcore, memcache): mockcore.write_memory_block8(0x20000410, [90, 91, 92, 93]) assert memcache.read_memory_block8(0x20000410, 4) == [90, 91, 92, 93] # Make sure we didn't cache anything. assert memcache._cache.search(0x20000410, 0x20000414) == set() def test_18_noncacheable_region_write(self, mockcore, memcache): memcache.write_memory_block8(0x20000410, [1, 2, 3, 4]) mockcore.write_memory_block8(0x20000410, [90, 91, 92, 93]) assert memcache.read_memory_block8(0x20000410, 4) == [90, 91, 92, 93] # Make sure we didn't cache anything. assert memcache._cache.search(0x20000410, 0x20000414) == set() def test_19_write_into_cached(self, mockcore, memcache): mockcore.write_memory_block8(4, [1, 2, 3, 4, 5, 6, 7, 8]) assert memcache.read_memory_block8(4, 8) == [1, 2, 3, 4, 5, 6, 7, 8] memcache.write_memory_block8(6, [128, 129, 130, 131]) assert memcache.read_memory_block8(4, 8) == [1, 2, 128, 129, 130, 131, 7, 8] assert len(list(memcache._cache.search(4, 12))[0].data) == 8 def test_20_empty_read(self, memcache): assert memcache.read_memory_block8(128, 0) == [] def test_21_empty_write(self, memcache): memcache.write_memory_block8(128, []) # TODO test read32/16/8 with and without callbacks pyocd-0.13.1/pyocd/core/0000755000175000017500000000000013373523011014656 5ustar neilneil00000000000000pyocd-0.13.1/pyocd/core/helpers.py0000644000175000017500000002434313373511253016705 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 __future__ import print_function from .session import Session from ..probe.aggregator import DebugProbeAggregator from time import sleep import colorama import six # Init colorama here since this is currently the only module that uses it. colorama.init() ## @brief Helper class for streamlining the probe discovery and session creation process. # # This class provides several static methods that wrap the DebugProbeAggregator methods # with a simple command-line user interface, or provide a single method that performs # a common access pattern. class ConnectHelper(object): ## @brief Return a list of Session objects for all connected debug probes. # # This method is useful for listing detailed information about connected probes, especially # those that have associated boards, as the Session object will have a Board instance. # # The returned list of sessions is sorted by the combination of the debug probe's # description and unique ID. # # @param blocking Specifies whether to wait for a probe to be connected if there are no # available probes. # @param unique_id String to match against probes' unique IDs using a contains match. If the # default of None is passed, then all available probes are matched. # @param options Dictionary of user options. # @param kwargs User options passed as keyword arguments. # # @return A list of Session objects. The returned Session objects are not yet active, in that # open() has not yet been called. If _blocking_ is True, the list will contain at least # one session. If _blocking_ is False and there are no probes connected then an empty list # will be returned. @staticmethod def get_sessions_for_all_connected_probes(blocking=True, unique_id=None, options=None, **kwargs): probes = ConnectHelper.get_all_connected_probes(blocking=blocking, unique_id=unique_id) sessions = [Session(probe, options=options, **kwargs) for probe in probes] return sessions ## @brief Return a list of DebugProbe objects for all connected debug probes. # # The returned list of debug probes is always sorted by the combination of the probe's # description and unique ID. # # @param blocking Specifies whether to wait for a probe to be connected if there are no # available probes. A message will be printed # @param unique_id String to match against probes' unique IDs using a contains match. If the # default of None is passed, then all available probes are matched. # @param print_wait_message Whether to print a message to the command line when waiting for a # probe to be connected and _blocking_ is True. # # @return A list of DebugProbe instances. If _blocking_ is True, the list will contain at least # one probe. If _blocking_ is False and there are no probes connected then an empty list # will be returned. @staticmethod def get_all_connected_probes(blocking=True, unique_id=None, print_wait_message=True): printedMessage = False while True: allProbes = DebugProbeAggregator.get_all_connected_probes(unique_id=unique_id) sortedProbes = sorted(allProbes, key=lambda probe:probe.description + probe.unique_id) if not blocking: break elif len(sortedProbes): break else: if print_wait_message and not printedMessage: print(colorama.Fore.YELLOW + "Waiting for a debug probe to be connected..." + colorama.Style.RESET_ALL) printedMessage = True sleep(0.01) assert len(sortedProbes) == 0 return sortedProbes ## @brief List the connected debug probes. # # @return List of zero or more DebugProbe objects that are currently connected, sorted by the # combination of the probe's description and unique ID. @staticmethod def list_connected_probes(): allProbes = ConnectHelper.get_all_connected_probes(blocking=False) if len(allProbes): ConnectHelper._print_probe_list(allProbes) else: print(colorama.Fore.RED + "No available debug probes are connected" + colorama.Style.RESET_ALL) ## @brief Create a session with a probe possibly chosen by the user. # # This method provides an easy to use command line interface for selecting one of the # connected debug probes, then creating and opening a Session instance. It has several # parameters that control filtering of probes by unique ID, automatic selection of the first # discovered probe, and whether to automaticallty open the created Session. In addition, you # can pass user options to the Session either with the _options_ parameter or directly as # keyword arguments. # # If, after application of the _unique_id_ and _return_first_ parameter, there are still # multiple debug probes to choose from, the user is presented with a simple command-line UI # to select a probe (or abort the selection process). # # @param blocking Specifies whether to wait for a probe to be connected if there are no # available probes. # @param return_first If more than one probe is connected, a _return_first_ of True will select # the first discovered probe rather than present a selection choice to the user. # @param unique_id String to match against probes' unique IDs using a contains match. If the # default of None is passed, then all available probes are matched. # @param board_id Deprecated alias of _unique_id_. # @param open_session Indicates whether the returned Session object should be opened for the # caller. If opening causes an exception, the Session will be automatically closed. # @param init_board Deprecated alias of _open_session_. # @param options Dictionary of user options. # @param kwargs User options passed as keyword arguments. # # @return Either None or a Session instance. If _open_session_ is True then the session will # have already been opened, the board and target initialized, and is ready to be used. @staticmethod def session_with_chosen_probe(blocking=True, return_first=False, unique_id=None, board_id=None, # board_id param is deprecated open_session=True, init_board=None, # init_board param is deprecated options=None, **kwargs): # Get all matching probes, sorted by name. board_id = unique_id or board_id allProbes = ConnectHelper.get_all_connected_probes(blocking=blocking, unique_id=board_id) # Print some help if the user specified a unique ID, but more than one probe matches. if (board_id is not None) and (len(allProbes) > 1) and not return_first: print(colorama.Fore.RED + "More than one debug probe matches unique ID '%s':" % board_id + colorama.Style.RESET_ALL) board_id = board_id.lower() for probe in allProbes: head, sep, tail = probe.unique_id.lower().rpartition(board_id) highlightedId = head + colorama.Fore.RED + sep + colorama.Style.RESET_ALL + tail print("%s | %s" % ( probe.description, highlightedId)) return None # Return if no boards are connected. if allProbes is None or len(allProbes) == 0: if board_id is None: print("No connected debug probes") else: print("A debug probe matching unique ID '%s' is not connected, or no connected probe matches" % board_id) return None # No boards to close so it is safe to return # Select first board if return_first: allProbes = allProbes[0:1] # Ask user to select boards if there is more than 1 left if len(allProbes) > 1: ConnectHelper._print_probe_list(allProbes) print(colorama.Fore.RED + " q => Quit") while True: print(colorama.Style.RESET_ALL) print("Enter the number of the debug probe to connect:") line = six.moves.input("> ") valid = False if line.strip().lower() == 'q': return None try: ch = int(line) valid = 0 <= ch < len(allProbes) except ValueError: pass if not valid: print(colorama.Fore.YELLOW + "Invalid choice: %s\n" % line) Session._print_probe_list(allProbes) print(colorama.Fore.RED + " q => Exit" + colorama.Style.RESET_ALL) else: break allProbes = allProbes[ch:ch + 1] # Let deprecated init_board override open_session if it was specified. if init_board is not None: open_session = init_board assert len(allProbes) == 1 session = Session(allProbes[0], options=options, **kwargs) if open_session: try: session.open() except: session.close() raise return session @staticmethod def _print_probe_list(probes): print(colorama.Fore.BLUE + "## => Board Name | Unique ID") print("-- -- ----------------------") for index, probe in enumerate(probes): print(colorama.Fore.GREEN + "%2d => %s | " % (index, probe.description) + colorama.Fore.CYAN + probe.unique_id + colorama.Style.RESET_ALL) print(colorama.Style.RESET_ALL, end='') pyocd-0.13.1/pyocd/core/coresight_target.py0000644000175000017500000002342513373511253020600 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 .target import Target from ..coresight import (dap, cortex_m, rom_table) from ..debug.svd import (SVDFile, SVDLoader) from ..debug.context import DebugContext from ..debug.cache import CachingDebugContext from ..debug.elf.elf import ELFBinaryFile from ..debug.elf.flash_reader import FlashReaderContext from ..utility.notification import Notification from ..utility.sequencer import CallSequence import logging ## # @brief Represents a chip that uses CoreSight debug infrastructure. # # An instance of this class is the root of the chip-level object graph. It has child # nodes for the DP and all cores. As a concrete subclass of Target, it provides methods # to control the device, access memory, adjust breakpoints, and so on. # # For single core devices, the CoreSightTarget has mostly equivalent functionality to # the CortexM object for the core. Multicore devices work differently. This class tracks # a "selected core", to which all actions are directed. The selected core can be changed # at any time. You may also directly access specific cores and perform operations on them. class CoreSightTarget(Target): def __init__(self, session, memoryMap=None): super(CoreSightTarget, self).__init__(session, memoryMap) self.root_target = self self.part_number = self.__class__.__name__ self.cores = {} self.dp = dap.DebugPort(session.probe, self) self._selected_core = 0 self._svd_load_thread = None self._root_contexts = {} self._new_core_num = 0 self._elf = None self._irq_table = None @property def selected_core(self): return self.cores[self._selected_core] @property def elf(self): return self._elf @elf.setter def elf(self, filename): if filename is None: self._elf = None else: self._elf = ELFBinaryFile(filename, self.memory_map) self.cores[0].elf = self._elf self.cores[0].set_target_context(FlashReaderContext(self.cores[0].get_target_context(), self._elf)) def select_core(self, num): if num not in self.cores: raise ValueError("invalid core number") logging.debug("selected core #%d" % num) self._selected_core = num @property def aps(self): return self.dp.aps @property ## @brief Waits for SVD file to complete loading before returning. def svd_device(self): if not self._svd_device and self._svd_load_thread: logging.debug("Waiting for SVD load to complete") self._svd_device = self._svd_load_thread.device return self._svd_device def load_svd(self): def svd_load_completed_cb(svdDevice): # logging.debug("Completed loading SVD") self._svd_device = svdDevice self._svd_load_thread = None if not self._svd_device and self._svd_location: # logging.debug("Started loading SVD") # Spawn thread to load SVD in background. self._svd_load_thread = SVDLoader(self._svd_location, svd_load_completed_cb) self._svd_load_thread.load() def add_core(self, core): core.halt_on_connect = self.halt_on_connect core.set_target_context(CachingDebugContext(DebugContext(core))) self.cores[core.core_number] = core self._root_contexts[core.core_number] = None def create_init_sequence(self): seq = CallSequence( ('load_svd', self.load_svd), ('dp_init', self.dp.init), ('power_up', self.dp.power_up_debug), ('find_aps', self.dp.find_aps), ('create_aps', self.dp.create_aps), ('init_ap_roms', self.dp.init_ap_roms), ('create_cores', self.create_cores), ('create_components', self.create_components), ('notify', lambda : self.notify(Notification(event=Target.EVENT_POST_CONNECT, source=self))) ) return seq def init(self): # Create and execute the init sequence. seq = self.create_init_sequence() seq.invoke() def _create_component(self, cmpid): cmp = cmpid.factory(cmpid.ap, cmpid, cmpid.address) cmp.init() def create_cores(self): self._new_core_num = 0 self._apply_to_all_components(self._create_component, filter=lambda c: c.factory == cortex_m.CortexM.factory) def create_components(self): self._apply_to_all_components(self._create_component, filter=lambda c: c.factory is not None and c.factory != cortex_m.CortexM.factory) def _apply_to_all_components(self, action, filter=None): # Iterate over every top-level ROM table. for ap in [x for x in self.dp.aps.values() if x.has_rom_table]: ap.rom_table.for_each(action, filter) def disconnect(self, resume=True): self.notify(Notification(event=Target.EVENT_PRE_DISCONNECT, source=self)) for core in self.cores.values(): core.disconnect(resume) self.dp.power_down_debug() @property def run_token(self): return self.selected_core.run_token def halt(self): return self.selected_core.halt() def step(self, disable_interrupts=True): return self.selected_core.step(disable_interrupts) def resume(self): return self.selected_core.resume() def mass_erase(self): if self.flash is not None: self.flash.init() self.flash.erase_all() return True else: return False def write_memory(self, addr, value, transfer_size=32): return self.selected_core.write_memory(addr, value, transfer_size) def read_memory(self, addr, transfer_size=32, now=True): return self.selected_core.read_memory(addr, transfer_size, now) def write_memory_block8(self, addr, value): return self.selected_core.write_memory_block8(addr, value) def write_memory_block32(self, addr, data): return self.selected_core.write_memory_block32(addr, data) def read_memory_block8(self, addr, size): return self.selected_core.read_memory_block8(addr, size) def read_memory_block32(self, addr, size): return self.selected_core.read_memory_block32(addr, size) def read_core_register(self, id): return self.selected_core.read_core_register(id) def write_core_register(self, id, data): return self.selected_core.write_core_register(id, data) def read_core_register(self, reg): return self.selected_core.read_core_register(reg) def read_core_registers_raw(self, reg_list): return self.selected_core.read_core_registers_raw(reg_list) def write_core_register(self, reg, data): self.selected_core.write_core_register(reg, data) def write_core_registers_raw(self, reg_list, data_list): self.selected_core.write_core_registers_raw(reg_list, data_list) def find_breakpoint(self, addr): return self.selected_core.find_breakpoint(addr) def set_breakpoint(self, addr, type=Target.BREAKPOINT_AUTO): return self.selected_core.set_breakpoint(addr, type) def get_breakpoint_type(self, addr): return self.selected_core.get_breakpoint_type(addr) def remove_breakpoint(self, addr): return self.selected_core.remove_breakpoint(addr) def set_watchpoint(self, addr, size, type): return self.selected_core.set_watchpoint(addr, size, type) def remove_watchpoint(self, addr, size, type): return self.selected_core.remove_watchpoint(addr, size, type) def reset(self, software_reset=None): return self.selected_core.reset(software_reset=software_reset) def reset_stop_on_reset(self, software_reset=None): return self.selected_core.reset_stop_on_reset(software_reset) def set_target_state(self, state): return self.selected_core.set_target_state(state) def get_state(self): return self.selected_core.get_state() def get_memory_map(self): return self.memory_map def set_vector_catch(self, enableMask): return self.selected_core.set_vector_catch(enableMask) def get_vector_catch(self): return self.selected_core.get_vector_catch() # GDB functions def get_target_xml(self): return self.selected_core.get_target_xml() def get_target_context(self, core=None): if core is None: core = self._selected_core return self.cores[core].get_target_context() def get_root_context(self, core=None): if core is None: core = self._selected_core if self._root_contexts[core] is None: return self.get_target_context() else: return self._root_contexts[core] def set_root_context(self, context, core=None): if core is None: core = self._selected_core self._root_contexts[core] = context @property def irq_table(self): if self._irq_table is None: if self.svd_device is not None: self._irq_table = {i.value : i.name for i in [i for p in self.svd_device.peripherals for i in p.interrupts]} return self._irq_table pyocd-0.13.1/pyocd/core/memory_map.py0000644000175000017500000002511313373511253017404 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-2017 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 xml.etree import ElementTree __all__ = ['MemoryRange', 'MemoryRegion', 'MemoryMap', 'RamRegion', 'RomRegion', 'FlashRegion', 'DeviceRegion', 'AliasRegion'] MAP_XML_HEADER = b""" """ def check_range(start, end=None, length=None, range=None): assert (start is not None) and ((isinstance(start, MemoryRange) or range is not None) or ((end is not None) ^ (length is not None))) if isinstance(start, MemoryRange): range = start if range is not None: start = range.start end = range.end elif end is None: end = start + length - 1 return start, end ## @brief A range of memory within a region. class MemoryRangeBase(object): def __init__(self, start=0, end=0, length=0, region=None): self._start = start if length != 0: self._end = self._start + length - 1 else: self._end = end self._region = region @property def start(self): return self._start @property def end(self): return self._end @property def length(self): return self._end - self._start + 1 @property def region(self): return self._region def contains_address(self, address): return (address >= self.start) and (address <= self.end) ## # @return Whether the given range is fully contained by the region. def contains_range(self, start, end=None, length=None, range=None): start, end = check_range(start, end, length, range) return self.contains_address(start) and self.contains_address(end) ## # @return Whether the region is fully within the bounds of the given range. def contained_by_range(self, start, end=None, length=None, range=None): start, end = check_range(start, end, length, range) return start <= self.start and end >= self.end ## # @return Whether the region and the given range intersect at any point. def intersects_range(self, start, end=None, length=None, range=None): start, end = check_range(start, end, length, range) return (start <= self.start and end >= self.start) or (start <= self.end and end >= self.end) \ or (start >= self.start and end <= self.end) ## @brief A range of memory within a region. class MemoryRange(MemoryRangeBase): def __init__(self, start=0, end=0, length=0, region=None): super(MemoryRange, self).__init__(start=start, end=end, length=length) self._region = region @property def region(self): return self._region def __repr__(self): return "<%s@0x%x start=0x%x end=0x%x length=0x%x region=%s>" % (self.__class__.__name__, id(self), self.start, self.end, self.length, self.region) ## @brief One contiguous range of memory. class MemoryRegion(MemoryRangeBase): def __init__(self, type='ram', start=0, end=0, length=0, blocksize=0, name='', is_boot_memory=False, is_powered_on_boot=True, is_cacheable=True, invalidate_cache_on_run=True, is_testable=True): super(MemoryRegion, self).__init__(start=start, end=end, length=length) self._type = type self._blocksize = blocksize if not name: self._name = self._type else: self._name = name self._is_boot_mem = is_boot_memory self._is_powered_on_boot = is_powered_on_boot self._is_cacheable = is_cacheable self._invalidate_cache_on_run = invalidate_cache_on_run self._is_testable = is_testable @property def type(self): return self._type @property def blocksize(self): return self._blocksize @property def name(self): return self._name @property def is_flash(self): return self._type == 'flash' @property def is_ram(self): return self._type == 'ram' @property def is_rom(self): return self._type == 'rom' @property def is_device(self): return self._type == 'device' @property def is_alias(self): return self._type == 'alias' @property def is_boot_memory(self): return self._is_boot_mem @property def is_powered_on_boot(self): return self._is_powered_on_boot @property def is_cacheable(self): return self._is_cacheable @property def invalidate_cache_on_run(self): return self._invalidate_cache_on_run @property def is_testable(self): return self._is_testable def __repr__(self): return "<%s@0x%x name=%s type=%s start=0x%x end=0x%x length=0x%x blocksize=0x%x>" % (self.__class__.__name__, id(self), self.name, self.type, self.start, self.end, self.length, self.blocksize) ## @brief Contiguous region of RAM. class RamRegion(MemoryRegion): def __init__(self, start=0, end=0, length=0, name='', is_boot_memory=False, is_powered_on_boot=True, is_cacheable=True, invalidate_cache_on_run=True, is_testable=True): super(RamRegion, self).__init__(type='ram', start=start, end=end, length=length, name=name, is_boot_memory=is_boot_memory, is_powered_on_boot=is_powered_on_boot, is_cacheable=is_cacheable, invalidate_cache_on_run=invalidate_cache_on_run, is_testable=is_testable) ## @brief Contiguous region of ROM. class RomRegion(MemoryRegion): def __init__(self, start=0, end=0, length=0, name='', is_boot_memory=False, is_powered_on_boot=True, is_cacheable=True, invalidate_cache_on_run=False, is_testable=True): super(RomRegion, self).__init__(type='rom', start=start, end=end, length=length, name=name, is_boot_memory=is_boot_memory, is_powered_on_boot=is_powered_on_boot, is_cacheable=is_cacheable, invalidate_cache_on_run=invalidate_cache_on_run, is_testable=is_testable) ## @brief Contiguous region of flash memory. class FlashRegion(MemoryRegion): def __init__(self, start=0, end=0, length=0, blocksize=0, name='', is_boot_memory=False, is_powered_on_boot=True, is_cacheable=True, invalidate_cache_on_run=True, is_testable=True): super(FlashRegion, self).__init__(type='flash', start=start, end=end, length=length, blocksize=blocksize, name=name, is_boot_memory=is_boot_memory, is_powered_on_boot=is_powered_on_boot, is_cacheable=is_cacheable, invalidate_cache_on_run=invalidate_cache_on_run, is_testable=is_testable) ## @brief Device or peripheral memory. class DeviceRegion(MemoryRegion): def __init__(self, start=0, end=0, length=0, name='', is_powered_on_boot=True): super(DeviceRegion, self).__init__(type='ram', start=start, end=end, length=length, name=name, is_boot_memory=False, is_powered_on_boot=is_powered_on_boot, is_cacheable=False, invalidate_cache_on_run=True, is_testable=False) ## @brief Alias of another region. class AliasRegion(MemoryRegion): def __init__(self, start=0, end=0, length=0, blocksize=0, name='', aliasOf=None, is_boot_memory=False, is_powered_on_boot=True, is_cacheable=True, invalidate_cache_on_run=True): super(AliasRegion, self).__init__(type='ram', start=start, end=end, length=length, name=name, is_boot_memory=is_boot_memory, is_powered_on_boot=is_powered_on_boot, is_cacheable=is_cacheable, invalidate_cache_on_run=invalidate_cache_on_run, is_testable=False) self._alias_reference = aliasOf @property def aliased_region(self): return self._alias_reference ## @brief Memory map consisting of memory regions. class MemoryMap(object): def __init__(self, *moreRegions): self._regions = [] if len(moreRegions): if type(moreRegions[0]) is list: self._regions = moreRegions[0] else: self._regions.extend(moreRegions) self._regions.sort(key=lambda x:x.start) @property def regions(self): return self._regions @property def region_count(self): return len(self._regions) def add_region(self, newRegion): self._regions.append(newRegion) self._regions.sort(key=lambda x:x.start) def get_boot_memory(self): for r in self._regions: if r.is_boot_memory: return r return None def get_region_for_address(self, address): for r in self._regions: if r.contains_address(address): return r return None def get_region_by_name(self, name): for r in self._regions: if r.name == name: return r return None def is_valid_address(self, address): return self.get_region_for_address(address) is not None def get_contained_regions(self, start, end=None, length=None, range=None): start, end = check_range(start, end, length, range) return [r for r in self._regions if r.contained_by_range(start, end)] def get_intersecting_regions(self, start, end=None, length=None, range=None): start, end = check_range(start, end, length, range) return [r for r in self._regions if r.intersects_range(start, end)] def get_regions_of_type(self, type): for r in self._regions: if r.type == type: yield r ## @brief Generate GDB memory map XML. def get_xml(self): root = ElementTree.Element('memory-map') for r in self._regions: mem = ElementTree.SubElement(root, 'memory', type=r.type, start=hex(r.start).rstrip("L"), length=hex(r.length).rstrip("L")) if r.is_flash: prop = ElementTree.SubElement(mem, 'property', name='blocksize') prop.text = hex(r.blocksize).rstrip("L") return MAP_XML_HEADER + ElementTree.tostring(root) ## @brief Enable iteration over the memory map. def __iter__(self): return iter(self._regions) def __repr__(self): return "" % (id(self), repr(self._regions)) pyocd-0.13.1/pyocd/core/__init__.py0000644000175000017500000000112713373511253016775 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2017 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. """ pyocd-0.13.1/pyocd/core/session.py0000644000175000017500000001370213373511253016723 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 ..board.board import Board import logging import logging.config import six import yaml DEFAULT_CLOCK_FREQ = 1000000 # 1 MHz log = logging.getLogger('session') ## @brief Top-level object for a debug session. # # This class represents a debug session with a single debug probe. It is the root of the object # graph, where it owns the debug probe and the board objects. # # Another important function of this class is that it contains a dictionary of session-scope # user options. These would normally be passed in from the command line, or perhaps a config file. # # See the ConnectHelper class for several methods that make it easy to create new # sessions, with or without user interaction in the case of multiple available debug probes. # # A Session instance can be used as a context manager. The session will *not* be automatically # opened. However, it will be closed when the `with` block is exited (which is harmless if the # session was never opened). A common pattern is to combine ConnectHelper.session_with_chosen_probe() # and a `with` block. Unless the `open_session` parameter to ConnectHelper.session_with_chosen_probe() # is changed from the default of True, the newly created Session will be opened for you prior to # entering the with block. # # Supported user options: # - auto_unlock # - config_file # - frequency # - halt_on_connect # - resume_on_disconnect # - target_override # - test_binary class Session(object): ## @brief Session constructor. # # Creates a new session using the provided debug probe. User options are merged from the # _options_ parameter and any keyword arguments. Normally a board instance is created that can # either be a generic board or a board associated with the debug probe. # # Passing in a _probe_ that is None is allowed. This is useful to create a session that operates # only as a container for user options. In this case, the board instance is not created, so the # #board attribute will be None. Such a Session cannot be opened. # # @param self # @param probe The DebugProbe instance. # @param options Optional user options dictionary. # @param kwargs User options passed as keyword arguments. def __init__(self, probe, options=None, **kwargs): self._probe = probe self._closed = True self._inited = False # Update options. self._options = options or {} self._options.update(kwargs) # Bail early if we weren't provided a probe. if probe is None: self._board = None return # Apply common configuration settings from the config file. config = self._get_config() probesConfig = config.pop('probes', None) self._options.update(config) # Pick up any config file options for this board. if probesConfig is not None: for uid, settings in probesConfig.items(): if uid.lower() in probe.unique_id.lower(): log.info("Using config settings for board %s" % (probe.unique_id)) self._options.update(settings) # Ask the probe if it has an associated board, and if not then we create a generic one. self._board = probe.create_associated_board(self) \ or Board(self, self._options.get('target_override', None)) def _get_config(self): # Load config file if one was provided via options. configPath = self._options.get('config_file', None) if isinstance(configPath, six.string_types): try: with open(configPath, 'r') as configFile: return yaml.safe_load(configFile) except IOError as err: log.warning("Error attempting to access board config file '%s': %s", configPath, err) return {} @property def is_open(self): return self._inited and not self._closed @property def probe(self): return self._probe @property def board(self): return self._board @property def options(self): return self._options def __enter__(self): assert self._probe is not None return self def __exit__(self, type, value, traceback): self.close() return False ## @brief Initialize the session def open(self): if not self._inited: assert self._probe is not None self._probe.open() self._probe.set_clock(self._options.get('frequency', DEFAULT_CLOCK_FREQ)) self._board.init() self._inited = True self._closed = False ## @brief Close the session. def close(self): if self._closed: return self._closed = True log.debug("uninit session %s", self) if self._inited: try: self.board.uninit() self._inited = False except: log.error("exception during board uninit:", exc_info=True) if self._probe.is_open: try: self._probe.disconnect() except: log.error("probe exception during disconnect:", exc_info=True) try: self._probe.close() except: log.error("probe exception during close:", exc_info=True) pyocd-0.13.1/pyocd/core/target.py0000644000175000017500000001273013373511253016526 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 .memory_interface import MemoryInterface from ..utility.notification import Notifier from .memory_map import MemoryMap class Target(MemoryInterface, Notifier): TARGET_RUNNING = 1 # Core is executing code. TARGET_HALTED = 2 # Core is halted in debug mode. TARGET_RESET = 3 # Core is being held in reset. TARGET_SLEEPING = 4 # Core is sleeping due to a wfi or wfe instruction. TARGET_LOCKUP = 5 # Core is locked up. # Types of breakpoints. # # Auto will select the best type given the # address and available breakpoints. BREAKPOINT_HW = 1 BREAKPOINT_SW = 2 BREAKPOINT_AUTO = 3 WATCHPOINT_READ = 1 WATCHPOINT_WRITE = 2 WATCHPOINT_READ_WRITE = 3 # Vector catch option masks. CATCH_NONE = 0 CATCH_HARD_FAULT = (1 << 0) CATCH_BUS_FAULT = (1 << 1) CATCH_MEM_FAULT = (1 << 2) CATCH_INTERRUPT_ERR = (1 << 3) CATCH_STATE_ERR = (1 << 4) CATCH_CHECK_ERR = (1 << 5) CATCH_COPROCESSOR_ERR = (1 << 6) CATCH_CORE_RESET = (1 << 7) CATCH_ALL = (CATCH_HARD_FAULT | CATCH_BUS_FAULT | CATCH_MEM_FAULT | CATCH_INTERRUPT_ERR \ | CATCH_STATE_ERR | CATCH_CHECK_ERR | CATCH_COPROCESSOR_ERR | CATCH_CORE_RESET) # Events EVENT_POST_CONNECT = 1 EVENT_PRE_DISCONNECT = 2 EVENT_PRE_RUN = 3 # data is run type EVENT_POST_RUN = 4 # data is run type EVENT_PRE_HALT = 5 # data is halt reason EVENT_POST_HALT = 6 # data is halt reason EVENT_PRE_RESET = 7 EVENT_POST_RESET = 8 EVENT_PRE_FLASH_PROGRAM = 9 EVENT_POST_FLASH_PROGRAM = 10 # Run types RUN_TYPE_RESUME = 1 RUN_TYPE_STEP = 2 # Halt reasons HALT_REASON_USER = 1 HALT_REASON_DEBUG = 2 def __init__(self, session, memoryMap=None): super(Target, self).__init__() self._session = session self.flash = None self.root_target = None self.part_number = "" self.memory_map = memoryMap or MemoryMap() self.halt_on_connect = session.options.get('halt_on_connect', True) self.auto_unlock = session.options.get('auto_unlock', True) self.has_fpu = False self._svd_location = None self._svd_device = None @property def session(self): return self._session @property def svd_device(self): return self._svd_device def is_locked(self): return False def create_init_sequence(self): raise NotImplementedError() def init(self): raise NotImplementedError() def disconnect(self, resume=True): pass def flush(self): self.session.probe.flush() def halt(self): raise NotImplementedError() def step(self, disable_interrupts=True): raise NotImplementedError() def resume(self): raise NotImplementedError() def mass_erase(self): raise NotImplementedError() def read_core_register(self, id): raise NotImplementedError() def write_core_register(self, id, data): raise NotImplementedError() def read_core_register(self, reg): raise NotImplementedError() def read_core_registers_raw(self, reg_list): raise NotImplementedError() def write_core_register(self, reg, data): raise NotImplementedError() def write_core_registers_raw(self, reg_list, data_list): raise NotImplementedError() def find_breakpoint(self, addr): raise NotImplementedError() def set_breakpoint(self, addr, type=BREAKPOINT_AUTO): raise NotImplementedError() def get_breakpoint_type(self, addr): raise NotImplementedError() def remove_breakpoint(self, addr): raise NotImplementedError() def set_watchpoint(self, addr, size, type): raise NotImplementedError() def remove_watchpoint(self, addr, size, type): raise NotImplementedError() def reset(self, software_reset=None): raise NotImplementedError() def reset_stop_on_reset(self, software_reset=None): raise NotImplementedError() def set_target_state(self, state): raise NotImplementedError() def get_state(self): raise NotImplementedError() @property def run_token(self): return 0 def is_running(self): return self.get_state() == Target.TARGET_RUNNING def is_halted(self): return self.get_state() == Target.TARGET_HALTED def get_memory_map(self): return self.memory_map def set_vector_catch(self, enableMask): raise NotImplementedError() def get_vector_catch(self): raise NotImplementedError() # GDB functions def get_target_xml(self): raise NotImplementedError() def get_target_context(self, core=None): raise NotImplementedError() def get_root_context(self, core=None): raise NotImplementedError() def set_root_context(self, context, core=None): raise NotImplementedError() pyocd-0.13.1/pyocd/core/memory_interface.py0000644000175000017500000001046713373511253020575 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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 ..utility import conversion ## @brief Interface for memory access. class MemoryInterface(object): ## @brief Write a single memory location. # # By default the transfer size is a word. def write_memory(self, addr, data, transfer_size=32): raise NotImplementedError() ## @brief Read a memory location. # # By default, a word will be read. def read_memory(self, addr, transfer_size=32, now=True): raise NotImplementedError() ## @brief Write an aligned block of 32-bit words. def write_memory_block32(self, addr, data): raise NotImplementedError() ## @brief Read an aligned block of 32-bit words. def read_memory_block32(self, addr, size): raise NotImplementedError() # @brief Shorthand to write a 32-bit word. def write32(self, addr, value): self.write_memory(addr, value, 32) # @brief Shorthand to write a 16-bit halfword. def write16(self, addr, value): self.write_memory(addr, value, 16) # @brief Shorthand to write a byte. def write8(self, addr, value): self.write_memory(addr, value, 8) # @brief Shorthand to read a 32-bit word. def read32(self, addr, now=True): return self.read_memory(addr, 32, now) # @brief Shorthand to read a 16-bit halfword. def read16(self, addr, now=True): return self.read_memory(addr, 16, now) # @brief Shorthand to read a byte. def read8(self, addr, now=True): return self.read_memory(addr, 8, now) ## @brief Read a block of unaligned bytes in memory. # @return an array of byte values def read_memory_block8(self, addr, size): res = [] # try to read 8bits data if (size > 0) and (addr & 0x01): mem = self.read8(addr) res.append(mem) size -= 1 addr += 1 # try to read 16bits data if (size > 1) and (addr & 0x02): mem = self.read16(addr) res.append(mem & 0xff) res.append((mem >> 8) & 0xff) size -= 2 addr += 2 # try to read aligned block of 32bits if (size >= 4): mem = self.read_memory_block32(addr, size // 4) res += conversion.u32le_list_to_byte_list(mem) size -= 4*len(mem) addr += 4*len(mem) if (size > 1): mem = self.read16(addr) res.append(mem & 0xff) res.append((mem >> 8) & 0xff) size -= 2 addr += 2 if (size > 0): mem = self.read8(addr) res.append(mem) return res ## @brief Write a block of unaligned bytes in memory. def write_memory_block8(self, addr, data): size = len(data) idx = 0 #try to write 8 bits data if (size > 0) and (addr & 0x01): self.write8(addr, data[idx]) size -= 1 addr += 1 idx += 1 # try to write 16 bits data if (size > 1) and (addr & 0x02): self.write16(addr, data[idx] | (data[idx+1] << 8)) size -= 2 addr += 2 idx += 2 # write aligned block of 32 bits if (size >= 4): data32 = conversion.byte_list_to_u32le_list(data[idx:idx + (size & ~0x03)]) self.write_memory_block32(addr, data32) addr += size & ~0x03 idx += size & ~0x03 size -= size & ~0x03 # try to write 16 bits data if (size > 1): self.write16(addr, data[idx] | (data[idx+1] << 8)) size -= 2 addr += 2 idx += 2 #try to write 8 bits data if (size > 0): self.write8(addr, data[idx]) pyocd-0.13.1/pyocd/core/exceptions.py0000644000175000017500000000373413373511253017425 0ustar neilneil00000000000000# pyOCD debugger # Copyright (c) 2018 Arm Limited # 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. class Error(RuntimeError): """Parent of all errors pyOCD can raise""" pass class ProbeError(Error): """Error communicating with device""" pass class TransferError(ProbeError): """Error ocurred with a transfer over SWD or JTAG""" pass class TransferTimeoutError(TransferError): """A SWD or JTAG timeout occurred""" pass class TransferFaultError(TransferError): """A SWD Fault occurred""" def __init__(self, faultAddress=None, length=None): super(TransferFaultError, self).__init__(faultAddress) self._address = faultAddress self._length = length @property def fault_address(self): return self._address @fault_address.setter def fault_address(self, addr): self._address = addr @property def fault_end_address(self): return (self._address + self._length - 1) if (self._length is not None) else self._address @property def fault_length(self): return self._length @fault_length.setter def fault_length(self, length): self._length = length def __str__(self): desc = "SWD/JTAG Transfer Fault" if self._address is not None: desc += " @ 0x%08x" % self._address if self._length is not None: desc += "-0x%08x" % self.fault_end_address return desc pyocd-0.13.1/pyocd.egg-info/0000755000175000017500000000000013373523011015420 5ustar neilneil00000000000000pyocd-0.13.1/pyocd.egg-info/PKG-INFO0000644000175000017500000002221113373523011016513 0ustar neilneil00000000000000Metadata-Version: 2.1 Name: pyocd Version: 0.13.1 Summary: Cortex-M debugger for Python Home-page: https://github.com/mbedmicro/pyOCD Author: Chris Reed, Martin Kojtal, Russ Butler Author-email: chris.reed@arm.com, martin.kojtal@arm.com, russ.butler@arm.com License: Apache 2.0 Description: pyOCD ===== pyOCD is an open source Python package for programming and debugging Arm Cortex-M microcontrollers using multiple supported types of USB debug probes. It is fully cross-platform, with support for Linux, macOS, and Windows. Several command line tools are provided that cover most use cases, or you can make use of the Python API to enable low-level target control. A common use for the Python API is to run and control CI tests. Three tools give you total control over your device: - `pyocd-gdbserver`: GDB remote server allows you to debug using gdb via either [GNU MCU Eclipse plug-in](https://gnu-mcu-eclipse.github.io/) or the console. - `pyocd-flashtool`: Program and erase an MCU's flash memory. - `pyocd-tool`: Interactive REPL control and inspection of the MCU. The API and tools provide these features: - halt, step, resume control - read/write memory - read/write core registers - set/remove hardware and software breakpoints - set/remove watchpoints - write to flash memory - load binary, hex, or ELF files into flash - reset control - access CoreSight DP and APs - and more! Requirements ------------ - Python 2.7.9 or later, or Python 3.6.0 or later - macOS, Linux, or Windows 7 or newer - Microcontroller with an Arm Cortex-M CPU - Supported debug probe - [CMSIS-DAP](http://www.keil.com/pack/doc/CMSIS/DAP/html/index.html), such as an on-board debug probe using [DAPLink](https://os.mbed.com/handbook/DAPLink) firmware. - STLinkV2, either on-board or the standalone version. Status ------ PyOCD is functionally reliable and fully useable. The API is considered unstable because we are planning some breaking changes to bring the naming convention into compliance with PEP8 prior to releasing version 1.0. We also plan to merge the three command line tools into a single tool. Documentation ------------- The pyOCD documentation is located [in the docs directory](docs/). Installing ---------- The latest stable version of pyOCD may be installed via [pip](https://pip.pypa.io/en/stable/index.html) as follows: ``` $ pip install -U pyocd ``` The latest pyOCD package is available [on PyPI](https://pypi.python.org/pypi/pyOCD/) as well as [on GitHub](https://github.com/mbedmicro/pyOCD/releases). To install the latest prerelease version from the HEAD of the master branch, you can do the following: ``` $ pip install --pre -U https://github.com/mbedmicro/pyOCD/archive/master.zip ``` You can also install directly from the source by cloning the git repository and running: ``` $ python setup.py install ``` Note that, depending on your operating system, you may run into permissions issues running these commands. You have a few options here: 1. Under Linux, run with `sudo -H` to install pyOCD and dependencies globally. (Installing with sudo should never be required for macOS.) 2. Specify the `--user` option to install local to your user. 3. Run the command in a [virtualenv](https://virtualenv.pypa.io/en/latest/) local to a specific project working set. ### libusb installation [pyusb](https://github.com/pyusb/pyusb) and its backend library [libusb](https://libusb.info/) are dependencies on all supported operating systems. pyusb is a regular Python package and will be installed along with pyOCD. However, libusb is binary shared library that does not get installed automatically via pip dependency management. How to install libusb depends on your OS: - macOS: use Homebrew: `brew install libusb` - Linux: should already be installed. - Windows: download libusb from [libusb.info](https://libusb.info/) and place the DLL in your Python installation folder next to python.exe. ### udev rules on Linux If you encounter an issue on Linux where `pyocd-tool list` won't detect attached boards without sudo, the reason is most likely USB device access permissions. In Ubuntu 16.04+ these are handled with udev and can be solved by adding a new udev rule. An example udev rule file is included in the [udev](https://github.com/mbedmicro/pyOCD/tree/master/udev) folder in the pyOCD repository. Just copy this file into `etc/udev/rules.d` to enable user access to both [DAPLink](https://os.mbed.com/handbook/DAPLink)-based debug probes as well as STLinkV2 and STLinkV3. If you use different, but compatible, debug probe, you can check the IDs with ``dmesg`` command. - Run ``dmesg`` - Plug in your board - Run ``dmesg`` again and check what was added - Look for line similar to ``usb 2-2.1: New USB device found, idVendor=0d28, idProduct=0204`` Standalone GDB server --------------------- When you install pyOCD via pip or setup.py, you will be able to execute the following in order to start a GDB server powered by pyOCD: ``` $ pyocd-gdbserver ``` You can get additional help by running ``pyocd-gdbserver --help``. Example command line GDB session showing how to connect to a running `pyocd-gdbserver` and load firmware: ``` $ arm-none-eabi-gdb application.elf target remote localhost:3333 load monitor reset ``` The `pyocd-gdbserver` executable is also usable as a drop in place replacement for OpenOCD in existing setups. The primary difference is the set of gdb monitor commands. Recommended GDB and IDE setup ----------------------------- The GDB server works well with [Eclipse](https://www.eclipse.org/) and the [GNU MCU Eclipse plug-ins](https://gnu-mcu-eclipse.github.io/). GNU MCU Eclipse fully supports pyOCD with an included pyOCD debugging plugin. To view peripheral register values either the built-in GNU MCU Eclipse register view can be used, or the Embedded System Register Viewer plugin can be installed. These can be installed from inside Eclipse using the following software update server addresses: - GNU MCU Eclipse: http://gnu-mcu-eclipse.sourceforge.net/updates - Embedded System Register Viewer: http://embsysregview.sourceforge.net/update In Eclipse, select the "Help -> Install New Software…" menu item. Then either click the "Add…" button and fill in the name and URL from above (once for each site), or simply copy the URL into the field where it says "type or select a site". Then you can select the software to install and click Next to start the process. Development setup ----------------- Please see the [Developers' Guide](docs/DEVELOPERS_GUIDE.md) for instructions on how to set up a development environment for pyOCD. Contributions ------------- We welcome contributions to pyOCD in any area. Please see the [contribution guidelines](CONTRIBUTING.md) for details. To report bugs, please [create an issue](https://github.com/mbedmicro/pyOCD/issues/new) in the GitHub project. License ------- PyOCD is licensed with Apache 2.0. See the [LICENSE](LICENSE) file for the full text of the license. Copyright © 2006-2018 Arm Ltd Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development :: Debuggers Classifier: Topic :: Software Development :: Embedded Systems Requires-Python: >=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* Description-Content-Type: text/markdown Provides-Extra: dissassembler pyocd-0.13.1/pyocd.egg-info/top_level.txt0000644000175000017500000000000613373523011020146 0ustar neilneil00000000000000pyocd pyocd-0.13.1/pyocd.egg-info/requires.txt0000644000175000017500000000036013373523011020017 0ustar neilneil00000000000000colorama future intelhex intervaltree pyelftools pyusb>=1.0.0b2 pyyaml six websocket-client [:platform_system == "Darwin"] hidapi [:platform_system == "Windows"] pywinusb>=0.4.0 [:python_version < "3.4"] enum34 [dissassembler] capstone pyocd-0.13.1/pyocd.egg-info/SOURCES.txt0000644000175000017500000001414013373523011017304 0ustar neilneil00000000000000.editorconfig .git_archival.txt .gitattributes .gitignore .pylintrc .travis.yml CONTRIBUTING.md Doxyfile LICENSE MANIFEST.in README.md dev-requirements.txt dfsh.sh pytest.ini setup.py docs/ADDING_NEW_TARGETS.md docs/API_EXAMPLES.md docs/ARCHITECTURE.md docs/AUTOMATED_TESTS.md docs/DEVELOPERS_GUIDE.md docs/HOW_TO_BUILD.md docs/MULTICORE_DEBUG.md docs/PYTHON_API.md docs/README.md docs/SESSION_OPTIONS.md docs/resources/Arm_logo_blue_150MN.png docs/resources/doxygen_footer.html docs/resources/doxygen_header.html docs/resources/doxygen_layout.xml docs/resources/doxygen_style.css pyocd/__init__.py pyocd/_version.py pyocd.egg-info/PKG-INFO pyocd.egg-info/SOURCES.txt pyocd.egg-info/dependency_links.txt pyocd.egg-info/entry_points.txt pyocd.egg-info/requires.txt pyocd.egg-info/top_level.txt pyocd/board/__init__.py pyocd/board/board.py pyocd/board/board_ids.py pyocd/board/mbed_board.py pyocd/core/__init__.py pyocd/core/coresight_target.py pyocd/core/exceptions.py pyocd/core/helpers.py pyocd/core/memory_interface.py pyocd/core/memory_map.py pyocd/core/session.py pyocd/core/target.py pyocd/coresight/__init__.py pyocd/coresight/ap.py pyocd/coresight/component.py pyocd/coresight/cortex_m.py pyocd/coresight/dap.py pyocd/coresight/dwt.py pyocd/coresight/fpb.py pyocd/coresight/rom_table.py pyocd/debug/__init__.py pyocd/debug/cache.py pyocd/debug/context.py pyocd/debug/semihost.py pyocd/debug/svd.py pyocd/debug/symbols.py pyocd/debug/breakpoints/__init__.py pyocd/debug/breakpoints/manager.py pyocd/debug/breakpoints/provider.py pyocd/debug/breakpoints/software.py pyocd/debug/elf/__init__.py pyocd/debug/elf/decoder.py pyocd/debug/elf/elf.py pyocd/debug/elf/flash_reader.py pyocd/debug/elf/symbols.py pyocd/flash/__init__.py pyocd/flash/flash.py pyocd/flash/flash_builder.py pyocd/gdbserver/__init__.py pyocd/gdbserver/context_facade.py pyocd/gdbserver/gdb_socket.py pyocd/gdbserver/gdb_websocket.py pyocd/gdbserver/gdbserver.py pyocd/gdbserver/signals.py pyocd/gdbserver/symbols.py pyocd/gdbserver/syscall.py pyocd/probe/__init__.py pyocd/probe/aggregator.py pyocd/probe/cmsis_dap_probe.py pyocd/probe/debug_probe.py pyocd/probe/stlink_probe.py pyocd/probe/pydapaccess/__init__.py pyocd/probe/pydapaccess/cmsis_dap_core.py pyocd/probe/pydapaccess/dap_access_api.py pyocd/probe/pydapaccess/dap_access_cmsis_dap.py pyocd/probe/pydapaccess/dap_settings.py pyocd/probe/pydapaccess/interface/__init__.py pyocd/probe/pydapaccess/interface/hidapi_backend.py pyocd/probe/pydapaccess/interface/interface.py pyocd/probe/pydapaccess/interface/pyusb_backend.py pyocd/probe/pydapaccess/interface/pywinusb_backend.py pyocd/probe/pydapaccess/interface/ws_backend.py pyocd/probe/stlink/__init__.py pyocd/probe/stlink/constants.py pyocd/probe/stlink/stlink.py pyocd/probe/stlink/usb.py pyocd/rtos/__init__.py pyocd/rtos/argon.py pyocd/rtos/common.py pyocd/rtos/freertos.py pyocd/rtos/provider.py pyocd/rtos/rtx5.py pyocd/rtos/zephyr.py pyocd/target/__init__.py pyocd/target/target_CC3220SF.py pyocd/target/target_K32W042S1M2xxx.py pyocd/target/target_LPC1114FN28_102.py pyocd/target/target_LPC11U24FBD64_401.py pyocd/target/target_LPC1768.py pyocd/target/target_LPC4088FBD144.py pyocd/target/target_LPC4330.py pyocd/target/target_LPC54114J256BD64.py pyocd/target/target_LPC54608J512ET180.py pyocd/target/target_LPC824M201JHI33.py pyocd/target/target_MAX32600.py pyocd/target/target_MK20DX128xxx5.py pyocd/target/target_MK22FN1M0Axxx12.py pyocd/target/target_MK22FN512xxx12.py pyocd/target/target_MK28FN2M0xxx15.py pyocd/target/target_MK64FN1M0xxx12.py pyocd/target/target_MK66FN2M0xxx18.py pyocd/target/target_MK82FN256xxx15.py pyocd/target/target_MKE15Z256xxx7.py pyocd/target/target_MKE18F256xxx16.py pyocd/target/target_MKL02Z32xxx4.py pyocd/target/target_MKL05Z32xxx4.py pyocd/target/target_MKL25Z128xxx4.py pyocd/target/target_MKL26Z256xxx4.py pyocd/target/target_MKL27Z256xxx4.py pyocd/target/target_MKL28Z512xxx7.py pyocd/target/target_MKL43Z256xxx4.py pyocd/target/target_MKL46Z256xxx4.py pyocd/target/target_MKL82Z128xxx7.py pyocd/target/target_MKV10Z128xxx7.py pyocd/target/target_MKV11Z128xxx7.py pyocd/target/target_MKW01Z128xxx4.py pyocd/target/target_MKW24D512xxx5.py pyocd/target/target_MKW36Z512xxx4.py pyocd/target/target_MKW40Z160xxx4.py pyocd/target/target_MKW41Z512xxx4.py pyocd/target/target_RTL8195AM.py pyocd/target/target_STM32F051T8.py pyocd/target/target_STM32F103RC.py pyocd/target/target_STM32F412xx.py pyocd/target/target_STM32F439xx.py pyocd/target/target_STM32L475xx.py pyocd/target/target_lpc4088dm.py pyocd/target/target_lpc4088qsb.py pyocd/target/target_lpc800.py pyocd/target/target_nRF51822_xxAA.py pyocd/target/target_nRF52832_xxAA.py pyocd/target/target_nRF52840_xxAA.py pyocd/target/target_ncs36510.py pyocd/target/target_w7500.py pyocd/target/family/__init__.py pyocd/target/family/flash_cortex_m.py pyocd/target/family/flash_kinetis.py pyocd/target/family/target_kinetis.py pyocd/test/__init__.py pyocd/test/conftest.py pyocd/test/mockcore.py pyocd/test/test_cmdline.py pyocd/test/test_conversion.py pyocd/test/test_memcache.py pyocd/test/test_memory_map.py pyocd/test/test_mockcore.py pyocd/test/test_regcache.py pyocd/test/test_semihosting.py pyocd/test/test_sequencer.py pyocd/test/test_timeout.py pyocd/tools/__init__.py pyocd/tools/flash_tool.py pyocd/tools/gdb_server.py pyocd/tools/pyocd.py pyocd/utility/__init__.py pyocd/utility/cmdline.py pyocd/utility/conversion.py pyocd/utility/mask.py pyocd/utility/notification.py pyocd/utility/progress.py pyocd/utility/py3_helpers.py pyocd/utility/sequencer.py pyocd/utility/timeout.py src/analyzer/.gitignore src/analyzer/Makefile src/analyzer/build.bat src/analyzer/generate_python.py src/analyzer/linker_script.ld src/analyzer/main.c src/analyzer/readme.txt src/gdb_test_program/Makefile src/gdb_test_program/build.bat src/gdb_test_program/gdb_test.bin src/gdb_test_program/linker_script.ld src/gdb_test_program/main.c src/gdb_test_program/readme.txt test/.gitignore test/automated_test.py test/basic_test.py test/blank_test.py test/connect_test.py test/cortex_test.py test/flash_test.py test/gdb_script.py test/gdb_server_json_test.py test/gdb_test.py test/parallel_test.py test/speed_test.py test/test_pyocd_tool.sh test/test_util.py udev/50-pyocd.rulespyocd-0.13.1/pyocd.egg-info/entry_points.txt0000644000175000017500000000022313373523011020713 0ustar neilneil00000000000000[console_scripts] pyocd-flashtool = pyocd.tools.flash_tool:main pyocd-gdbserver = pyocd.tools.gdb_server:main pyocd-tool = pyocd.tools.pyocd:main pyocd-0.13.1/pyocd.egg-info/dependency_links.txt0000644000175000017500000000000113373523011021466 0ustar neilneil00000000000000 pyocd-0.13.1/LICENSE0000644000175000017500000002167013373511253013630 0ustar neilneil00000000000000Apache 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: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and 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 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. END OF TERMS AND CONDITIONS pyocd-0.13.1/setup.cfg0000644000175000017500000000004613373523011014431 0ustar neilneil00000000000000[egg_info] tag_build = tag_date = 0 pyocd-0.13.1/setup.py0000644000175000017500000000521513373522714014336 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2012-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 setuptools import setup, find_packages setup( name="pyocd", use_scm_version={ 'local_scheme': 'dirty-tag', 'write_to': 'pyocd/_version.py' }, setup_requires=[ 'setuptools_scm!=1.5.3,!=1.5.4', 'setuptools_scm_git_archive', ], description="Cortex-M debugger for Python", long_description=open('README.md', 'r').read(), long_description_content_type='text/markdown', author="Chris Reed, Martin Kojtal, Russ Butler", author_email="chris.reed@arm.com, martin.kojtal@arm.com, russ.butler@arm.com", url='https://github.com/mbedmicro/pyOCD', license="Apache 2.0", # Allow installation on 2.7.9+, and 3.4+ even though we officially only support 3.6+. python_requires=">=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", install_requires = [ 'intelhex', 'six', 'enum34;python_version<"3.4"', 'future', 'websocket-client', 'intervaltree', 'colorama', 'pyelftools', 'pyusb>=1.0.0b2', 'pywinusb>=0.4.0;platform_system=="Windows"', 'hidapi;platform_system=="Darwin"', 'pyyaml', ], classifiers=[ "Development Status :: 4 - Beta", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Debuggers", "Topic :: Software Development :: Embedded Systems", ], extras_require={ 'dissassembler': ['capstone'] }, entry_points={ 'console_scripts': [ 'pyocd-gdbserver = pyocd.tools.gdb_server:main', 'pyocd-flashtool = pyocd.tools.flash_tool:main', 'pyocd-tool = pyocd.tools.pyocd:main', ], }, packages=find_packages(), include_package_data=True, # include files from MANIFEST.in ) pyocd-0.13.1/dfsh.sh0000755000175000017500000000033513373523000014072 0ustar neilneil00000000000000#!/bin/sh set -e if [ -d ./binaries/ ]; then rm -rf ./binaries/ fi if [ -d ./elf_files/ ]; then rm -rf ./elf_files/ fi if [ -f ./src/gdb_test_program/gdb_test.elf ]; then rm ./src/gdb_test_program/gdb_test.elf fi pyocd-0.13.1/test/0000755000175000017500000000000013373523011013567 5ustar neilneil00000000000000pyocd-0.13.1/test/automated_test.py0000755000175000017500000002766013373511253017206 0ustar neilneil00000000000000#!/usr/bin/env python """ mbed CMSIS-DAP debugger Copyright (c) 2015-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 __future__ import print_function import os, sys parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd.core.session import Session from pyocd.core.helpers import ConnectHelper from pyocd.utility.conversion import float32_to_u32 from pyocd.probe.aggregator import DebugProbeAggregator import logging from time import time from test_util import (TestResult, Test, IOTee, RecordingLogHandler, get_session_options) import argparse from xml.etree import ElementTree import multiprocessing as mp import io from basic_test import BasicTest from speed_test import SpeedTest from cortex_test import CortexTest from flash_test import FlashTest from gdb_test import GdbTest from gdb_server_json_test import GdbServerJsonTest from connect_test import ConnectTest XML_RESULTS = "test_results.xml" LOG_FORMAT = "%(relativeCreated)07d:%(levelname)s:%(module)s:%(message)s" LOG_FILE = "automated_test_result.txt" SUMMARY_FILE = "automated_test_summary.txt" JOB_TIMEOUT = 30 * 60 # 30 minutes # Put together list of tests. test_list = [ BasicTest(), GdbServerJsonTest(), ConnectTest(), SpeedTest(), CortexTest(), FlashTest(), GdbTest(), ] def print_summary(test_list, result_list, test_time, output_file=None): for test in test_list: test.print_perf_info(result_list, output_file=output_file) Test.print_results(result_list, output_file=output_file) print("", file=output_file) print("Test Time: %.3f" % test_time, file=output_file) if Test.all_tests_pass(result_list): print("All tests passed", file=output_file) else: print("One or more tests has failed!", file=output_file) def split_results_by_board(result_list): boards = {} for result in result_list: if result.board_name in boards: boards[result.board_name].append(result) else: boards[result.board_name] = [result] return boards def generate_xml_results(result_list): board_results = split_results_by_board(result_list) suite_id = 0 total_failures = 0 total_tests = 0 total_time = 0 root = ElementTree.Element('testsuites', name="pyocd" ) root.text = "\n" for board_name, results in board_results.items(): total = 0 failures = 0 suite_time = 0 suite = ElementTree.SubElement(root, 'testsuite', name=board_name, id=str(suite_id)) suite.text = "\n" suite.tail = "\n" suite_id += 1 for result in results: total += 1 if not result.passed: failures += 1 case = result.get_test_case() suite.append(case) suite_time += result.time suite.set('tests', str(total)) suite.set('failures', str(failures)) suite.set('time', "%.3f" % suite_time) total_tests += total total_failures += failures total_time += suite_time root.set('tests', str(total_tests)) root.set('failures', str(total_failures)) root.set('time', "%.3f" % total_time) ElementTree.ElementTree(root).write(XML_RESULTS, encoding="UTF-8", xml_declaration=True) def print_board_header(outputFile, board, n, includeDividers=True, includeLeadingNewline=False): header = "TESTING BOARD {name} [{target}] [{uid}] #{n}".format( name=board.name, target=board.target_type, uid=board.unique_id, n=n) if includeDividers: divider = "=" * len(header) if includeLeadingNewline: print("\n" + divider, file=outputFile) else: print(divider, file=outputFile) print(header, file=outputFile) if includeDividers: print(divider + "\n", file=outputFile) ## @brief Run all tests on a given board. # # When multiple test jobs are being used, this function is the entry point executed in # child processes. # # Always writes both stdout and log messages of tests to a board-specific log file, and saves # the output for each test to a string that is stored in the TestResult object. Depending on # the logToConsole and commonLogFile parameters, output may also be copied to the console # (sys.stdout) and/or a common log file for all boards. # # @param board_id Unique ID of the board to test. # @param n Unique index of the test run. # @param loglevel Log level passed to logger instance. Usually INFO or DEBUG. # @param logToConsole Boolean indicating whether output should be copied to sys.stdout. # @param commonLogFile If not None, an open file object to which output should be copied. def test_board(board_id, n, loglevel, logToConsole, commonLogFile): probe = DebugProbeAggregator.get_probe_with_id(board_id) assert probe is not None session = Session(probe, **get_session_options()) board = session.board originalStdout = sys.stdout originalStderr = sys.stderr # Open board-specific output file. log_filename = "automated_test_results_%s_%d.txt" % (board.name, n) if os.path.exists(log_filename): os.remove(log_filename) log_file = open(log_filename, "a", buffering=1) # 1=Unbuffered # Setup logging. log_handler = RecordingLogHandler(None) log_handler.setFormatter(logging.Formatter(LOG_FORMAT)) root_logger = logging.getLogger() root_logger.setLevel(loglevel) root_logger.addHandler(log_handler) result_list = [] try: # Write board header to board log file, common log file, and console. print_board_header(log_file, board, n) if commonLogFile: print_board_header(commonLogFile, board, n, includeLeadingNewline=(n != 0)) print_board_header(originalStdout, board, n, logToConsole, includeLeadingNewline=(n != 0)) # Skip this board if we don't have a test binary. if board.test_binary is None: print("Skipping board %s due to missing test binary" % board.unique_id) return result_list # Run all tests on this board. for test in test_list: print("{} #{}: starting {}...".format(board.name, n, test.name), file=originalStdout) # Set a unique port for the GdbTest. if isinstance(test, GdbTest): test.n = n # Create a StringIO object to record the test's output, an IOTee to copy # output to both the log file and StringIO, then set the log handler and # stdio to write to the tee. testOutput = io.StringIO() tee = IOTee(log_file, testOutput) if logToConsole: tee.add(originalStdout) if commonLogFile is not None: tee.add(commonLogFile) log_handler.stream = tee sys.stdout = tee sys.stderr = tee test_start = time() result = test.run(board) test_stop = time() result.time = test_stop - test_start tee.flush() result.output = testOutput.getvalue() result_list.append(result) passFail = "PASSED" if result.passed else "FAILED" print("{} #{}: finished {}... {} ({:.3f} s)".format( board.name, n, test.name, passFail, result.time), file=originalStdout) finally: # Restore stdout/stderr in case we're running in the parent process (1 job). sys.stdout = originalStdout sys.stderr = originalStderr root_logger.removeHandler(log_handler) log_handler.flush() log_handler.close() return result_list def main(): parser = argparse.ArgumentParser(description='pyOCD automated testing') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument('-q', '--quiet', action="store_true", help='Hide test progress for 1 job') parser.add_argument('-j', '--jobs', action="store", default=1, type=int, metavar="JOBS", help='Set number of concurrent board tests (default is 1)') parser.add_argument('-b', '--board', action="append", metavar="ID", help="Limit testing to boards with specified unique IDs. Multiple boards can be listed.") args = parser.parse_args() # Force jobs to 1 when running under CI until concurrency issues with enumerating boards are # solved. Specifically, the connect test has intermittently failed to open boards on Linux and # Win7. This is only done under CI, and in this script, to make testing concurrent runs easy. if 'CI_TEST' in os.environ: args.jobs = 1 # Disable multiple jobs on macOS prior to Python 3.4. By default, multiprocessing uses # fork() on Unix, which doesn't work on the Mac because CoreFoundation requires exec() # to be used in order to init correctly (CoreFoundation is used in hidapi). Only on Python # version 3.4+ is the multiprocessing.set_start_method() API available that lets us # switch to the 'spawn' method, i.e. exec(). if args.jobs > 1 and sys.platform.startswith('darwin') and sys.version_info[0:2] < (3, 4): print("WARNING: Cannot support multiple jobs on macOS prior to Python 3.4. Forcing 1 job.") args.jobs = 1 # Setup logging based on concurrency and quiet option. level = logging.DEBUG if args.debug else logging.INFO if args.jobs == 1 and not args.quiet: # Create common log file. if os.path.exists(LOG_FILE): os.remove(LOG_FILE) logToConsole = True commonLogFile = open(LOG_FILE, "a") else: logToConsole = False commonLogFile = None board_list = [] result_list = [] # Put together list of boards to test board_list = ConnectHelper.get_all_connected_probes(blocking=False) board_id_list = sorted(b.unique_id for b in board_list) # Filter boards. if args.board: board_id_list = [b for b in board_id_list if any(c for c in args.board if c.lower() in b.lower())] # If only 1 job was requested, don't bother spawning processes. start = time() if args.jobs == 1: for n, board_id in enumerate(board_id_list): result_list += test_board(board_id, n, level, logToConsole, commonLogFile) else: # Create a pool of processes to run tests. try: pool = mp.Pool(args.jobs) # Issue board test job to process pool. async_results = [pool.apply_async(test_board, (board_id, n, level, logToConsole, commonLogFile)) for n, board_id in enumerate(board_id_list)] # Gather results. for r in async_results: result_list += r.get(timeout=JOB_TIMEOUT) finally: pool.close() pool.join() stop = time() test_time = (stop - start) print_summary(test_list, result_list, test_time) with open(SUMMARY_FILE, "w") as output_file: print_summary(test_list, result_list, test_time, output_file) generate_xml_results(result_list) exit_val = 0 if Test.all_tests_pass(result_list) else -1 exit(exit_val) #TODO - check if any threads are still running? if __name__ == "__main__": # set_start_method is only available in Python 3.4+. if sys.version_info[0:2] >= (3, 4): mp.set_start_method('spawn') main() pyocd-0.13.1/test/gdb_script.py0000644000175000017500000004373313373511253016300 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 __future__ import print_function # Notes about this script # 1. This script runs inside arm-none-eabi-gdb-py # 2. GDB processes commands inside a queue on a worker # thread. Commands that change the state of the target # should run from this queue via gdb.post_event(cb). # 3. After running a command that changes the state of a target # in the background, like "continue&", the code needs to # return so the event processing that occurs on the worker # thread can continue. No target state changes will be # seen until the worker thread gets a chance to process the data. # 4. To make the code flow better with #3 the main test function, # run_test, takes advantage of the 'yield' call. After # performing a background operation that causes the target run # 'yield' must be called with a timeout value. The code # will wait for the target to halt for the time specified and # if no signal arrives in that time the target is explicitly # halted. # 5. Only use packages in the standard library in this script. # Since the current version of arm-none-eabi-gdb-py.exe is # only 32 bit on windows, there must be a 32 bit python # install for it to work. If your primary version of python # is 64 bit, you can install the 32 bit version as a non # primary version. This will allow arm-none-eabi-gdb-py.exe # to work. The only problem with this is that when pyOCD # is installed through pip only the 64 bit version of # pyOCD and it's dependencies will get installed. # If only the standard library is used here then this # script will have no external dependencies. import gdb from time import time from threading import Timer from functools import partial from random import randrange from itertools import product import traceback import json import sys # We expect arm-none-eabi-gdb-py to only run Python 2.x. If it moves # to Python 3, we need to know about it, so print a warning. print("arm-none-eabi-gdb-py is using Python %s" % sys.version) if sys.version_info.major != 2: print("*** Unexpected arm-none-eabi-gdb-py Python version %d! ***" % sys.version_info.major) DEFAULT_TIMEOUT = 2.0 STACK_OFFSET = 0x800 TEST_RAM_OFFSET = 0x800 MAX_TEST_SIZE = 0x1000 MAX_BKPT = 10 assert STACK_OFFSET < MAX_TEST_SIZE assert TEST_RAM_OFFSET < MAX_TEST_SIZE monitor_commands = [ "help", "help reset", "help halt", "init", "reset", "reset halt", "halt", "arm semihosting enable", "arm semihosting disable", "set vector-catch n", "set vector-catch a", "set step-into-interrupt on", "set step-into-interrupt off", # Invalid Command "fawehfawoefhad" ] SIZE_TO_C_TYPE = { 1: "uint8_t*", 2: "uint16_t*", 4: "uint32_t*", } TO_GDB_ACCESS = { "read": gdb.WP_READ, "write": gdb.WP_WRITE, "read_write": gdb.WP_ACCESS, } def gdb_execute(cmd): print("Executing command:", cmd) gdb.execute(cmd) def test_step_type(step_type): step_count = 20 start = time() for _ in range(step_count): gdb_execute(step_type) end = time() seconds_per_operation = (end - start) / step_count return seconds_per_operation def is_event_breakpoint(event, bkpt=None): if not isinstance(event, gdb.BreakpointEvent): return False if bkpt is None: return True return event.breakpoints[-1] is bkpt def is_event_signal(event, signal_name): if not isinstance(event, gdb.SignalEvent): return False return event.stop_signal == signal_name def has_read(name): if name == "read": return True if name == "read_write": return True assert name == "write" return False def has_write(name): if name == "write": return True if name == "read_write": return True assert name == "read" return False def size_to_type(size): return SIZE_TO_C_TYPE[size] def to_gdb_access(access): return TO_GDB_ACCESS[access] def should_trigger_break(bkpt_size, bkpt_access, bkpt_addr, size, access, addr): left_access_addr = addr right_access_addr = addr + size - 1 left_bkpt_addr = bkpt_addr right_bkpt_addr = bkpt_addr + bkpt_size overlap = (left_access_addr <= right_bkpt_addr and right_access_addr >= left_bkpt_addr) read_break = has_read(bkpt_access) and has_read(access) write_break = has_write(bkpt_access) and has_write(access) should_break = overlap and (read_break or write_break) return should_break def valid_watchpoint(bkpt_size, bkpt_access, bkpt_addr): # Unaligned breakpoints are not allowed return bkpt_addr % bkpt_size == 0 # Initial setup testn = int(gdb.parse_and_eval("$testn")) test_param_filename = "test_params%d.txt" % testn with open(test_param_filename, "rb") as f: test_params = json.loads(f.read()) def run_test(): test_result = {} test_port = test_params["test_port"] rom_start = test_params['rom_start'] ram_start = test_params['ram_start'] ram_length = test_params['ram_length'] invalid_addr = test_params["invalid_start"] error_on_invalid_access = test_params["expect_error_on_invalid_access"] ignore_hw_bkpt_result = test_params["ignore_hw_bkpt_result"] target_test_elf = test_params["test_elf"] assert ram_length >= MAX_TEST_SIZE stack_addr = ram_start + STACK_OFFSET test_ram_addr = ram_start + TEST_RAM_OFFSET fail_count = 0 try: # Turn off confirmations that would block the script gdb_execute("set pagination off") gdb_execute("set confirm off") # Allow GDB to access even unmapped regions gdb_execute("set mem inaccessible-by-default off") # Set raw logging gdb_execute("set remotelogfile gdb_test_raw%d.txt" % testn) # Connect to server gdb_execute("target remote localhost:%d" % test_port) # Show memory regions, useful for debug and verification. gdb_execute("info mem") # Possibly useful other commands for reference: # info breakpoints # info mem # show code-cache # show stack-cache # show dcache # show mem inaccessible-by-default # show can-use-hw-watchpoints # info all-registers # set logging file gdb.txt # set logging on # Test running the monitor commands for command in monitor_commands: gdb_execute("mon %s" % command) # Load target-specific test program into flash. gdb_execute("load %s" % target_test_elf) # Reset the target and let it run so it has # a chance to disable the watchdog gdb_execute("mon reset halt") gdb_execute("c&") event = yield(0.1) if not is_event_signal(event, "SIGINT"): fail_count += 1 print("Error - target not interrupted as expected") # Load test program and symbols test_binary = "../src/gdb_test_program/gdb_test.bin" test_elf = "../src/gdb_test_program/gdb_test.elf" gdb_execute("restore %s binary 0x%x" % (test_binary, ram_start)) gdb_execute("add-symbol-file %s 0x%x" % (test_elf, ram_start)) # Set pc to the test program. Make sure # interrupts are disabled to prevent # other code from running. gdb_execute("set $primask = 1") gdb_execute("set $sp = 0x%x" % stack_addr) gdb_execute("b main") breakpoint = gdb.Breakpoint("main") gdb_execute("set $pc = main") gdb_execute("c&") event = yield(DEFAULT_TIMEOUT) if not is_event_breakpoint(event, breakpoint): fail_count += 1 print("Error - could not set pc to function") breakpoint.delete() ## Stepping removed as a workaround for a GDB bug. Launchpad issue tracking this is here: ## https://bugs.launchpad.net/gcc-arm-embedded/+bug/1700595 # # # Test the speed of the different step types # test_result["step_time_si"] = test_step_type("si") # test_result["step_time_s"] = test_step_type("s") # test_result["step_time_n"] = test_step_type("n") test_result["step_time_si"] = -1 test_result["step_time_s"] = -1 test_result["step_time_n"] = -1 # TODO,c1728p9 - test speed getting stack trace # TODO,c1728p9 - test speed with cache turned on # TODO,c1728p9 - check speed vs breakpoints # Let target run to initialize variables gdb_execute("c&") event = yield(0.1) if not is_event_signal(event, "SIGINT"): fail_count += 1 print("Error - target not interrupted as expected") # Check number of supported breakpoints, along # with graceful handling of a request using # more than the supported number of breakpoints break_list = [] for i in range(MAX_BKPT): addr = rom_start + i * 4 breakpoint = gdb.Breakpoint("*0x%x" % addr) break_list.append(breakpoint) while True: try: gdb_execute("c&") yield(0.1) break except gdb.error: bkpt = break_list.pop() bkpt.delete() test_result["breakpoint_count"] = len(break_list) for bkpt in break_list: bkpt.delete() # Check number of supported watchpoints, along # with graceful handling of a request using # more than the supported number of watchpoints watch_list = [] for i in range(MAX_BKPT): addr = rom_start + i * 4 breakpoint = gdb.Breakpoint("*0x%x" % addr, gdb.BP_WATCHPOINT, gdb.WP_ACCESS) watch_list.append(breakpoint) while True: try: gdb_execute("c&") yield(0.1) break except gdb.error: bkpt = watch_list.pop() bkpt.delete() test_result["watchpoint_count"] = len(watch_list) for bkpt in watch_list: bkpt.delete() # Make sure breakpoint is hit as expected rmt_func = "breakpoint_test" gdb_execute("set var run_breakpoint_test = 1") breakpoint = gdb.Breakpoint(rmt_func) gdb_execute("c&") event = yield(DEFAULT_TIMEOUT) if not is_event_breakpoint(event, breakpoint): fail_count += 1 print("Error - breakpoint 1 test failed") func_name = gdb.selected_frame().function().name if rmt_func != func_name: fail_count += 1 print("ERROR - break occurred at wrong function %s" % func_name) breakpoint.delete() gdb_execute("set var run_breakpoint_test = 0") # Let target run, make sure breakpoint isn't hit gdb_execute("set var run_breakpoint_test = 1") gdb_execute("c&") event = yield(0.1) if not is_event_signal(event, "SIGINT"): fail_count += 1 print("Error - target not interrupted as expected") gdb_execute("set var run_breakpoint_test = 0") # Make sure hardware breakpoint is hit as expected rmt_func = "breakpoint_test" gdb_execute("set var run_breakpoint_test = 1") gdb_execute("hbreak %s" % rmt_func) gdb_execute("c&") event = yield(DEFAULT_TIMEOUT) # TODO, c1728p9 - determine why there isn't a breakpoint event returned # if not is_event_breakpoint(event): # fail_count += 1 # print("Error - breakpoint 2 test failed") func_name = gdb.selected_frame().function().name if rmt_func != func_name and not ignore_hw_bkpt_result: fail_count += 1 print("ERROR - break occurred at wrong function %s" % func_name) gdb_execute("clear %s" % rmt_func) gdb_execute("set var run_breakpoint_test = 0") # Test valid memory write addr_value_list = [(test_ram_addr + i * 4, randrange(1, 50)) for i in range(4)] for addr, value in addr_value_list: gdb_execute("set *((int *) 0x%x) = 0x%x" % (addr, value)) # Test invalid memory write invalid_addr_list = [invalid_addr + i * 4 for i in range(4)] for addr in invalid_addr_list: try: gdb_execute("set *((int *) 0x%x) = 0x%x" % (addr, randrange(1, 50))) if error_on_invalid_access: fail_count += 1 print("Error - invalid memory write did not fault @ 0x%x" % addr) except gdb.MemoryError: pass # Test valid memory read for addr, value in addr_value_list: val_read = gdb.parse_and_eval("*((int *) 0x%x)" % addr) val_read = int(val_read) assert value == val_read # Test invalid memory read for addr in invalid_addr_list: try: gdb_execute("x 0x%x" % addr) if error_on_invalid_access: fail_count += 1 print("Error - invalid memory read did not fault @ 0x%x" % addr) except gdb.MemoryError: pass # Test watchpoints access_addr = long(gdb.parse_and_eval("&watchpoint_write_buffer[1]")) bkpt_sizes = [1, 2, 4] bkpt_accesses = ["read", "write", "read_write"] # use "range(-4, 8, 1)" for extended testing bkpt_addresses = [access_addr + offset for offset in range(0, 4, 1)] sizes = [1, 2, 4] accesses = ["read", "write", "read_write"] addresses = [access_addr] generator = product(bkpt_sizes, bkpt_accesses, bkpt_addresses, sizes, accesses, addresses) for bkpt_size, bkpt_access, bkpt_addr, size, access, addr in generator: gdb_size = size_to_type(bkpt_size) gdb_access = to_gdb_access(bkpt_access) gdb_execute("set var watchpoint_write = %i" % (1 if has_write(access) else 0)) gdb_execute("set var watchpoint_read = %i" % (1 if has_read(access) else 0)) gdb_execute("set var watchpoint_size = %i" % size) gdb_execute("set var write_address = %i" % addr) breakpoint = gdb.Breakpoint("*(%s)0x%x" % (gdb_size, bkpt_addr), gdb.BP_WATCHPOINT, gdb_access) # Run until breakpoint is hit gdb_execute("c&") event = yield(0.1) bkpt_hit = not is_event_signal(event, "SIGINT") # Compare against expected result should_break = should_trigger_break(bkpt_size, bkpt_access, bkpt_addr, size, access, addr) valid = valid_watchpoint(bkpt_size, bkpt_access, bkpt_addr) if valid and bkpt_hit != should_break: fail_count += 1 print("Error - watchpoint problem:") print(" Watchpoint was hit %s" % bkpt_hit) print(" Watchpoint should be hit %s" % should_break) print(" bkpt_size %s, bkpt_access %s, bkpt_address 0x%x, " "size %s, access %s, addr 0x%x" % (bkpt_size, bkpt_access, bkpt_addr, size, access, addr)) print() breakpoint.delete() # TODO,c1728p9 - test reading/writing registers # TODO,c1728p9 - test stepping into interrupts # TODO,c1728p9 - test vector catch # -test hard fault handling # -test reset catch # TODO,c1728p9 - test signals/hard fault if fail_count: print("Test completed with %i errors" % fail_count) else: print("Test completed successfully") except: print("Main Error:") traceback.print_exc() fail_count += 1 finally: test_result["fail_count"] = fail_count test_result_filename = "test_results%d.txt" % testn with open(test_result_filename, "wb") as f: f.write(json.dumps(test_result)) gdb_execute("detach") gdb_execute("quit %i" % fail_count) ignore_events = True interrupt_timer = None interrupt_arg = None generator = run_test() # Post task to halt the processor def post_interrupt_task(interrupt_arg): # Halt the target by interrupting it # This must only run on GDB's queue def interrupt_task(): if not interrupt_arg["aborted"]: gdb_execute("interrupt") gdb.post_event(interrupt_task) # Run the main test by repreatedly calling the generator # This must only run on GDB's queue def run_generator(event): global ignore_events global interrupt_timer global interrupt_arg ignore_events = True if interrupt_timer is not None: interrupt_timer.cancel() interrupt_arg["aborted"] = True interrupt_arg = None stop_delay = 0 try: stop_delay = generator.send(event) except: print("Error") traceback.print_exc() interrupt_arg = {"aborted": False} interrupt_timer = Timer(stop_delay, post_interrupt_task, [interrupt_arg]) interrupt_timer.start() ignore_events = False # Runs on stop events and posts run_generator to the # main queue so it can continue execution def stop_handler(event): if ignore_events: return bound_run_generator = partial(run_generator, event) gdb.post_event(bound_run_generator) gdb.events.stop.connect(stop_handler) # Start testing bound_run_generator = partial(run_generator, None) gdb.post_event(bound_run_generator) pyocd-0.13.1/test/gdb_test.py0000644000175000017500000001564213373511253015751 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 __future__ import print_function # Note # To run this script GNU Tools ARM Embedded must be installed, # along with python for the same architecture. The program # "arm-none-eabi-gdb-py.exe" requires python for the same # architecture (x86 or 64) to work correctly. Also, on windows # the GNU Tools ARM Embedded bin directory needs to be added to # your path. import os import json import sys from subprocess import Popen, STDOUT, PIPE, check_output import argparse import logging import traceback import tempfile from pyocd.tools.gdb_server import GDBServerTool from pyocd.core.helpers import ConnectHelper from pyocd.utility.py3_helpers import to_str_safe from test_util import (Test, TestResult, get_session_options) # TODO, c1728p9 - run script several times with # with different command line parameters PYTHON_GDB = "arm-none-eabi-gdb-py" OBJCOPY = "arm-none-eabi-objcopy" parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class GdbTestResult(TestResult): def __init__(self): super(self.__class__, self).__init__(None, None, None) self.name = "gdbserver" class GdbTest(Test): def __init__(self): super(self.__class__, self).__init__("Gdb Test", test_gdb) self.n = 0 def print_perf_info(self, result_list, output_file=None): pass def run(self, board): try: result = self.test_function(board.unique_id, self.n) except Exception as e: result = GdbTestResult() result.passed = False print("Exception %s when testing board %s" % (e, board.unique_id)) traceback.print_exc(file=sys.stdout) result.board = board result.test = self return result TEST_RESULT_KEYS = [ "breakpoint_count", "watchpoint_count", "step_time_si", "step_time_s", "step_time_n", "fail_count", ] def test_gdb(board_id=None, n=0): temp_test_elf_name = None result = GdbTestResult() with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session: board = session.board memory_map = board.target.get_memory_map() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.get_boot_memory() target_type = board.target_type binary_file = os.path.join(parentdir, 'binaries', board.test_binary) if board_id is None: board_id = board.unique_id test_clock = 10000000 test_port = 3333 + n telnet_port = 4444 + n error_on_invalid_access = True # Hardware breakpoints are not supported above 0x20000000 on # CortexM devices ignore_hw_bkpt_result = 1 if ram_region.start >= 0x20000000 else 0 if target_type in ("nrf51", "nrf52", "nrf52840"): # Override clock since 10MHz is too fast test_clock = 1000000 # Reading invalid ram returns 0 or nrf51 error_on_invalid_access = False if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 # Program with initial test image board.flash.flash_binary(binary_file, rom_region.start) # Generate an elf from the binary test file. temp_test_elf_name = tempfile.mktemp('.elf') objcopyOutput = check_output([OBJCOPY, "-v", "-I", "binary", "-O", "elf32-littlearm", "-B", "arm", "-S", "--set-start", "0x%x" % rom_region.start, "--change-addresses", "0x%x" % rom_region.start, binary_file, temp_test_elf_name], stderr=STDOUT) print(to_str_safe(objcopyOutput)) # Need to escape backslashes on Windows. if sys.platform.startswith('win'): temp_test_elf_name = temp_test_elf_name.replace('\\', '\\\\') # Write out the test configuration test_params = { "test_port" : test_port, "rom_start" : rom_region.start, "rom_length" : rom_region.length, "ram_start" : ram_region.start, "ram_length" : ram_region.length, "invalid_start" : 0x3E000000, "invalid_length" : 0x1000, "expect_error_on_invalid_access" : error_on_invalid_access, "ignore_hw_bkpt_result" : ignore_hw_bkpt_result, "test_elf" : temp_test_elf_name, } test_param_filename = "test_params%d.txt" % n with open(test_param_filename, "w") as f: f.write(json.dumps(test_params)) # Run the test gdb = [PYTHON_GDB, "-ex", "set $testn=%d" % n, "--command=gdb_script.py"] output_filename = "output_%s_%d.txt" % (board.target_type, n) with open(output_filename, "w") as f: program = Popen(gdb, stdin=PIPE, stdout=f, stderr=STDOUT) args = ['-p=%i' % test_port, "-f=%i" % test_clock, "-b=%s" % board_id, "-T=%i" % telnet_port, '-Oboard_config_file=test_boards.json'] server = GDBServerTool() server.run(args) program.wait() # Read back the result test_result_filename = "test_results%d.txt" % n with open(test_result_filename, "r") as f: test_result = json.loads(f.read()) # Print results if set(TEST_RESULT_KEYS).issubset(test_result): print("----------------Test Results----------------") print("HW breakpoint count: %s" % test_result["breakpoint_count"]) print("Watchpoint count: %s" % test_result["watchpoint_count"]) print("Average instruction step time: %s" % test_result["step_time_si"]) print("Average single step time: %s" % test_result["step_time_s"]) print("Average over step time: %s" % test_result["step_time_n"]) print("Failure count: %i" % test_result["fail_count"]) result.passed = test_result["fail_count"] == 0 else: result.passed = False # Cleanup if temp_test_elf_name and os.path.exists(temp_test_elf_name): os.remove(temp_test_elf_name) os.remove(test_result_filename) os.remove(test_param_filename) return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD gdb test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) test_gdb() pyocd-0.13.1/test/flash_test.py0000644000175000017500000003776413373511253016323 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 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 __future__ import print_function import argparse, os, sys from time import sleep, time from random import randrange import math import struct import traceback import argparse parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd.core.helpers import ConnectHelper from pyocd.probe.pydapaccess import DAPAccess from pyocd.utility.conversion import float32_to_u32 from pyocd.flash.flash import Flash from pyocd.flash.flash_builder import FlashBuilder from pyocd.utility.progress import print_progress from test_util import (Test, TestResult, get_session_options) addr = 0 size = 0 board = None import logging class FlashTestResult(TestResult): def __init__(self): super(FlashTestResult, self).__init__(None, None, None) self.name = "flash" self.chip_erase_rate_erased = None self.page_erase_rate_same = None self.page_erase_rate = None self.analyze = None self.analyze_rate = None self.chip_erase_rate = None class FlashTest(Test): def __init__(self): super(FlashTest, self).__init__("Flash Test", flash_test) def print_perf_info(self, result_list, output_file=None): result_list = list(filter(lambda x: isinstance(x, FlashTestResult), result_list)) print("\n\n------ Analyzer Performance ------", file=output_file) perf_format_str = "{:<10}{:<12}{:<18}{:<18}" print(perf_format_str.format("Target", "Analyzer", "Rate", "Time"), file=output_file) print("", file=output_file) for result in result_list: if result.passed: analyze_rate = "%.3f KB/s" % (result.analyze_rate / float(1000)) analyze_time = "%.3f s" % result.analyze_time else: analyze_rate = "Fail" analyze_time = "Fail" print(perf_format_str.format(result.board, result.analyze, analyze_rate, analyze_time), file=output_file) print("", file=output_file) print("\n\n------ Test Rate ------", file=output_file) rate_format_str = "{:<10}{:<20}{:<20}{:<20}" print(rate_format_str.format("Target", "Chip Erase", "Page Erase", "Page Erase (Same data)"), file=output_file) print("", file=output_file) for result in result_list: if result.passed: chip_erase_rate = "%.3f KB/s" % (result.chip_erase_rate / float(1000)) page_erase_rate = "%.3f KB/s" % (result.page_erase_rate / float(1000)) page_erase_rate_same = "%.3f KB/s" % (result.page_erase_rate_same / float(1000)) else: chip_erase_rate = "Fail" page_erase_rate = "Fail" page_erase_rate_same = "Fail" print(rate_format_str.format(result.board, chip_erase_rate, page_erase_rate, page_erase_rate_same), file=output_file) print("", file=output_file) def run(self, board): try: result = self.test_function(board.unique_id) except Exception as e: result = FlashTestResult() result.passed = False print("Exception %s when testing board %s" % (e, board.unique_id)) traceback.print_exc(file=sys.stdout) result.board = board result.test = self return result def same(d1, d2): if len(d1) != len(d2): return False for i in range(len(d1)): if d1[i] != d2[i]: return False return True def flash_test(board_id): with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session: board = session.board target_type = board.target_type test_clock = 10000000 if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 memory_map = board.target.get_memory_map() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] ram_start = ram_region.start ram_size = ram_region.length target = board.target flash = board.flash flash_info = flash.get_flash_info() session.probe.set_clock(test_clock) test_pass_count = 0 test_count = 0 result = FlashTestResult() # Test each flash region separately. for rom_region in memory_map.get_regions_of_type('flash'): if not rom_region.is_testable: continue rom_start = rom_region.start rom_size = rom_region.length print("\n\n===== Testing flash region '%s' from 0x%08x to 0x%08x ====" % (rom_region.name, rom_region.start, rom_region.end)) binary_file = os.path.join(parentdir, 'binaries', board.test_binary) with open(binary_file, "rb") as f: data = f.read() data = struct.unpack("%iB" % len(data), data) unused = rom_size - len(data) # Make sure data doesn't overflow this region. if unused < 0: data = data[:rom_size] unused = 0 addr = rom_start size = len(data) # Turn on extra checks for the next 4 tests flash.set_flash_algo_debug(True) print("\n------ Test Basic Page Erase ------") info = flash.flash_block(addr, data, False, False, progress_cb=print_progress()) data_flashed = target.read_memory_block8(addr, size) if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Basic Chip Erase ------") info = flash.flash_block(addr, data, False, True, progress_cb=print_progress()) data_flashed = target.read_memory_block8(addr, size) if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_CHIP_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Smart Page Erase ------") info = flash.flash_block(addr, data, True, False, progress_cb=print_progress()) data_flashed = target.read_memory_block8(addr, size) if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Smart Chip Erase ------") info = flash.flash_block(addr, data, True, True, progress_cb=print_progress()) data_flashed = target.read_memory_block8(addr, size) if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_CHIP_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 flash.set_flash_algo_debug(False) print("\n------ Test Basic Page Erase (Entire region) ------") new_data = list(data) new_data.extend(unused * [0x77]) info = flash.flash_block(addr, new_data, False, False, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 result.page_erase_rate = float(len(new_data)) / float(info.program_time) else: print("TEST FAILED") test_count += 1 print("\n------ Test Fast Verify ------") info = flash.flash_block(addr, new_data, progress_cb=print_progress(), fast_verify=True) if info.program_type == FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Offset Write ------") addr = rom_start + rom_size // 2 page_size = flash.get_page_info(addr).size new_data = [0x55] * page_size * 2 info = flash.flash_block(addr, new_data, progress_cb=print_progress()) data_flashed = target.read_memory_block8(addr, len(new_data)) if same(data_flashed, new_data) and info.program_type is FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Multiple Block Writes ------") addr = rom_start + rom_size // 2 page_size = flash.get_page_info(addr).size more_data = [0x33] * page_size * 2 addr = (rom_start + rom_size // 2) + 1 #cover multiple pages fb = flash.get_flash_builder() fb.add_data(rom_start, data) fb.add_data(addr, more_data) fb.program(progress_cb=print_progress()) data_flashed = target.read_memory_block8(rom_start, len(data)) data_flashed_more = target.read_memory_block8(addr, len(more_data)) if same(data_flashed, data) and same(data_flashed_more, more_data): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Overlapping Blocks ------") test_pass = False addr = (rom_start + rom_size // 2) #cover multiple pages page_size = flash.get_page_info(addr).size new_data = [0x33] * page_size fb = flash.get_flash_builder() fb.add_data(addr, new_data) try: fb.add_data(addr + 1, new_data) except ValueError as e: print("Exception: %s" % e) test_pass = True if test_pass: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Empty Block Write ------") # Freebee if nothing asserts fb = flash.get_flash_builder() fb.program() print("TEST PASSED") test_pass_count += 1 test_count += 1 print("\n------ Test Missing Progress Callback ------") # Freebee if nothing asserts addr = rom_start flash.flash_block(rom_start, data, True) print("TEST PASSED") test_pass_count += 1 test_count += 1 # Only run test if the reset handler can be programmed (rom start at address 0) if rom_start == 0: print("\n------ Test Non-Thumb reset handler ------") non_thumb_data = list(data) # Clear bit 0 of 2nd word - reset handler non_thumb_data[4] = non_thumb_data[4] & ~1 flash.flash_block(rom_start, non_thumb_data) flash.flash_block(rom_start, data) print("TEST PASSED") test_pass_count += 1 test_count += 1 # Note - The decision based tests below are order dependent since they # depend on the previous state of the flash if rom_start == flash_info.rom_start: print("\n------ Test Chip Erase Decision ------") new_data = list(data) new_data.extend([0xff] * unused) # Pad with 0xFF info = flash.flash_block(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_CHIP_ERASE: print("TEST PASSED") test_pass_count += 1 result.chip_erase_rate_erased = float(len(new_data)) / float(info.program_time) else: print("TEST FAILED") test_count += 1 print("\n------ Test Chip Erase Decision 2 ------") new_data = list(data) new_data.extend([0x00] * unused) # Pad with 0x00 info = flash.flash_block(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_CHIP_ERASE: print("TEST PASSED") test_pass_count += 1 result.chip_erase_rate = float(len(new_data)) / float(info.program_time) else: print("TEST FAILED") test_count += 1 print("\n------ Test Page Erase Decision ------") new_data = list(data) new_data.extend([0x00] * unused) # Pad with 0x00 info = flash.flash_block(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 result.page_erase_rate_same = float(len(new_data)) / float(info.program_time) result.analyze = info.analyze_type result.analyze_time = info.analyze_time result.analyze_rate = float(len(new_data)) / float(info.analyze_time) else: print("TEST FAILED") test_count += 1 print("\n------ Test Page Erase Decision 2 ------") new_data = list(data) size_same = unused * 5 // 6 size_differ = unused - size_same new_data.extend([0x00] * size_same) # Pad 5/6 with 0x00 and 1/6 with 0xFF new_data.extend([0x55] * size_differ) info = flash.flash_block(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n\nTest Summary:") print("Pass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("FLASH TEST SCRIPT PASSED") else: print("FLASH TEST SCRIPT FAILED") target.reset() result.passed = test_count == test_pass_count return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD flash test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) DAPAccess.set_args(args.daparg) # Set to debug to print some of the decisions made while flashing session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options()) test = FlashTest() result = [test.run(session.board)] test.print_perf_info(result) pyocd-0.13.1/test/connect_test.py0000644000175000017500000001661313373511253016645 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger 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. """ from __future__ import print_function import os, sys import traceback import argparse from collections import namedtuple parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd.core.helpers import ConnectHelper from pyocd.core.target import Target from test_util import (Test, TestResult, get_session_options) import logging STATE_NAMES = { Target.TARGET_RUNNING : "running", Target.TARGET_HALTED : "halted", Target.TARGET_RESET : "reset", Target.TARGET_SLEEPING : "sleeping", Target.TARGET_LOCKUP : "lockup", } RUNNING = Target.TARGET_RUNNING HALTED = Target.TARGET_HALTED class ConnectTestCase(object): def __init__(self, prev_exit_state, halt_on_connect, expected_state, disconnect_resume, exit_state): self.prev_exit_state = prev_exit_state self.halt_on_connect = halt_on_connect self.expected_state = expected_state self.disconnect_resume = disconnect_resume self.exit_state = exit_state class ConnectTestResult(TestResult): def __init__(self): super(ConnectTestResult, self).__init__(None, None, None) self.name = "connect" class ConnectTest(Test): def __init__(self): super(ConnectTest, self).__init__("Connect Test", connect_test) def run(self, board): try: result = self.test_function(board) except Exception as e: print("Exception %s when testing board %s" % (e, board.unique_id)) result = ConnectTestResult() result.passed = False traceback.print_exc(file=sys.stdout) result.board = board result.test = self return result def connect_test(board): board_id = board.unique_id binary_file = os.path.join(parentdir, 'binaries', board.test_binary) print("binary file: %s" % binary_file) test_pass_count = 0 test_count = 0 result = ConnectTestResult() # Install binary. live_session = ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) live_board = live_session.board memory_map = board.target.get_memory_map() rom_region = memory_map.get_boot_memory() rom_start = rom_region.start def test_connect(halt_on_connect, expected_state, resume): print("Connecting with halt_on_connect=%s" % halt_on_connect) live_session = ConnectHelper.session_with_chosen_probe( board_id=board_id, init_board=False, halt_on_connect=halt_on_connect, resume_on_disconnect=resume, **get_session_options()) live_session.open() live_board = live_session.board print("Verifying target is", STATE_NAMES.get(expected_state, "unknown")) actualState = live_board.target.get_state() # Accept sleeping for running, as a hack to work around nRF52840-DK test binary. # TODO remove sleeping hack. if (actualState == expected_state) \ or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING): passed = 1 print("TEST PASSED") else: passed = 0 print("TEST FAILED (state={}, expected={})".format( STATE_NAMES.get(actualState, "unknown"), STATE_NAMES.get(expected_state, "unknown"))) print("Disconnecting with resume=%s" % resume) live_session.close() live_session = None return passed # TEST CASE COMBINATIONS test_cases = [ # ConnectTestCase( RUNNING, False, RUNNING, False, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, True, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, False, RUNNING, True, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, False, HALTED, False, HALTED ), ConnectTestCase( HALTED, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, False, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, False, RUNNING, False, RUNNING ), ] print("\n\n----- TESTING CONNECT/DISCONNECT -----") print("Flashing new binary") live_board.flash.flash_binary(binary_file, rom_start) live_board.target.reset() test_count += 1 print("Verifying target is running") if live_board.target.is_running(): test_pass_count += 1 print("TEST PASSED") else: print("TEST FAILED") print("Disconnecting with resume=True") live_session.options['resume_on_disconnect'] = True live_session.close() live_session = None # Leave running. # Run all the cases. for case in test_cases: test_count += 1 did_pass = test_connect( halt_on_connect=case.halt_on_connect, expected_state=case.expected_state, resume=case.disconnect_resume ) test_pass_count += did_pass case.passed=did_pass print("\n\nTest Summary:") print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( "#", "Prev Exit", "Halt on Connect", "Expected", "Disconnect Resume", "Exit", "Passed")) for i, case in enumerate(test_cases): print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( i, STATE_NAMES[case.prev_exit_state], repr(case.halt_on_connect), STATE_NAMES[case.expected_state], repr(case.disconnect_resume), STATE_NAMES[case.exit_state], "PASS" if case.passed else "FAIL")) print("\nPass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("CONNECT TEST SCRIPT PASSED") else: print("CONNECT TEST SCRIPT FAILED") result.passed = (test_count == test_pass_count) return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD connect test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options()) test = ConnectTest() result = [test.run(session.board)] test.print_perf_info(result) pyocd-0.13.1/test/gdb_server_json_test.py0000644000175000017500000001536213373511253020367 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 __future__ import print_function import argparse, os, sys from time import sleep, time from random import randrange import math import argparse import subprocess import json import traceback parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd import __version__ from pyocd.core.helpers import ConnectHelper from pyocd.utility.conversion import float32_to_u32 from test_util import Test, TestResult import logging from random import randrange class GdbServerJsonTestResult(TestResult): def __init__(self): super(GdbServerJsonTestResult, self).__init__(None, None, None) self.name = "gdb_server_json" class GdbServerJsonTest(Test): def __init__(self): super(GdbServerJsonTest, self).__init__("Gdb Server Json Test", gdb_server_json_test) def print_perf_info(self, result_list, output_file=None): pass def run(self, board): try: result = self.test_function(board.unique_id) except Exception as e: result = GdbServerJsonTestResult() result.passed = False print("Exception %s when testing board %s" % (e, board.unique_id)) traceback.print_exc(file=sys.stdout) result.board = board result.test = self return result def gdb_server_json_test(board_id, testing_standalone=False): test_count = 0 test_pass_count = 0 def validate_basic_keys(data): did_pass = True print('pyocd_version', end=' ') p = 'pyocd_version' in data if p: p = data['pyocd_version'] == __version__ if p: print("PASSED") else: did_pass = False print("FAILED") print('version', end=' ') p = 'version' in data if p: v = data['version'] p = 'major' in v and 'minor' in v if p: p = v['major'] == 1 and v['minor'] == 0 if p: print("PASSED") else: did_pass = False print("FAILED") print('status', end=' ') p = 'status' in data if p: p = data['status'] == 0 if p: print("PASSED") else: did_pass = False print("FAILED") return did_pass def validate_boards(data): did_pass = True print('boards', end=' ') p = 'boards' in data and type(data['boards']) is list if p: b = data['boards'] if p: print("PASSED") else: did_pass = False print("FAILED") # Only if we're running this test standalone do we want to compare against the list # of boards returned by ConnectHelper.get_sessions_for_all_connected_probes(). When running in the full # automated test suite, there could be other test jobs running concurrently that have # exclusive access to the boards they are testing. Thus, those boards will not show up # in the return list and this test will fail. if testing_standalone: try: all_sessions = ConnectHelper.get_sessions_for_all_connected_probes(blocking=False) all_mbeds = [x.board for x in all_sessions] p = len(all_mbeds) == len(b) matching_boards = 0 if p: for mbed in all_mbeds: for brd in b: if mbed.unique_id == brd['unique_id']: matching_boards += 1 p = 'info' in brd and 'target' in brd and 'board_name' in brd if not p: break if not p: break p = matching_boards == len(all_mbeds) if p: print("PASSED") else: did_pass = False print("FAILED") except Exception as e: print("FAILED") traceback.print_exc(file=sys.stdout) did_pass = False else: # Check for required keys in all board info dicts. p = True for brd in b: p = ('unique_id' in brd and 'info' in brd and 'target' in brd and 'board_name' in brd) if not p: break if p: print("PASSED") else: did_pass = False print("FAILED") return did_pass def validate_targets(data): did_pass = True print('targets', end=' ') p = 'targets' in data and type(data['targets']) is list if p: targets = data['targets'] for t in targets: p = 'name' in t and 'part_number' in t if not p: break if p: print("PASSED") else: did_pass = False print("FAILED") return did_pass result = GdbServerJsonTestResult() print("\n\n----- TESTING BOARDS LIST -----") out = subprocess.check_output(['pyocd-gdbserver', '--list', '--json']) data = json.loads(out) test_count += 2 if validate_basic_keys(data): test_pass_count += 1 if validate_boards(data): test_pass_count += 1 print("\n\n----- TESTING TARGETS LIST -----") out = subprocess.check_output(['pyocd-gdbserver', '--list-targets', '--json']) data = json.loads(out) test_count += 2 if validate_basic_keys(data): test_pass_count += 1 if validate_targets(data): test_pass_count += 1 result.passed = test_count == test_pass_count return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyocd-gdbserver json output test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) gdb_server_json_test(None, testing_standalone=True) pyocd-0.13.1/test/basic_test.py0000644000175000017500000001773213373511253016300 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2006-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 __future__ import print_function import argparse, os, sys from time import sleep from random import randrange import math parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd.core.helpers import ConnectHelper from pyocd.utility.conversion import float32_to_u32 from test_util import (Test, get_session_options) import logging class BasicTest(Test): def __init__(self): super(BasicTest, self).__init__("Basic Test", run_basic_test) def run_basic_test(board_id): return basic_test(board_id, None) def basic_test(board_id, file): with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session: board = session.board addr = 0 size = 0 f = None binary_file = "l1_" if file is None: binary_file = os.path.join(parentdir, 'binaries', board.test_binary) else: binary_file = file print("binary file: %s" % binary_file) memory_map = board.target.get_memory_map() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.get_boot_memory() addr = ram_region.start size = 0x502 addr_bin = rom_region.start addr_flash = rom_region.start + rom_region.length // 2 target = board.target flash = board.flash print("\n\n------ GET Unique ID ------") print("Unique ID: %s" % board.unique_id) print("\n\n------ TEST READ / WRITE CORE REGISTER ------") pc = target.read_core_register('pc') print("initial pc: 0x%X" % target.read_core_register('pc')) # write in pc dummy value target.write_core_register('pc', 0x3D82) print("now pc: 0x%X" % target.read_core_register('pc')) # write initial pc value target.write_core_register('pc', pc) print("initial pc value rewritten: 0x%X" % target.read_core_register('pc')) msp = target.read_core_register('msp') psp = target.read_core_register('psp') print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp)) control = target.read_core_register('control') faultmask = target.read_core_register('faultmask') basepri = target.read_core_register('basepri') primask = target.read_core_register('primask') print("CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask)) target.write_core_register('primask', 1) newPrimask = target.read_core_register('primask') print("New PRIMASK = 0x%02x" % newPrimask) target.write_core_register('primask', primask) newPrimask = target.read_core_register('primask') print("Restored PRIMASK = 0x%02x" % newPrimask) if target.has_fpu: s0 = target.read_core_register('s0') print("S0 = %g (0x%08x)" % (s0, float32_to_u32(s0))) target.write_core_register('s0', math.pi) newS0 = target.read_core_register('s0') print("New S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) target.write_core_register('s0', s0) newS0 = target.read_core_register('s0') print("Restored S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) print("\n\n------ TEST HALT / RESUME ------") print("resume") target.resume() sleep(0.2) print("halt") target.halt() print("HALT: pc: 0x%X" % target.read_core_register('pc')) sleep(0.2) print("\n\n------ TEST STEP ------") print("reset and halt") target.reset_stop_on_reset() currentPC = target.read_core_register('pc') print("HALT: pc: 0x%X" % currentPC) sleep(0.2) for i in range(4): print("step") target.step() newPC = target.read_core_register('pc') print("STEP: pc: 0x%X" % newPC) currentPC = newPC sleep(0.2) print("\n\n------ TEST READ / WRITE MEMORY ------") target.halt() print("READ32/WRITE32") val = randrange(0, 0xffffffff) print("write32 0x%X at 0x%X" % (val, addr)) target.write_memory(addr, val) res = target.read_memory(addr) print("read32 at 0x%X: 0x%X" % (addr, res)) if res != val: print("ERROR in READ/WRITE 32") print("\nREAD16/WRITE16") val = randrange(0, 0xffff) print("write16 0x%X at 0x%X" % (val, addr + 2)) target.write_memory(addr + 2, val, 16) res = target.read_memory(addr + 2, 16) print("read16 at 0x%X: 0x%X" % (addr + 2, res)) if res != val: print("ERROR in READ/WRITE 16") print("\nREAD8/WRITE8") val = randrange(0, 0xff) print("write8 0x%X at 0x%X" % (val, addr + 1)) target.write_memory(addr + 1, val, 8) res = target.read_memory(addr + 1, 8) print("read8 at 0x%X: 0x%X" % (addr + 1, res)) if res != val: print("ERROR in READ/WRITE 8") print("\n\n------ TEST READ / WRITE MEMORY BLOCK ------") data = [randrange(1, 50) for x in range(size)] target.write_memory_block8(addr, data) block = target.read_memory_block8(addr, size) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") print("\n\n------ TEST RESET ------") target.reset() sleep(0.1) target.halt() for i in range(5): target.step() print("pc: 0x%X" % target.read_core_register('pc')) print("\n\n------ TEST PROGRAM/ERASE PAGE ------") # Fill 3 pages with 0x55 page_size = flash.get_page_info(addr_flash).size fill = [0x55] * page_size flash.init() for i in range(0, 3): address = addr_flash + page_size * i # Test only supports a location with 3 aligned # pages of the same size current_page_size = flash.get_page_info(addr_flash).size assert page_size == current_page_size assert address % current_page_size == 0 flash.erase_page(address) flash.program_page(address, fill) # Erase the middle page flash.erase_page(addr_flash + page_size) # Verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased data = target.read_memory_block8(addr_flash, page_size * 3) expected = fill + [0xFF] * page_size + fill if data == expected: print("TEST PASSED") else: print("TEST FAILED") print("\n\n----- FLASH NEW BINARY -----") flash.flash_binary(binary_file, addr_bin) target.reset() if __name__ == "__main__": parser = argparse.ArgumentParser(description='A CMSIS-DAP python debugger') parser.add_argument('-f', help='binary file', dest="file") parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) file = args.file basic_test(None, file) pyocd-0.13.1/test/test_util.py0000644000175000017500000001142413373511253016164 0ustar neilneil00000000000000""" mbed CMSIS-DAP debugger Copyright (c) 2015-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 __future__ import print_function import logging import os import sys import traceback from xml.etree import ElementTree import six isPy2 = (sys.version_info[0] == 2) # Returns common option values passed in when creating test sessions. def get_session_options(): return { 'config_file' : 'test_boards.yaml', 'frequency' : 1000000, # 1 MHz } class IOTee(object): def __init__(self, *args): self.outputs = list(args) def add(self, output): self.outputs.append(output) def write(self, message): if isPy2 and isinstance(message, str): message = message.decode('UTF-8') for out in self.outputs: out.write(message) def flush(self): for out in self.outputs: out.flush() class RecordingLogHandler(logging.Handler): def __init__(self, iostream, level=logging.NOTSET): super(RecordingLogHandler, self).__init__(level) self.stream = iostream def emit(self, record): try: message = self.format(record) if isPy2 and isinstance(message, unicode): message = message.encode('UTF-8') self.stream.write(six.u(message + "\n")) except: self.handleError(record) class TestResult(object): def __init__(self, test_board, test, result): self.passed = result self._board = test_board.target_type if test_board else 'unknown' self.board_name = test_board.name if test_board else "" self.test = test self.name = "test" self.time = 0 self.output = "" @property def board(self): return self._board @board.setter def board(self, newBoard): self._board = newBoard.target_type if newBoard else 'unknown' self.board_name = newBoard.name def get_test_case(self): case = ElementTree.Element('testcase', name=self.name, classname="{}.{}.{}".format(self.board_name, self.board, self.name), status=("passed" if self.passed else "failed"), time="%.3f" % self.time ) case.text = "\n" case.tail = "\n" if not self.passed: failed = ElementTree.SubElement(case, 'failure', message="failure", type="failure" ) system_out = ElementTree.SubElement(case, 'system-out') system_out.text = self.output return case class Test(object): def __init__(self, name, function): self.name = name self.test_function = function def run(self, board): """ Run test and return the result Override this function to return a custom result """ passed = False try: self.test_function(board.unique_id) passed = True except Exception as e: print("Exception %s when testing board %s" % (e, board.unique_id)) traceback.print_exc(file=sys.stdout) result = TestResult(board, self, passed) result.name = self.name return result def print_perf_info(self, result_list, output_file=None): """ Print performance info if any """ pass @staticmethod def print_results(result_list, output_file=None): msg_format_str = "{:<15}{:<21}{:<15}{:<15}" print("\n\n------ TEST RESULTS ------") print(msg_format_str .format("Target", "Test", "Result", "Time"), file=output_file) print("", file=output_file) for result in result_list: status_str = "Pass" if result.passed else "Fail" print(msg_format_str.format(result.board, result.test.name, status_str, "%.3f" % result.time), file=output_file) @staticmethod def all_tests_pass(result_list): passed = True for result in result_list: if not result.passed: passed = False break if len(result_list) <= 0: passed = False return passed pyocd-0.13.1/test/test_pyocd_tool.sh0000755000175000017500000000073713373511253017354 0ustar neilneil00000000000000#!/bin/bash # Run through all pyocd-tool commands. pyocd-tool -tcortex_m -dinfo < target remote localhost:3333 load monitor reset ``` The `pyocd-gdbserver` executable is also usable as a drop in place replacement for OpenOCD in existing setups. The primary difference is the set of gdb monitor commands. Recommended GDB and IDE setup ----------------------------- The GDB server works well with [Eclipse](https://www.eclipse.org/) and the [GNU MCU Eclipse plug-ins](https://gnu-mcu-eclipse.github.io/). GNU MCU Eclipse fully supports pyOCD with an included pyOCD debugging plugin. To view peripheral register values either the built-in GNU MCU Eclipse register view can be used, or the Embedded System Register Viewer plugin can be installed. These can be installed from inside Eclipse using the following software update server addresses: - GNU MCU Eclipse: http://gnu-mcu-eclipse.sourceforge.net/updates - Embedded System Register Viewer: http://embsysregview.sourceforge.net/update In Eclipse, select the "Help -> Install New Software…" menu item. Then either click the "Add…" button and fill in the name and URL from above (once for each site), or simply copy the URL into the field where it says "type or select a site". Then you can select the software to install and click Next to start the process. Development setup ----------------- Please see the [Developers' Guide](docs/DEVELOPERS_GUIDE.md) for instructions on how to set up a development environment for pyOCD. Contributions ------------- We welcome contributions to pyOCD in any area. Please see the [contribution guidelines](CONTRIBUTING.md) for details. To report bugs, please [create an issue](https://github.com/mbedmicro/pyOCD/issues/new) in the GitHub project. License ------- PyOCD is licensed with Apache 2.0. See the [LICENSE](LICENSE) file for the full text of the license. Copyright © 2006-2018 Arm Ltd pyocd-0.13.1/Doxyfile0000644000175000017500000032645213373511253014337 0ustar neilneil00000000000000# Doxyfile 1.8.14 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = pyOCD # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = v0.13.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines (in the resulting output). You can put ^^ in the value part of an # alias to insert a newline as if a physical newline was in the original file. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = YES # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 0. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = YES # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = YES # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = YES # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 0 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = NO # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = docs/resources/doxygen_layout.xml # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = docs/README.md \ pyocd \ docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: https://www.gnu.org/software/libiconv/) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.idl \ *.ddl \ *.odl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.cs \ *.d \ *.php \ *.php4 \ *.php5 \ *.phtml \ *.inc \ *.m \ *.markdown \ *.md \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.for \ *.tcl \ *.vhd \ *.vhdl \ *.ucf \ *.qsf \ *.as \ *.js # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = # If clang assisted parsing is enabled you can provide the clang parser with the # path to the compilation database (see: # http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files # were built. This is equivalent to specifying the "-p" option to a clang tool, # such as clang-check. These options will then be passed to the parser. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse-libclang=ON option for CMake. # The default value is: 0. CLANG_COMPILATION_DATABASE_PATH= 0 #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = docs/resources/doxygen_header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = docs/resources/doxygen_footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = docs/resources/doxygen_style.css # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = docs/resources/Arm_logo_blue_150MN.png # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via Javascript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML # page. Disable this option to support browsers that do not have Javascript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = YES # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: https://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 1 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. # The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /