Giter Club home page Giter Club logo

pyswd's Introduction

PYSWD

Is a python module for debugging microcontrollers with SWD using ST-Link/V2 (/V2-1) or V3 debugger.

This package also contain small command line tool.

Goal

Is to create python module for access debugging interface on MCU with SWD interface.

Main purpose of python module is to create automated functional and hardware tests from simple python scripts and without special firmware for microcontroller.

Compatibility

OS

PYSWD will work on Linux, Mac and Windows.

Python

Python 3.7+

Dependencies

  • pyusb - prefer latest version from github, especially on Windows platgorm
  • libusb

Installation:

from downloaded sources

pip3 install .

reinstall (upgrade):

pip3 install --upgrade .

install for editing

pip3 install --editable .

uninstall:

pip3 uninstall pyswd

using make

make test
make install
make editable
make uninstall

Python SWD module documentation

swd.Swd:

swd.Swd(swd_frequency=4000000, logger=None, serial_no='')

Arguments:

  • swd_frequency: SWD communication frequency
  • logger: logging interface (optional)
  • serial_no: serial number of connected USB ST-Link debugger (optional). Serial number can be also part from begin or end, if more devices are detected then it stops with error
>>> import swd
>>> dev = swd.Swd()

ST-Link version

property with ST-Link version

Return:

instance of StlinkVersion

>>> dev.get_version().str
'ST-Link/V2 V2J27S6'

Target voltage

Get target voltage measured by ST-Link

Return:

float target voltage in volts

>>> dev.get_target_voltage()
3.21

ID code

Get MCU ID code

Return:

32bit unsigned with ID code

>>> hex(dev.get_idcode())
'0xbb11477'

Get memory register

get_mem32(address)

Arguments:

  • address: address in memory, must be aligned to 32bits

Return:

32bit unsigned data from memory

>>> hex(dev.get_mem32(0x08000000))
'0x20001000'

Set memory register

set_mem32(address, data)

Arguments:

  • address: address in memory, must be aligned to 32bits
  • data: 32bit unsigned data
>>> dev.set_mem32(0x20000200, 0x12345678)
>>> hex(dev.get_mem32(0x20000200))
'0x12345678'

Read memory

  • read_mem(address, size) - automatically select read access
  • read_mem8(address, size) - read using 8 bit access
  • read_mem16(address, size) - read using 16 bit access
  • read_mem32(address, size) - read using 32 bit access

Arguments:

  • address: address in memory
  • size: number of bytes to read from memory

Return:

iterable of read data

>>> data = dev.read_mem(0x08000000, 16)
>>> ' '.join(['%02x' % d for d in data])
'00 10 00 20 45 00 00 08 41 00 00 08 41 00 00 08'

Write memory

  • write_mem(address, data) - automatically select write access
  • write_mem8(address, data) - write using 8 bit access
  • write_mem16(address, data) - write using 16 bit access
  • write_mem32(address, data) - write using 32 bit access

Arguments:

  • address: address in memory
  • data: list or iterable of bytes whic will be stored into memory
>>> dev.write_mem(0x20000100, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
>>> data = dev.read_mem(0x20000100, 15)
>>> ' '.join(['%02x' % d for d in data])
'01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f'

Fill memory

  • fill_mem(address, pattern, size) - automatically select fill access
  • fill_mem8(address, pattern, size) - fill using 8 bit access
  • fill_mem16(address, pattern, size) - fill using 16 bit access
  • fill_mem32(address, pattern, size) - fill using 32 bit access

Arguments:

  • address: address in memory
  • pattern: list or iterable of bytes whic will be stored into memory
  • size: number of bytes to fill memory
>>> dev.fill_mem(0x20000300, [5, 6, 7], 20)
>>> data = dev.read_mem(0x20000300, 20)
>>> ' '.join(['%02x' % d for d in data])
'05 06 07 05 06 07 05 06 07 05 06 07 05 06 07 05 06 07 05 06'

Read core register

get_reg(register) On CortexM platform this will work only if program is halted

Arguments:

  • register: is numeric coded register (e.g. 0: R0, 1: R1, ...)

Return:

32bit unsigned data

>>> hex(dev.get_reg(1))
'0x0800012e'

Read all core registers

get_reg_all() On CortexM platform this will work only if program is halted

Return:

list of 32bit unsigned data for all registers

>>> dev.get_reg_all()
[0,  0,  16942,  10,  100,  0,  0,  0,  0,  0,  0,  0,  10,  604502776,  134288075,  134284002,  1627389952,  604502776,  0,  0,  67125248]

Write core register

get_reg(register) On CortexM platform this will work only if program is halted

Arguments:

  • register: is numeric coded register (e.g. 0: R0, 1: R1, ...)
  • data: 32bit unsigned data
>>> dev.set_reg(1, 0x12345678)

swd.CortexM:

swd.CortexM(swd)

Arguments:

  • swd: instance of Swd
>>> import swd
>>> dev = swd.Swd()
>>> cm = swd.CortexM(dev)

Read core register

get_reg(register) On CortexM platform this will work only if program is halted

Arguments:

  • register: name of register (e.g.: 'R0', 'R1', 'SP', 'PC', ...)

Return:

32bit unsigned data

>>> hex(cm.get_reg('PC'))
'0x0800012e'

Write core register

set_reg(register) On CortexM platform this will work only if program is halted

Arguments:

  • register: name of register (e.g.: 'R0', 'R1', 'SP', 'PC', ...)
  • data: 32bit unsigned data
>>> cm.set_reg('R2', 0x12345678)

Read all core registers

get_reg_all() On CortexM platform this will work only if program is halted

Return:

dictionary with register name as key and as value 32bit unsigned data for each register

>>> cm.get_reg_all()
{'LR': 134288075,
 'MSP': 604502776,
 'PC': 134284002,
 'PSP': 0,
 'PSR': 1627389952,
 'R0': 0,
 'R1': 0,
 'R10': 0,
 'R11': 0,
 'R12': 10,
 'R2': 16942,
 'R3': 10,
 'R4': 100,
 'R5': 0,
 'R6': 0,
 'R7': 0,
 'R8': 0,
 'R9': 0,
 'SP': 604502776}

Reset

reset()

>>> cm.reset()

Reset and halt

reset_halt()

>>> cm.reset_halt()

Halt core

halt()

>>> cm.halt()

step program

step()

>>> cm.step()

Run in debug mode

run()

>>> cm.run()

Disable debug mode and run

nodebug()

>>> cm.nodebug()

Check if MCU is halted

is_halted()

Return:

True if MCU is halted, or False if is running

>>> cm.is_halted()
True

Python application

Simple tool for access MCU debugging features from command line. Is installed together with python module.

$ pyswd --help

Usage:

pyswd [-h] [-V] [-q] [-d] [-i] [-v] [-f FREQ] [action [action ...]]

positional arguments:

action                actions will be processed sequentially

Optional arguments:

-h, --help            show this help message and exit
-V, --version         show program's version number and exit
-q, --quite           quite output
-d, --debug           increase debug output
-i, --info            increase info output
-v, --verbose         increase verbose output
-f FREQ, --freq FREQ  set SWD frequency
-s SERIAL, --serial SERIAL
                        select ST-Link by serial number (enough is part of serial number: begin or end

List of available actions:

  dump8:{addr}[:{size}]     print content of memory 8 bit register or dump
  dump16:{addr}[:{size}]    print content of memory 16 bit register or dump
  dump32:{addr}[:{size}]    print content of memory 32 bit register or dump
  dump:{addr}[:{size}]      print content of memory 32 bit register or 8 bit dump

  set8:{addr}:{data}[:{data}..]     set 8 bit memory
  set16:{addr}:{data}[:{data}..]    set 16 bit memory
  set32:{addr}:{data}[:{data}..]    set 32 bit memory
  set:{addr}:{data}[:{data}..]      set 32 bit memory register or 8 bit memory area

  fill8:{addr}:{size}:{pattern}     fill memory with 8 bit pattern

  reg:all                   print all core register
  reg:{reg}                 print content of core register
  reg:{reg}:{data}          set core register

  reset[:halt]              reset core or halt after reset
  run[:nodebug]             run core
  step[:{n}]                step core (n-times)
  halt                      halt core

  sleep:{seconds}           sleep (float) - insert delay between commands

(numerical values can be in different formats, like: 42, 0x2a, 0o52, 0b101010, 32K, 1M, ..)

License

Whole project is under MIT license

pyswd's People

Contributors

pavelrevak avatar primeordinalsoup avatar schneidersoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyswd's Issues

ST-Link not detected

Hi Pavel,

I just installed swd and wrote a small program to start with. But it does not find my ST-Link V3 nor a STM32-Nucleo board. I found issue #15 which looked for all devices and copied that to my program, so I hav this now:

#!/usr/bin/env python3 
# coding: utf-8 

import sys
import swd
import usb


def main ():
    devices = []
    # dev = usb.core.find(idVendor = 0x0483, idProduct = 0x374B, iProduct = 0x5, find_all = True)
    dev = usb.core.find(find_all = True)
    for device in dev:
        devices.append (device)
        print (hex(device.idVendor), hex(device.idProduct), device.serial_number)
        
    STLink = swd.Swd (swd_frequency=4000000, serial_no='')
    print (STLink)


if __name__ == '__main__':
    sys.exit(main())    

it produces this output:

0x4f2 0xb613 None
0x4f2 0xb604 0001
Traceback (most recent call last):
  File "E:\Projects\Software\Python\PySWD_Test\source\PySWD_Test.py", line 22, in <module>
    sys.exit(main())
  File "E:\Projects\Software\Python\PySWD_Test\source\PySWD_Test.py", line 17, in main
    STLink = swd.Swd (swd_frequency=4000000, serial_no='')
  File "C:\Users\Martin\AppData\Roaming\Python\Python310\site-packages\swd\swd.py", line 15, in __init__
    driver = _Stlink(
  File "C:\Users\Martin\AppData\Roaming\Python\Python310\site-packages\swd\stlink\__init__.py", line 114, in __init__
    usb = _usb.StlinkUsb(serial_no, debug=debug)
  File "C:\Users\Martin\AppData\Roaming\Python\Python310\site-packages\swd\stlink\usb.py", line 222, in __init__
    raise NoDeviceFoundException()
swd.stlink.usb.NoDeviceFoundException

With the upper dev = ... line nothing is found
I changed idProduct to 0x374B (instead of 0x374F as in issue #15), because I found this value in Windows device manager.
I'm running Python 3.10 under Win 10
(also swd.Swd () does not accept a keyword argument 'logger': error message is :TypeError: Swd.init() got an unexpected keyword argument 'logger')

Thanks for any help
Martin

Operation timed out

Hi, I'm getting an error while using the read_mem() function

I think the error happens when using read_mem() with a (size > 4) and (size % 4 != 0)

ST-Link version: ST-Link/V2-1 V2J28M18

Code to reproduce

import swd
import time

dev = swd.Swd()

while True:
    print('reading')
    data = list(dev.read_mem(0x20000000, 5))
    print(data)
    time.sleep(1)

First read is successful but Exception is thrown at second read. ST-Link needs to be unpluged and repluged to make it work again.

Traceback

Traceback (most recent call last):
  File "swd\stlinkcom.py", line 77, in write
    count = self._dev.write(self.PIPE_OUT, data, tout)
  File "Python\Python36-32\lib\site-packages\usb\core.py", line 948, in write
    self.__get_timeout(timeout)
  File "Python\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 824, in bulk_write
    timeout)
  File "Python\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 920, in __write
    _check(retval)
  File "Python\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 10060] Operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    data = list(dev.read_mem(0x20000000, 5))
  File "swd\swd.py", line 147, in read_mem
    yield from self._drv.read_mem8(address, chunk_size)
  File "swd\_log.py", line 29, in wrapper
    ret = func(*args, **kwargs)
  File "swd\stlink.py", line 370, in read_mem8
    return self._com.xfer(cmd, rx_length=size)
  File "swd\_log.py", line 29, in wrapper
    ret = func(*args, **kwargs)
  File "swd\stlinkcom.py", line 185, in xfer
    self._dev.write(command, tout)
  File "swd\_log.py", line 29, in wrapper
    ret = func(*args, **kwargs)
  File "swd\stlinkcom.py", line 80, in write
    raise StlinkComException("USB Error: %s" % err)
swd.stlinkcom.StlinkComException: USB Error: [Errno 10060] Operation timed out

Slow to connect

I do not know if this is normal but it takes more than 10 seconds to connect for me.

import time
import libusb_package
import usb.core
import usb.backend.libusb1
libusb1_backend = usb.backend.libusb1.get_backend(find_library=libusb_package.find_library)

import swd

x = time.time()
dev = swd.Swd()
y = time.time()
print('CONNECTED in {} seconds'.format(y-x))
# py -3 swdspeedtest.py
CONNECTED in 12.987221956253052 seconds

I would like to get connection speed closer to 2 seconds or less.
Perhaps it is related to libusb not pyswd? Any suggestions?

Usage of read_mem and write_mem

I wonder if read_mem and write_mem with the suffixes 8, 16, 32 all use and store data in bytes.
So what memory view do I get for write_mem32 (0x20000000, [1, 2, 3, 4])?
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 = interpreting data as 32 bit values?
01 02 03 04 00 00 00 00 00 00 00 00 00 00 00 00 = interpreting data as 8 bit values but write them in 32 bit accesses?
The same reverse for read_memX
It seems, that data is always in bytes (??) Is there a way to get 32bit data in and out or must I do the processing on my own?

set jtag speed issue

firstly thanks what a splendid piece of tidy python!

i found that it was not setting the jtag speed as expected because the hash is unordered. i made a fix, do you want a pull request for it?

Cannot get target voltage

When no target is connected it is not possible to get the target voltage.

example:

	print(swd.Swd().get_target_voltage())

Gives:

swd.stlink.StlinkException: Get IDCODE error

When debugging connection issues it is good to be able to determine if the target is powered. This is also a first indication for if the connector or adapter is connected properly.

swd.stlink broken

Getting a "module 'swd' has no attribute 'stlink'" error

Downgrading to commit d8f25cd (before the stlink driver was split into a sub-module) resolves the error.

Will pyswd run on Raspberry Pi?

Hi Pavel,
well, the question is in the title. If yes, then some instructions on installing would be appreciated.
Thanks a lot.
Martin

Disconnect

Is there a way to disconnect the Swd interface?

Command failure on certain versions

I have noticed that some stlinkv2 versions do not work as expected
I use the following python code:

import swd

dev = swd.Swd()
print(dev.get_version().str)
print(dev.get_target_voltage())
print(dev.get_idcode())

cm = swd.CortexM(dev)

cm.halt()
cm.reset()
cm.run()

print(cm.get_reg('PC'))

And get the following output:

$ python3 swdtest.py 
ST-Link/V2 V2J38S7
3.23
463475831
Traceback (most recent call last):
  File "swdtest.py", line 14, in <module>
    print(cm.get_reg('PC'))
  File "/usr/local/lib/python3.8/dist-packages/swd/cortexm.py", line 61, in get_reg
    return self._swd.get_reg(CortexM._get_reg_index(reg))
  File "/usr/local/lib/python3.8/dist-packages/swd/swd.py", line 58, in get_reg
    return self._drv.get_reg(register)
  File "/usr/local/lib/python3.8/dist-packages/swd/stlink/__init__.py", line 251, in get_reg
    _check_status(status)
  File "/usr/local/lib/python3.8/dist-packages/swd/stlink/__init__.py", line 56, in _check_status
    raise StlinkException(_com.StlinkCom.STATUS.MESSAGES[status])
swd.stlink.StlinkException: Command error

With a different stlinkv2

$ python3 swdtest.py 
ST-Link/V2 V2J33S7
3.23
463475831
0

Cannot find ST Link

Using the PyUSB I was able to find the ST link however having issues with the pyswd.
image
image

Can't write data to flash

Dose it can't support write data to flash memery? When I write data to flash,like write address 0x08000000 in stm32f103cb,it can not work!

Update Pypi Version

Hello,

the Pipy version is still stuck at version 1.0.0 which was released 2 years ago.

Create another release to make available the bug fixes in usb.py as they are quite necessary.

Thanks.

Error when loading large data

When trying to load write_mem a very large piece of data

.local/lib/python3.7/site-packages/swd/swd.py", line 180, in write_mem
    del chunk[:chunk_size32]
TypeError: 'bytes' object does not support item deletion

IDCODE confusing

CortexM(sdw.Swd()).get_idcode() gets the Stlinks IDCODE(or some other value from it) rather than the target IDCODE.
To get the target IDCODE you must use:
sdw.Swd().get_mem32(0xE0042000)

Consider changing the function name?

example get_idcode() = 2BA01477 (corresponding to Cortex ®-M4 with FPU r0p1) STM32F446xx
example swd.get_mem32(0xE0042000) = 10006430 (F103 XL REV.A)

No backend available

Hello, How to install properly?
I run under Windows.
I've installed packages pyswd 1.0.0 and pyusb 1.1.1 by just "pip install pyswd" command. When I run python and after import swd package, firstly I try to initialize by "dev = swd.Swd()" I get error "No backend available".

Please help me.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.