diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 10c0e935a..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: '{build}' -environment: - matrix: - - GENERATOR: "MSYS Makefiles" - ARCH: i686 # this is for 32-bit MinGW-w64 - - GENERATOR: "MSYS Makefiles" - ARCH: 64 -cache: - - i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - - x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - - libusb-1.0.20.7z -build_script: -- ps: | - mkdir build - cd build - if ($env:GENERATOR -ne "MSYS Makefiles") { - cmake .. -G"$env:GENERATOR" - cmake --build . --config Debug - } -- cmd: | - if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/stlink/scripts/appveyor-mingw.sh) diff --git a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md new file mode 100644 index 000000000..255596955 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md @@ -0,0 +1,38 @@ +--- +name: Bug Report (only valid if template is reused!) +about: 'Please read #906 before submitting a ticket.' +title: "[STM32 device name]: [Title]" +labels: '' +assignees: '' + +--- + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: + +- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) +- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) +- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) +- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) +- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) + +Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** + +Thank you for your support. + +The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 2d565a3f7..344a53ea6 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: Bug Report -about: Create a report to help us improve -title: "[Your device name]: [Title]" -labels: bug/needs-investigation +about: 'Please read #906 before submitting a ticket.' +title: "[STM32 device name]: [Title]" +labels: '' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 821b406bc..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ -# Bug Report - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: The bug report may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bf626eb97..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,32 +0,0 @@ -# Feature Request - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This feature request may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/support_question.md b/.github/ISSUE_TEMPLATE/support_question.md deleted file mode 100644 index 795c13a6e..000000000 --- a/.github/ISSUE_TEMPLATE/support_question.md +++ /dev/null @@ -1,32 +0,0 @@ -# Support question - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to help you with your question, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This support question may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/.gitignore b/.gitignore index 3a3a5f38a..09b9b33de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build +build-mingw obj-* *.user* +.project diff --git a/.travis.sh b/.travis.sh index 05568d37d..cc0958bf5 100755 --- a/.travis.sh +++ b/.travis.sh @@ -5,15 +5,67 @@ ls -1 /usr/bin/clang* ls -1 /usr/bin/scan-build* echo "----" -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev -else #("$TRAVIS_OS_NAME" == "osx") - brew install libusb -fi +echo "WORK DIR:$DIR" +DIR=$PWD + +if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then + echo "--> Building Release for Windows (x86-64) ..." + mkdir -p build-mingw && cd build-mingw + echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && rm -rf build-mingw && cd - + + echo "--> Building Release for Windows (i686) ..." + mkdir -p build-mingw && cd build-mingw + echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && rm -rf build-mingw && cd - + +elif [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo apt-get update -qq || true + sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev + + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && cd - -echo "=== Building Debug" -mkdir -p build/Debug && cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - + echo "--> Building Release with package..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make package && cd - -echo "=== Building Release" -mkdir -p build/Release && cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - +elif [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew install libusb + + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && cd - + + echo "--> Building Release with package..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make package && cd - + +else # local test-build + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ + make && cd - + + echo "--> Building Release with package..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ + make package && cd - +fi diff --git a/.travis.yml b/.travis.yml index b0f985012..17db35765 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,26 +1,140 @@ +language: c -compiler: - - gcc - - clang +jobs: + include: + ### 64-bit builds on AMD64 ### + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-5 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + - os: linux + dist: xenial + env: BADGE=linux + compiler: clang-3.7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-6.0 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + + - os: linux + dist: bionic + env: BADGE=linux-mingw + name: linux-mingw + compiler: gcc-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm', 'mingw-w64'] + + ### 32-bit builds on AMD64 ### + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-5 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: xenial + env: BADGE=linux + compiler: clang-3.7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-6.0 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; -language: c -os: - - linux - - osx + ### macOS ### + - os: osx + env: BADGE=osx + compiler: gcc + addons: + homebrew: + packages: + - gcc + - libusb + - gtk+3 + - os: osx + env: BADGE=osx + compiler: clang + addons: + homebrew: + packages: + - clang + - libusb + - gtk+3 -addons: - apt: - sources: - - sourceline: 'ppa:ubuntu-toolchain-r/test' - packages: - - clang - - g++-6 - - gcc-6 - - libusb-1.0.0-dev + ### Windows ### +# - os: windows +# env: BADGE=windows +# compiler: gcc script: - git fetch --tags - printenv - cmake --version - - ./.travis.sh + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi +# - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then cmd.exe /C 'mingw64-build.bat'; fi diff --git a/.version b/.version index dc1e644a1..9c6d6293b 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.0 +1.6.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2832464a2..3195bae3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,104 @@ -Stlink ChangeLog +stlink ChangeLog ================ +v1.6.1 +====== + +Release date: 2020-06-01 + +This release drops support for some older operating systems. Check project README for details. + +Features: + +* Basic compatibility for STLink-v3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) + - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 + - Compatibility with the STLink-v3 firmware which dropped support for the previous API v1 + - As of firmware version J11 the ST-LINK-V1 programmer supports API v2 commands as well +* Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) +* Added connect under reset to stlink_open_usb( ) ([#577](https://github.com/stlink-org/stlink/pull/577), [#963](https://github.com/stlink-org/stlink/pull/963)) +* Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) +* Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) +* Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) +* Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +* Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) +* Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) +* Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) +* Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) +* Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) +* STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) + - Enable mass erase with a flash programming check + - Handle G4 Cat3 devices with configurable dual bank flash by using a helper + +Updates & changes: + +* [doc] Updated compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) +* Defined libusb version compatibility for supported systems via LIBUSB_API_VERSION ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) +* Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +* [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) +* Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) +* Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) +* Updated STLink-v1 driver for macOS ([#735](https://github.com/stlink-org/stlink/pull/735), [#964](https://github.com/stlink-org/stlink/pull/964)) +* Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#870](https://github.com/stlink-org/stlink/pull/870), [#955](https://github.com/stlink-org/stlink/pull/955)) + - [refactoring] Update, corrections & cleanup for build settings (see #955 for details) + - New cpack package-config for DEB and RPM build + - Update for travis build configuration: builds for clang -m32, clang-9, MinGW-cross on linux + - Updated steps for release preparation + - Project contributors now listed in separate file + - Test files & gui now use shared stlink-library +* [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) +* Added more error info to WLOGs during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) +* [doc] Added missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) +* Added check for libssp during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) +* Silenced unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) +* [doc] Defined libusb & cmake version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) +* Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) +* [doc] st-flash --flash=n[k][m] command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) +* [refactoring] Improved cmake build process ([#912](https://github.com/stlink-org/stlink/pull/912)) + - Set up a libusb log level accordingly to verbosity ([#894](https://github.com/stlink-org/stlink/pull/894) + - [compatibility] Updated libusb to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895) + - Updated compiling doc & version support ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899)) + - Version requirements & pkg-maintainer + - Fixed install paths in build script + - Updated C-flag -std=gnu99 to gnu11) + - Added cmake uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) + - Integrated module GNUInstallDirs.cmake ([#557](https://github.com/stlink-org/stlink/pull/557)) + - [doc] Defined version compatibility and installation instructions for macOS + - [refactoring] libusb detection + - Deprecated old appveyor-mingw script +* [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) +* [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) +* [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) +* [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) +* [refactoring] st-util: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) +* [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) +* Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) +* [refactoring] Cleanup of cmake build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) + - libusb package extraction no longer requires 7zip as an external unarchiver + +Fixes: + +* Fixed wait-loop for flash_loader_run() ([#290](https://github.com/stlink-org/stlink/pull/290)) +* Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +* Clear the PG bit before setting the PER bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) +* Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) +* Fixed st-info --probe mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) +* [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) +* Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) +* Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) +* Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) +* Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) +* Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) +* Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) +* Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) +* st-flash: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) +* [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) +* Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) +* Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959)) +* Set static link for libssp (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) +* Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) +* Fixed formatting for options display in st-flash & st-info (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) + + v1.6.0 ====== @@ -8,51 +106,53 @@ Release date: 2020-02-20 Major changes and added features: -* Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760)) -* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) -* Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) -* Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776)) -* Added support to write option bytes for the STM32G0 ([#778](https://github.com/texane/stlink/pull/778)) -* Added simple read/write support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786)) -* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/texane/stlink/pull/789)) -* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/texane/stlink/pull/790)) -* Initial support for STM32L41X ([#799](https://github.com/texane/stlink/pull/799)) -* Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) -* Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) -* Added support to read and write option bytes for STM32F2 series (Orie22) -* Added full support for STLINK CHIP ID L4RX (Brad Natelborg) -* Added support to write option bytes to STM32F4 devices (Davey Struijk) +* Initial support for STM32L41X ([#754](https://github.com/stlink-org/stlink/pull/754), [#799](https://github.com/stlink-org/stlink/pull/799)) +* Verified support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/stlink-org/stlink/pull/759), [#760](https://github.com/stlink-org/stlink/pull/760), [#797](https://github.com/stlink-org/stlink/pull/797)) +* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/stlink-org/stlink/pull/767), [#768](https://github.com/stlink-org/stlink/pull/768)) +* Added call to clear PG bit after writing to flash ([#773](https://github.com/stlink-org/stlink/pull/773)) +* Added support to write option bytes for the STM32G0 ([#778](https://github.com/stlink-org/stlink/pull/778)) +* Added support for STM32WB55 chips ([#786](https://github.com/stlink-org/stlink/pull/786), [#810](https://github.com/stlink-org/stlink/pull/810), [#816](https://github.com/stlink-org/stlink/pull/816)) +* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/stlink-org/stlink/pull/789)) +* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/stlink-org/stlink/pull/790)) +* Build for Windows under Debian/Ubuntu ([#802](https://github.com/stlink-org/stlink/pull/802)) +* Allow for 64 bytes serials ([#809](https://github.com/stlink-org/stlink/pull/809)) +* Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/stlink-org/stlink/pull/814), [#839](https://github.com/stlink-org/stlink/pull/839)) +* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/stlink-org/stlink/pull/819), [#861](https://github.com/stlink-org/stlink/pull/861)) +* Added support for writing option bytes on STM32L0xx ([#830](https://github.com/stlink-org/stlink/pull/830)) +* Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/stlink-org/stlink/pull/836), [#837](https://github.com/stlink-org/stlink/pull/837)) +* Added support to read and write option bytes for STM32F446 ([#843](https://github.com/stlink-org/stlink/pull/843)) Updates and fixes: -* Build failure when platform is 32 bit, but stuct stat.st_size is 64 bit. ([#629](https://github.com/texane/stlink/pull/629)) -* Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) -* Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) -* Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) -* Fixed Debug error on line 123 in CMakeLists.txt (@xor-gate) -* Only do bank calculation on STM32L4 devices with dual banked flash ([#751](https://github.com/texane/stlink/pull/751)) -* Updated STM32F3xx chip ID that covers a few different devices ([#758](https://github.com/texane/stlink/pull/758)) -* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) -* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#763](https://github.com/texane/stlink/pull/763)) -* win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) -* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) -* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) -* Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) -* Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) -* Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) -* Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) -* Added support for writing option bytes on STM32L0 (Adrian Imboden) -* Updated documentation on software structure ([#851](https://github.com/texane/stlink/pull/851)) +* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) +* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +* Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) +* Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) +* Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/stlink-org/stlink/pull/745)) +* Fixed double dash issue in doc/man ([#746](https://github.com/stlink-org/stlink/pull/746), [#747](https://github.com/stlink-org/stlink/pull/747)) +* Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/stlink-org/stlink/pull/748)) +* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/stlink-org/stlink/pull/751)) +* Added O_BINARY option to open file ([#753](https://github.com/stlink-org/stlink/pull/753)) +* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +* win32: move usleep definition to unistd.h ([#765](https://github.com/stlink-org/stlink/pull/765)) +* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/stlink-org/stlink/pull/770), [#771](https://github.com/stlink-org/stlink/pull/771)) +* Added howto for sending NRST signal through GDB ([#774](https://github.com/stlink-org/stlink/pull/774), [#776](https://github.com/stlink-org/stlink/pull/776), [#779](https://github.com/stlink-org/stlink/pull/779)) +* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/stlink-org/stlink/pull/775)) +* Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803)) +* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/stlink-org/stlink/pull/821), [#835](https://github.com/stlink-org/stlink/pull/835), [#859](https://github.com/stlink-org/stlink/pull/859)) +* Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/stlink-org/stlink/pull/828)) +* Fixed flash size of STM32 Discovery vl ([#829](https://github.com/stlink-org/stlink/pull/829)) +* Updated documentation on software structure ([#851](https://github.com/stlink-org/stlink/pull/851)) General project updates: -* Updated issue templates, README.md and CHANGELOG.md (Nightwalker-87) -* Added CODE_OF_CONDUCT (Nightwalker-87) +* Updated README.md, CHANGELOG.md and issue templates (Nightwalker-87) * Fixed travis build config file (Nightwalker-87) +* Added CODE_OF_CONDUCT (Nightwalker-87) * Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) + v1.5.1 ====== @@ -60,29 +160,33 @@ Release date: 2018-09-13 Major changes and added features: -* Added button to export stm32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) -* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) -* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) -* Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) -* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) -* Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) -* Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) -* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) -* Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) +* Added reset through AIRCR ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) +* Added creation of icons for .desktop file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) +* Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) +* Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) +* Updated libusb to 1.0.22 ([#695](https://github.com/stlink-org/stlink/pull/695)) - (related Bugs: [#438](https://github.com/stlink-org/stlink/pull/438), [#632](https://github.com/stlink-org/stlink/pull/632)) +* Added icons for STLink GUI ([#697](https://github.com/stlink-org/stlink/pull/697)) +* Added support for STM32L4R9 target ([#694](https://github.com/stlink-org/stlink/pull/694), [#699](https://github.com/stlink-org/stlink/pull/699)) +* Added memory map for STM32F411RE target ([#709](https://github.com/stlink-org/stlink/pull/709)) +* Implemented intel hex support for GTK GUI ([#713](https://github.com/stlink-org/stlink/pull/713), [#718](https://github.com/stlink-org/stlink/pull/718)) -Fixes: +Updates and fixes: + +* Fixed missing flash_loader for STM32L0x ([#269](https://github.com/stlink-org/stlink/pull/269), [#274](https://github.com/stlink-org/stlink/pull/274), [#654](https://github.com/stlink-org/stlink/pull/654), [#675](https://github.com/stlink-org/stlink/pull/675)) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/stlink-org/stlink/pull/634), [#696](https://github.com/stlink-org/stlink/pull/696)) +* Added semihosting parameter documentation in doc/man ([#674](https://github.com/stlink-org/stlink/pull/674)) +* Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/stlink-org/stlink/pull/676)) +* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/stlink-org/stlink/pull/680)) +* Debian packaging, CMake and README.md fixes ([#682](https://github.com/stlink-org/stlink/pull/682), [#683](https://github.com/stlink-org/stlink/pull/683)) +* Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) +* Fix for libusb deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) +* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/stlink-org/stlink/pull/706)) +* [regression] stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) +* Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) +* Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/stlink-org/stlink/pull/726), [#727](https://github.com/stlink-org/stlink/pull/727), [#728](https://github.com/stlink-org/stlink/pull/728), [#729](https://github.com/stlink-org/stlink/pull/729), [#730](https://github.com/stlink-org/stlink/pull/730), [#731](https://github.com/stlink-org/stlink/pull/731), [#732](https://github.com/stlink-org/stlink/pull/732)) +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/stlink-org/stlink/pull/733)) -* Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) -* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) -* Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) -* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) -* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) -* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) -* Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) -* Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#729](https://github.com/texane/stlink/pull/729), [#731](https://github.com/texane/stlink/pull/731)) -* Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) v1.5.0 ====== @@ -91,16 +195,22 @@ Release date: 2018-02-16 Major changes and added features: -* STM32F72xx73xx support ([#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) -* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) +* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/stlink-org/stlink/pull/615), [#657](https://github.com/stlink-org/stlink/pull/657)) +* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/stlink-org/stlink/pull/641)) +* Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/stlink-org/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) -Fixes: +Updates and fixes: + +* Fixed verification of flash error for STM32L496x device ([#617](https://github.com/stlink-org/stlink/pull/617), [#618](https://github.com/stlink-org/stlink/pull/618)) +* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/stlink-org/stlink/pull/622), [#635](https://github.com/stlink-org/stlink/pull/635)) +* Updated changelog in debian package ([#630](https://github.com/stlink-org/stlink/pull/630)) +* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/stlink-org/stlink/pull/633), [#636](https://github.com/stlink-org/stlink/pull/636)) +* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/stlink-org/stlink/pull/637)) +* Fixed memory map for STM32L496xx boards ([#639](https://github.com/stlink-org/stlink/pull/639)) +* Fixed __FILE__ base name extraction ([#624](https://github.com/stlink-org/stlink/pull/624), [#628](https://github.com/stlink-org/stlink/pull/628), [#648](https://github.com/stlink-org/stlink/pull/648)) +* Added debian/triggers to run ldconfig ([#664](https://github.com/stlink-org/stlink/pull/664)) +* Fixed build on Fedora with GCC 8 ([#666](https://github.com/stlink-org/stlink/pull/666), [#667](https://github.com/stlink-org/stlink/pull/667), [#668](https://github.com/stlink-org/stlink/pull/668)) -* Fixed memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) -* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) -* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#636](https://github.com/texane/stlink/pull/636)) -* Fixed verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) -* Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) v1.4.0 ====== @@ -109,21 +219,28 @@ Release date: 2017-07-01 Major changes and added features: -* Added support for STM32L452 target ([#608](https://github.com/texane/stlink/pull/608)) -* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) -* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) -* Added support for STM32L011 target ([#572](https://github.com/texane/stlink/pull/572)) -* Allow building of debian package with CPack (@xor-gate) +* Allow building of debian package with CPack ([#554](https://github.com/stlink-org/stlink/pull/554), commit [#5b69f25](https://github.com/stlink-org/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) +* Added support for STM32L011 target ([#564](https://github.com/stlink-org/stlink/pull/564), [#565](https://github.com/stlink-org/stlink/pull/565), [#572](https://github.com/stlink-org/stlink/pull/572)) +* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/stlink-org/stlink/pull/592)) +* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/stlink-org/stlink/pull/602)) +* Added support for STM32L452 target ([#603](https://github.com/stlink-org/stlink/pull/603), [#608](https://github.com/stlink-org/stlink/pull/608)) Updates and fixes: -* Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) -* Skipped GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) -* Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) -* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) -* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) -* Fixed low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) -* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) +* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) +* Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) +* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) +* Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) +* Fixed building with mingw64 ([#569](https://github.com/stlink-org/stlink/pull/569), [#573](https://github.com/stlink-org/stlink/pull/573), [#578](https://github.com/stlink-org/stlink/pull/578), [#582](https://github.com/stlink-org/stlink/pull/582), [#584](https://github.com/stlink-org/stlink/pull/584), [#610](https://github.com/stlink-org/stlink/pull/610), [#846](https://github.com/stlink-org/stlink/pull/846)) +* Fixed possible memory leak ([#570](https://github.com/stlink-org/stlink/pull/570), [#571](https://github.com/stlink-org/stlink/pull/571)) +* Fixed installation path for shared objects ([#581](https://github.com/stlink-org/stlink/pull/581)) +* Fixed a few -Wformat warnings ([#582](https://github.com/stlink-org/stlink/pull/582)) +* Removed unused defines in mimgw.h ([#583](https://github.com/stlink-org/stlink/pull/583)) +* Skip GTK detection when cross-compiling ([#588](https://github.com/stlink-org/stlink/pull/588)) +* Fixed compilation with GCC 7 ([#590](https://github.com/stlink-org/stlink/pull/590), [#591](https://github.com/stlink-org/stlink/pull/591)) +* Fixed flashing to 'f0 device' targets ([#594](https://github.com/stlink-org/stlink/pull/594), [#595](https://github.com/stlink-org/stlink/pull/595)) +* Fixed wrong counting when flashing ([#605](https://github.com/stlink-org/stlink/pull/605)) + v1.3.1 ====== @@ -132,16 +249,19 @@ Release date: 2017-02-25 Major changes and added features: -* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) (@xor-gate) -* Stripped full paths to source files in log (commit [#2c0ab7f](https://github.com/texane/stlink/commit/2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667)) -* Added support for STM32F413 target ([#549](https://github.com/texane/stlink/pull/549)) -* Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) +* Added support for Semihosting `SYS_READC` ([#546](https://github.com/stlink-org/stlink/pull/546)) +* Added support for STM32F413 ([#549](https://github.com/stlink-org/stlink/pull/549), [#550](https://github.com/stlink-org/stlink/pull/550), [#758](https://github.com/stlink-org/stlink/pull/758)) +* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/stlink-org/stlink/pull/558), [#598](https://github.com/stlink-org/stlink/pull/598)) Updates and fixes: -* Updated documentation markdown files -* Compilation fixes ([#552](https://github.com/texane/stlink/pull/552)) -* Fixed compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) +* cmake/CPackConfig.cmake: Fixup OSX zip filename +* Updated source repositories in README.md: Windows, macOS, Alpine Linux +* Compilation fixes ([#547](https://github.com/stlink-org/stlink/pull/547), [#551](https://github.com/stlink-org/stlink/pull/551), [#552](https://github.com/stlink-org/stlink/pull/552)) +* Stripped full paths to source files in log ([#548](https://github.com/stlink-org/stlink/pull/548)) +* Fixed incorrect release folder name in docs ([#560](https://github.com/stlink-org/stlink/pull/560)) +* Fixed compilation when path includes spaces ([#561](https://github.com/stlink-org/stlink/pull/561)) + v1.3.0 ====== @@ -150,37 +270,49 @@ Release date: 2017-01-28 Major changes and added features: -* Deprecation of autotools (autoconf, automake) ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) -* Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) -* Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) -* Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) -* Support serial numbers argument for `st-util` and `st-flash` for multi-programmer setups ([#541](https://github.com/texane/stlink/pull/541)) -* Added kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) -* Added manpages (generated with pandoc from Markdown) ([#464](https://github.com/texane/stlink/pull/464)) -* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) -* Added support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) +* Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/stlink-org/stlink/pull/83), [#431](https://github.com/stlink-org/stlink/pull/431), [#434](https://github.com/stlink-org/stlink/pull/434), [#465](https://github.com/stlink-org/stlink/pull/465)) +* Added intel hex file reading for `st-flash` ([#110](https://github.com/stlink-org/stlink/pull/110), [#157](https://github.com/stlink-org/stlink/pull/157), [#457](https://github.com/stlink-org/stlink/pull/547), [#459](https://github.com/stlink-org/stlink/pull/549)) +* Added support for ARM semihosting to `st-util` ([#147](https://github.com/stlink-org/stlink/pull/147), [#227](https://github.com/stlink-org/stlink/pull/227), [#454](https://github.com/stlink-org/stlink/pull/454), [#455](https://github.com/stlink-org/stlink/pull/455)) +* Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), ([#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) +* Merge st-probe tool into st-info ([#398](https://github.com/stlink-org/stlink/pull/398)) +* Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) +* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) +* Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) +* st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), ([#527](https://github.com/stlink-org/stlink/pull/527), ([#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: -* STM32L432 ([#501](https://github.com/texane/stlink/pull/501)) -* STM32F412 ([#538](https://github.com/texane/stlink/pull/538)) -* STM32F410 ([#9c635e4](https://github.com/texane/stlink/commit/9c635e419deca697ff823000aad2e39d47ec8d6c)) -* Added memory map for STM32F401XE ([#460](https://github.com/texane/stlink/pull/460)) -* L0x Category 5 devices ([#406](https://github.com/texane/stlink/pull/406)) -* Added L0 Category 2 device (chip id: 0x425) ([#72b8e5e](https://github.com/texane/stlink/commit/72b8e5ec87e4fa386a8e94fe68df29467d4354ce)) +* STM32F401XE: Added memory map for device ([#460](https://github.com/stlink-org/stlink/pull/460)) +* STM32F410RBTx ([#418](https://github.com/stlink-org/stlink/pull/418)) +* STM32F412 ([#537](https://github.com/stlink-org/stlink/pull/537), [#538](https://github.com/stlink-org/stlink/pull/538)) +* STM32F7xx ([#324](https://github.com/stlink-org/stlink/pull/324), [#326](https://github.com/stlink-org/stlink/pull/326), [#327](https://github.com/stlink-org/stlink/pull/327), [#337](https://github.com/stlink-org/stlink/pull/337)) +* STM32F7x7x ([#433](https://github.com/stlink-org/stlink/pull/433), [#435](https://github.com/stlink-org/stlink/pull/435), [#436](https://github.com/stlink-org/stlink/pull/436), [#509](https://github.com/stlink-org/stlink/pull/509)) +* STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/stlink-org/stlink/pull/414)) +* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/stlink-org/stlink/pull/387), [#406](https://github.com/stlink-org/stlink/pull/406)) +* STM32L4xx ([#321](https://github.com/stlink-org/stlink/pull/321)) +* STM32L432 ([#500](https://github.com/stlink-org/stlink/pull/500), [#501](https://github.com/stlink-org/stlink/pull/501)) Updates and fixes: -* Set SWDCLK and fixed jtag_reset bug ([#254](https://github.com/texane/stlink/pull/254), [#291](https://github.com/texane/stlink/pull/291), [#475](https://github.com/texane/stlink/pull/475), [#533](https://github.com/texane/stlink/pull/533), [#534](https://github.com/texane/stlink/pull/534)) -* Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) -* Fixed Cygwin build ([#68b0f3b](https://github.com/texane/stlink/commit/68b0f3bddc3c4aaffe34caa6a3201029edd8ad56)) -* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) -* Fixed memory map for STM32F4 (@zulusw) -* Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390)) -* `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) -* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) +* Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) +* Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/stlink-org/stlink/pull/325)) +* Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) +* Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) +* Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) +* Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) +* Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) +* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) +* Set SWDCLK and fixed jtag_reset bug ([#462](https://github.com/stlink-org/stlink/pull/462), [#475](https://github.com/stlink-org/stlink/pull/475), [#534](https://github.com/stlink-org/stlink/pull/534)) +* doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/stlink-org/stlink/pull/478), commit [#be66bbf](https://github.com/stlink-org/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) +* Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/stlink-org/stlink/pull/479)) +* Fixed Cygwin build ([#487](https://github.com/stlink-org/stlink/pull/487), ([#506](https://github.com/stlink-org/stlink/pull/506)) +* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/stlink-org/stlink/pull/489)) +* Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/stlink-org/stlink/pull/510), [#511](https://github.com/stlink-org/stlink/pull/511)) +* Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/stlink-org/stlink/pull/514), [#525](https://github.com/stlink-org/stlink/pull/525)) + v1.2.0 ====== @@ -193,15 +325,12 @@ Features added: * Added stlink usb probe API functions (Jerry Jacobs) * Added parameter to specify one stlink v2 of many (Georg von Zengen) -Changes: - -* Refactoring/fixes of flash loader (Maxime Coquelin) - Updates and fixes: -* Synchronized cache for stm32f7 (Tristan Gingold) +* Refactoring/fixes of flash loader (Maxime Coquelin) +* Synchronized cache for STM32F7 (Tristan Gingold) * Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) -* Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) +* Fix on STM32L4 to clear flash mass erase flags on CR (Bruno Dal Bo) * Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) * Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) * Mac OS X El Capitan platform support confirmation (Nikolay) @@ -211,18 +340,24 @@ Updates and fixes: * Make sure MCU is halted before running RAM based flashloaders (mlundinse) * Could not flash STM32_F3_SMALL (Max Chen) * STM32F4 8-bit support for 1.8v operation (Andy Isaacson) -* Fixed F2 memory map (Nicolas Schodet) -* Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) +* Fixed STM32F2xx memory map (Nicolas Schodet) +* Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) +* Fixed segfault when programmer is already busy and NULL pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +* Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) +* Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) +* Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: * STM32L053R8 (Jean-Luc Béchennec) * STM32F7 Support (mlundinse) * Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) -* Basic support for F446 (Pavel Kirienko) +* Basic support for STM32F446 (Pavel Kirienko) * STM32F303 High Density +* STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) * STM32L1xx Cat.2 devices (Nicolas Schodet) +* STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) Board support added for: diff --git a/CMakeLists.txt b/CMakeLists.txt index 90378f9ed..86282775e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,229 +1,300 @@ -cmake_minimum_required(VERSION 2.8.7) -set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) +### +# General cmake settings +### + +cmake_minimum_required(VERSION 3.4.2) +cmake_policy(SET CMP0042 NEW) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +### +# General project settings +### + project(stlink C) -set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") -set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") -set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") -set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") - -if( IS_DIRECTORY ${LIB_INSTALL_DIR}) - set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") - set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") -else() - set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") - set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" ) -endif() - -if( IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) +set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") +include(GNUInstallDirs) # Define GNU standard installation directories + +## Determine project version +include(${CMAKE_MODULE_PATH}/get_version.cmake) + +## Set C build flags +if (NOT MSVC) + include(${CMAKE_MODULE_PATH}/c_flags.cmake) +else () + message(STATUS "MSVC C Flags override to /MT") + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") +endif () + +## Set installation directories for header files ### TODO: Clean this up... +if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") - set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}" ) -else() + set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}") +else () set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") -endif() - -option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) -option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) -option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) - -if (POLICY CMP0042) - # Newer cmake on MacOS should use @rpath - cmake_policy (SET CMP0042 NEW) endif () -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") -include(cmake/Version.cmake) -if(NOT MSVC) - include(cmake/CFlags.cmake) -endif() ### # Dependencies ### -find_package(LibUSB REQUIRED) -if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - find_package(PkgConfig) - pkg_check_modules(gtk gtk+-3.0) + +find_package(libusb REQUIRED) + +## Package configuration (pkg-config) on unix-based systems +if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + #add_subdirectory(cmake/pkgconfig) + find_package(PkgConfig) + pkg_check_modules(GTK3 gtk+-3.0) endif () +## Check for system-specific additional header files and libraries include(CheckIncludeFile) + CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) - add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) -endif() + add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) +endif () CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) - add_definitions(-DSTLINK_HAVE_UNISTD_H) -endif() + add_definitions(-DSTLINK_HAVE_UNISTD_H) +endif () -if (CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Debug") -endif() +include(CheckLibraryExists) -if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - include(CTest) -endif() +CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) +if (_stack_chk_fail_exists) + set(SSP_LIB -static ssp) +else () + set(SSP_LIB "") +endif () + + +### +# Main build process +### + +## Define include directories to avoid absolute paths for header defines +include_directories(${LIBUSB_INCLUDE_DIR}) + +# ==== +include_directories(${PROJECT_SOURCE_DIR}/include) ### TODO: Clean this up... +include_directories(${PROJECT_BINARY_DIR}/include/stlink) +include_directories(${PROJECT_SOURCE_DIR}/include/stlink) +include_directories(${PROJECT_SOURCE_DIR}/include/stlink/tools) +# ==== + +include_directories(src) +include_directories(src/tools) ### TODO: Clean this up... set(STLINK_HEADERS - include/stlink.h - include/stlink/usb.h - include/stlink/sg.h - include/stlink/logging.h - include/stlink/mmap.h - include/stlink/chipid.h - include/stlink/flash_loader.h -) + include/stlink.h + include/stlink/backend.h + include/stlink/chipid.h + include/stlink/commands.h + include/stlink/flash_loader.h + include/stlink/reg.h + src/logging.h + src/md5.h + src/sg.h + src/usb.h + ) set(STLINK_SOURCE - src/chipid.c - src/common.c - src/usb.c - src/sg.c - src/logging.c - src/flash_loader.c -) - -if (WIN32 OR MSYS OR MINGW) - set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") + src/common.c + src/chipid.c + src/flash_loader.c + src/logging.c + src/md5.c + src/sg.c + src/usb.c + ) + +if (WIN32 OR MINGW OR MSYS) + include_directories(src/mingw) + set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/mmap.h;src/mingw/mingw.h") endif () -include_directories(${LIBUSB_INCLUDE_DIR}) -include_directories(include) -include_directories(${PROJECT_BINARY_DIR}/include) -include_directories(src/mingw) if (MSVC) - include_directories(src/win32) - include_directories(src/getopt) - # Use string.h rather than strings.h and disable annoying warnings - add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) + include_directories(src/win32) + include_directories(src/getopt) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) +endif () + +## Include test execution for test-targets for target Debug +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + include(CTest) endif () + +### +# Libraries +### + +set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") + +# Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). +execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}" ") + + ### # Shared library ### -if (NOT WIN32) -set(STLINK_LIB_SHARED ${PROJECT_NAME}) -else () -set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) -endif() -add_library(${STLINK_LIB_SHARED} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} -) -target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) +# Set library name +if (NOT WIN32) + set(STLINK_LIB_SHARED ${PROJECT_NAME}) +else (WIN32) + set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) +endif () -if (WIN32 OR MSYS OR MINGW) - set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) -else() - set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) -endif() +add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} ${STLINK_SOURCE}) +set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") -set_target_properties(${STLINK_LIB_SHARED} - PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${STLINK_SHARED_VERSION} -) - -# Link shared library with apple OS libraries -if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC}) -endif() - -if (WIN32 OR MSYS OR MINGW) - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32) -else() - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) -endif() +set_target_properties(${STLINK_LIB_SHARED} PROPERTIES + SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_SHARED_VERSION} + OUTPUT_NAME ${PROJECT_NAME} + ) + +# Link shared library +if (APPLE) # ... with Apple macOS libraries + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) +elseif (WIN32) # ... with Windows libraries + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) +else () + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) +endif () +install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) -install(TARGETS ${STLINK_LIB_SHARED} - DESTINATION ${STLINK_LIBRARY_PATH} -) ### # Static library ### -set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) -add_library(${STLINK_LIB_STATIC} STATIC - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} -) +# Set library name +set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) -# Link shared library with apple OS libraries -if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC}) -endif() +add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} ${STLINK_SOURCE}) -if (WIN32 OR MSYS OR MINGW) - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32) -else() - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) -endif() +set(STLINK_STATIC_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) +message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}") +message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") +message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") + +set_target_properties(${STLINK_LIB_STATIC} PROPERTIES + SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_STATIC_VERSION} + OUTPUT_NAME ${PROJECT_NAME} + ) + +# Link static library +if (APPLE) # ... with Apple macOS libraries + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) +elseif (WIN32) # ... with Windows libraries + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) +else () + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) +endif () -set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) +install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) -if (STLINK_STATIC_LIB) - install(TARGETS ${STLINK_LIB_STATIC} - ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} - ) -endif() ### -# Tools +# Build toolset executables ### -add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) -if (WIN32 OR APPLE) - target_link_libraries(st-flash ${STLINK_LIB_STATIC}) -else() - target_link_libraries(st-flash ${STLINK_LIB_SHARED}) -endif() +set(ST-UTIL_SOURCES src/st-util/gdb-remote.c src/st-util/gdb-server.c src/st-util/semihosting.c) + +if (MSVC) + # Add getopt to sources + set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/getopt/getopt.c") +endif () + +add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) add_executable(st-info src/tools/info.c) +add_executable(st-util ${ST-UTIL_SOURCES}) + if (WIN32 OR APPLE) - target_link_libraries(st-info ${STLINK_LIB_STATIC}) -else() - target_link_libraries(st-info ${STLINK_LIB_SHARED}) -endif() + target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) + target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) + target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) +else () + target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) + target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) + target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) +endif () -install(TARGETS st-flash st-info - RUNTIME DESTINATION bin -) +install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) + + +### +# Device configuration (Linux only) +### if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - if (STLINK_INSTALL_MODPROBE_CONF) - install(FILES etc/modprobe.d/stlink_v1.conf - DESTINATION ${STLINK_MODPROBED_DIR}/) - endif() - if (STLINK_INSTALL_UDEV_RULES) - file(GLOB RULES_FILES etc/udev/rules.d/*.rules) - install(FILES ${RULES_FILES} - DESTINATION ${STLINK_UDEV_RULES_DIR}/) - endif() -endif() - -add_subdirectory(src/gdbserver) -add_subdirectory(src/tools/gui) - -### -# Others -### -add_subdirectory(usr/lib/pkgconfig) -add_subdirectory(include) -add_subdirectory(doc/man) -add_subdirectory(tests) - -include(cmake/CPackConfig.cmake) -include(CPack) + ## Install modprobe.d conf files to /etc/modprobe.d/ (explicitly hardcoded) + set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") + install(FILES ${CMAKE_SOURCE_DIR}/config/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}) + + ## Install udev rules files to /etc/udev/rules.d/ (explicitly hardcoded) + set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "udev rules directory") + file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) + install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) +endif () + + +### +# Additional build tasks +### + +# ==== +add_subdirectory(include) # contains subordinate CMakeLists for version config and old header includes + ### TODO: Clean this up ... +# ==== + +add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI +add_subdirectory(tests) # contains subordinate CMakeLists to build test executables +add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages + +option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) +add_subdirectory(doc/man) # contains subordinate CMakeLists to generate manpages + + +### +# Uninstall target +### + +if (NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" + IMMEDIATE @ONLY + ) + add_custom_target( + uninstall COMMAND ${CMAKE_COMMAND} + -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake + ) +endif () diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..a9bb02661 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contribution guidelines + +## Contributing to the stlink project +We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Assistance with maintaining + +We use GitHub to host code, to track issues and feature requests, as well as accept pull requests. +Report a bug by [opening a new issue]() with one of the available templates. It's that easy! + + +## Coding conventions +To read code written by other contributors can turn out to be quite demanding - a variable which seems to self-explaining, may appear cryptic to other readers. If you plan to contribute, please take this into account and feel encouraged to help others understand your code. In order to help you along, we have composed some contribution guidelines for this project. As this project already has a history you may find parts in the codebase that do not seem to comply with these guidelines, but we are trying to improve continuosly. However we can do even better, if every contributor considers the following points: + +* Naming of all source code elements as well as comments should exclusively be written in English. +* All functions and global variables should be fully explained. This includes a short description on _what_ the respective function does (but not necessarily _how_ this is achieved), an explantion of transfer parameters and/or return values (if applicable). +* Use [fixed width integer types](http://en.cppreference.com/w/c/types/integer) wherever possible and size-appropiate datatypes. +* Only make use of the datatype `char` for specific characters, otherwise use `int8_t` or `uint8_t` respectively. + + +### Coding Style +* Use 4 spaces for indentation rather than tabs (the latter results in inconsistent appearance on different platforms) +* Use `/* your comment */` formatting for multi-line comments or section titles and `// your comment` for inline comments. +* Please try to avoid special characters where possible, as they are interpreted differently on particular platforms and systems. Otherwise these may result in mojibake within the sourcecode or cause translation errors when compiling. +* Use state-of-the-art UTF-8 encoding whereever possible. + + +## Github Flow +We Use [Github Flow](https://guides.github.com/introduction/flow/index.html) which implies that all code changes happen through Pull Requests (PRs). +They are the best way to propose changes to the codebase and we actively welcome your own ones: + +1. PRs should focus on _one_ single topic. +2. Fork the repo and create your branch from `develop`. +3. Begin to implement your changes on a local or personal branch. +4. Take a look at existing PR and check if these target the same part of the codebase. + Should this be the case, you are encouraged to get in touch with the respective author and discuss on how to proceed. +5. Keep your personal feature-branch up to date with the current development branch, by merging in recent changes regularly. +6. Don't open a PR unless your contribution has evolved to a somehow completed set of changes. +7. If you've changed major features, update the documentation. +8. Ensure your PR passes our travis CI tests. +9. Issue that pull request! + + +## License +When you submit code changes, your submissions are understood to be under the same [BSD-3 License](LICENSE.md) that covers this project.
Feel free to contact the project maintainers should there be any related questions. diff --git a/LICENSE.md b/LICENSE.md index 3d464ca1e..4cb795b18 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,29 +1,29 @@ -Copyright (c) 2011 The stlink project (github.com/texane/stlink) contributors. - All rights reserved. -Copyright (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. +BSD 3-Clause License + +Copyright (c) 2020, stlink-org +All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Martin Capitanio nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile index 7f81488bb..53b0ddcde 100644 --- a/Makefile +++ b/Makefile @@ -1,49 +1,64 @@ ## -# This Makefile is used to drive building of Debug and Release -# targets of CMake +# This Makefile is used to drive building of CMake build targets ## + MAKEFLAGS += -s +# additional flags for cmake, e.g. install path -DCMAKE_INSTALL_PREFIX=$(HOME)/.local +CMAKEFLAGS += + all: release ci: debug release test help: - @echo " release: Run a release build" - @echo " debug: Run a debug build" - @echo " lint: Lint check all source-code" - @echo " test: Build and run tests" - @echo " clean: Clean all build output" - @echo "rebuild_cache: Rebuild all CMake caches" + @echo " debug: Run a debug build" + @echo " release: Run a release build" + @echo " install: Install release build" + @echo " uninstall: Uninstall release build" + @echo " package: Package release build" + @echo " lint: Lint check all source-code" + @echo " test: Build and run tests" + @echo " clean: Clean all build output" + @echo "rebuild_cache: Rebuild all CMake caches" rebuild_cache: build/Debug build/Release - @$(MAKE) -C build/Debug rebuild_cache - @$(MAKE) -C build/Release rebuild_cache + @$(MAKE) -C build/Debug rebuild_cache + @$(MAKE) -C build/Release rebuild_cache debug: build/Debug - @echo "[DEBUG]" - @$(MAKE) -C build/Debug + @echo "[DEBUG]" + @$(MAKE) -C build/Debug release: build/Release - @echo "[RELEASE]" - @$(MAKE) -C build/Release + @echo "[RELEASE]" + @$(MAKE) -C build/Release + +install: build/Release + @echo "[INSTALL] Release" + @$(MAKE) -C build/Release install + +uninstall: build/Release + @echo "[UNINSTALL] Release" + @$(MAKE) -C build/Release uninstall package: build/Release - @echo "[PACKAGE] Release" - @$(MAKE) -C build/Release package + @echo "[PACKAGE] Release" + @$(MAKE) -C build/Release package test: debug - @$(MAKE) -C build/Debug test + @echo "[TEST] Debug" + @$(MAKE) -C build/Debug test build/Debug: - @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ build/Release: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: - @echo "[CLEAN]" - @rm -Rf build + @echo "[CLEAN]" + @rm -Rf build .PHONY: clean diff --git a/README.md b/README.md index 3bc6c2c80..21ab9f48b 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,83 @@ -Open source version of the STMicroelectronics Stlink Tools +Open source version of the STMicroelectronics STlink Tools ========================================================== [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) -[![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) -[![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) -[![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/texane/stlink) +[![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) +[![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) +![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) +![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) +[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. -## Introduction +#### License + +The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**. -This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. -These programmer boards are available in four versions: +## Introduction + +STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. +It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -* **STLINKv1:** +* **STLINK/v1** _(obsolete as of 21-11-2019)_ - transport layer: SCSI passthru commands over USB - - present on STM32VL discovery kits -* **STLINKv2:** - * transport layer: raw USB commands - * present on STM32L discovery and nucleo and later kits -* **STLINKv2-1:** - * transport layer: raw USB commands - * present on some STM32 nucleo boards -* **STLINKv3:** - * _not yet supported by this toolset (but planned)_ + - stand-alone programmer and present on STM32VL Discovery boards +* **STLINK/v2** + - transport layer: raw USB commands + - stand-alone programmer and present on STM32L Discovery and Nucleo boards +* **STLINK/v2-1** + - transport layer: raw USB commands + - present on some STM32 Nucleo boards +* **STLINK/v3** + - transport layer: raw USB commands + - stand-alone programmer + +On the user level there is no difference in handling or operation between these different revisions. + +The STlink toolset includes: + +* a communication library (libstlink.a), +* a programmer and chip information tool (st-info), +* a flash manipulation tool (st-flash), +* a GDB server (st-util) and +* a GUI-Interface (stlink-gui) _[optional]_ + +## Supported operating systems and hardware combinations -## Supported hardware combinations +Currently known working combinations of programmers and targets are listed in [devices_boards.md](doc/devices_boards.md). -Currently known working combinations of programmers and targets are listed in [doc/tested-boards.md](doc/tested-boards.md). +Supported operating systems are listed in [version_support.md](doc/version_support.md). + +The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
+Please note that on macOS this support is limited to versions 10.13 - 10.15. + +## Tutorial & HOWTO + +Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. ## Installation -**Windows**: download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. +**Windows**: + +As of Release v1.6.1 stand-alone Windows binaries are made available (again) on the release page of the project. +Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is a 32-bit). +Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). -**macOS**: install [from homebrew](http://brewformulas.org/Stlink) or download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. +**macOS**: + +We recommend to install from: + +* [homebrew](https://formulae.brew.sh/formula/stlink) or +* [MacPorts](https://ports.macports.org/port/stlink) + +Alternatively one can compile and install from source as described in our [compiling manual](doc/compiling.md#macOS). **Linux**: @@ -55,9 +92,8 @@ We recommend to install `stlink-tools` from the package repository of the used d **Other Operating Systems**: -* RedHat/CentOS 7: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) -* FreeBSD: Users can install [from freshports](https://www.freshports.org/devel/stlink) -* OpenBSD: Users need to install [from source](doc/compiling.md). +* RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) +* FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) ## Installation from source (advanced users) @@ -70,198 +106,22 @@ When there is no executable available for your platform or you need the latest ( * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) * Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. * Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing github issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** -* Please start new forks from the develop branch if possible as pull requests will go into this branch as well. - +* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** +* Please start new forks from the develop branch, as pull requests will go into this branch as well. -## License - -The stlink library and tools are licensed under the [BSD license](LICENSE.md). - -The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. +Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). # Current state of the project ## Known missing features -Some features are currently missing from the `texane/stlink` toolset. +Some features are currently missing from the `stlink-org/stlink` toolset. Here we would appreciate any help and would love to welcome new contributors who want to get involved: -* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/texane/stlink/issues/136)) -* OTP area programming ([#202](https://github.com/texane/stlink/issues/202)) -* EEPROM area programming ([#318](https://github.com/texane/stlink/issues/218)) -* Protection bits area reading ([#346](https://github.com/texane/stlink/issues/346)) -* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/texane/stlink/issues/412)) -* MCU hotplug ([#449](https://github.com/texane/stlink/issues/449)) -* Writing options bytes (region) ([#458](https://github.com/texane/stlink/issues/458)) -* Control programming speed ([#462](https://github.com/texane/stlink/issues/462)) -* Support for STLINKv3 programmer ([#820](https://github.com/texane/stlink/issues/820)) - - -## Known bugs -### Sometimes flashing only works after a mass erase - -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: - -``` -2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram -2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error -2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 -``` - -Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) - - -### Flash size is detected as zero bytes size - -It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: - -``` -st-flash write prog.bin 0x8000000 -2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... -2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 -2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -As you can see, it gives out something unexpected like -``` -Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -``` -st-info --probe -Found 1 stlink programmers - serial: 303030303030303030303031 -openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" - flash: 0 (pagesize: 2048) - sram: 65536 - chipid: 0x0414 - descr: F1 High-density device -``` - -Try to remove the write protection (probably only possible with ST Link Utility from ST itself). - -Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) - - -# HOWTO -## Using the gdb server - -To run the gdb server: - -``` -$ make && [sudo] ./st-util - -There are a few options: - -./st-util - usage: - - -h, --help Print this help - -vXX, --verbose=XX Specify a specific verbosity level (0..99) - -v, --verbose Specify generally verbose logging - -s X, --stlink_version=X - Choose what version of stlink to use, (defaults to 2) - -1, --stlinkv1 Force stlink version 1 - -p 4242, --listen_port=1234 - Set the gdb server listen port. (default port: 4242) - -m, --multi - Set gdb server to extended mode. - st-util will continue listening for connections after disconnect. - -n, --no-reset - Do not reset board on connection. -``` - -The STLINKv2 device to use can be specified in the environment -variable `STLINK_DEVICE` in the format `:`. - -Then, in your project directory, someting like this... -(remember, you need to run an _ARM_ gdb, not an x86 gdb) - -``` -$ arm-none-eabi-gdb fancyblink.elf -... -(gdb) tar extended-remote :4242 -... -(gdb) load -Loading section .text, size 0x458 lma 0x8000000 -Loading section .data, size 0x8 lma 0x8000458 -Start address 0x80001c1, load size 1120 -Transfer rate: 1 KB/sec, 560 bytes/write. -(gdb) -... -(gdb) continue -``` - - -## Resetting the chip from GDB - -You may reset the chip using GDB if you want. You'll need to use `target -extended-remote' command like in this session: - -``` -(gdb) target extended-remote localhost:4242 -Remote debugging using localhost:4242 -0x080007a8 in _startup () -(gdb) kill -Kill the program being debugged? (y or n) y -(gdb) run -Starting program: /home/whitequark/ST/apps/bally/firmware.elf -``` - -Remember that you can shorten the commands. `tar ext :4242` is good enough -for GDB. - -If you need to send a hard reset signal through `NRST` pin, you can use the following command: - -``` -(gdb) monitor jtag_reset -``` - - -## Running programs from SRAM - -You can run your firmware directly from SRAM if you want to. Just link -it at 0x20000000 and do - -``` -(gdb) load firmware.elf -``` - -It will be loaded, and pc will be adjusted to point to start of the -code, if it is linked correctly (i.e. ELF has correct entry point). - - -## Writing to flash - -The GDB stub ships with a correct memory map, including the flash area. -If you would link your executable to `0x08000000` and then do - -``` -(gdb) load firmware.elf -``` - -then it would be written to the memory. - - -## Writing Option Bytes - -Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) -``` -./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 -./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 -``` - - -## FAQ - -Q: My breakpoints do not work at all or only work once. - -A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. - -Q: At some point I use GDB command `next', and it hangs. - -A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. - -Q: Load command does not work in GDB. - -A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. +* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/stlink-org/stlink/issues/136)) +* OTP & EEPROM area programming ([#202](https://github.com/stlink-org/stlink/issues/202), [#333](https://github.com/stlink-org/stlink/issues/333), [#686](https://github.com/stlink-org/stlink/issues/686)) +* Protection bits area reading ([#346](https://github.com/stlink-org/stlink/issues/346)) +* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/stlink-org/stlink/issues/412)) +* MCU hotplug ([#449](https://github.com/stlink-org/stlink/issues/449)) +* Writing options bytes (region) ([#458](https://github.com/stlink-org/stlink/issues/458)) +* Enhanced support for STLINKv3 programmer ([#820](https://github.com/stlink-org/stlink/issues/820)) diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake deleted file mode 100644 index 20768453b..000000000 --- a/cmake/CPackConfig.cmake +++ /dev/null @@ -1,27 +0,0 @@ -set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set (CPACK_SET_DESTDIR "ON") -if (APPLE) - set(CPACK_GENERATOR "ZIP") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set (CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") -elseif (WIN32) - set(CPACK_GENERATOR "ZIP") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") - set (CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") - message(STATUS "Debian-based Linux OS detected") - set(CPACK_GENERATOR "DEB") - - if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) - endif() - - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/texane/stlink") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jerry Jacobs") - set(CPACK_PACKAGE_CONTACT "jerry.jacobs@xor-gate.org") - set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 stlink programmer tools") -endif() diff --git a/cmake/Version.cmake b/cmake/Version.cmake deleted file mode 100644 index e74d775d6..000000000 --- a/cmake/Version.cmake +++ /dev/null @@ -1,51 +0,0 @@ -# Determine project version -# * Using Git -# * Local .version file -find_package (Git QUIET) -if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") - # Working off a git repo, using git versioning - # Check if HEAD is pointing to a tag - execute_process ( - COMMAND "${GIT_EXECUTABLE}" describe --always --tag - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE PROJECT_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - # If the sources have been changed locally, add -dirty to the version. - execute_process ( - COMMAND "${GIT_EXECUTABLE}" diff --quiet - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - RESULT_VARIABLE res) - - if (res EQUAL 1) - set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") - endif() - - # strip a leading v off of the version as proceeding code expectes just the version numbering. - string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) - - string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) - list(LENGTH PROJECT_VERSION_LIST len) - if(len EQUAL 3) - list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) - list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) - list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) - endif() -elseif(EXISTS ${PROJECT_SOURCE_DIR}/.version) - # If git is not available (e.g. when building from source package) - # we can extract the package version from .version file. - file (STRINGS .version PROJECT_VERSION) - - # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting - string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) - list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) - list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) - list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) -else() - message(FATAL_ERROR "Unable to determine project version") -endif() - -message(STATUS "stlink version: ${PROJECT_VERSION}") -message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake deleted file mode 100644 index 663e08175..000000000 --- a/cmake/c_flag_overrides.cmake +++ /dev/null @@ -1,7 +0,0 @@ -if(MSVC) - message(STATUS "MSVC C Flags override to /MT") - set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") -endif() diff --git a/cmake/linux-mingw32.cmake b/cmake/linux-mingw32.cmake deleted file mode 100644 index 2044a7e22..000000000 --- a/cmake/linux-mingw32.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# Sample toolchain file for building for Windows from an Debian/Ubuntu Linux system. -# -# Typical usage: -# *) install cross compiler: `sudo apt-get install mingw-w64` -# *) cd build -# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake .. - -set(CMAKE_SYSTEM_NAME Windows) -set(TOOLCHAIN_PREFIX i686-w64-mingw32) - -# cross compilers to use for C and C++ -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - -# target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands to -# search for headers/libs in the target environment and -# search for programs in the build host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file diff --git a/cmake/linux-mingw64.cmake b/cmake/linux-mingw64.cmake deleted file mode 100644 index db4bd70d0..000000000 --- a/cmake/linux-mingw64.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# Sample toolchain file for building for Windows from an Ubuntu Linux system. -# -# Typical usage: -# *) install cross compiler: `sudo apt-get install mingw-w64` -# *) cd build -# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake .. - -set(CMAKE_SYSTEM_NAME Windows) -set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) - -# cross compilers to use for C and C++ -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - -# target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands to -# search for headers/libs in the target environment and -# search for programs in the build host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7Zip.cmake deleted file mode 100644 index e4d33dfce..000000000 --- a/cmake/modules/Find7Zip.cmake +++ /dev/null @@ -1,5 +0,0 @@ -find_program(ZIP_EXECUTABLE NAMES 7z.exe p7zip - HINTS - "C:\\Program Files\\7-Zip\\" - "C:\\Program Files (x86)\\7-Zip\\" -) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake deleted file mode 100644 index 5233e489d..000000000 --- a/cmake/modules/FindLibUSB.cmake +++ /dev/null @@ -1,132 +0,0 @@ -# FindLibUSB.cmake -# Once done this will define -# -# LIBUSB_FOUND - System has libusb -# LIBUSB_INCLUDE_DIR - The libusb include directory -# LIBUSB_LIBRARY - The libraries needed to use libusb -# LIBUSB_DEFINITIONS - Compiler switches required for using libusb - -# FreeBSD -if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr/include - ) -else () - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr - /usr/local - /opt - PATH_SUFFIXES libusb-1.0 - ) -endif() - -if (APPLE) - set(LIBUSB_NAME libusb-1.0.a) -elseif(MSYS OR MINGW) - set(LIBUSB_NAME usb-1.0) -elseif(MSVC) - set(LIBUSB_NAME libusb-1.0.lib) -elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set(LIBUSB_NAME usb) -else() - set(LIBUSB_NAME usb-1.0) -endif() - -if (MSYS OR MINGW) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) - endif () -elseif(MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) - endif () -else() - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS - /usr - /usr/local - /opt) -endif () - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - -mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) - -if(NOT LIBUSB_FOUND) - if(WIN32 OR MSVC OR MINGW OR MSYS) - find_package(7Zip REQUIRED) - - set(LIBUSB_WIN_VERSION 1.0.22) - set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) - set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) - - if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) - message(STATUS "libusb archive already in build folder") - else() - message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") - file(DOWNLOAD - https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} - ) - endif() - file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - - if(${ZIP_EXECUTABLE} MATCHES "p7zip") - execute_process(COMMAND ${ZIP_EXECUTABLE} -d --keep -f ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - else() - execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) - endif() - - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include - PATH_SUFFIXES libusb-1.0 - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - - if (MSYS OR MINGW) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - endif () - elseif(MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - endif () - endif () - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - endif() -else() - message(STATUS "found USB") -endif() diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake new file mode 100644 index 000000000..bc613779d --- /dev/null +++ b/cmake/modules/Findlibusb.cmake @@ -0,0 +1,156 @@ +# Findlibusb.cmake +# Find and install external libusb library + +# Once done this will define +# +# LIBUSB_FOUND libusb present on system +# LIBUSB_INCLUDE_DIR the libusb include directory +# LIBUSB_LIBRARY the libraries needed to use libusb +# LIBUSB_DEFINITIONS compiler switches required for using libusb + +include(FindPackageHandleStandardArgs) + +if (APPLE) # macOS + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) + set(LIBUSB_NAME libusb-1.0.a) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") + endif () + +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr/include + ) + set(LIBUSB_NAME usb) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") + endif () + +elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian + # for MinGW/MSYS/MSVC: 64-bit or 32-bit? + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH 64) + else () + set(ARCH 32) + endif () + + if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) + + if (MINGW OR MSYS) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static + ) + else (MSVC) + set(LIBUSB_NAME libusb-1.0.lib) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + ) + endif () + endif () + + if (NOT LIBUSB_FOUND) + # Preparations for installing libusb library + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) + if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + endif () + + # Get libusb package + if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) + message(STATUS "libusb archive already in build folder") + else () # ... download the package + message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") + file(DOWNLOAD + https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ) + endif () + + file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) + + # Extract libusb package with cmake + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xv ${LIBUSB_WIN_ARCHIVE_PATH} + WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER} + ) + + # Find path to libusb library + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include + PATH_SUFFIXES libusb-1.0 + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + + if (MINGW OR MSYS) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + + else (MSVC) + set(LIBUSB_NAME libusb-1.0.lib) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + endif () + message(STATUS "Missing libusb library has been installed") + endif () + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + +else () # all other OS (unix-based) + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "libusb library not found on your system! Install libusb 1.0.x from your package repository.") + endif () +endif () diff --git a/cmake/CFlags.cmake b/cmake/modules/c_flags.cmake similarity index 80% rename from cmake/CFlags.cmake rename to cmake/modules/c_flags.cmake index b76856d24..520182e37 100644 --- a/cmake/CFlags.cmake +++ b/cmake/modules/c_flags.cmake @@ -1,3 +1,6 @@ +# c_flags.cmake +# Configure C compiler flags + include(CheckCCompilerFlag) function(add_cflag_if_supported flag) @@ -11,10 +14,10 @@ function(add_cflag_if_supported flag) if (C_SUPPORTS${flagclean}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) - endif() + endif () endfunction() -add_cflag_if_supported("-std=gnu99") +add_cflag_if_supported("-std=gnu11") add_cflag_if_supported("-Wall") add_cflag_if_supported("-Wextra") add_cflag_if_supported("-Wshadow") @@ -34,17 +37,17 @@ add_cflag_if_supported("-Wimplicit-function-declaration") # /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here ## if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") - add_cflag_if_supported("-Wredundant-decls") + add_cflag_if_supported("-Wredundant-decls") endif () if (NOT WIN32) - add_cflag_if_supported("-fPIC") + add_cflag_if_supported("-fPIC") endif () -if(${CMAKE_BUILD_TYPE} MATCHES "Debug") - add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") -else() - add_cflag_if_supported("-O2") +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") +else () + add_cflag_if_supported("-O2") add_cflag_if_supported("-Werror") -endif() +endif () diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake new file mode 100644 index 000000000..b80f0c9db --- /dev/null +++ b/cmake/modules/get_version.cmake @@ -0,0 +1,109 @@ +# get_version.cmake +# Determine project version by using Git or a local .version file + +set(__detect_version 0) + +find_package(Git) +set(ERROR_FLAG "0") + +if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") + # Working off a git repo, using git versioning + + # Check if HEAD is pointing to a tag + execute_process ( + COMMAND "${GIT_EXECUTABLE}" describe --always --tag + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE PROJECT_VERSION + RESULT_VARIABLE GIT_DESCRIBE_RESULT + ERROR_VARIABLE GIT_DESCRIBE_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (GIT_DESCRIBE_RESULT EQUAL 0) + + # If the sources have been changed locally, add -dirty to the version. + execute_process ( + COMMAND "${GIT_EXECUTABLE}" diff --quiet + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE res + ) + if (res EQUAL 1) + set(PROJECT_VERSION "${PROJECT_VERSION}-dirty") + endif () + + # Strip a leading v off of the version as proceeding code expects just the version numbering. + string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) + + # Read version string + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(LENGTH PROJECT_VERSION_LIST len) + if (len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + set(__detect_version 1) + set(__version_str "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") + + # Compare git-Version with version read from .version file in source folder + if (EXISTS "${PROJECT_SOURCE_DIR}/.version") + + # Local .version file found, read version string... + file(READ "${PROJECT_SOURCE_DIR}/.version" __version_file) + + # ...the version does not match with git-version string + if (NOT __version_str STREQUAL __version_file) + message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}.") + endif () + + else (EXISTS "${PROJECT_SOURCE_DIR}/.version") + + # No local .version file found: Create a new one... + file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) + + endif () + + message(STATUS "stlink version: ${PROJECT_VERSION}") + message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") + + else (len EQUAL 3) + message(STATUS "Failed to extract version parts from \"${PROJECT_VERSION}\"") + set(ERROR_FLAG "1") + endif (len EQUAL 3) + + else (GIT_DESCRIBE_RESULT EQUAL 0) + message(WARNING "git describe failed: ${GIT_DESCRIBE_ERROR}") + set(ERROR_FLAG "1") + endif(GIT_DESCRIBE_RESULT EQUAL 0) +endif () + +## +# Failure to read version via git +# Possible cases: +# -> git is not found or +# -> /.git does not exist or +# -> GIT_DESCRIBE failed or +# -> version string is of invalid format +## +if (NOT GIT_FOUND OR NOT EXISTS "${PROJECT_SOURCE_DIR}/.git" OR ERROR_FLAG EQUAL 1) + message(STATUS "Git and/or repository not found.") # e.g. when building from source package + message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file instead...") + if (EXISTS ${PROJECT_SOURCE_DIR}/.version) + file(STRINGS .version PROJECT_VERSION) + + # Read version string + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(LENGTH PROJECT_VERSION_LIST len) + if (len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + set(__detect_version 1) + else () + message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") + endif () + else (EXISTS ${PROJECT_SOURCE_DIR}/.version) + message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" does not exist.") + message(FATAL_ERROR "Unable to determine project version") + endif () +endif () diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake index f39f8d952..ff9053197 100644 --- a/cmake/modules/pandocology.cmake +++ b/cmake/modules/pandocology.cmake @@ -42,10 +42,10 @@ include(CMakeParseArguments) -if(NOT EXISTS ${PANDOC_EXECUTABLE}) +if (NOT EXISTS ${PANDOC_EXECUTABLE}) find_program(PANDOC_EXECUTABLE pandoc) mark_as_advanced(PANDOC_EXECUTABLE) -endif() +endif () ############################################################################### # Based on code from UseLATEX @@ -93,6 +93,7 @@ function(pandocology_get_file_extension varname filename) STRING(REGEX MATCH "\\.[^.]*\$" result "${name}") SET(${varname} "${result}" PARENT_SCOPE) endfunction() + ############################################################################### function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var) @@ -132,7 +133,7 @@ This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them: $ rm -r CMakeFiles/ CmakeCache.txt ") - ENDIF() + ENDif () endfunction() # This builds a document @@ -170,7 +171,7 @@ function(add_document target_name) if (NOT PANDOC_EXECUTABLE) message(WARNING "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.") return() - endif() + endif () set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE) set(oneValueArgs PRODUCT_DIRECTORY) @@ -187,29 +188,29 @@ function(add_document target_name) if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex") # if (NOT "${target_extension}" STREQUAL ".tex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'") - endif() - endif() + endif () + endif () if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN) if (SOURCE_LEN GREATER 1) MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option") - endif() + endif () # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1)) pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES}) pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES}) if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'") - endif() + endif () SET(check_target ${source_stemname}.pdf) IF (NOT ${check_target} STREQUAL ${target_name}) MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'") - endif() - endif() + endif () + endif () ## set up output directory if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "") set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product") - endif() + endif () get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE) # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE) @@ -231,7 +232,7 @@ function(add_document target_name) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources) if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources) - endif() + endif () endforeach() ## primary command @@ -254,7 +255,7 @@ function(add_document target_name) # we produce the target in the source directory, in case other build targets require it as a source COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false) ) - endif() + endif () add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) else() add_custom_command( @@ -266,7 +267,7 @@ function(add_document target_name) COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name} ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) - endif() + endif () ## figure out what all is going to be produced by this build set, and set ## those as dependencies of the primary target @@ -274,14 +275,14 @@ function(add_document target_name) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_name}) if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name}) - endif() + endif () if (${ADD_DOCUMENT_EXPORT_PDF}) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf) - endif() + endif () if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz) - endif() + endif () ## primary target # # target cannot have same (absolute name) as dependencies: @@ -325,7 +326,7 @@ function(add_document target_name) ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) add_to_make_clean(${product_directory}/${target_stemname}.pdf) - endif() + endif () ## copy products if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) @@ -335,7 +336,7 @@ function(add_document target_name) COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory} ) add_to_make_clean(${product_directory}/${target_name}) - endif() + endif () ## copy resources if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) @@ -358,7 +359,7 @@ function(add_document target_name) # ALL # DEPENDS ${product_directory}/${target_stemname}.tbz # ) - endif() + endif () endfunction(add_document) @@ -370,4 +371,3 @@ endfunction() function(add_pandoc_document) add_document(${ARGV}) endfunction() - diff --git a/cmake/modules/set_toolchain.cmake b/cmake/modules/set_toolchain.cmake new file mode 100644 index 000000000..3c40e917e --- /dev/null +++ b/cmake/modules/set_toolchain.cmake @@ -0,0 +1,20 @@ +# set_toolchain.cmake +# Toolchain file for cross-building on a Debian/Ubuntu Linux system + +### +# Set toolchain and configure target environment on the build host system +### + +# Set cross compilers to use for C and C++ +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +# Set path to directory with headers and libraries of the cross compiler +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +# Modify default behavior of FIND_XXX() commands to search for headers and libraries +# in the target environment and search for programs in the build host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/packaging/CMakeLists.txt b/cmake/packaging/CMakeLists.txt new file mode 100644 index 000000000..1cf640552 --- /dev/null +++ b/cmake/packaging/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(deb) +add_subdirectory(rpm) +add_subdirectory(windows) + +include(cpack_config.cmake) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake new file mode 100644 index 000000000..f36a50b40 --- /dev/null +++ b/cmake/packaging/cpack_config.cmake @@ -0,0 +1,115 @@ +# cpack_config.cmake +# Configure and generate packages for distribution + +### +# Configure package +### + +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set(CPACK_PACKAGE_DESCRIPTION "Open source STM32 MCU programming toolset") +set(CPACK_PACKAGE_VENDOR "stlink-org") +set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/stlink-org/stlink") + +set(CPACK_SET_DESTDIR "ON") +set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") + +if (APPLE) # macOS + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") + set(CPACK_INSTALL_PREFIX "") + +elseif (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Windows + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") + set(CPACK_INSTALL_PREFIX "") + +elseif (WIN32) # Windows cross-build on Debian/Ubuntu + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}") + set(CPACK_INSTALL_PREFIX "") + +elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is available on Debian/Ubuntu only + message(STATUS "Debian-based Linux OS detected") + + set(CPACK_GENERATOR "DEB;RPM") # RPM requires package `rpm` + + ### + # Debian (DEB) + ### + + # CPACK_DEB_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME + + ## DEB package file name + # CPack DEB generator generates package file name in deb format: + # _-_.deb + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + + # CPACK_DEBIAN_PACKAGE_VERSION --> Default: CPACK_PACKAGE_VERSION + + ## Set debian_revision number + # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. + set(CPACK_DEBIAN_PACKAGE_RELEASE "1") + + # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi ") + # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) + # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” + # CPACK_DEBIAN_ARCHIVE_TYPE --> Default: “gnutar” + # CPACK_DEBIAN_COMPRESSION_TYPE --> Default: “gzip” + # CPACK_DEBIAN_PACKAGE_PRIORITY --> Default: “optional” + # CPACK_DEBIAN_PACKAGE_HOMEPAGE --> Default: CMAKE_PROJECT_HOMEPAGE_URL + set(CPACK_DEBIAN_PACKAGE_SUGGESTS "libgtk-3-dev, pandoc") + + ## Additional package files in Debian-specific format: + # * changelog (package changelog) + # * copyright (license file) + # * rules + # * postinst-script + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/changelog" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/copyright" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/rules" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/postinst" + ) + + ### + # Slackware & Redhat (RPM) + ### + + set(CPACK_SET_DESTDIR "OFF") # Required for relocatable package + + # CPACK_RPM_PACKAGE_SUMMARY --> Default: CPACK_PACKAGE_DESCRIPTION_SUMMARY + # CPACK_RPM_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME + + ## RPM package file name + # Allow rpmbuild to generate package file name + set(CPACK_RPM_FILE_NAME RPM-DEFAULT) + + # CPACK_RPM_PACKAGE_VERSION --> Default: CPACK_PACKAGE_VERSION + # CPACK_RPM_PACKAGE_ARCHITECTURE --> Default: Native architecture output by uname -m + + ## Set rpm revision number + # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. + set(CPACK_RPM_PACKAGE_RELEASE "1") + + set(CPACK_RPM_PACKAGE_LICENSE "BSD-3") + # CPACK_RPM_PACKAGE_GROUP --> Default: “unknown” (RPM Groups are deprecated on Fedora) + # CPACK_RPM_PACKAGE_VENDOR --> Default: CPACK_PACKAGE_VENDOR (as it is set) + # CPACK_RPM_PACKAGE_URL --> Default: CMAKE_PROJECT_HOMEPAGE_URL + set(CPACK_RPM_PACKAGE_DESCRIPTION CPACK_DEBIAN_PACKAGE_DESCRIPTION) + + ## Add package changelog in rpm-specific format + set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_SOURCE_DIR}/cmake/packaging/rpm/changelog") + +else () + # No package configuration on other platforms ... +endif () + + +### +# Build packages +### + +include(CPack) diff --git a/cmake/packaging/deb/CMakeLists.txt b/cmake/packaging/deb/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog new file mode 100644 index 000000000..f4b644176 --- /dev/null +++ b/cmake/packaging/deb/changelog @@ -0,0 +1,49 @@ +stlink (1.6.0+ds-1) unstable; urgency=medium + + * Merge tag 'v1.6.0' into debian + * Bump Standards-Version to 4.5.0, no changes. + * Update libstlink1 symbols file for 1.6.0. + + -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 + +stlink (1.5.1+ds-2) unstable; urgency=medium + + * Mark library packages as Multi-Arch: same. + * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for the patch! (Closes: #941320) + * Vcs-Git: add -b debian + * Set Rules-Requires-Root: no + * Bump Standards-Version to 4.4.0 + + -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 + +stlink (1.5.1+ds-1) unstable; urgency=medium + + * Merge tag 'v1.5.1' into debian. See upstream changelog for info: + https://github.com/stlink-org/stlink/releases/tag/v1.5.1 + * Mark packages as linux-any, other systems not supported. + + -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 + +stlink (1.5.0+ds-1) unstable; urgency=medium + + * Upload to unstable. (Closes: #869421) + + -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 + +stlink (1.4.0) unstable; urgency=low + + -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 + +stlink (1.3.1) unstable; urgency=low + + -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 + +stlink (1.3.0) unstable; urgency=low + + -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 + +stlink (1.2.1) unstable; urgency=low + + * Initial Debian-Packaged Release. + + -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control new file mode 100644 index 000000000..d96746e65 --- /dev/null +++ b/cmake/packaging/deb/control @@ -0,0 +1,9 @@ +Source: stlink +Maintainer: Luca Bocassi +Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev +Standards-Version: 4.1.3 +Section: electronics +Priority: optional +Homepage: https://github.com/stlink-org/stlink +Vcs-Git: https://github.com/stlink-org/stlink.git +Vcs-Browser: https://github.com/stlink-org/stlink diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright new file mode 100644 index 000000000..a14d4eb6e --- /dev/null +++ b/cmake/packaging/deb/copyright @@ -0,0 +1,37 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: stlink +Upstream-Contact: Luca Bocassi +Source: https://github.com/stlink-org/stlink +Disclaimer: +Comment: +Files: * +Copyright: 2011-2020 stlink-org + Martin Capitanio [capnm] + Fabien Le Mentec [texane] + Jerry Jacobs [xor-gate] + [Nightwalker-87] + and many others... + A list of contributors can be found in "contributors.txt". +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/packaging/deb/postinst b/cmake/packaging/deb/postinst new file mode 100644 index 000000000..bc74428ae --- /dev/null +++ b/cmake/packaging/deb/postinst @@ -0,0 +1,4 @@ +#!/bin/bash +# This `DEBIAN/postinst` script is run post-installation + +depmod -a diff --git a/debian/rules b/cmake/packaging/deb/rules similarity index 92% rename from debian/rules rename to cmake/packaging/deb/rules index e183fffb7..2f80faeac 100755 --- a/debian/rules +++ b/cmake/packaging/deb/rules @@ -11,7 +11,7 @@ include /usr/share/dpkg/default.mk export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: - dh $@ --buildsystem cmake + dh $@ --buildsystem cmake --with cpack override_dh_auto_configure: dh_auto_configure -- \ diff --git a/cmake/packaging/rpm/CMakeLists.txt b/cmake/packaging/rpm/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog new file mode 100644 index 000000000..de2400d65 --- /dev/null +++ b/cmake/packaging/rpm/changelog @@ -0,0 +1,2 @@ +* Mon Jun 01 2020 Vasiliy Glazov - 1.6.1 +- Initial RPM-packaged release diff --git a/cmake/packaging/windows/CMakeLists.txt b/cmake/packaging/windows/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh new file mode 100644 index 000000000..d38f8d62f --- /dev/null +++ b/cmake/packaging/windows/generate_binaries.sh @@ -0,0 +1,28 @@ +### +# Build package with binaries for Windows +### + +# Install this cross-compiler toolchain: +#sudo apt-get install mingw-w64 + +# x86_64 +mkdir build-mingw +cd build-mingw +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. +make package +cp dist/*.zip ../build/Release/dist +cd .. +rm -rf build-mingw + +# i686 +mkdir build-mingw +cd build-mingw +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. +make package +cp dist/*.zip ../build/Release/dist +cd .. +rm -rf build-mingw diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/cmake/pkgconfig/CMakeLists.txt similarity index 59% rename from usr/lib/pkgconfig/CMakeLists.txt rename to cmake/pkgconfig/CMakeLists.txt index a656ff623..53870fee4 100644 --- a/usr/lib/pkgconfig/CMakeLists.txt +++ b/cmake/pkgconfig/CMakeLists.txt @@ -5,10 +5,11 @@ set(PKG_CONFIG_CFLAGS "-I\${includedir}") set(PKG_CONFIG_REQUIRES "libusb-1.0") configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" -) + "${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + ) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ -) +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig + ) diff --git a/usr/lib/pkgconfig/pkg-config.pc.cmake b/cmake/pkgconfig/pkgconfig.pc.cmake similarity index 100% rename from usr/lib/pkgconfig/pkg-config.pc.cmake rename to cmake/pkgconfig/pkgconfig.pc.cmake index 4170bf84b..4f881daec 100644 --- a/usr/lib/pkgconfig/pkg-config.pc.cmake +++ b/cmake/pkgconfig/pkgconfig.pc.cmake @@ -1,11 +1,11 @@ +prefix=${CMAKE_INSTALL_PREFIX} deb_host_multiarch=${CMAKE_LIBRARY_PATH} +libdir=${PKG_CONFIG_LIBDIR} +includedir=${PKG_CONFIG_INCLUDEDIR} + Name: ${PROJECT_NAME} Description: ${PROJECT_DESCRIPTION} Version: ${PROJECT_VERSION} -Requires: ${PKG_CONFIG_REQUIRES} -prefix=${CMAKE_INSTALL_PREFIX} -includedir=${PKG_CONFIG_INCLUDEDIR} -libdir=${PKG_CONFIG_LIBDIR} Libs: ${PKG_CONFIG_LIBS} Cflags: ${PKG_CONFIG_CFLAGS} - +Requires: ${PKG_CONFIG_REQUIRES} diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 000000000..0c9f6a437 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif () + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach (file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program("@CMAKE_COMMAND@" + ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if (NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif () + else (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif () +endforeach () diff --git a/etc/modprobe.d/stlink_v1.conf b/config/modprobe.d/stlink_v1.conf similarity index 100% rename from etc/modprobe.d/stlink_v1.conf rename to config/modprobe.d/stlink_v1.conf diff --git a/etc/udev/rules.d/49-stlinkv1.rules b/config/udev/rules.d/49-stlinkv1.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv1.rules rename to config/udev/rules.d/49-stlinkv1.rules diff --git a/etc/udev/rules.d/49-stlinkv2-1.rules b/config/udev/rules.d/49-stlinkv2-1.rules similarity index 84% rename from etc/udev/rules.d/49-stlinkv2-1.rules rename to config/udev/rules.d/49-stlinkv2-1.rules index 15a797a05..b89b84012 100644 --- a/etc/udev/rules.d/49-stlinkv2-1.rules +++ b/config/udev/rules.d/49-stlinkv2-1.rules @@ -10,6 +10,10 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ MODE:="0666", \ SYMLINK+="stlinkv2-1_%n" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3752", \ + MODE:="0666", \ + SYMLINK+="stlinkv2-1_%n" + # If you share your linux system with other users, or just don't like the # idea of write permission for everybody, you can replace MODE:="0666" with # OWNER:="yourusername" to create the device owned by you, or with diff --git a/etc/udev/rules.d/49-stlinkv2.rules b/config/udev/rules.d/49-stlinkv2.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv2.rules rename to config/udev/rules.d/49-stlinkv2.rules diff --git a/etc/udev/rules.d/49-stlinkv3.rules b/config/udev/rules.d/49-stlinkv3.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv3.rules rename to config/udev/rules.d/49-stlinkv3.rules diff --git a/contributors.txt b/contributors.txt new file mode 100644 index 000000000..fec7510c3 --- /dev/null +++ b/contributors.txt @@ -0,0 +1,131 @@ +List of contributors to the stlink project: + +Alexey Cherevatenko +Alexey Panarin +Anatoli Klassen [dev26th] +Andrea Mucignat +Andrew Andrianov [necromant] +Andrey Yurovsky +Andy Isaacson +Áron Radics +A. Sheaff +Björn Hauffe +Ihor Bobalo +Breton M. Saunders +Bruno Dal Bo +Brian Team [dot4qu] +Burns Fisher +Cheng Guokai (Xim) [chenguokai] +Chris Dew +Chris Hiszpanski +Chris Li +Chris Samuelson +Christian Deussen [nullsub] +Christophe Levantis +Craig Lilley +Dan Dev +Dan Hepler +Daniel Campoverde [alx741] +Daniel O'Connor +Dave Flogeras +Dave Murphy [WinterMute] +Dave Vandervies [dj3vande] +Denis Fokin +Denis Osterland +Dmitry Bravikov [bravikov] +Efe Can İçöz +Ethan Zonca +Fabien Chouteau +Florian Hars +Friedrich Beckmann +Gabriel Górski [Glaeqen] +Geoffrey Brown +George Talusan [gtalusan] +Georg von Zengen +Giuseppe Barba +Greg Alexander [galexander1] +Greg Meiste [meisteg] +Guillaume Revaillot [grevaillot] +Hakkavélin +Halt Hammerzeit +htk +Ian Griffiths +Jack Peel +Jakub Tyszkowski +Jan Sarenik +Jean-Luc Béchennec +Jean-Marie Lemetayer +Jeff Kent +Jeffrey Nelson +Jens Hoffmann +Jerome Lambourg +Jim Paris +Jiří Netolický +Jerry Nosky [jnosky] +Jochen Wilhelmy [Jochen0x90h] +Johannes Taelman +Jonas Danielsson +Jonas Norling +Josh Bialkowski +Karl Palsson [karlp] +Kevlar Harness +Kyle Manna +Lari Lehtomäki +Lutz Freitag [nerdmaennchen] +Martin Nowak +Matteo Collina +Max Chen +Maxime Coquelin [mcoquelin-stm32] +Maxime Vincent +Michael Pratt [prattmic] +Michael Sparmann +Mike Szczys +Miklós Márton [martonmiklos] +Magnus Lundin [mlu] +mux +Ned Konz +Nic McDonald +Nicolas Schodet +Oleksiy Slyshyk [slyshykO] +Olivier Croquette +Olivier Gay +Onno Kortmann +orangeudav +Pavel Kirienko +Pekka Nikander +Pete Nelson +Peter Torelli [petertorelli] +Peter Zotov +Petteri Aimonen +Piotr Haber +Rene Hopf [rene-dev] +Robin Kreis +Roger Wolff [rewolff] +Rob Spanton +Rytis Karpuska +Sean Simmons +Sergey Alirzaev +Simon Derr [sderr] +Simon Wright +Stany Marcel +Stefan Misik +Sven Wegener +Joel Bodenmann [Tectu] +Tuomo Kaikkonen +Theodore A. Roth +Thomas Gärtner +Tobias Badertscher +Tom de Boer +Tristan Gingold +Uli Köhler +Uwe Bonnes [UweBonnes] +Vadim Kaushan +Vasiliy Glazov [Vascom] +Vegard Storheil Eriksen +Viacheslav Dobromyslov +Victor Mayoral Vilches +William Ransohoff [WRansohoff] +Wojciech A. Koszek +Woodrow Douglass + +... and others diff --git a/debian/.gitignore b/debian/.gitignore deleted file mode 100644 index 7624d1c9b..000000000 --- a/debian/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.debhelper -files -debhelper-build-stamp -*.log -*.substvars -libstlink-dev -libstlink -stlink-gui -stlink-tools -tmp diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index ac18fd872..000000000 --- a/debian/changelog +++ /dev/null @@ -1,129 +0,0 @@ -stlink (1.5.0) unstable; urgency=medium - - [ Jerry Jacobs ] - * README.md: Update version badge to v1.4.0 - - [ Viallard Anthony ] - * Add support of STM32L496xx/4A6xx devices (#615) - - [ rdlim ] - * Fix verification of flash error for STM32L496x device (#617) (#618) - - [ dflogeras ] - * Add note about availability in Gentoo package manager (#622) - - [ yaofei zheng ] - * update debian package version (#630) - - [ Lyle Cheatham ] - * Minor formatting fix in FAQ section of README.md (#631) - - [ Vasiliy Glazov ] - * README.md: Added information about Fedora and RedHat/CentOS packages. - (#635) - * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems (#636) - - [ Gwenhael Goavec-Merou ] - * fix write for microcontroler with RAM size less or equal to 32K (#637) - - [ Mateusz Krawiec ] - * Fix memory map for stm32l496xx boards. (#639) - - [ Rüdiger Fortanier ] - * Add unknown chip output (#641) - - [ Slyshyk Oleksiy ] - * fix __FILE__ base name extraction, #628 (#648) - - [ texane ] - * STM32F72xx73xx support, from bob.feretich@rafresearch.com - - [ Kirill Kolyshkin ] - * debian/triggers: add (to run ldconfig) (#664) - - [ Slyshyk Oleksiy ] - * Try to fix #666 issue (#667) - * Try to fix 666 issue (#668) - - [ Jerry Jacobs ] - * Update ChangeLog.md - * Update README.md - - [ texane ] - * STM32F042K6 Nucleo-32 Board reported to work, by frank@bauernoeppel.de - - [ Anatol Pomozov ] - * Update .version file to match release number (#670) - - -- Anatol Pomozov Mon, 19 Feb 2018 11:00:29 -0800 - -libstlink (1.4.0) unstable; urgency=low - - * Major changes and added features - - Add support for STM32L452 target (#608) - - Initial support to compile with Microsoft Visual Studio 2017 (#602) - - Added support for flashing second bank on STM32F10x_XL (#592) - - Add support for STM32L011 target (#572) - - Allow building of debian package with CPack (@xor-gate) - * Updates and fixes - - Fix compilation with GCC 7 (#590) - - Skip GTK detection if we're cross-compiling (#588) - - Fix possible memory leak (#570) - - Fix building with mingw64 (#569, #610) - - Update libusb to 1.0.21 for Windows (#562) - - Fixing low-voltage flashing on STM32F7 parts. (#567) - - Update libusb to 1.0.21 for Windows (#562) - - -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 - -libstlink (1.3.1) unstable; urgency=low - - * Major changes and added features: - - Add preliminary support for STM32L011 to see it after probe (chipid 0x457) (@xor-gate) - - Strip full paths to source files in log (commit #2c0ab7f) - - Add support for STM32F413 target (#549) - - Add support for Semihosting SYS_READC (#546) - * Updates and fixes: - - Update documentation markdown files - - Compilation fixes (#552) - - Fix compilation when path includes spaces (#561) - - -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 - -libstlink (1.3.0) unstable; urgency=low - - * Major changes and added features: - - Deprecation of autotools (autoconf, automake) (@xor-gate) - - Removal of undocumented st-term utility, which is now replaced by st-util ARM semihosting feature (#3fd0f09) - - Add support for native debian packaging (#444, #485) - - Add intel hex file reading for st-flash (#459) - - Add --reset command to st-flash (#505) - - Support serial numbers argument for st-util and st-flash for multi-programmer setups (#541) - - Add kill ('k') command to gdb-server for st-util (#9804416) - - Add manpages (generated with pandoc from Markdown) (#464) - - Rewrite commandline parsing for st-flash (#459) - - Add support for ARM semihosting to st-util (#454, #455) - * Chip support added for: - - STM32L432 (#501) - - STM32F412 (#538) - - STM32F410 (#9c635e4) - - Add memory map for STM32F401XE (#460) - - L0x Category 5 devices (#406) - - Add L0 Category 2 device (chip id: 0x425) (#72b8e5e) - * Updates and fixes: - - Fixed STM32F030 erase error (#442) - - Fixed Cygwin build (#68b0f3b) - - Reset flash mass erase (MER) bit after mass erase for safety (#489) - - Fix memory map for STM32F4 (@zulusw) - - Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) - - st-util don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) - - Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) - - Redesign of st-flash commandline options parsing (pull-request #459) (@dev26th) - - -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - -libstlink (1.2.1) unstable; urgency=low - - * Initial Debian-Packaged Release. - - -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144f..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index e33fc757c..000000000 --- a/debian/control +++ /dev/null @@ -1,53 +0,0 @@ -Source: stlink -Priority: optional -Maintainer: Andrew 'Necromant' Andrianov -Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.1.3 -Section: electronics -Homepage: https://github.com/texane/stlink -Vcs-Git: https://github.com/texane/stlink.git -Vcs-Browser: https://github.com/texane/stlink - -Package: libstlink-dev -Section: libdevel -Architecture: any -Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains the development files for stlink. - -Package: libstlink1 -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains the shared library for stlink. - -Package: stlink-tools -Architecture: any -Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains commandline utilities for stlink, and modprobe and - udev rules. - -Package: stlink-gui -Architecture: any -Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), - ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains a GUI tool for stlink. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 941a4a011..000000000 --- a/debian/copyright +++ /dev/null @@ -1,174 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: stlink -Upstream-Contact: Andrew 'Necromant' Andrianov -Source: https://github.com/texane/stlink - -Files: * -Copyright: 2011-2018 agpanarin - 2011-2018 Alexey Cherevatenko - 2011-2018 Anatoli - 2011-2018 Andrea Mucignat - 2011-2018 Andrew 'Necromant' Andrianov - 2011-2018 Andrey Yurovsky - 2011-2018 Andy Isaacson - 2011-2018 Áron RADICS - 2011-2018 A Sheaff - 2011-2018 Björn Hauffe - 2011-2018 bob - 2011-2018 Breton M. Saunders - 2011-2018 Bruno Dal Bo - 2011-2018 Burns - 2011-2018 Chris Dew - 2011-2018 Chris Hiszpanski - 2011-2018 Chris Li - 2011-2018 Chris Samuelson - 2011-2018 Christophe Levantis - 2011-2018 Craig Lilley - 2011-2018 dandev37 - 2011-2018 Dan Hepler - 2011-2018 Daniel Campoverde [alx741] - 2011-2018 Daniel O'Connor - 2011-2018 Dave Flogeras - 2011-2018 Dave Murphy - 2011-2018 Dave Vandervies - 2011-2018 Denis Fokin - 2011-2018 Denis Osterland - 2011-2018 Dmitry Bravikov - 2011-2018 Efe Can İçöz - 2011-2018 Ethan Zonca - 2011-2018 Fabien Chouteau - 2011-2018 Fabien Le Mentec - 2011-2018 fhars - 2011-2018 Friedrich Beckmann - 2011-2018 Geoffrey Brown - 2011-2018 George Talusan - 2011-2018 Georg von Zengen - 2011-2018 giuseppe barba - 2011-2018 Greg Alexander - 2011-2018 Greg Meiste - 2011-2018 Hakkavélin - 2011-2018 htk - 2011-2018 Ian Griffiths <6thimage@gmail.com> - 2011-2018 Jack Peel - 2011-2018 Jakub Tyszkowski - 2011-2018 Jan Sarenik - 2011-2018 Jean-Luc Béchennec - 2011-2018 Jean-Marie Lemetayer - 2011-2018 Jeff Kent - 2011-2018 Jeffrey Nelson - 2011-2018 Jens Hoffmann - 2011-2018 Jerome Lambourg - 2011-2018 Jerry Jacobs - 2011-2018 Jim Paris - 2011-2018 Jiří Netolický - 2011-2018 jnosky - 2011-2018 jnosky - 2011-2018 JohannesTaelman - 2011-2018 Jonas Danielsson - 2011-2018 Jonas Norling - 2011-2018 Josh Bialkowski - 2011-2018 Karl Palsson - 2011-2018 kevin - 2011-2018 Kyle Manna - 2011-2018 Lari Lehtomäki - 2011-2018 le mentec fabien - 2011-2018 Martin Nowak - 2011-2018 Matteo Collina - 2011-2018 Max Chen - 2011-2018 Maxime Coquelin - 2011-2018 Maxime Vincent - 2011-2018 Michael Pratt - 2011-2018 Michael Sparmann - 2011-2018 Mike Szczys - 2011-2018 mlundinse - 2011-2018 mux - 2011-2018 Ned Konz - 2011-2018 Nic McDonald - 2011-2018 Nicolas Schodet - 2011-2018 Nikolay - 2011-2018 nullsub - 2011-2018 Olivier Croquette - 2011-2018 Olivier Gay - 2011-2018 Onno Kortmann - 2011-2018 orangeudav - 2011-2018 Pavel Kirienko - 2011-2018 Pekka Nikander - 2011-2018 Pete - 2011-2018 Peter Zotov - 2011-2018 Petteri Aimonen - 2011-2018 Piotr Haber - 2011-2018 Rene Hopf - 2011-2018 Robin Kreis - 2011-2018 Rob Spanton - 2011-2018 Rytis Karpuska - 2011-2018 Sean Simmons - 2011-2018 Sergey Alirzaev - 2011-2018 Simon Wright - 2011-2018 Stany MARCEL - 2011-2018 Stefan Misik - 2011-2018 Sven Wegener - 2011-2018 Tectu - 2011-2018 tekaikko - 2011-2018 texane - 2011-2018 Theodore A. Roth - 2011-2018 Thomas Gärtner - 2011-2018 Tobias Badertscher - 2011-2018 Tom de Boer - 2011-2018 Tristan Gingold - 2011-2018 Uli Köhler - 2011-2018 Uwe Bonnes - 2011-2018 Vadim Kaushan - 2011-2018 Vegard Storheil Eriksen - 2011-2018 Viacheslav Dobromyslov - 2011-2018 Victor Mayoral Vilches - 2011-2018 Wojciech A. Koszek - 2011-2018 Woodrow Douglass - 2011-2018 The "Capt'ns Missing Link" Authors. -License: BSD-3-clause - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - . - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Files: flashloaders/stm32l0x.s - flashloaders/stm32lx.s -Copyright: 2010 Spencer Oliver - 2011 Øyvind Harboe - 2011 Clement Burin des Roziers -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index 418e536e9..000000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,7 +0,0 @@ -[buildpackage] -upstream-tag = %(version)s -debian-branch = debian - -[dch] -git-log = --first-parent -customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install deleted file mode 100644 index 0c3543cd9..000000000 --- a/debian/libstlink-dev.install +++ /dev/null @@ -1,5 +0,0 @@ -usr/include/* -usr/lib/*/lib*.a -usr/lib/*/pkgconfig/* -usr/lib/*/lib*.so - diff --git a/debian/libstlink1.install b/debian/libstlink1.install deleted file mode 100644 index 3ddde5841..000000000 --- a/debian/libstlink1.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/lib*.so.* diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols deleted file mode 100644 index 51fa9bdb1..000000000 --- a/debian/libstlink1.symbols +++ /dev/null @@ -1,125 +0,0 @@ -libstlink.so.1 libstlink1 #MINVER# - _parse_version@Base 1.5.0 - _stlink_sg_close@Base 1.5.0 - _stlink_sg_core_id@Base 1.5.0 - _stlink_sg_current_mode@Base 1.5.0 - _stlink_sg_enter_jtag_mode@Base 1.5.0 - _stlink_sg_enter_swd_mode@Base 1.5.0 - _stlink_sg_exit_debug_mode@Base 1.5.0 - _stlink_sg_exit_dfu_mode@Base 1.5.0 - _stlink_sg_force_debug@Base 1.5.0 - _stlink_sg_jtag_reset@Base 1.5.0 - _stlink_sg_read_all_regs@Base 1.5.0 - _stlink_sg_read_debug32@Base 1.5.0 - _stlink_sg_read_mem32@Base 1.5.0 - _stlink_sg_read_reg@Base 1.5.0 - _stlink_sg_reset@Base 1.5.0 - _stlink_sg_run@Base 1.5.0 - _stlink_sg_status@Base 1.5.0 - _stlink_sg_step@Base 1.5.0 - _stlink_sg_version@Base 1.5.0 - _stlink_sg_write_debug32@Base 1.5.0 - _stlink_sg_write_mem32@Base 1.5.0 - _stlink_sg_write_mem8@Base 1.5.0 - _stlink_sg_write_reg@Base 1.5.0 - _stlink_usb_close@Base 1.5.0 - _stlink_usb_core_id@Base 1.5.0 - _stlink_usb_current_mode@Base 1.5.0 - _stlink_usb_enter_swd_mode@Base 1.5.0 - _stlink_usb_exit_debug_mode@Base 1.5.0 - _stlink_usb_exit_dfu_mode@Base 1.5.0 - _stlink_usb_force_debug@Base 1.5.0 - _stlink_usb_jtag_reset@Base 1.5.0 - _stlink_usb_read_all_regs@Base 1.5.0 - _stlink_usb_read_all_unsupported_regs@Base 1.5.0 - _stlink_usb_read_debug32@Base 1.5.0 - _stlink_usb_read_mem32@Base 1.5.0 - _stlink_usb_read_reg@Base 1.5.0 - _stlink_usb_read_unsupported_reg@Base 1.5.0 - _stlink_usb_reset@Base 1.5.0 - _stlink_usb_run@Base 1.5.0 - _stlink_usb_set_swdclk@Base 1.5.0 - _stlink_usb_status@Base 1.5.0 - _stlink_usb_step@Base 1.5.0 - _stlink_usb_target_voltage@Base 1.5.0 - _stlink_usb_version@Base 1.5.0 - _stlink_usb_write_debug32@Base 1.5.0 - _stlink_usb_write_mem32@Base 1.5.0 - _stlink_usb_write_mem8@Base 1.5.0 - _stlink_usb_write_reg@Base 1.5.0 - _stlink_usb_write_unsupported_reg@Base 1.5.0 - calculate_F4_sectornum@Base 1.5.0 - calculate_F7_sectornum@Base 1.5.0 - calculate_L4_page@Base 1.5.0 - is_bigendian@Base 1.5.0 - read_uint16@Base 1.5.0 - read_uint32@Base 1.5.0 - send_recv@Base 1.5.0 - send_usb_data_only@Base 1.5.0 - send_usb_mass_storage_command@Base 1.5.0 - stlink_calculate_pagesize@Base 1.5.0 - stlink_chip_id@Base 1.5.0 - stlink_chipid_get_params@Base 1.5.0 - stlink_close@Base 1.5.0 - stlink_clr_hw_bp@Base 1.5.0 - stlink_core_id@Base 1.5.0 - stlink_core_stat@Base 1.5.0 - stlink_cpu_id@Base 1.5.0 - stlink_current_mode@Base 1.5.0 - stlink_enter_swd_mode@Base 1.5.0 - stlink_erase_flash_mass@Base 1.5.0 - stlink_erase_flash_page@Base 1.5.0 - stlink_exit_debug_mode@Base 1.5.0 - stlink_exit_dfu_mode@Base 1.5.0 - stlink_fcheck_flash@Base 1.5.0 - stlink_flash_loader_init@Base 1.5.0 - stlink_flash_loader_run@Base 1.5.0 - stlink_flash_loader_write_to_sram@Base 1.5.0 - stlink_force_debug@Base 1.5.0 - stlink_fread@Base 1.5.0 - stlink_fwrite_flash@Base 1.5.0 - stlink_fwrite_sram@Base 1.5.0 - stlink_get_erased_pattern@Base 1.5.0 - stlink_is_core_halted@Base 1.5.0 - stlink_jtag_reset@Base 1.5.0 - stlink_load_device_params@Base 1.5.0 - stlink_mwrite_flash@Base 1.5.0 - stlink_mwrite_sram@Base 1.5.0 - stlink_open_usb@Base 1.5.0 - stlink_parse_ihex@Base 1.5.0 - stlink_print_data@Base 1.5.0 - stlink_probe_usb@Base 1.5.0 - stlink_probe_usb_free@Base 1.5.0 - stlink_q@Base 1.5.0 - stlink_read_all_regs@Base 1.5.0 - stlink_read_all_unsupported_regs@Base 1.5.0 - stlink_read_debug32@Base 1.5.0 - stlink_read_mem32@Base 1.5.0 - stlink_read_reg@Base 1.5.0 - stlink_read_unsupported_reg@Base 1.5.0 - stlink_reset@Base 1.5.0 - stlink_run@Base 1.5.0 - stlink_run_at@Base 1.5.0 - stlink_set_hw_bp@Base 1.5.0 - stlink_set_swdclk@Base 1.5.0 - stlink_stat@Base 1.5.0 - stlink_status@Base 1.5.0 - stlink_step@Base 1.5.0 - stlink_target_voltage@Base 1.5.0 - stlink_v1_open@Base 1.5.0 - stlink_v1_open_inner@Base 1.5.0 - stlink_verify_write_flash@Base 1.5.0 - stlink_version@Base 1.5.0 - stlink_write_debug32@Base 1.5.0 - stlink_write_dreg@Base 1.5.0 - stlink_write_flash@Base 1.5.0 - stlink_write_mem32@Base 1.5.0 - stlink_write_mem8@Base 1.5.0 - stlink_write_reg@Base 1.5.0 - stlink_write_unsupported_reg@Base 1.5.0 - stm32l1_write_half_pages@Base 1.5.0 - ugly_init@Base 1.5.0 - ugly_log@Base 1.5.0 - write_buffer_to_sram@Base 1.5.0 - write_uint16@Base 1.5.0 - write_uint32@Base 1.5.0 diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 89ae9db8f..000000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install deleted file mode 100644 index b419ac054..000000000 --- a/debian/stlink-gui.install +++ /dev/null @@ -1,4 +0,0 @@ -/usr/bin/stlink-gui* -/usr/share/stlink/stlink-gui.ui -/usr/share/applications/stlink-gui.desktop -/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/debian/stlink-tools.install b/debian/stlink-tools.install deleted file mode 100644 index ca875a0e6..000000000 --- a/debian/stlink-tools.install +++ /dev/null @@ -1,3 +0,0 @@ -/usr/bin/st-* -lib/udev/rules.d/*.rules -etc/modprobe.d/*.conf diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages deleted file mode 100644 index 6a461c09e..000000000 --- a/debian/stlink-tools.manpages +++ /dev/null @@ -1 +0,0 @@ -doc/man/st-*.1 diff --git a/debian/watch b/debian/watch deleted file mode 100644 index cc653ca9f..000000000 --- a/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=3 -opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ - https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz diff --git a/doc/app-example/CMakeLists.txt b/doc/app-example/CMakeLists.txt index 0e91bed6f..5f71a5d4f 100644 --- a/doc/app-example/CMakeLists.txt +++ b/doc/app-example/CMakeLists.txt @@ -1,28 +1,23 @@ -# Warning: This example assumes that you are building on a host -# with pkg-config available (e.g. linux). The logic required to -# build under windows/mingw and/or mac was intentionally omitted -# to keep this CMakeLists as small as possible +# Warning: This example assumes that you are building on a host with pkg-config available (e.g. linux). +# The logic required to build under windows/mingw and/or mac was intentionally omitted to keep this +# CMakeLists as small as possible. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.4.2) project(st-hello) -set(PROJECT_VERSION 0.1) +set(PROJECT_VERSION 0.1) + set(SRCS main.c) +include_directories(${STLINK_INCLUDE_DIRS}) + find_package(PkgConfig) pkg_check_modules(STLINK REQUIRED stlink) set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror") -include_directories( - ${STLINK_INCLUDE_DIRS} -) - add_executable(${PROJECT_NAME} ${SRCS}) -target_link_libraries(${PROJECT_NAME} - ${STLINK_LIBRARIES} -) +target_link_libraries(${PROJECT_NAME} ${STLINK_LIBRARIES}) -install(TARGETS ${PROJECT_NAME} - DESTINATION bin) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/doc/app-example/README.md b/doc/app-example/README.md index 683056171..f3a0bf9bb 100644 --- a/doc/app-example/README.md +++ b/doc/app-example/README.md @@ -1,2 +1,2 @@ This is a simple standalone application example that uses libstlink. -You can use this as a boilerplate for your own app development +It can be used as a boilerplate for app development. diff --git a/doc/app-example/main.c b/doc/app-example/main.c index 12621434a..b8e64b259 100644 --- a/doc/app-example/main.c +++ b/doc/app-example/main.c @@ -2,8 +2,7 @@ #include #include -static stlink_t *stlink_open_first(void) -{ +static stlink_t *stlink_open_first(void) { stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); if (sl == NULL) @@ -13,8 +12,7 @@ static stlink_t *stlink_open_first(void) } -int main() -{ +int main() { stlink_t* sl = NULL; sl = stlink_open_first(); @@ -25,5 +23,6 @@ int main() fprintf(stderr, "STlink device opened, that's cool!\n"); stlink_close(sl); + return 0; } diff --git a/doc/compiling.md b/doc/compiling.md index 61bb12e6e..428d9cc3c 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,203 +1,245 @@ # Compiling from sources -## Package requirements +## Microsoft Windows (10, 8.1) +### Common Requirements -* CMake (v2.8.7 or later) -* C compiler (gcc, clang or mingw) -* libusb 1.0 (v1.0.13 or later) -* libusb-dev 1.0 (v1.0.13 or later) -* (optional) pandoc for generating manpages from markdown +On Windows users should ensure that the following software is installed: -Run from the root of the source directory: +* `git` (_optional, but recommended_) +* `cmake` (3.17.0 or later) +* `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 -``` -$ make release -$ make debug -``` -The debug target should only be necessary for people who want - to modify the sources and run under a debugger. -The top level Makefile is just a handy wrapper for: +### Installation -``` -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=Debug .. -$ make -``` +1. Install `git` from +2. Install `cmake` from
+ Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. +3. Install + - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
+ - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 +4. Create a new destination folder at a place of your choice +5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` +6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
+ or download the stlink zip-sourcefolder from the Release page on GitHub + +#### MSVC toolchain - minimal installation + +Visual Studio IDE is not necessary, only Windows SDK & build tools are required (~3,3GB). + +1. Open +2. Navigate through menus as follows (might change overtime) + + `All downloads > Tools for Visual Studio 2019 > Build Tools for Visual Studio 2019 > Download` +3. Start downloaded executable. After Visual Studio Installer bootstraps and main window pops up, open `Individual Components` tab, and pick + - latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) + - latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) +4. After installation finishes, you can press `Launch` button in Visual Studio Installer's main menu. + - Thus you can open `Developer Command Prompt for VS 2019`. It is `cmd.exe` instance with adjusted PATHs including eg. `msbuild`. + - Alternatively, you can use `Developer Powershell for VS 2019` which is the same thing for `powershell.exe`. Both are available from Start menu. + - Another option is to add `msbuild` to PATH manually. Its location should be `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin`. Then, it should be available from any `powershell.exe` or `cmd.exe` session. -You could install to a user folder e.g `$HOME`: +### Building +#### MinGW-w64 -``` -$ cd build/Release; make install DESTDIR=$HOME -``` +1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` +2. Execute `./mingw64-build.bat` + +NOTE:
+Per default the build script (currently) uses `C:\Program Files\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin`.
+When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
+This can be achieved by opening the .bat file with a common text editor. -Or system wide: +#### MSVC toolchain + +1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. +2. Make sure the build folder exists (`mkdir build` if not). +3. From the build folder, run cmake (`cd build; cmake ..`). + +This will create a solution file `stlink.sln` in the build folder. +Now, you can build whole `stlink` suite using following command: ``` -$ cd build/Release; sudo make install +msbuild /m /p:Configuration=Release stlink.sln ``` +Options: +- `/m` - compilation runs in parallel utilizing multiple cores +- `/p:Configuration=Release` - generates *Release*, optimized build. -## Linux +Directory `\build\Release` contains final executables. +(`st-util.exe` is located in `\build\src\gdbserver\Release`). -## Common requirements +**NOTE 1:** -* Debian based distros (debian, ubuntu) - * `build-essential` -* `cmake` -* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0-0-dev` package) -* (optional) for `stlink-gui` we need libgtk-3-dev +Executables link against libusb.dll library. It has to be placed in the same directory as binaries or in PATH. +It can be copied from: `\build\3rdparty\libusb-{version}\MS{arch}\dll\libusb-1.0.dll`. -### Fixing cannot open shared object file +**NOTE 2:** -When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`. +[ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for `stlink` to work. -## Permissions with udev +## Linux +### Common requirements -Make sure you install udev files which are necessary to run the tools without root - permissions. By default most distributions don't allow access to USB devices. The - udev rules create devices nodes and set the group of this to `stlink. +Install the following packages from your package repository: -The rules are located in the `etc/udev/rules.d` directory. You will need to copy it -to /etc/udev/rules.d, and then either execute as root (or reboot your machine): +* `git` +* `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) +* `build-essential` (on Debian based distros (Debian, Ubuntu)) +* `cmake` (3.4.2 or later, use the latest version available from the repository) +* `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) +* `pkg-config` +* `libusb-1.0` +* `libusb-1.0-0-dev` (development headers for building) +* `libgtk-3-dev` (_optional_, needed for `stlink-gui`) +* `pandoc` (_optional_, needed for generating manpages from markdown) -``` -$ udevadm control --reload-rules -$ udevadm trigger -``` +or execute (Debian-based systems only): `apt-get install gcc build-essential cmake libusb-1.0 libusb-1.0-0-dev libgtk-3-dev pandoc` -Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. You must - make sure the `stlink` group exists and the user who is trying to access is added - to this group. +(Replace gcc with the intended C-compiler if necessary or leave out any optional package not needed.) -### Note for STLINKv1 usage -The STLINKv1's SCSI emulation is very broken, so the best thing to do -is tell your operating system to completely ignore it. +### Installation -Options (do one of these before you plug it in) +1. Open a new terminal console +2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` +3. Change to this directory: `cd ~/git` +4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` -* 2. `modprobe -r usb-storage && modprobe usb-storage` -* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` -* 2. `modprobe -r usb-storage && modprobe usb-storage` -### Build Debian Package +### Building -To build the debian package you need the following extra packages: `devscripts debhelper`. +1. Change into the project source directory: `cd stlink` +2. Run `make clean` -- required by some linux variants. +3. Run `make release` to create the _Release_ target +4. Run `make debug` to create the _Debug_ target (_optional_)
+ The debug target is only necessary in order to modify the sources and to run under a debugger. + +The top level Makefile is just a handy wrapper for: + +##### MinGW64: +```sh +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake -S .. +$ make ``` -$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 -$ debuild -uc -us + +##### MinGW32: + +```sh +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S .. +$ make ``` -## Mac OS X +As an alternative you may also install +- to a user folder e.g `$HOME` with `cd build/Release && make install DESTDIR=$HOME` +- or system wide with `cd build/Release && sudo make install`. -When compiling on a mac you need the following: +When installing system-wide, the dynamic library cache needs to be updated with the command `ldconfig`. -* A compiler toolchain (XCode) -* CMake -* Libusb 1.0 -The best way is to install [homebrew](http://brew.sh) which is a package manager - for opensource software which is missing from the Apple App Store. Then install - the dependencies: +### Build a Debian Package -``` -brew install libusb cmake +To build the debian package you need the following extra packages: `devscripts debhelper`. + +```sh +$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 +$ debuild -uc -us ``` -Compile as described in the first section of this document. -## Build using different directories for udev and modprobe +### Set permissions with udev -To put the udev or the modprobe configuration files into a different directory -during installation you can use the following cmake options: +By default most distributions don't allow access to USB devices. +Therefore make sure you install udev files which are necessary to run the tools without root permissions.
+udev rules create devices nodes and set the group of these to `stlink`. -``` -$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ - -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. -``` +The rules are located in the subdirectory `config/udev/rules.d` within the sourcefolder and are automatically installed along with `sudo make install` on linux. +Afterwards it may be necessary to reload the udev rules: -## Build using different directory for shared libs +```sh +$ cp etc/udev/rules.d /etc/udev/rules.d +$ udevadm control --reload-rules +$ udevadm trigger +``` -To put the compiled shared libs into a different directory during installation -you can use the following cmake option: +Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`.
+You need to ensure that the group `stlink` exists and the user who is trying to access these devices is a member of this group. -``` -$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. -``` -## Windows (MinGW64) +### Note on the use of STLink-v1 programmers (legacy): -### Prequistes +As the STLINKv1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
+Choose one of the following options _before_ connecting the device to your computer: -* 7Zip -* CMake 2.8 or higher -* MinGW64 GCC toolchain (5.3.0) +* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +* _OR_ + 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` + 2. `modprobe -r usb-storage && modprobe usb-storage` +* _OR_ + 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` + 2. `modprobe -r usb-storage && modprobe usb-storage` -### Installation -1. Install 7Zip from -2. Install CMake from -3. Install MinGW64 from (mingw-w64-install.exe) -4. Git clone or download stlink sourcefiles zip +## macOS +### Common requirements -### Building +The best and recommended way is to install a package manager for open source software, +either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). -Check and execute (in the script folder) `\scripts\mingw64-build.bat` +Then install the following dependencies from the package repository: -NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` - the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` +* `git` +* `gcc` or `llvm` (for clang) (C-compiler) +* `cmake` +* `pkg-config` +* `libusb` +* `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) -## Windows (Visual Studio) +To do this with only one simple command, type: -### Prerequisites +* for homebrew: + - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or + - with clang: `sudo brew install git llvm cmake libusb gtk+3` or +* for MacPorts: + - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or + - with clang: `sudo port install git llvm-10 cmake libusb gtk3` -* 7Zip -* CMake (tested with version 3.9.0-rc2) -* Visual Studio 2017 Community (other versions will likely work but are untested; the Community edition is free for open source -development) ### Installation -1. Install 7Zip from -2. Install CMake from -3. Git clone or download stlink sourcefiles zip +1. Open a new terminal window +2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` +3. Change to this directory: `cd ~/git` +4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` + ### Building -These instructions are for a 32bit version. +1. Change into the project source directory: `cd stlink` +2. Run `make release` to create the _Release_ target +3. Run `make debug` to create the _Debug_ target (_optional_)
+ The debug target is only necessary in order to modify the sources and to run under a debugger. -In a command prompt, change directory to the folder where the stlink files were cloned (or unzipped). -Make sure the build folder exists (`mkdir build` if not). -From the build folder, run cmake (`cd build; cmake ..`). -This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or -Release) and build the solution normally (F7). +## Build options +### Build using a different directory for shared libs -NOTES: This solution will link to the dll version of libusb-1.0. To debug or run the executable, the dll version of libusb-1.0 must -be either on the path, or in the same folder as the executable. It can be copied from here: -`build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +To put the compiled shared libs into a different directory during installation, +you can use the cmake option `cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..`. -## Linux (MinGW64) -### Prequistes +### Standard installation directories -* 7Zip -* CMake 2.8 or higher -* MinGW64 GCC toolchain (5.3.0) +The cmake build system of this toolset includes `GNUInstallDirs` to define GNU standard installation directories. +This module provides install directory variables as defined by the GNU Coding Standards. -### Installation (Debian / Ubuntu) +Below are the preset default cmake options, which apply if none of these options are redefined: -sudo apt install p7zip mingw-w64 +* `-DCMAKE_INSTALL_SYSCONFDIR=/etc` +* `-DCMAKE_INSTALL_PREFIX=/usr/local` -### Building -These instructions are for a 32bit version. - -```sh -cd -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S . -B ./build/linux-mingw32 -cmake --build ./build/linux-mingw32 --target all -``` +Author: nightwalker-87 diff --git a/doc/devices_boards.md b/doc/devices_boards.md new file mode 100644 index 000000000..8291f7532 --- /dev/null +++ b/doc/devices_boards.md @@ -0,0 +1,259 @@ +Boards supported by the STlink toolset +====================================== + +The following devices are supported by the STlink tools. + +All Boards are expected to work with ST-Link-v2 programmers. + + +**STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x440 | STM32F0**30**x**8** | +| 0x442 | STM32F0**30**x**C** | +| 0x444 | STM32F0**3**xx**4** | +| 0x444 | STM32F0**3**xx**6** | +| 0x445 | STM32F0**4**xxx | +| 0x440 | STM32F0**5**xxx | +| 0x445 | STM32F0**70**x**6** | +| 0x448 | STM32F0**70**x**B** | +| 0x448 | STM32F0**71**xx | +| 0x448 | STM32F0**72**xx | +| 0x442 | STM32F0**9**xxx | + +Tested boards [incl. STLink programmers]: +* Nucleo-F030R8 [v2-1] +* Nucleo-32 [v2-1] +* STM32F0-Discovery [v2] +* STM320518-EVAL +* Nucleo-F072RB [v2-1] +* Nucleo-F091RC [v2-1] + + +**STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** + +| Product-Code | Product Line | +| --- | --- | +| STM32F10**0**yyxx | Value line (V) | +| STM32F10**1**yyxx | Access line (A) | +| STM32F10**2**yyxx | USB Access line (USB-A) | +| STM32F10**3**yyxx | Performance line (P) | +| STM32F10**5**yyxx | Connectivity line (C) | +| STM32F10**7**yyxx | Connectivity line (C) | + +| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | +| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | +| 0x414 | High density | xC xD xE | | F101 | F103 | | | +| 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
F107 | +| 0x420 | Medium density value | x8 xB | F100 | | | | | +| 0x428 | High density Value | xC xD xE | F100 | | | | | +| 0x430 | XL-Density | xF XG | | F101 | | F103 | | + +Tested boards [incl. STLink programmers]: +* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] +* STM32F103-Bluepill: C8Tx & R8xx [v2] +* Nucleo-F103RB [v2-1] +* HY-STM32 (STM32F103VETx) [v1, v2] +* DecaWave EVB1000 (STM32F105RCTx) [v1, v2] + + +**STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID)** + +| Chip-ID | Product-Code | Product Line | +| --- | --- | --- | +| 0x411 | STM32F2yyxx | (all devices) | + + +**STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM3F1c_CORE_ID)** + +| Product-Code | Chip-ID | STLink
Programmer | Boards | +| --- | --- | --- | --- | +| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
STM32F103C8T6 clone from China Key Systems (CKS) | +| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
STM32F103C8T6 clone from China Key Systems (CKS) | + + +**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID)** + +| Product-Code | Product Line | +| --- | --- | +| STM32F3**01**yyxx | Access line (A) | +| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | +| STM32F3**03**yyxx | Performance line (P) | +| STM32F3**34**yy | Digital Power line (DP) | +| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | +| STM32F3**18**yy | General Purpose line (GP) 64k/16k | +| STM32F3**28**yy | General Purpose line (GP) 64k/16k | +| STM32F3**58**yy | General Purpose line (GP) 265k/48k | +| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | +| STM32F3**98**yy | General Purpose line (GP) 512k/80k | + +| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | +| --- | --- | --- | --- | --- | --- | --- | +| 0x422 | _N/A_ | xB xC | | F302 | F303 | | +| 0x422 | _N/A_ | - | | | | F358 | +| 0x432 | _N/A_ | - | | | | F373
F378 | +| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | +| 0x438 | _N/A_ | - | | | | F334
F328 | +| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | +| 0x439 | _N/A_ | - | | | | F318 | +| 0x446 | _N/A_ | xD xE | | F302 | F303 | | +| 0x446 | _N/A_ | - | | | | F398 | + +Tested boards [incl. STLink programmers]: +* Nucleo-F302K8 [v2-1] +* Nucleo-F303K8 [v2-1] +* STM32F3348-Discovery [v2-1] +* Nucleo-F334R8 [v2-1] +* STM32F303-Discovery [v2] +* Nucleo-F303RE [v2-1] + + +**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** + +| Product-Code | Chip-ID | STLink
Programmer | Boards | +| --- | --- | --- | --- | +| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
_unsupported_ | + + +**STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x413 | STM32F4**0**xxx | +| 0x413 | STM32F4**1**xxx | +| 0x419 | STM32F4**2**xxx | +| 0x419 | STM32F4**3**xxx | +| 0x423 | STM32F4**01**x**B** | +| 0x423 | STM32F4**01**x**C** | +| 0x433 | STM32F4**01**x**D** | +| 0x433 | STM32F4**01**x**E** | +| 0x458 | STM32F4**10**xx | +| 0x431 | STM32F4**11**xx | +| 0x441 | STM32F4**12**xx | +| 0x421 | STM32F4**46**xx | +| 0x434 | STM32F4**69**xx | +| 0x434 | STM32F4**79**xx | +| 0x463 | STM32F4**13**xx | +| 0x463 | STM32F4**23**xx | + +Tested boards [incl. STLink programmers]: +* STM32F407-Discovery [v2] +* 32F411E-Discovery with gyro, audio [v2] +* 32F429I-Discovery with LCD [v2] +* 32F439VIT6-Discovery [v2] (reseated MCU) +* Nucleo-F401RE [v2-1] +* Nucleo-F411RE [v2-1] +* 32F413H-Discovery [v2-1] + + +**STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x452 | STM32F7**2**xxx | +| 0x452 | STM32F7**3**xxx | +| 0x449 | STM32F7**4**xxx | +| 0x449 | STM32F7**5**xxx | +| 0x451 | STM32F7**6**xxx | +| 0x451 | STM32F7**7**xxx | + +Tested boards [incl. STLink programmers]: +* STM32F756NGHx evaluation board [v2-1] +* 32F769I-Discovery [v2-1] +* Nucleo-F722ZE [v2-1] +* Nucleo-F746ZG [v2-1] + + +**STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x466 | STM32G0**3**xxx | +| 0x466 | STM32G0**4**xxx | +| 0x460 | STM32G0**7**xxx | +| 0x460 | STM32G0**8**xxx | + + +**STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x468 | STM32G4**31**xx | +| 0x468 | STM32G4**41**xx | +| 0x469 | STM32G4**7**xxx | +| 0x469 | STM32G4**8**xxx | + + +**STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x457 | STM32L0**1**xxx | +| 0x457 | STM32L0**2**xxx | +| 0x425 | STM32L0**31**xx | +| 0x425 | STM32L0**41**xx | +| 0x417 | STM32L0**5**xxx | +| 0x417 | STM32L0**6**xxx | +| 0x447 | STM32L0**7**xxx | +| 0x447 | STM32L0**8**xxx | + +Tested boards [incl. STLink programmers]: +* Nucleo-L053R8 [v2-1] + + +**STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x416 | STM32L1xxx**6** | +| 0x416 | STM32L1xxx**8** | +| 0x416 | STM32L1xxx**B** | +| 0x429 | STM32L1xxx**6A** | +| 0x429 | STM32L1xxx**8A** | +| 0x429 | STM32L1xxx**BA** | +| 0x427 | STM32L1xxx**C** | +| 0x436 | STM32L1xxx**D** | +| 0x437 | STM32L1xxx**E** | + +Tested boards [incl. STLink programmers]: +* Nucleo-L152RE [v2-1] +* 32L152C-Discovery [v2] + + +**STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x464 | STM32L4**12**xx | +| 0x464 | STM32L4**22**xx | +| 0x435 | STM32L4**3**xxx | +| 0x435 | STM32L4**4**xxx | +| 0x462 | STM32L4**5**xxx | +| 0x462 | STM32L4**6**xxx | +| 0x415 | STM32L4**7**xxx | +| 0x415 | STM32L4**8**xxx | +| 0x461 | STM32L4**96**xx | +| 0x461 | STM32L4**A6**xx | +| 0x470 | STM32L4**R**xx | +| 0x470 | STM32L4**S**xx | +| 0x471 | STM32L4**P5**xx | +| 0x471 | STM32L4**Q5**xx | + +Tested boards [incl. STLink programmers]: +* Nucleo-L432KC [v2-1] +* Nucleo-L452RE [v2-1] +* Nucleo-L476RG [v2-1] +* Nucleo-L496ZG [v2-1] +* 32L4R9I-Discovery [v2-1] + + +**STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x495 | STM32WB**50**xx | +| 0x495 | STM32WB**55**xx | +| 0x497 | STM32WLE**5**xx | diff --git a/doc/flashloaders.md b/doc/flashloaders.md new file mode 100644 index 000000000..6a7cb3504 --- /dev/null +++ b/doc/flashloaders.md @@ -0,0 +1,54 @@ +# Flashloaders + +## What do flashloaders do + +The on-chip FLASH of STM32 needs to be written once a byte/half word/word/double word, which would lead to a unbearably long flashing time if the process is solely done by `stlink` from the host side. Flashloaders are introduced to cooperate with `stlink` so that the flashing process is divided into two stages. In the first stage, `stlink` loads flashloaders and flash data to SRAM where busy check is not applied. In the second stage, flashloaders are kick-started, writing data from SRAM to FLASH, where a busy check is applied. Thus the write-check\_if\_busy cycle of flashing is done solely by STM32 chip, which saves considerable time in communications between `stlink` and STM32. + +As SRAM is usually less in size than FLASH, `stlink` only flashes one page (may be less if SRAM is insufficient) at a time. The whole flashing process may consist of server launches of flashloaders. + +## The flahsing process + +1. `st-flash` loads compiled binary of corresponding flashloader to SRAM by calling `stlink_flash_loader_init` in `src/flash_loader.c` +2. `st-flash` erases corresponding flash page by calling `stlink_erase_flash_page` in `common.c`. +3. `st-flash` calls `stlink_flash_loader_run` in `flash_loader.c`. In this function + + buffer of one flash page is written to SRAM following the flashloader + + the buffer start address (in SRAM) is written to register `r0` + + the target start address (in FLASH, page aligned) is written to register `r1` + + the buffer size is written to register `r2` + + the start address (for now 0x20000000) of flash loader is written to `r15` (`pc`) + + After that, launching the flashloader and waiting for a halted core (triggered by our flashloader) and confirming that flashing is completed with a zeroed `r2` +4. flashloader part: much like a `memcpy` with busy check + + copy a single unit of data from SRAM to FLASH + + (for most devices) wait until flash is not busy + + trigger a breakpoint which halts the core when finished + +## Constraints + +Thus for developers who want to modify flashloaders, the following constraints should be satisfied. + +* only thumb-1 (for stm32f0 etc) or (thumb-1 and thumb-2) (for stm32f1 etc) instructions can be used, no ARM instructions. +* no stack, since it may overwrite buffer data. +* for most devices, after writing a single unit data, wait until FLASH is not busy. +* for some devices, check if there are any errors during flashing process. +* respect unit size of a single copy. +* after flashing, trigger a breakpint to halt the core. +* a sucessful run ends with `r2` set to zero when halted. +* be sure that flashloaders are at least be capable of running at 0x20000000 (the base address of SRAM) + + +For devices that need to wait until the flash is not busy, check FLASH_SR_BUSY bit. For devices that need to check if there is any errors during flash, check FLASH\_SR\_(X)ERR where `X` can be any error state + +FLASH_SR related offset and copy unit size may be found in ST official reference manuals and/or some header files in other open source projects. Clean room document provides some of them. + + +## Debug tricks + +If you find some flashloaders to be broken or you need to write a new flashloader for new devices, the following tricks may help. + +1. Modify `WAIT_ROUNDS` marco to a bigger value so that you will have time to kill st-flash when it is waiting for a halted core. +2. run `st-flash` and kill it after the flashloader is loaded to SRAM +3. launch `st-util` and `gdb`/`lldb` +4. set a breakpoint at the base address of SRAM +5. jump to the base address and start your debug + +The tricks work because by this means, most work (flash unlock, flash erase, load flashloader to SRAM) would have been done automatically, saving time to construct a debug environment. \ No newline at end of file diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 949cd2fcf..23da9e150 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,37 +1,36 @@ -set(MANPAGES - st-util - st-flash - st-info -) +### +# Generate manpages +### -# Only generate manpages with pandoc in Debug builds -if(${STLINK_GENERATE_MANPAGES}) - include(pandocology) +set(MANPAGES st-util st-flash st-info) - foreach(manpage ${MANPAGES}) - add_document( - ${manpage}.1 - SOURCES ${manpage}.md - PANDOC_DIRECTIVES -s -t man - PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - endforeach() -else() - message(STATUS "Manpage generation disabled") -endif() +# Only generate manpages with pandoc in Debug builds +if (${STLINK_GENERATE_MANPAGES}) + include(pandocology) + foreach (manpage ${MANPAGES}) + add_document( + ${manpage}.1 + SOURCES ${manpage}.md + PANDOC_DIRECTIVES -s -t man + PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + endforeach () +else () + message(STATUS "Manpage generation disabled") +endif () # Install from output folder or this folder -foreach(manpage ${MANPAGES}) - if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) - set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") - elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - else() - message(AUTHOR_WARNING "Manpage ${manpage} not generated") - endif() +foreach (manpage ${MANPAGES}) + if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) + set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") + elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + else() + message(AUTHOR_WARNING "Manpage ${manpage} not generated") + endif () - if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) - unset(f) - endif() -endforeach() + if (f AND NOT WIN32) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/man/man1) + unset(f) + endif () +endforeach () diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 36df7daa8..c2654f280 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -1,52 +1,55 @@ -.\" Automatically generated by Pandoc 2.4 +.\" Automatically generated by Pandoc 2.9 .\" -.TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" +.TH "st-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" .hy .SH NAME .PP -st\-flash \- Flash binary files to STM32 device +st-flash - Flash binary files to STM32 device .SH SYNOPSIS .PP -\f[I]st\-flash\f[R] [\f[I]OPTIONS\f[R]] {read|write|erase} +\f[I]st-flash\f[R] [\f[I]OPTIONS\f[R]] {read|write|erase} [\f[I]FILE\f[R]] .SH DESCRIPTION .PP Flash binary files to arbitrary sections of memory, or read arbitrary addresses of memory out to a binary file. .PP -You can use this instead of st\-util(1) if you prefer, but remember to +You can use this instead of st-util(1) if you prefer, but remember to use the \f[B].bin\f[R] image, rather than the \f[B].elf\f[R] file. .PP Use hexadecimal format for the \f[I]ADDR\f[R] and \f[I]SIZE\f[R]. .SH COMMANDS .TP -.B write \f[I]FILE\f[R] \f[I]ADDR\f[R] +write \f[I]FILE\f[R] \f[I]ADDR\f[R] Write firmware \f[I]FILE\f[R] to device starting from \f[I]ADDR\f[R] .TP -.B read \f[I]FILE\f[R] \f[I]ADDR\f[R] \f[I]SIZE\f[R] +read \f[I]FILE\f[R] \f[I]ADDR\f[R] \f[I]SIZE\f[R] Read firmware from device starting from \f[I]ADDR\f[R] up to \f[I]SIZE\f[R] bytes to \f[I]FILE\f[R] .TP -.B erase +erase Perform a mass erasing of the device firmware .TP -.B reset +reset Reset the target .SH OPTIONS .TP -.B \-\-version +--version Print version information .TP -.B \-\-debug +--debug TODO .TP -.B \-\-reset +--reset TODO .TP -.B \-\-serial \f[I]iSerial\f[R] +--opt +Enable ignore ending empty bytes optimization +.TP +--serial \f[I]iSerial\f[R] TODO .TP -.B \-\-flash=fsize +--flash=fsize Where fsize is the size in decimal, octal, or hex followed by an optional multiplier `k' for KB, or `m' for MB. Use a leading \[lq]0x\[rq] to specify hexadecimal, or a leading zero for @@ -57,7 +60,7 @@ Flash \f[C]firmware.bin\f[R] to device .IP .nf \f[C] -$ st\-flash write firmware.bin 0x8000000 +$ st-flash write firmware.bin 0x8000000 \f[R] .fi .PP @@ -65,7 +68,7 @@ Read firmware from device (4096 bytes) .IP .nf \f[C] -$ st\-flash read firmware.bin 0x8000000 0x1000 +$ st-flash read firmware.bin 0x8000000 0x1000 \f[R] .fi .PP @@ -73,12 +76,12 @@ Erase firmware from device .IP .nf \f[C] -$ st\-flash erase +$ st-flash erase \f[R] .fi .SH SEE ALSO .PP -st\-util(1), st\-info(1) +st-util(1), st-info(1) .SH COPYRIGHT .PP This work is copyrighted. diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 1860a8c72..d5565e923 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -20,6 +20,9 @@ You can use this instead of st-util(1) if you prefer, but remember to use the Use hexadecimal format for the *ADDR* and *SIZE*. +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. + # COMMANDS write *FILE* *ADDR* @@ -45,6 +48,9 @@ reset \--reset : TODO +\--opt +: Enable ignore ending empty bytes optimization + \--serial *iSerial* : TODO diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 67d9373d7..94a430000 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -11,38 +11,41 @@ st-info - Provides information about connected STLink and STM32 devices # DESCRIPTION + Provides information about connected STLink programmers and STM32 devices: -Serial code, openocd, flash, sram, page size, chipid, description. +Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. +The STLink device to probe can be specified via the environment variable +STLINK_DEVICE on the format :. # OPTIONS \--version : Print version information -\--flash -: Display amount of flash memory available in the device +\--probe +: Display the summarized information of the connected programmers and devices -\--sram -: Display amount of sram memory available in device +\--serial +: Display the serial code of the device -\--descr -: Display textual description of the device +\--hla-serial +: Display the hex escaped serial code of the device + +\--flash +: Display amount of flash memory available in the device \--pagesize : Display the page size of the device +\--sram +: Display amount of sram memory available in device + \--chipid : Display the chip ID of the device -\--serial -: Display the serial code of the device - -\--hla-serial -: Display the hex escaped serial code of the device - -\--probe -: Display the summarized information of the connected programmers and devices +\--descr +: Display textual description of the device # EXAMPLES diff --git a/doc/man/st-util.md b/doc/man/st-util.md index e62261213..9a54fb309 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -17,10 +17,8 @@ Run the main binary of the local package (src/main.rs). If a port number is not specified using the **--listen_port** option, the default **4242** port will be used. -Stlink version 2 is used by default unless the option **--stlinkv1** is given. - -The STLinkV2 device to use can be specified in the environment -variable STLINK_DEVICE on the format :. +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. # OPTIONS @@ -36,12 +34,6 @@ variable STLINK_DEVICE on the format :. -v, \--verbose : Specify generally verbose logging --s *X*, \--stlink_version=*X* -: Choose what version of stlink to use, (defaults to 2) - --1, \--stlinkv1 -: Force stlink version 1 - -p *4242*, \--listen_port=1234 : Set the gdb server listen port. (default port: 4242) diff --git a/doc/release.md b/doc/release.md index c2dca87b2..b44183b80 100644 --- a/doc/release.md +++ b/doc/release.md @@ -1,10 +1,11 @@ Release ======= -This document describes the steps takes for developers to create a release +This document describes the necessary steps for developers to create a release: -1. Update `.version` with semantic version: `x.x.x` -2. Update `README.md` with semantic version `x.x.x` in commits badge -2. Create and push git tag and commits `git tag x.x.x` -3. Create source tarball/zipfile with `make dist` -4. Create binary package with `make package` +1. Update `CHANGELOG.md` +2. Update `.version` with semantic version: `x.x.x` +3. Update `README.md` with semantic version `x.x.x` in commits badge +4. Create and push git tag and commits `git tag x.x.x` +5. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` +6. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project diff --git a/doc/tested-boards.md b/doc/tested-boards.md deleted file mode 100644 index b28163a30..000000000 --- a/doc/tested-boards.md +++ /dev/null @@ -1,58 +0,0 @@ -Stlink tested and compatible boards -=================================== - -STLink v1 (as found on the 32VL Discovery board) - -Known working targets: - -* STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32) -* CKS32F103 (chinese STM32F103-Clone) - -No information: - -* everything else! - -STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: - -* STM32F0 (STM32F0 Discovery board) -* STM32F030F4P6 (custom board) -* STM32F051R8T6 (STM320518-EVAL board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32F103VET6 (HY-STM32 board) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (Discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L1xx (STM32L Discovery board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32L496ZG (STM32-Nucleo-L496ZG board) - - -* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) - - -STLink v2-1 (as found on the Nucleo boards), known working targets: - -* STM32F030R8T6 (STM32 Nucleo-F030R8 board) -* STM32F042K6 (STM32 Nucleo-32 Board) -* STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) -* STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) -* STM32F401xx (STM32 Nucleo-F401RE board) -* STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STM32F7 evaluation board) -* STM32F769NI (STM32F7 discovery board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) -* STM32L152RE (STM32-Nucleo-L152RE board -* STM32L452RET6 (STM32 Nucleo-L452RE board) -* STM32L476RG (STM32 Nucleo-L476RG board) - - -Please report any and all known working combinations so I can update this! diff --git a/doc/tutorial.md b/doc/tutorial.md index 35c607ac0..81315dbef 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1,72 +1,99 @@ -Using STM32 discovery kits with open source tools -======== +stlink Tools Tutorial +===================== -This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. +## Available tools and options -Installing a GNU toolchain -========================== +| Option | Tool | Description | Available
since | +| --- | --- | --- | --- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash,
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
the end of binary file. This may cause some garbage data left after a flash operation.
This option was enabled by default in earlier releases. | v1.6.1 | +| --version | st-info,
st-flash,
st-util | Print version information. | | +| --help | st-flash,
st-util | Print list of available commands. _(To be added to this table.)_ | | -Any toolchain supporting the cortex m3 should do. You can find the -necessary to install such a toolchain here: +### st-flash: Checksum for binary files +When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. +The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). -``` -https://github.com/esden/summon-arm-toolchain -``` +### stlink-gui +The `stlink` toolset also provides a GUI which is an optional feature. It is only installed if a gtk3 toolset has been detected during package installation or compilation from source. It is not available for Windows. If you prefer to have an user interface on the latter system, please use the official `ST-LINK Utility` instead. -Details for the installation are provided in the topmost `README` file. -This documentation assumes the toolchains is installed in a -`$TOOLCHAIN_PATH`. +The stlink-gui offers the following features: +* Connect/disconnect to a present STlink programmer +* Display basic device information +* Select a binary file from the local filesystem to flash it to the detected device connected to the programmer +* Export the memory of the connected chip to a file which can be saved to the local filesystem +* Display of the memory address map in the main window for each, the device memory and a loaded binary file -Installing STLINK -================= +Within the GUI main window tooltips explain the available user elements. -STLINK is open source software to program and debug ST’s STM32 Discovery -kits. Those kits have an onboard chip that translates USB commands sent -by the host PC into JTAG/SWD commands. This chip is called STLINK, (yes, -isn’t that confusing? suggest a better name!) and comes in 2 versions -(STLINK v1 and v2). From a software point of view, those versions differ -only in the transport layer used to communicate (v1 uses SCSI passthru -commands, while v2 uses raw USB). From a user point of view, they are -identical. +## Solutions to common problems +### a) Verify if udev rules are set correctly (by Dave Hylands) -Before continuing, the following dependencies must be met: +To investigate, start by plugging your STLINK device into the usb port. Then run `lsusb`. You should see an entry something like the following: -- libusb-1.0 -- cmake +``` +Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) +``` + +Note the bus number (005) and the Device (017). You should then do: +`ls -l /dev/bus/usb/005/017` (replacing 005 and 017 appropriately). -Also make sure `gtk+` version 3.0 is installed. (`sudo apt-get install gtk+-3.0` or similiar) +On my system I see the following: -STLINK should run on any system meeting the above constraints. +``` +crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 +``` -The STLINK software source code is retrieved using: +which is world writable (this is from the `MODE:="0666"` below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: ``` -$> git clone https://github.com/texane/stlink.git +# stm32 nucleo boards, with onboard st/linkv2-1 +# ie, STM32F0, STM32F4. +# STM32VL has st/linkv1, which is quite different + +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ + MODE:="0666", \ + SYMLINK+="stlinkv2-1_%n" + +# If you share your linux system with other users, or just don't like the +# idea of write permission for everybody, you can replace MODE:="0666" with +# OWNER:="yourusername" to create the device owned by you, or with +# GROUP:="somegroupname" and mange access using standard unix groups. ``` -Everything can be built from the top directory: +and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. + +Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: ``` -$> cd stlink -$> make -$> cd build/Release && make install DESTDIR=_install +sudo udevadm control --reload-rules +sudo udevadm trigger ``` -It includes: +to ensure that the rules actually take effect. Using the trigger command means that you shouldn't need to unplug and replug the device, but you might want to try that for good measure as well. + +If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. + + +------ +( Content below is currently unrevised and may be outdated as of Apr 2020. ) + +Using STM32 discovery kits with open source tools +======== + +This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. + +## Installing a GNU toolchain -- a communication library (libstlink.a), -- a GDB server (st-util), -- a flash manipulation tool (st-flash). -- a programmer and chip information tool (st-info) +Any toolchain supporting the cortex m3 should do. -Using the GDB server -==================== - +## Using the GDB server -This assumes you have got the libopencm3 project downloaded in `ocm3`. -The libopencm3 project has some good, reliable examples for each of the -Discovery boards. +This assumes you have got the [libopencm3](http://www.libopencm3.org) project downloaded in `ocm3`. +The libopencm3 project provides a firmware library, with solid examples for Cortex M3, M4 and M0 processors +from any vendor. It has some good, reliable examples for each of the Discovery boards. Even if you don’t plan on using libopencm3, the examples they provide will help you verify that: @@ -77,19 +104,15 @@ will help you verify that: - Your arm-none-eabi-gdb is functional - Your board is functional -A GDB server must be started to interact with the STM32. Depending on -the discovery kit you are using, you must run one of the 2 commands: +A GDB server must be started to interact with the STM32 by running +st-util tool : ``` -# STM32VL discovery kit (onboard ST-link) -$> ./st-util --stlinkv1 - -# STM32L or STM32F4 discovery kit (onboard ST-link/V2) -$> ./st-util +$> st-util # Full help for other options (listen port, version) -$> ./st-util --help -``` +$> st-util --help +``` Then, GDB can be used to interact with the kit: @@ -113,7 +136,7 @@ command line, now we can simply “load” the target: ``` (gdb) load -``` +``` st-util will load all sections into their appropriate addresses, and “correctly” set the PC register. So, to run your freshly loaded program, @@ -127,24 +150,18 @@ Your program should now be running, and, if you used one of the blinking examples from libopencm3, the LEDs on the board should be blinking for you. -Building and flashing a program -=============================== + +## Building and flashing a program If you want to simply flash binary files to arbitrary sections of memory, or read arbitary addresses of memory out to a binary file, use the st-flash tool, as shown below: ``` -# stlinkv1 command to read 4096 from flash into out.bin +# stlink command to read 4096 from flash into out.bin $> ./st-flash read out.bin 0x8000000 4096 -# stlinkv2 command -$> ./st-flash read out.bin 0x8000000 4096 - -# stlinkv1 command to write the file in.bin into flash -$> ./st-flash write in.bin 0x8000000 - -# stlinkv2 command +# stlinkv command to write the file in.bin into flash $> ./st-flash write in.bin 0x8000000 ``` @@ -154,7 +171,7 @@ It is also possible to write a hexfile which is more convinient: $> ./st-flash --format ihex write myapp.hex ``` -#### +#### Of course, you can use this instead of the gdb server, if you prefer. Just remember to use the “.bin” image, rather than the .elf file. @@ -167,30 +184,132 @@ $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 Upon reset, the board LEDs should be blinking. -Notes -===== -Disassembling THUMB code in GDB -------------------------------- +## Using the gdb server -By default, the disassemble command in GDB operates in ARM mode. The -programs running on CORTEX-M3 are compiled in THUMB mode. To correctly -disassemble them under GDB, uses an odd address. For instance, if you -want to disassemble the code at 0x20000000, use:\ +To run the gdb server: + +``` +$ make && [sudo] ./st-util + +There are a few options: + +./st-util - usage: + + -h, --help Print this help + -vXX, --verbose=XX Specify a specific verbosity level (0..99) + -v, --verbose Specify generally verbose logging + -p 4242, --listen_port=1234 + Set the gdb server listen port. (default port: 4242) + -m, --multi + Set gdb server to extended mode. + st-util will continue listening for connections after disconnect. + -n, --no-reset + Do not reset board on connection. +``` + +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. + +Then, in your project directory, someting like this... +(remember, you need to run an _ARM_ gdb, not an x86 gdb) + +``` +$ arm-none-eabi-gdb fancyblink.elf +... +(gdb) tar extended-remote :4242 +... +(gdb) load +Loading section .text, size 0x458 lma 0x8000000 +Loading section .data, size 0x8 lma 0x8000458 +Start address 0x80001c1, load size 1120 +Transfer rate: 1 KB/sec, 560 bytes/write. +(gdb) +... +(gdb) continue +``` + + +## Resetting the chip from GDB + +You may reset the chip using GDB if you want. You'll need to use `target +extended-remote' command like in this session: + +``` +(gdb) target extended-remote localhost:4242 +Remote debugging using localhost:4242 +0x080007a8 in _startup () +(gdb) kill +Kill the program being debugged? (y or n) y +(gdb) run +Starting program: /home/whitequark/ST/apps/bally/firmware.elf +``` + +Remember that you can shorten the commands. `tar ext :4242` is good enough +for GDB. + +If you need to send a hard reset signal through `NRST` pin, you can use the following command: + +``` +(gdb) monitor jtag_reset +``` + + +## Disassembling THUMB code in GDB + +By default, the disassemble command in GDB operates in ARM mode. The programs running on CORTEX-M3 are compiled in THUMB mode. +To correctly disassemble them under GDB, uses an odd address. For instance, if you want to disassemble the code at 0x20000000, use: ``` (gdb) disassemble 0x20000001 ``` -References -========== -- - documentation related to the STM32L mcu +## Running programs from SRAM + +You can run your firmware directly from SRAM if you want to. Just link +it at 0x20000000 and do + +``` +(gdb) load firmware.elf +``` + +It will be loaded, and pc will be adjusted to point to start of the +code, if it is linked correctly (i.e. ELF has correct entry point). + + +## Writing to flash + +The GDB stub ships with a correct memory map, including the flash area. +If you would link your executable to `0x08000000` and then do + +``` +(gdb) load firmware.elf +``` + +then it would be written to the memory. + + +## Writing Option Bytes + +Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) +``` +./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 +./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 +``` + + +FAQ +=== + +Q: My breakpoints do not work at all or only work once. + +A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. + +Q: At some point I use GDB command `next', and it hangs. + +A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. -- - documentation related to the STM32L discovery kit +Q: Load command does not work in GDB. -- - libopencm3, a project providing a firmware library, with solid - examples for Cortex M3, M4 and M0 processors from any vendor. +A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. diff --git a/doc/version_support.md b/doc/version_support.md new file mode 100644 index 000000000..4d1f724f7 --- /dev/null +++ b/doc/version_support.md @@ -0,0 +1,82 @@ + +_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of Apr 2020) + + +## Supported Operating Systems +### Microsoft Windows + +On Windows users should ensure that cmake 3.17.0 is installed.
+Up on compiling c-make will check **automatically**, whether `libusb` 1.0.20 or later is present.
+If this is not the case, the installation routine will download the latest version (1.0.23 at the time of writing).
+Thus no user interaction regarding libusb is necessary. + +* Windows 10 +* Windows 8.1 + + +### Apple macOS + +| Package Repository | libusb
version | cmake
version | gtk-3
version | Supported macOS versions | +| --- | --- | --- | --- | --- | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | + +NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or 10.15 are required. + + +### Linux-/Unix-based: + +| Operating System | libusb
version | cmake
version | gtk-3
version | Notes | +| --- | --- | --- | --- | --- | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.24.18
gtk+3.0-dev | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3-devel | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
gtk3-devel | | named `libusbx`, but
`libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3.0-devel
lib64gtk+3.0-devel | | +| PCLinuxOS | 1.0.23
lib64usb1.0 | 3.17.0 | 3.24.18
lib64gtk+3.0-devel | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
libgtk-3-devel | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
libgtk-3-dev | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
libgtk+3.0-devel
lib64gtk+3.0-devel | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
libgtk-3-dev | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
gtk3-devel | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
gtk+3.0-dev | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
libgtk-3-dev | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
libgtk+3.0-devel
lib64gtk+3.0-devel | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
gtk+3.0-dev | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
gtk3-devel | named `libusbx`, but
`libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
libgtk+3.0-devel
lib64gtk+3.0-devel | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
gtk3-devel | named `libusbx`, but
`libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
libgtk-3-dev | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
gtk+3.0-dev | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
gtk3-devel | named `libusbx`, but
`libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
gtk3-devel | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
gtk3-devel | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
libgtk-3-dev | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
libgtk-3-dev | | +| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
gtk+3 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
libgtk-3-dev | | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
libgtk+3.0-devel
lib64gtk+3.0-devel | | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
(integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | + + +## Unsupported Operating Systems (as of Release v1.6.1) + +| Operating System | libusb
version | cmake
version | End of OS-Support | Notes | +| --- | --- | --- | --- | --- | +| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
`libusb`-codebase is used | +| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
`libusb`-codebase is used | +| Slackware 14.1 | 1.0.**9** | **2.8.12** | | +| Slackware 14.0 | 1.0.**9** | **2.8.8** | | + +_All other operating systems which are not listed are unsupported._ + +Author: nightwalker-87 diff --git a/doc/wiki_old.md b/doc/wiki_old.md deleted file mode 100644 index 81e70a277..000000000 --- a/doc/wiki_old.md +++ /dev/null @@ -1,108 +0,0 @@ -Welcome to the stlink wiki! (Archived: 2014-08-11) - -Misc: -Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html - -FAQ: -Q: Where can I get help? Is there a forum or maybe a mailing list? - -A: todo - -Q: How can I install stlink and flash binaries on Mac OS X ? - -A: **20140811: ** installed on Mac OS X 10.9.4 with ports method, however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! Only older firmware on STlink v2 works. - -[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) - -`sudo port install libusb automake autoconf pkgconfig` - -`aclocal --force -I /opt/local/share/aclocal` - -`git clone https://github.com/texane/stlink.git stlink-utility` - -`cd stlink-utility` - -`./autogen.sh` - -`./configure` - -`make` - - -Then trying to flash the image with STLINK v2 : - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> libusb_handle_events() timeout -> -> [!] send_recv - -After downgrading the firmware, flashing works -ST-Link/V2 debugger with downgraded V2.14.3 firmware: - -https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k - -as described here: - -http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in -> pages of 1024 bytes -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 -> (0x8000000) -> -> Flash page at addr: 0x08006000 erased -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! - - -Installation of openOCD on Mac OS X with STlink-v2 has been successful: - -`sudo port install openocd +jlink +stlink +ft2232` - -`/opt/local/bin/openocd --version` - -> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) - -`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` - -> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) -> -> Licensed under GNU GPL v2 -> -> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html -> -> Info : This adapter doesn't support configurable speed -> -> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 -> -> Info : using stlink api v2 -> -> Info : Target voltage: 3.244269 -> -> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints - -and connecting to the server through telnet yields a successful installation - -`telnet localhost 4444` - -> Connected to localhost. -> -> Escape character is '^]'. -> -> Open On-Chip Debugger diff --git a/flashloaders/Makefile b/flashloaders/Makefile new file mode 100644 index 000000000..7b17cb2a0 --- /dev/null +++ b/flashloaders/Makefile @@ -0,0 +1,38 @@ +# Note that according to the original GPLed code, compiling is noted to be +# as simple as gcc -c, this fails with my tests where this will lead to a wrong +# address read by the program. +# This makefile will save your time from dealing with compile errors +# Adjust CC if needed + +CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc + +CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib + +all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o + +stm32vl.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o +stm32f0.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o +stm32l.o: stm32lx.s + $(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o +stm32f4.o: stm32f4.s + $(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o +stm32f4_lv.o: stm32f4lv.s + $(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o +stm32l4.o: stm32l4.s + $(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o +stm32f7.o: stm32f7.s + $(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o +stm32f7_lv.o: stm32f7lv.s + $(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o + +clean: + rm *.o + + + + + + diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md new file mode 100644 index 000000000..a468efe49 --- /dev/null +++ b/flashloaders/cleanroom.md @@ -0,0 +1,233 @@ +Original Chinese version can be found below. + +# Clean Room Documentation English Version + +Code is situated in section `.text` + +Shall add a compile directive at the head: `.syntax unified` + +**Calling convention**: + +All parameters would be passed over registers + +`r0`: the base address of the copy source +`r1`: the base address of the copy destination +`r2`: the total word (4 bytes) count to be copied (with expeptions) + +**What the program is expected to do**: + +Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. + +**Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). + +**Requirement**: After every single copy, wait until the flash finishes. The detailed single copy length and the way to check can be found below. Address of `flash_base` shall be two-bytes aligned. + +## stm32f0.s + +**Exception**: `r2` stores the total half word (2 bytes) count to be copied + +`flash_base`: 0x40022000 + +`FLASH_CR`: offset from `flash_base` is 16 + +`FLASH_SR`: offset from `flash_base` is 12 + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +[https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special requirements**: + +Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. + +How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. + +Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. + +## stm32f4.s + +`flash_base`: 0x40023c00 + +`FLASH_SR`: offset from `flash_base` is 0xe (14) + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + + +**Special requirements**: + +Copy one word each time. +How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. + +## stm32f4lv.s + +`flash_base`: 0x40023c00 + +`FLASH_SR`: offset from `flash_base` is 0xe (14) + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +**Special Requirements**: + +Copy one byte each time. + +How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. + +## stm32f7.s + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +Mostly same with `stm32f4.s`. Require establishing a memory barrier after every copy and before checking for finished writing by `dsb sy` + +## stm32f7lv.s + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special Requirements**: + +Mostly same with `stm32f7.s`. Copy one byte each time. + +## stm32l0x.s + +**Special Requirements**: + +Copy one word each time. No wait for write. + +## stm32l4.s + +**Exception**: r2 stores the double word count to be copied. + +`flash_base`: 0x40022000 +`FLASH_BSY`: offset from `flash_base` is 0x12 + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special Requirements**: + +Copy one double word each time (More than one registers are allowed). + +How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. + +## stm32lx.s + +Same with stm32l0x.s. + + +# 净室工程文档-原始中文版 + +代码位于的section:`.text` +编译制导添加`.syntax unified` + +传入参数约定: + +参数全部通过寄存器传递 + +`r0`: 拷贝源点起始地址 +`r1`: 拷贝终点起始地址 +`r2`: 拷贝word(4字节)数(存在例外) + +程序功能:将数据从源点拷贝到终点,在拷贝完毕后触发断点以结束执行,结束时`r2`值需清零表明传输完毕。 + +限制:不可使用栈,可自由使用的临时寄存器为`R3`到`R12`。`R13`为`sp`(stack pointer),`R14`为lr(一般用于储存跳转地址),`R15`为`pc`(program counter)。 + +要求:每完成一次拷贝,需等待flash完成写入,单次拷贝宽度、检查写入完成的方式见每个文件的具体要求。 + +特殊地址`flash_base`存放地址需2字节对齐。 + +## stm32f0.s + +例外:`r2`:拷贝half word(2字节)数 + +特殊地址定义:`flash_base`:定义为0x40022000 + +`FLASH_CR`: 相对`flash_base`的offset为16 + +`FLASH_SR`: 相对`flash_base`的offset为12 + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +[https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +特殊要求: +每次拷贝开始前需要读出FLASH_CR处的4字节内容,将其最低bit设置为1,写回FLASH_CR。 + +每次写入数据宽度为2字节(半字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若非4,则应直接准备退出。 + +退出:全部拷贝执行完毕后触发断点前,将FLASH_CR处4字节内容最低bit清为0,写回FLASH_CR。 + + + +## stm32f4.s + +特殊地址定义: `flash_base`:定义为0x40023c00 + +`FLASH_SR`:相对flash_base的offset为0xe(14) + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +特殊要求: + +每次写入的数据宽度为4字节(字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 + +## stm32f4lv.s + +特殊地址定义:`flash_base`:定义为0x40023c00 + +`FLASH_SR`:相对`flash_base`的offset为0xe (14) + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +特殊要求: + +每次写入的数据宽度为1字节(1/4字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 + +## stm32f7.s + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +要求同stm32f4.s,额外要求在每次拷贝执行完毕、flash写入成功检测前,执行`dsb sy`指令以建立内存屏障。 + + +## stm32f7lv.s + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) +要求基本同stm32f7.s,差异要求为每次写入的数据宽度为1字节(1/4字)。 + +## stm32l0x.s + +特殊要求: + +每次写入的数据宽度为4字节(字) + +无需实现检查flash写入完成功能 + +## stm32l4.s + +例外:`r2`: 拷贝双字(8字节)数 + +特殊地址定义:`flash_base`: 0x40022000 + +`FLASH_BSY`:相对flash_base的offset为0x12 + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +拷贝方式:一次性拷贝连续的8个字节(使用两个连续寄存器作中转)并写入 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_BSY处半字(2字节),若其最低位非1,可继续拷贝。 + +## stm32lx.s + +要求与stm32l0x.s相同 \ No newline at end of file diff --git a/flashloaders/linker.ld b/flashloaders/linker.ld new file mode 100644 index 000000000..4d06433ea --- /dev/null +++ b/flashloaders/linker.ld @@ -0,0 +1,9 @@ +/*. Entry Point *./ +ENTRY( copy ) + + +/*. Specify the memory areas .*/ +MEMORY +{ + RAM ( xrw) : ORIGIN = 0x20000000 , LENGTH = 64K +} \ No newline at end of file diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index fe12f90f3..f30e4bfc6 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,32 +1,77 @@ -/* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ - -write: - ldr r4, STM32_FLASH_BASE - mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - mov r6, #4 /* PGERR */ -write_half_word: - ldr r3, [r4, #16] /* FLASH->CR */ - orr r3, r5 - str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - ldrh r3, [r0] /* r3 = *sram */ - strh r3, [r1] /* *flash = r3 */ -busy: - ldr r3, [r4, #12] /* FLASH->SR */ - tst r3, r5 /* FLASH_SR_BUSY */ - beq busy - - tst r3, r6 /* PGERR */ - bne exit - - add r0, r0, #2 /* sram += 2 */ - add r1, r1, #2 /* flash += 2 */ - sub r2, r2, #0x01 /* count-- */ - cmp r2, #0 - bne write_half_word + .syntax unified + .text + + .global copy +copy: + /* + * These two NOPs here are a safety precaution, added by Pekka Nikander + * while debugging the STM32F05x support. They may not be needed, but + * there were strange problems with simpler programs, like a program + * that had just a breakpoint or a program that first moved zero to register r2 + * and then had a breakpoint. So, it appears safest to have these two nops. + * + * Feel free to remove them, if you dare, but then please do test the result + * rigorously. Also, if you remove these, it may be a good idea first to + * #if 0 them out, with a comment when these were taken out, and to remove + * these only a few months later... But YMMV. + */ + nop + nop + ldr r7, =flash_base + ldr r4, [r7] + ldr r7, =flash_off_cr + ldr r6, [r7] + adds r6, r6, r4 + ldr r7, =flash_off_sr + ldr r5, [r7] + adds r5, r5, r4 + +loop: + # FLASH_CR ^= 1 + ldr r7, =0x1 + ldr r3, [r6] + orrs r3, r3, r7 + str r3, [r6] + + # copy 2 bytes + ldrh r3, [r0] + strh r3, [r1] + + ldr r7, =2 + adds r0, r0, r7 + adds r1, r1, r7 + + # wait if FLASH_SR == 1 +wait: + ldr r7, =0x1 + ldr r3, [r5] + tst r3, r7 + beq wait + + # exit if FLASH_SR != 4 + ldr r7, =0x4 + tst r3, r7 + bne exit + + # loop if r2 != 0 + ldr r7, =0x1 + subs r2, r2, r7 + cmp r2, #0 + bne loop + exit: - ldr r3, [r4, #16] /* FLASH->CR */ - bic r3, r5 - str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - bkpt #0x00 + # FLASH_CR &= ~1 + ldr r7, =0x1 + ldr r3, [r6] + bics r3, r3, r7 + str r3, [r6] + + bkpt -STM32_FLASH_BASE: .word 0x40022000 + .align 2 +flash_base: + .word 0x40022000 +flash_off_cr: + .word 0x10 +flash_off_sr: + .word 0x0c diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 21f5a8f7f..a88ad9e02 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,32 +1,36 @@ -.global start -.syntax unified + .syntax unified + .text -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp + .global copy +copy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] +loop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] + add r0, r0, #4 + add r1, r1, #4 + + # wait if FLASH_SR == 1 wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait + ldrh r3, [r10] + tst r3, #0x1 + beq wait - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne loop -.align 2 +exit: + bkpt + .align 2 flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index f60ee8797..41467a9ef 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,33 +1,42 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] + .syntax unified + .text + .global copy +copy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + + # tip 1: original r2 indicates the count of 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + # tip 2: r2 is always a power of 2 + mov r2, r2, lsl#2 + +loop: + # copy 1 byte + ldrb r3, [r0] + strb r3, [r1] + + add r0, r0, #1 + add r1, r1, #1 + + # wait if FLASH_SR == 1 wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + ldrh r3, [r10] + tst r3, #0x1 + beq wait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne loop -.align 2 +exit: + bkpt + .align 2 flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 0334c80a0..3779a5ea6 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,33 +1,39 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] - dsb sy + .syntax unified + .text + .global copy +copy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + +loop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] + + add r0, r0, #4 + add r1, r1, #4 + + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + ldrh r3, [r10] + tst r3, #0x1 + beq wait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne loop -.align 2 +exit: + bkpt + .align 2 flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 650922719..e7b66cc2c 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,34 +1,45 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] - dsb sy + .syntax unified + .text + .global copy +copy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + + # tip 1: original r2 indicates the count in 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + # tip 2: r2 is always a power of 2 + mov r2, r2, lsl#2 + +loop: + # copy 1 byte + ldrb r3, [r0] + strb r3, [r1] + + add r0, r0, #1 + add r1, r1, #1 + + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + ldrh r3, [r10] + tst r3, #0x1 + beq wait -.align 2 + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne loop + +exit: + bkpt + .align 2 flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index fcbd06e39..f9c257e2e 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -1,64 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.S - .text .syntax unified - .cpu cortex-m0plus - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - count -*/ + .text - // Go to compare - b test_done + .global copy +copy: +loop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr r4, [r0] - // Store the word to address in r1, increment by 4 - str r4, [r1] - // Decrement r2 - subs r2, #1 - adds r1, #4 - // does not matter, only first addr is important - // next 15 bytes are in sequnce RM0367 page 66 - adds r0, #4 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bcc.n write_word + # loop if r2 != 0 + ldr r7, =1 + subs r2, r2, r7 + cmp r2, #0 + bne loop - // Set breakpoint to exit - bkpt #0x00 +exit: + bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 6aa2be050..32c27a057 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,39 +1,38 @@ -.global start -.syntax unified + .syntax unified + .text -@ Adapted from stm32f4.s -@ STM32L4's flash controller expects double-word writes, has the flash -@ controller mapped in a different location with the registers we care about -@ moved down from the base address, and has BSY moved to bit 16 of SR. -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp -@ r5 = temp + .global copy +copy: + ldr r12, flash_base + ldr r10, flash_off_bsy + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] /* copy doubleword from source to target */ - ldr r5, [r0, #4] - str r4, [r1] - str r5, [r1, #4] +loop: + # copy 8 bytes + ldr r3, [r0] + ldr r4, [r0, #4] + str r3, [r1] + str r4, [r1, #4] + add r0, r0, #8 + add r1, r1, #8 + + # wait if FLASH_BSY[0b] == 1 wait: - ldrh r4, [r3, #0x12] /* high half of status register */ - tst r4, #1 /* BSY = bit 16 */ - bne wait + ldrh r3, [r10] + tst r3, #0x1 + beq wait - add r0, #8 - add r1, #8 - sub r2, #1 - b next -done: - bkpt + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne loop -.align 2 +exit: + bkpt + .align 2 flash_base: .word 0x40022000 +flash_off_bsy: + .word 0x12 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 10e5644bf..f9c257e2e 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,60 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.s - .text .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - output, remaining word count -*/ + .text - // Go to compare - b test_done + .global copy +copy: +loop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr.w ip, [r0], #4 - // Store the word to address in r1, increment by 4 - str.w ip, [r1], #4 - // Decrement r2 - subs r2, #1 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bhi write_word + # loop if r2 != 0 + ldr r7, =1 + subs r2, r2, r7 + cmp r2, #0 + bne loop - // Set breakpoint to exit - bkpt #0x00 +exit: + bkpt diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index a5121aee5..6cf397659 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,17 +1,9 @@ configure_file( - "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" - "${CMAKE_BINARY_DIR}/include/stlink/version.h" -) -file(GLOB STLINK_HEADERS - "stlink/*.h" - "${CMAKE_BINARY_DIR}/include/stlink/*.h" -) -install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h - DESTINATION ${STLINK_INCLUDE_PATH} -) -install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h - DESTINATION ${STLINK_INCLUDE_PATH} -) -install(FILES ${STLINK_HEADERS} - DESTINATION ${STLINK_INCLUDE_PATH}/stlink -) + "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" + "${CMAKE_BINARY_DIR}/include/stlink/version.h" + ) + +file(GLOB STLINK_HEADERS "stlink/*.h" "${CMAKE_BINARY_DIR}/include/stlink/*.h") +install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}/stlink) diff --git a/include/stlink.h b/include/stlink.h index a69e357b5..c87c6b173 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -1,9 +1,10 @@ /* - * File: stlink.h + * File: stlink.h * - * This should contain all the common top level stlink interfaces, regardless - * of how the backend does the work.... + * This should contain all the common top level stlink interfaces, + * regardless of how the backend does the work.... */ + #ifndef STLINK_H #define STLINK_H @@ -19,230 +20,287 @@ extern "C" { #define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - // Max data transfer size. - // 6kB = max mem32_read block, 8kB sram - //#define Q_BUF_LEN 96 -#define Q_BUF_LEN (1024 * 100) - - // STLINK_DEBUG_RESETSYS, etc: -#define STLINK_CORE_RUNNING 0x80 -#define STLINK_CORE_HALTED 0x81 -#define STLINK_CORE_STAT_UNKNOWN -1 - -#define STLINK_GET_VERSION 0xf1 -#define STLINK_GET_CURRENT_MODE 0xf5 -#define STLINK_GET_TARGET_VOLTAGE 0xF7 - -#define STLINK_DEBUG_COMMAND 0xF2 -#define STLINK_DFU_COMMAND 0xF3 -#define STLINK_DFU_EXIT 0x07 - - // STLINK_GET_CURRENT_MODE -#define STLINK_DEV_DFU_MODE 0x00 -#define STLINK_DEV_MASS_MODE 0x01 -#define STLINK_DEV_DEBUG_MODE 0x02 -#define STLINK_DEV_UNKNOWN_MODE -1 - - // TODO - possible poor names... -#define STLINK_SWD_ENTER 0x30 -#define STLINK_SWD_READCOREID 0x32 // TBD -#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 -#define STLINK_JTAG_READDEBUG_32BIT 0x36 -#define STLINK_JTAG_DRIVE_NRST 0x3c - -#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 - -#define STLINK_APIV3_SET_COM_FREQ 0x61 -#define STLINK_APIV3_GET_COM_FREQ 0x62 - -#define STLINK_APIV3_GET_VERSION_EX 0xFB - -// Baud rate divisors for SWDCLK -#define STLINK_SWDCLK_4MHZ_DIVISOR 0 -#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 -#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2 -#define STLINK_SWDCLK_950KHZ_DIVISOR 3 -#define STLINK_SWDCLK_480KHZ_DIVISOR 7 -#define STLINK_SWDCLK_240KHZ_DIVISOR 15 -#define STLINK_SWDCLK_125KHZ_DIVISOR 31 -#define STLINK_SWDCLK_100KHZ_DIVISOR 40 -#define STLINK_SWDCLK_50KHZ_DIVISOR 79 -#define STLINK_SWDCLK_25KHZ_DIVISOR 158 -#define STLINK_SWDCLK_15KHZ_DIVISOR 265 -#define STLINK_SWDCLK_5KHZ_DIVISOR 798 - -#define STLINK_SERIAL_MAX_SIZE 64 - -#define STLINK_V3_MAX_FREQ_NB 10 - +/* Max data transfer size */ +// 6kB = max mem32_read block, 8kB sram +//#define Q_BUF_LEN 96 +#define Q_BUF_LEN (1024 * 100) + +// STLINK_DEBUG_RESETSYS, etc: +enum target_state { + TARGET_UNKNOWN = 0, + TARGET_RUNNING = 1, + TARGET_HALTED = 2, + TARGET_RESET = 3, + TARGET_DEBUG_RUNNING = 4, +}; + +#define STLINK_CORE_RUNNING 0x80 +#define STLINK_CORE_HALTED 0x81 + +#define STLINK_GET_VERSION 0xF1 +#define STLINK_GET_CURRENT_MODE 0xF5 +#define STLINK_GET_TARGET_VOLTAGE 0xF7 + +#define STLINK_DEBUG_COMMAND 0xF2 +#define STLINK_DFU_COMMAND 0xF3 +#define STLINK_DFU_EXIT 0x07 + +// STLINK_GET_CURRENT_MODE +#define STLINK_DEV_DFU_MODE 0x00 +#define STLINK_DEV_MASS_MODE 0x01 +#define STLINK_DEV_DEBUG_MODE 0x02 +#define STLINK_DEV_UNKNOWN_MODE -1 + +// TODO - possible poor names... +#define STLINK_SWD_ENTER 0x30 +#define STLINK_SWD_READCOREID 0x32 // TBD +#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 +#define STLINK_JTAG_READDEBUG_32BIT 0x36 +#define STLINK_JTAG_DRIVE_NRST 0x3C + +#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 + +#define STLINK_APIV3_SET_COM_FREQ 0x61 +#define STLINK_APIV3_GET_COM_FREQ 0x62 + +#define STLINK_APIV3_GET_VERSION_EX 0xFB + +/* Baud rate divisors for SWDCLK */ +#define STLINK_SWDCLK_4MHZ_DIVISOR 0 +#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 +#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2 +#define STLINK_SWDCLK_950KHZ_DIVISOR 3 +#define STLINK_SWDCLK_480KHZ_DIVISOR 7 +#define STLINK_SWDCLK_240KHZ_DIVISOR 15 +#define STLINK_SWDCLK_125KHZ_DIVISOR 31 +#define STLINK_SWDCLK_100KHZ_DIVISOR 40 +#define STLINK_SWDCLK_50KHZ_DIVISOR 79 +#define STLINK_SWDCLK_25KHZ_DIVISOR 158 +#define STLINK_SWDCLK_15KHZ_DIVISOR 265 +#define STLINK_SWDCLK_5KHZ_DIVISOR 798 + +#define STLINK_SERIAL_MAX_SIZE 64 + +#define STLINK_V3_MAX_FREQ_NB 10 + +/* Cortex Debug Control Block */ +#define DCB_DHCSR 0xE000EDF0 +#define DCB_DCRSR 0xE000EDF4 +#define DCB_DCRDR 0xE000EDF8 +#define DCB_DEMCR 0xE000EDFC + +/* DCB_DHCSR bit and field definitions */ +#define DBGKEY (0xA05F << 16) +#define C_DEBUGEN (1 << 0) +#define C_HALT (1 << 1) +#define C_STEP (1 << 2) +#define C_MASKINTS (1 << 3) +#define S_REGRDY (1 << 16) +#define S_HALT (1 << 17) +#define S_SLEEP (1 << 18) +#define S_LOCKUP (1 << 19) +#define S_RETIRE_ST (1 << 24) +#define S_RESET_ST (1 << 25) + +/* Map the relevant features, quirks and workaround for specific firmware version of stlink */ +#define STLINK_F_HAS_TRACE (1<<0) +#define STLINK_F_HAS_SWD_SET_FREQ (1<<1) +#define STLINK_F_HAS_JTAG_SET_FREQ (1<<2) +#define STLINK_F_HAS_MEM_16BIT (1<<3) +#define STLINK_F_HAS_GETLASTRWSTATUS2 (1<<4) +#define STLINK_F_HAS_DAP_REG (1<<5) +#define STLINK_F_QUIRK_JTAG_DP_READ (1<<6) +#define STLINK_F_HAS_AP_INIT (1<<7) +#define STLINK_F_HAS_DPBANKSEL (1<<8) +#define STLINK_F_HAS_RW8_512BYTES (1<<9) - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 - enum stlink_flash_type { - STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, - STLINK_FLASH_TYPE_L0, - STLINK_FLASH_TYPE_F4, - STLINK_FLASH_TYPE_L4, - STLINK_FLASH_TYPE_F1_XL, - STLINK_FLASH_TYPE_G0, - STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB - }; - - struct stlink_reg { - uint32_t r[16]; - uint32_t s[32]; - uint32_t xpsr; - uint32_t main_sp; - uint32_t process_sp; - uint32_t rw; - uint32_t rw2; - uint8_t control; - uint8_t faultmask; - uint8_t basepri; - uint8_t primask; - uint32_t fpscr; - }; - - typedef uint32_t stm32_addr_t; +enum stlink_flash_type { + STLINK_FLASH_TYPE_UNKNOWN = 0, + STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ + STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank, apparently */ + STLINK_FLASH_TYPE_F4, // used by f2, f4, f7 */ + STLINK_FLASH_TYPE_L0, // l0, l1 */ + STLINK_FLASH_TYPE_L4, // l4, l4+ */ + STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_G4, + STLINK_FLASH_TYPE_WB +}; + +struct stlink_reg { + uint32_t r[16]; + uint32_t s[32]; + uint32_t xpsr; + uint32_t main_sp; + uint32_t process_sp; + uint32_t rw; + uint32_t rw2; + uint8_t control; + uint8_t faultmask; + uint8_t basepri; + uint8_t primask; + uint32_t fpscr; +}; + +typedef uint32_t stm32_addr_t; typedef struct flash_loader { - stm32_addr_t loader_addr; /* loader sram adddr */ - stm32_addr_t buf_addr; /* buffer sram address */ +stm32_addr_t loader_addr; // loader sram addr +stm32_addr_t buf_addr; // buffer sram address } flash_loader_t; - typedef struct _cortex_m3_cpuid_ { - uint16_t implementer_id; - uint16_t variant; - uint16_t part; - uint8_t revision; - } cortex_m3_cpuid_t; - - typedef struct stlink_version_ { - uint32_t stlink_v; - uint32_t jtag_v; - uint32_t swim_v; - uint32_t st_vid; - uint32_t stlink_pid; - } stlink_version_t; - - enum transport_type { - TRANSPORT_TYPE_ZERO = 0, - TRANSPORT_TYPE_LIBSG, - TRANSPORT_TYPE_LIBUSB, - TRANSPORT_TYPE_INVALID - }; - - typedef struct _stlink stlink_t; - -#include "stlink/backend.h" - - struct _stlink { - struct _stlink_backend *backend; - void *backend_data; - - // Room for the command header - unsigned char c_buf[C_BUF_LEN]; - // Data transferred from or to device - unsigned char q_buf[Q_BUF_LEN]; - int q_len; - - // transport layer verboseness: 0 for no debug info, 10 for lots - int verbose; - uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID - uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx - - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; - - enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() - - /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() - - // bootloader - // sys_base and sys_size are not used by the tools, but are only there to - // download the bootloader code (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() - - struct stlink_version_ version; - }; - - int stlink_enter_swd_mode(stlink_t *sl); - int stlink_enter_jtag_mode(stlink_t *sl); - int stlink_exit_debug_mode(stlink_t *sl); - int stlink_exit_dfu_mode(stlink_t *sl); - void stlink_close(stlink_t *sl); - int stlink_core_id(stlink_t *sl); - int stlink_reset(stlink_t *sl); - int stlink_jtag_reset(stlink_t *sl, int value); - int stlink_run(stlink_t *sl); - int stlink_status(stlink_t *sl); - int stlink_version(stlink_t *sl); - int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); - int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - int stlink_step(stlink_t *sl); - int stlink_current_mode(stlink_t *sl); - int stlink_force_debug(stlink_t *sl); - int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); - - int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - uint8_t stlink_get_erased_pattern(stlink_t *sl); - int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); - int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); - - int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); - int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); - uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); - uint16_t read_uint16(const unsigned char *c, const int pt); - void stlink_core_stat(stlink_t *sl); - void stlink_print_data(stlink_t *sl); - unsigned int is_bigendian(void); - uint32_t read_uint32(const unsigned char *c, const int pt); - void write_uint32(unsigned char* buf, uint32_t ui); - void write_uint16(unsigned char* buf, uint16_t ui); - bool stlink_is_core_halted(stlink_t *sl); - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); - int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - int stlink_load_device_params(stlink_t *sl); - int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); - int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); - -#include "stlink/sg.h" -#include "stlink/usb.h" -#include "stlink/reg.h" -#include "stlink/commands.h" -#include "stlink/chipid.h" -#include "stlink/flash_loader.h" -#include "stlink/version.h" +typedef struct _cortex_m3_cpuid_ { + uint16_t implementer_id; + uint16_t variant; + uint16_t part; + uint8_t revision; +} cortex_m3_cpuid_t; + +enum stlink_jtag_api_version { + STLINK_JTAG_API_V1 = 1, + STLINK_JTAG_API_V2, + STLINK_JTAG_API_V3, +}; + +typedef struct stlink_version_ { + uint32_t stlink_v; + uint32_t jtag_v; + uint32_t swim_v; + uint32_t st_vid; + uint32_t stlink_pid; + // jtag api version supported + enum stlink_jtag_api_version jtag_api; + // one bit for each feature supported. See macros STLINK_F_* + uint32_t flags; +} stlink_version_t; + +enum transport_type { + TRANSPORT_TYPE_ZERO = 0, + TRANSPORT_TYPE_LIBSG, + TRANSPORT_TYPE_LIBUSB, + TRANSPORT_TYPE_INVALID +}; + +typedef struct _stlink stlink_t; + +#include + +struct _stlink { + struct _stlink_backend *backend; + void *backend_data; + + // Room for the command header + unsigned char c_buf[C_BUF_LEN]; + // Data transferred from or to device + unsigned char q_buf[Q_BUF_LEN]; + int q_len; + + // transport layer verboseness: 0 for no debug info, 10 for lots + int verbose; + int opt; + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + enum target_state core_stat; // set by stlink_status() + + char serial[STLINK_SERIAL_MAX_SIZE]; + int serial_size; + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + + enum stlink_flash_type flash_type; + // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + bool has_dual_bank; + + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + + /* sram settings */ + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + + /* option settings */ + stm32_addr_t option_base; + size_t option_size; + + // bootloader + // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + + struct stlink_version_ version; +}; + +int stlink_enter_swd_mode(stlink_t *sl); +int stlink_enter_jtag_mode(stlink_t *sl); +int stlink_exit_debug_mode(stlink_t *sl); +int stlink_exit_dfu_mode(stlink_t *sl); +void stlink_close(stlink_t *sl); +int stlink_core_id(stlink_t *sl); +int stlink_reset(stlink_t *sl); +int stlink_jtag_reset(stlink_t *sl, int value); +int stlink_run(stlink_t *sl); +int stlink_status(stlink_t *sl); +int stlink_version(stlink_t *sl); +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); +int stlink_step(stlink_t *sl); +int stlink_current_mode(stlink_t *sl); +int stlink_force_debug(stlink_t *sl); +int stlink_target_voltage(stlink_t *sl); +int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + +int stlink_erase_flash_mass(stlink_t* sl); +int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +uint8_t stlink_get_erased_pattern(stlink_t *sl); +int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); + +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); + +int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); +uint16_t read_uint16(const unsigned char *c, const int pt); +void stlink_core_stat(stlink_t *sl); +void stlink_print_data(stlink_t *sl); +unsigned int is_bigendian(void); +uint32_t read_uint32(const unsigned char *c, const int pt); +void write_uint32(unsigned char* buf, uint32_t ui); +void write_uint16(unsigned char* buf, uint16_t ui); +bool stlink_is_core_halted(stlink_t *sl); +int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int stlink_load_device_params(stlink_t *sl); + +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); + +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus } diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 368e157a7..98164a8fc 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -28,7 +28,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F3 = 0x422, STLINK_CHIPID_STM32_F4_LP = 0x423, STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, + STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, /* assigned to some L1 "Medium-plus" chips */ STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, STLINK_CHIPID_STM32_L1_CAT2 = 0x429, STLINK_CHIPID_STM32_F1_XL = 0x430, @@ -36,23 +36,11 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, - /* - * 0x435 covers STM32L43xxx and STM32L44xxx devices - * 0x461 covers STM32L496xx and STM32L4A6xx devices - * 0x462 covers STM32L45xxx and STM32L46xxx devices - * 0x464 covers STM32L41xxx and STM32L42xxx devices - */ - STLINK_CHIPID_STM32_L43X = 0x435, - STLINK_CHIPID_STM32_L496X = 0x461, - STLINK_CHIPID_STM32_L46X = 0x462, - STLINK_CHIPID_STM32_L41X = 0x464, - /* - * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" - * and some that are called "High". 0x427 is assigned to the other "Medium- - * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and - * 0x436 HIGH. - */ - STLINK_CHIPID_STM32_L1_HIGH = 0x436, + STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ + STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ + STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ + STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ + STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 chips called "Medium-Plus" and to some called "High" */ STLINK_CHIPID_STM32_L152_RE = 0x437, STLINK_CHIPID_STM32_F334 = 0x438, STLINK_CHIPID_STM32_F3_SMALL = 0x439, @@ -69,12 +57,12 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G071/081 + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G031/041 - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board + STLINK_CHIPID_STM32_L4RX = 0x470, /* taken from the STM32L4R9I-DISCO board */ STLINK_CHIPID_STM32_WB55 = 0x495 }; @@ -85,11 +73,14 @@ struct stlink_chipid_params { uint32_t chip_id; char *description; enum stlink_flash_type flash_type; + bool has_dual_bank; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; uint32_t bootrom_base; uint32_t bootrom_size; + uint32_t option_base; + uint32_t option_size; }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); diff --git a/include/stlink/commands.h b/include/stlink/commands.h index acf664cb1..a6830ff26 100644 --- a/include/stlink/commands.h +++ b/include/stlink/commands.h @@ -2,26 +2,35 @@ #define STLINK_COMMANDS_H_ enum stlink_debug_commands { - STLINK_DEBUG_ENTER_JTAG = 0x00, - STLINK_DEBUG_GETSTATUS = 0x01, - STLINK_DEBUG_FORCEDEBUG = 0x02, - STLINK_DEBUG_RESETSYS = 0x03, - STLINK_DEBUG_READALLREGS = 0x04, - STLINK_DEBUG_READREG = 0x05, - STLINK_DEBUG_WRITEREG = 0x06, - STLINK_DEBUG_READMEM_32BIT = 0x07, - STLINK_DEBUG_WRITEMEM_32BIT = 0x08, - STLINK_DEBUG_RUNCORE = 0x09, - STLINK_DEBUG_STEPCORE = 0x0a, - STLINK_DEBUG_SETFP = 0x0b, - STLINK_DEBUG_WRITEMEM_8BIT = 0x0d, - STLINK_DEBUG_CLEARFP = 0x0e, - STLINK_DEBUG_WRITEDEBUGREG = 0x0f, - STLINK_DEBUG_ENTER = 0x20, - STLINK_DEBUG_EXIT = 0x21, - STLINK_DEBUG_READCOREID = 0x22, - STLINK_DEBUG_APIV2_ENTER = 0x30, - STLINK_DEBUG_ENTER_SWD = 0xa3 + STLINK_DEBUG_ENTER_JTAG = 0x00, + STLINK_DEBUG_GETSTATUS = 0x01, + STLINK_DEBUG_FORCEDEBUG = 0x02, + STLINK_DEBUG_APIV1_RESETSYS = 0x03, + STLINK_DEBUG_APIV1_READALLREGS = 0x04, + STLINK_DEBUG_APIV1_READREG = 0x05, + STLINK_DEBUG_APIV1_WRITEREG = 0x06, + STLINK_DEBUG_READMEM_32BIT = 0x07, + STLINK_DEBUG_WRITEMEM_32BIT = 0x08, + STLINK_DEBUG_RUNCORE = 0x09, + STLINK_DEBUG_STEPCORE = 0x0a, + STLINK_DEBUG_APIV1_SETFP = 0x0b, + STLINK_DEBUG_WRITEMEM_8BIT = 0x0d, + STLINK_DEBUG_APIV1_CLEARFP = 0x0e, + STLINK_DEBUG_APIV1_WRITEDEBUGREG = 0x0f, + STLINK_DEBUG_APIV1_ENTER = 0x20, + STLINK_DEBUG_EXIT = 0x21, + STLINK_DEBUG_READCOREID = 0x22, + STLINK_DEBUG_APIV2_ENTER = 0x30, + STLINK_DEBUG_APIV2_READ_IDCODES = 0x31, + STLINK_DEBUG_APIV2_RESETSYS = 0x32, + STLINK_DEBUG_APIV2_READREG = 0x33, + STLINK_DEBUG_APIV2_WRITEREG = 0x34, + STLINK_DEBUG_APIV2_WRITEDEBUGREG = 0x35, + STLINK_DEBUG_APIV2_READDEBUGREG = 0x36, + STLINK_DEBUG_APIV2_READALLREGS = 0x3A, + STLINK_DEBUG_APIV2_GETLASTRWSTATUS = 0x3B, + STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 = 0x3E, + STLINK_DEBUG_ENTER_SWD = 0xa3 }; #endif /* STLINK_COMMANDS_H_ */ diff --git a/include/stlink/flash_loader.h b/include/stlink/flash_loader.h index 95042f7b6..5f4526114 100644 --- a/include/stlink/flash_loader.h +++ b/include/stlink/flash_loader.h @@ -10,7 +10,7 @@ #include #include -#include "stlink.h" +#include #ifdef __cplusplus extern "C" { diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 8ca1eddf9..3a4dc3ec4 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -2,10 +2,12 @@ #define STLINK_TOOLS_FLASH_H_ #include + #include #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 +#define ENABLE_OPT 1 enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; @@ -13,7 +15,6 @@ enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, F struct flash_opts { enum flash_cmd cmd; - const char* devname; uint8_t serial[STLINK_SERIAL_MAX_SIZE]; const char* filename; stm32_addr_t addr; @@ -24,11 +25,13 @@ struct flash_opts enum flash_area area; uint32_t val; size_t flash_size; /* --flash=n[k][m] */ + int opt; /* enable empty tail data drop optimization */ + int freq; /* --freq=n[k][m] frequency of JTAG/SWD */ + bool connect_under_reset; }; -#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0 } +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); #endif // STLINK_FLASH_H_ - diff --git a/include/stm32.h b/include/stm32.h index 9a01baaf4..c71718653 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -15,9 +15,10 @@ #define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_L0_CATx_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) -#define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #endif /* STM32_H */ diff --git a/mingw64-build.bat b/mingw64-build.bat new file mode 100644 index 000000000..eeaacddab --- /dev/null +++ b/mingw64-build.bat @@ -0,0 +1,9 @@ +@echo on + +mkdir build-mingw +cd build-mingw +set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% +cmake -G "MinGW Makefiles" .. +mingw32-make +mingw32-make install DESTDIR=install +mingw32-make package diff --git a/scripts/run_clang_analyze.sh b/run_clang_analyze.sh similarity index 64% rename from scripts/run_clang_analyze.sh rename to run_clang_analyze.sh index 8d5c5a988..fd1b78b55 100755 --- a/scripts/run_clang_analyze.sh +++ b/run_clang_analyze.sh @@ -1,6 +1,7 @@ #!/bin/bash -# Run this hacky script in project root directory to start -# clang static analysis. Adjust ccc-analyzer path if nesesary +# Run this hacky script in project root directory to start clang static analysis. +# Adjust ccc-analyzer path if necessary + CCC_ANALYZER=/usr/share/clang/scan-build-3.5/ccc-analyzer mkdir -p build-clang-analyze/reports cd build-clang-analyze diff --git a/scripts/appveyor-mingw.sh b/scripts/appveyor-mingw.sh deleted file mode 100644 index 4842410ba..000000000 --- a/scripts/appveyor-mingw.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -set -e -cd `dirname "$0"`/.. -if [ "$ARCH" = "i686" ]; then - f=i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f - fi - 7z x $f > /dev/null - mv mingw32 /MinGW -else - f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f - fi - 7z x $f > /dev/null - mv mingw64 /MinGW -fi -cd build -cmake .. -G"$GENERATOR" -cmake --build . --config RelWithDebInfo diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat deleted file mode 100644 index 3f92ae8e0..000000000 --- a/scripts/mingw64-build.bat +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin;%PATH% -cmake -G "MinGW Makefiles" .. -mingw32-make -mingw32-make install DESTDIR=_install -mingw32-make package diff --git a/src/chipid.c b/src/chipid.c index df07d524f..fcc1c55eb 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -1,11 +1,11 @@ -#include "stlink.h" -#include "stlink/chipid.h" +#include +#include static const struct stlink_chipid_params devices[] = { { //RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, - .description = "F76xxx device", + .description = "F76xxx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 45.2 .flash_pagesize = 0x800, // No flash pages @@ -16,7 +16,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0385 and DS10916 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F7 device", + .description = "F7xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages @@ -27,7 +27,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0431 and DS document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F72XXX, - .description = "F72 device", + .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff07a22, // section 35.2 .flash_pagesize = 0x800, // No flash pages @@ -37,7 +37,7 @@ static const struct stlink_chipid_params devices[] = { }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, - .description = "F1 Medium-density device", + .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -47,13 +47,15 @@ static const struct stlink_chipid_params devices[] = { }, { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, - .description = "F2 device", + .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, }, { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, @@ -67,7 +69,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4 device", + .description = "F4xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -77,7 +79,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .description = "F46x and F47x device", + .description = "F46x/F47x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -87,7 +89,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_HD, - .description = "F42x and F43x device", + .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -97,7 +99,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F4 device (low power)", + .description = "F4xx (low power)", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -107,7 +109,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F411RE, - .description = "F4 device (low power) - stm32f411re", + .description = "stm32f411re", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -117,7 +119,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F4 device (Dynamic Efficency)", + .description = "F4xx (Dynamic Efficency)", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -127,7 +129,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, - .description = "F1 High-density device", + .description = "F1xx High-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -139,7 +141,7 @@ static const struct stlink_chipid_params devices[] = { // This ignores the EEPROM! (and uses the page erase size, // not the sector write protection...) .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, - .description = "L1 Med-density device", + .description = "L1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, @@ -149,7 +151,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .description = "L1 Cat.2 device", + .description = "L1xx Cat.2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, @@ -159,7 +161,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, - .description = "L1 Medium-Plus-density device", + .description = "L1xx Medium-Plus-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, @@ -169,13 +171,15 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, - .description = "L1 High-density device", + .description = "L1xx High-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, }, { .chip_id = STLINK_CHIPID_STM32_L152_RE, @@ -189,7 +193,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1 Connectivity line device", + .description = "F1 Connectivity line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -199,7 +203,7 @@ static const struct stlink_chipid_params devices[] = { }, {//Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, - .description = "F1 Medium/Low-density Value Line device", + .description = "F1xx Value Line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -210,18 +214,20 @@ static const struct stlink_chipid_params devices[] = { { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. .chip_id = STLINK_CHIPID_STM32_F446, - .description = "F446 device", + .description = "F446", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, }, { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. .chip_id = STLINK_CHIPID_STM32_F410, - .description = "F410 device", + .description = "F410", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x4000, @@ -233,7 +239,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F303VCT6 device from STM32 F3 Discovery board. // Support based on DM00043574.pdf (RM0316) document. .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F3 device", + .description = "F3xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -245,7 +251,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F373VCT6 device from STM32 F373 eval board // Support based on 303 above (37x and 30x have same memory map) .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F3 device", + .description = "F3xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -255,7 +261,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, - .description = "F1 High-density value line device", + .description = "F1xx High-density value line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -265,7 +271,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_XL, - .description = "F1 XL-density device", + .description = "F1xx XL-density", .flash_type = STLINK_FLASH_TYPE_F1_XL, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -277,7 +283,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .description = "F07x device", + .description = "F07x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 @@ -289,7 +295,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F0 device", + .description = "F0xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -301,7 +307,7 @@ static const struct stlink_chipid_params devices[] = { // RM0402 document was used to find these parameters // Table 4. .chip_id = STLINK_CHIPID_STM32_F412, - .description = "F4 device", + .description = "F412", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) .flash_pagesize = 0x4000, // Table 5. Flash module organization ? @@ -313,7 +319,7 @@ static const struct stlink_chipid_params devices[] = { // RM0430 DocID029473 Rev 2 document was used to find these parameters // Figure 2, Table 4, Table 5, Section 35.2 .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F4 device", + .description = "F413", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) @@ -323,7 +329,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F09X, - .description = "F09X device", + .description = "F09X", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) @@ -335,7 +341,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F04, - .description = "F04x device", + .description = "F04x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -347,7 +353,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_SMALL, - .description = "F0 small device", + .description = "F0xx small", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -358,7 +364,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32F30x .chip_id = STLINK_CHIPID_STM32_F3_SMALL, - .description = "F3 small device", + .description = "F3xx small", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -370,43 +376,49 @@ static const struct stlink_chipid_params devices[] = { // STM32L0x // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0x3 device", + .description = "L0x3", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x2000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L0x Category 5 // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .description = "L0x Category 5 device", + .description = "L0xx Category 5", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x5000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L0x Category 2 // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0x Category 2 device", + .description = "L0xx Category 2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x2000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32F334, STM32F303x6/8, and STM32F328 // From RM0364 and RM0316 .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F3xx medium density device", // (RM0316 sec 33.6.1) + .description = "F334 medium density", // (RM0316 sec 33.6.1) .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -418,7 +430,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F303RET6 device from STM32 F3 Nucelo board. // Support based on DM00043574.pdf (RM0316) document rev 5. .chip_id = STLINK_CHIPID_STM32_F303_HIGH, - .description = "F303 high density device", + .description = "F303 high density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register .flash_pagesize = 0x800, // 4.2.1 Flash memory organization @@ -430,7 +442,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L4x6 // From RM0351. .chip_id = STLINK_CHIPID_STM32_L4, - .description = "L4 device", + .description = "L4xx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) @@ -439,13 +451,15 @@ static const struct stlink_chipid_params devices[] = { // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0x18000, .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L4RX // From DM00310109.pdf .chip_id = STLINK_CHIPID_STM32_L4RX, - .description = "L4Rx device", + .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 @@ -457,7 +471,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L41X // From RM0394 Rev 4 and DS12469 Rev 5 .chip_id = STLINK_CHIPID_STM32_L41X, - .description = "L41x device", + .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) .flash_pagesize = 0x800, // 2K (DS12469, sec 3.4, page 17) @@ -471,7 +485,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L43X // From RM0392. .chip_id = STLINK_CHIPID_STM32_L43X, - .description = "L43x/L44x device", + .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) @@ -480,13 +494,15 @@ static const struct stlink_chipid_params devices[] = { // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STLINK_CHIPID_STM32_L496X // Support based on en.DM00083560.pdf (RM0351) document rev 5. .chip_id = STLINK_CHIPID_STM32_L496X, - .description = "L496x/L4A6x device", + .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) @@ -494,13 +510,15 @@ static const struct stlink_chipid_params devices[] = { // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STLINK_CHIPID_STM32_L46X // From RM0394 (updated version of RM0392?). .chip_id = STLINK_CHIPID_STM32_L46X, - .description = "L45x/46x device", + .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) .flash_pagesize = 0x800, // 2K (sec 3.2, page 73; also appears in sec 3.3.1 and tables 7 on pages 73-74) @@ -513,7 +531,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32L011 .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L011 device", + .description = "L011", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -522,42 +540,68 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000 }, { - // STM32GG030/031/041 (from RM0444) + // STM32G030/031/041 (from RM0454 & RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G030/G031/G041 device", + .description = "G030/G031/G041", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x2000, // 8K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000 // 8K (sec 2.2.2 table 3) + .bootrom_size = 0x2000, // 8K (sec 2.2.2 table 3) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32G071/081 (from RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G070/G071/G081 device", + .description = "G070/G071/G081", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x9000, // 36K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (sec 2.2.2 table 2) + .bootrom_size = 0x7000, // 28K (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32G431/441 (from RM0440) .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G4 Category-2 device", + .description = "G4 Category-2", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2K (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 .sram_size = 0x8000, // 32K (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (table 2) + .bootrom_size = 0x7000, // 28K (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G471/473/474/483/484 (from RM0440) + .chip_id = STLINK_CHIPID_STM32_G4_CAT3, + .description = "G4 Category-3", + .flash_type = STLINK_FLASH_TYPE_G4, + .has_dual_bank = true, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2K (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128K (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28K (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32WB55 (from RM0434) .chip_id = STLINK_CHIPID_STM32_WB55, - .description = "WB55 device", + .description = "WB55", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, .flash_pagesize = 0x1000, // 4K @@ -576,8 +620,6 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x0, .bootrom_size = 0x0 }, - - }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) diff --git a/src/common.c b/src/common.c index 6226c893b..e8f7cebc6 100644 --- a/src/common.c +++ b/src/common.c @@ -1,9 +1,9 @@ #define DEBUG_FLASH 0 - #include #include #include #include +#include #include #include @@ -11,19 +11,19 @@ #include #include -#include "stlink.h" -#include "stlink/mmap.h" -#include "stlink/logging.h" +#include +#include "mmap.h" +#include "logging.h" +#include "md5.h" -#ifndef _WIN32 -#define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate) +#ifndef O_BINARY +#define O_BINARY 0 #endif + #ifdef _MSC_VER #define __attribute__(x) #endif -/* todo: stm32l15xxx flash memory, pm0062 manual */ - /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) @@ -32,6 +32,7 @@ #define FLASH_ACR (FLASH_REGS_ADDR + 0x00) #define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) +#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) #define FLASH_SR (FLASH_REGS_ADDR + 0x0c) #define FLASH_CR (FLASH_REGS_ADDR + 0x10) #define FLASH_AR (FLASH_REGS_ADDR + 0x14) @@ -50,17 +51,36 @@ #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xCDEF89AB + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + #define FLASH_SR_BSY 0 +#define FLASH_SR_PG_ERR 2 +#define FLASH_SR_WRPRT_ERR 4 #define FLASH_SR_EOP 5 +#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) + #define FLASH_CR_PG 0 #define FLASH_CR_PER 1 #define FLASH_CR_MER 2 +#define FLASH_CR_OPTPG 4 #define FLASH_CR_STRT 6 #define FLASH_CR_LOCK 7 +#define FLASH_CR_OPTWRE 9 - -//32L = 32F1 same CoreID as 32F4! #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) #define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) #define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) @@ -76,13 +96,13 @@ // Flash registers common to STM32G0 and STM32G4 series. #define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20) +#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) // G0 (RM0444 Table 1, sec 3.7) // Mostly the same as G4 chips, but the notation @@ -119,6 +139,7 @@ #define STM32Gx_FLASH_CR_PNB (3) /* Page number */ #define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ #define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ #define STM32Gx_FLASH_CR_STRT (16) /* Start */ #define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */ #define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ @@ -127,8 +148,14 @@ #define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ #define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ #define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ + // G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ + +// G4 FLASH option register +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) @@ -154,6 +181,7 @@ // WB Flash control register. #define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ #define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ // WB Flash status register. #define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ @@ -181,20 +209,23 @@ #define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) #define STM32L4_FLASH_CR_OPBITS \ - ((1lu<chip_id) { + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MEDIUM: + case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: + case STLINK_CHIPID_STM32_L1_HIGH: + return STM32L1_FLASH_REGS_ADDR; + default: + return STM32L0_FLASH_REGS_ADDR; + } +} + static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { uint32_t rdp; stlink_read_debug32(sl, FLASH_WRPR, &rdp); @@ -328,54 +366,81 @@ static inline uint32_t read_flash_cr2(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - uint32_t cr_lock_shift, cr = read_flash_cr(sl); + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - else - cr_lock_shift = FLASH_CR_LOCK; + } else { + ELOG("unsupported flash method, abort\n"); + return -1; + } - return cr & (1u << cr_lock_shift); + stlink_read_debug32(sl, cr_reg, &n); + return n & (1u << cr_lock_shift); } static void unlock_flash(stlink_t *sl) { uint32_t key_reg; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; /* the unlock sequence consists of 2 write cycles where 2 key values are written to the FLASH_KEYR register. an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { key_reg = STM32L4_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; - else - key_reg = FLASH_KEYR; + } else { + ELOG("unsupported flash method, abort\n"); + return; + } - stlink_write_debug32(sl, key_reg, FLASH_KEY1); - stlink_write_debug32(sl, key_reg, FLASH_KEY2); + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY2); + stlink_write_debug32(sl, FLASH_KEYR2, flash_key1); + stlink_write_debug32(sl, FLASH_KEYR2, flash_key2); } } +/* unlock flash if already locked */ static int unlock_flash_if(stlink_t *sl) { - /* unlock flash if already locked */ - if (is_flash_locked(sl)) { unlock_flash(sl); if (is_flash_locked(sl)) { @@ -390,9 +455,16 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; @@ -404,11 +476,12 @@ static void lock_flash(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; + ELOG("unsupported flash method, abort\n"); + return; } - n = read_flash_cr(sl) | (1u << cr_lock_shift); + stlink_read_debug32(sl, cr_reg, &n); + n |= (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { @@ -417,6 +490,156 @@ static void lock_flash(stlink_t *sl) { } } +static bool is_flash_option_locked(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) + return !(n & (1u << optlock_shift)); + return n & (1u << optlock_shift); + +} + +static int lock_flash_option(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg, n; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + if (active_bit_level == 0) + n &= ~(1u << optlock_shift); + else + n |= (1u << optlock_shift); + stlink_write_debug32(sl, optcr_reg, n); + + return 0; +} + +static int unlock_flash_option(stlink_t *sl) +{ + uint32_t optkey_reg; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + return 0; +} + +static int unlock_flash_option_if(stlink_t *sl) { + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return -1; + } + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return -1; + } + } + DLOG("Successfully unlocked flash option\n"); + return 0; +} static void set_flash_cr_pg(stlink_t *sl) { uint32_t cr_reg, x; @@ -514,7 +737,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + if (sl->has_dual_bank) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; @@ -533,7 +759,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { stlink_write_debug32(sl, cr_reg, val); } - if(v) + if (v) val |= cr_mer; else val &= ~cr_mer; @@ -610,17 +836,23 @@ static void set_flash_cr2_strt(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_reg = FLASH_F4_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; - else - sr_reg = FLASH_SR; + } else { + ELOG("unsupported flash method, abort"); + return -1; + } stlink_read_debug32(sl, sr_reg, &res); @@ -637,17 +869,21 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_busy_shift = FLASH_F4_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; - else - sr_busy_shift = FLASH_SR_BSY; + } else { + ELOG("unsupported flash method, abort"); + return -1; + } res = read_flash_sr(sl) & (1 << sr_busy_shift); @@ -679,6 +915,31 @@ static void wait_flash_busy_progress(stlink_t *sl) { fprintf(stdout, "\n"); } +static int check_flash_error(stlink_t *sl) +{ + uint32_t res = 0; + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + default: + break; + } + + if (res) { + ELOG("Flash programming error : %#010x\n", res); + return -1; + } + + return 0; +} + static inline unsigned int is_flash_eop(stlink_t *sl) { return read_flash_sr(sl) & (1 << FLASH_SR_EOP); } @@ -727,12 +988,12 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1<implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; return -1; - + } cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; @@ -830,7 +1095,9 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { * @return 0 for success, or -1 for unsupported core type. */ int stlink_load_device_params(stlink_t *sl) { - ILOG("Loading device parameters....\n"); + // This seems to normally work so is unnecessary info for a normal + // user. Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); uint32_t chip_id; @@ -846,7 +1113,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_id = 0x413; } - params = stlink_chipid_get_params(sl->chip_id); // chipid.c + params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); return -1; @@ -874,7 +1141,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = (flash_size & 0xff) * 1024; } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { // 0 is 384k and 1 is 256k - if ( flash_size == 0 ) { + if ( flash_size == 0){ sl->flash_size = 384 * 1024; } else { sl->flash_size = 256 * 1024; @@ -882,23 +1149,43 @@ int stlink_load_device_params(stlink_t *sl) { } else { sl->flash_size = flash_size * 1024; } + sl->flash_type = params->flash_type; + sl->has_dual_bank = params->has_dual_bank; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; //medium and low devices have the same chipid. ram size depends on flash size. //STM32F100xx datasheet Doc ID 16455 Table 2 - if(sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ sl->sram_size = 0x1000; } + if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + +#if 0 + // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - (unsigned int)sl->flash_pgsz); + (unsigned int)sl->flash_pgsz); +#else + ILOG("%s: %zd KiB SRAM, %zd KiB flash in at least %zd %s pages.\n", + params->description, sl->sram_size / 1024, sl->flash_size / 1024, + (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, + (sl->flash_pgsz < 1024)? "byte" : "KiB"); +#endif return 0; } @@ -938,6 +1225,7 @@ int stlink_status(stlink_t *sl) { * @param slv output parsed version object */ void _parse_version(stlink_t *sl, stlink_version_t *slv) { + sl->version.flags = 0; if (sl->version.stlink_v < 3) { uint32_t b0 = sl->q_buf[0]; //lsb uint32_t b1 = sl->q_buf[1]; @@ -955,6 +1243,15 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { slv->swim_v = b1 & 0x3f; slv->st_vid = (b3 << 8) | b2; slv->stlink_pid = (b5 << 8) | b4; + /* ST-LINK/V1 from J11 switch to api-v2 (and support SWD) */ + if (slv->stlink_v == 1) + slv->jtag_api = slv->jtag_v > 11? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; + else { + slv->jtag_api = STLINK_JTAG_API_V2; + /* preferred API to get last R/W status from J15 */ + if (sl->version.jtag_v >= 15) + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } } else { // V3 uses different version format, for reference see OpenOCD source // (that was written from docs available from ST under NDA): @@ -964,6 +1261,9 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { slv->jtag_v = sl->q_buf[2]; slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; } return; } @@ -1011,9 +1311,9 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); + DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); - return ret; + return ret; } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { @@ -1042,7 +1342,7 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); - if (len > 0x40 ) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour + if (len > 0x40){ // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour fprintf(stderr, "Error: Data length > 64: +%d byte.\n", len); abort(); @@ -1121,13 +1421,8 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct s bool stlink_is_core_halted(stlink_t *sl) { - bool ret = false; - - stlink_status(sl); - if (sl->q_buf[0] == STLINK_CORE_HALTED) - ret = true; - - return ret; + stlink_status(sl); + return sl->core_stat == TARGET_HALTED; } int stlink_step(stlink_t *sl) { @@ -1153,8 +1448,6 @@ int stlink_current_mode(stlink_t *sl) { } - - // End of delegates.... Common code below here... // Endianness @@ -1196,21 +1489,21 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { // this function is called by stlink_status() // do not call stlink_core_stat() directly, always use stlink_status() void stlink_core_stat(stlink_t *sl) { - if (sl->q_len <= 0) - return; - - switch (sl->q_buf[0]) { - case STLINK_CORE_RUNNING: - sl->core_stat = STLINK_CORE_RUNNING; + switch (sl->core_stat ) { + case TARGET_RUNNING: DLOG(" core status: running\n"); return; - case STLINK_CORE_HALTED: - sl->core_stat = STLINK_CORE_HALTED; + case TARGET_HALTED: DLOG(" core status: halted\n"); return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; default: - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - fprintf(stderr, " core status: unknown\n"); + DLOG(" core status: unknown\n"); } } @@ -1218,7 +1511,7 @@ void stlink_print_data(stlink_t * sl) { if (sl->q_len <= 0 || sl->verbose < UDEBUG) return; if (sl->verbose > 2) - fprintf(stdout, "data_len = %d 0x%x\n", sl->q_len, sl->q_len); + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); for (int i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { @@ -1229,9 +1522,9 @@ void stlink_print_data(stlink_t * sl) { fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); */ } - fprintf(stdout, " %02x", (unsigned int) sl->q_buf[i]); + DLOG(" %02x", (unsigned int) sl->q_buf[i]); } - fputs("\n\n", stdout); + DLOG("\n\n"); } /* memory mapped file */ @@ -1254,13 +1547,19 @@ static int map_file(mapped_file_t* mf, const char* path) { } if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat() == -1\n"); + fprintf(stderr, "fstat(%s) == -1\n", path); goto on_error; } - - mf->base = (uint8_t*) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (sizeof(st.st_size) != sizeof(size_t)) { + /* On 32 bit systems, check if there is an overflow */ + if (st.st_size > (off_t)UINT32_MAX) { + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + goto on_error; + } + } + mf->base = (uint8_t*) mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED\n"); + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); goto on_error; } @@ -1311,6 +1610,30 @@ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { return 0; } +static void md5_calculate(mapped_file_t *mf) { + /* calculate md5 checksum of given binary file */ + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); + for (int i = 0; i < (int) sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } + printf(", "); +} + +static void stlink_checksum(mapped_file_t *mp) { + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } + printf("stlink checksum: 0x%08x\n", sum); +} + static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { unsigned int val; /* set stack*/ @@ -1347,7 +1670,7 @@ int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr len = length; - if(len & 3) { + if (len & 3) { len -= len & 3; } @@ -1366,7 +1689,7 @@ int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr stlink_write_mem32(sl, addr + (uint32_t) off, size); } - if(length > len) { + if (length > len) { memcpy(sl->q_buf, data + len, length - len); stlink_write_mem8(sl, addr + (uint32_t) len, length - len); } @@ -1391,6 +1714,9 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { fprintf(stderr, "map_file() == -1\n"); return -1; } + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); /* check addr range is inside the sram */ if (addr < sl->sram_base) { @@ -1410,7 +1736,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { len = mf.len; - if(len & 3) { + if (len & 3) { len -= len & 3; } @@ -1429,7 +1755,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { stlink_write_mem32(sl, addr + (uint32_t) off, size); } - if(mf.len > len) { + if (mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); stlink_write_mem8(sl, addr + (uint32_t) len, mf.len - len); } @@ -1513,7 +1839,7 @@ struct stlink_fread_ihex_worker_arg { static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { uint32_t addr = the_arg->addr; uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); - if(17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) return false; the_arg->lba = (addr & 0xFFFF0000); @@ -1523,26 +1849,26 @@ static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* th static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { uint8_t count = the_arg->buf_pos; - if(count == 0) return true; + if (count == 0) return true; uint32_t addr = the_arg->addr; - if(the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if(!stlink_fread_ihex_newsegment(the_arg)) return false; + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) return false; } uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); - if(9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) return false; - for(uint8_t i = 0; i < count; ++i) { + for (uint8_t i = 0; i < count; ++i) { uint8_t b = the_arg->buf[i]; sum += b; - if(2 != fprintf(the_arg->file, "%02X", b)) + if (2 != fprintf(the_arg->file, "%02X", b)) return false; } - if(4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) return false; the_arg->addr += count; @@ -1563,9 +1889,9 @@ static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg* the_arg, static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { struct stlink_fread_ihex_worker_arg* the_arg = (struct stlink_fread_ihex_worker_arg*)arg; - for(ssize_t i = 0; i < len; ++i) { - if(the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if(!stlink_fread_ihex_writeline(the_arg)) return false; + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) return false; } the_arg->buf[the_arg->buf_pos++] = block[i]; @@ -1575,11 +1901,11 @@ static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { } static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { - if(!stlink_fread_ihex_writeline(the_arg)) return false; + if (!stlink_fread_ihex_writeline(the_arg)) return false; // FIXME do we need the Start Linear Address? - if(13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF return false; return (0 == fclose(the_arg->file)); @@ -1596,11 +1922,11 @@ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr return -1; } - if(is_ihex) { + if (is_ihex) { struct stlink_fread_ihex_worker_arg arg; - if(stlink_fread_ihex_init(&arg, fd, addr)) { + if (stlink_fread_ihex_init(&arg, fd, addr)) { error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if(!stlink_fread_ihex_finalize(&arg)) + if (!stlink_fread_ihex_finalize(&arg)) error = -1; } else { @@ -1640,18 +1966,18 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ flashaddr -= 0x100000; } if (flashaddr<0x4000) return (offset + 0); - else if(flashaddr<0x8000) return(offset + 1); - else if(flashaddr<0xc000) return(offset + 2); - else if(flashaddr<0x10000) return(offset + 3); - else if(flashaddr<0x20000) return(offset + 4); + else if (flashaddr<0x8000) return(offset + 1); + else if (flashaddr<0xc000) return(offset + 2); + else if (flashaddr<0x10000) return(offset + 3); + else if (flashaddr<0x20000) return(offset + 4); else return offset + (flashaddr/0x20000) +4; } uint32_t calculate_F7_sectornum(uint32_t flashaddr){ flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address - if(flashaddr<0x20000) return(flashaddr/0x8000); - else if(flashaddr<0x40000) return(4); + if (flashaddr<0x20000) return(flashaddr/0x8000); + else if (flashaddr<0x40000) return(4); else return(flashaddr/0x40000) +4; } @@ -1666,7 +1992,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { sl->chip_id == STLINK_CHIPID_STM32_L496X || sl->chip_id == STLINK_CHIPID_STM32_L4RX) { // This chip use dual banked flash - if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t) sl->flash_size / 2; if (flashaddr >= banksize) { flashaddr -= banksize; @@ -1677,7 +2003,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { // For 1MB chips without the dual-bank option set, the page address will // overflow into the BKER bit, which gives us the correct bank:page value. - return bker | flashaddr/sl->flash_pgsz; + return bker | flashaddr/(uint32_t)sl->flash_pgsz; } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ @@ -1696,14 +2022,14 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ sector -= 12; } if (sector<4) sl->flash_pgsz=0x4000; - else if(sector<5) sl->flash_pgsz=0x10000; + else if (sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { uint32_t sector=calculate_F7_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x8000; - else if(sector<5) sl->flash_pgsz=0x20000; + else if (sector<5) sl->flash_pgsz=0x20000; else sl->flash_pgsz=0x40000; } return (uint32_t) sl->flash_pgsz; @@ -1784,10 +2110,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* check if the locks are set */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if((val & (1<<0))||(val & (1<<1))) { + if ((val & (1<<0))||(val & (1<<1))) { /* disable pecr protection */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); /* check pecr.pelock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -1797,8 +2123,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } /* unlock program memory */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); /* check pecr.prglock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -1821,7 +2147,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) */ do { stlink_read_debug32(sl, STM32L_FLASH_SR, &val) - } while((val & (1 << 0)) != 0); + } while ((val & (1 << 0)) != 0); #endif /* fix_to_be_confirmed */ @@ -1853,7 +2179,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) // Set the page to erase. if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); // sec 3.10.5 - PNB[7:0] is offset by 3. @@ -1862,14 +2188,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. val &= ~(0x7F << 3); @@ -1893,6 +2219,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* unlock if locked */ unlock_flash_if(sl); + /* clear the pg bit */ + clear_flash_cr_pg(sl); + /* set the page erase bit */ set_flash_cr_per(sl); @@ -1941,11 +2270,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { /* TODO: User MER bit to mass-erase G0, G4, WB series. */ if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ - int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; + int i = 0, num_pages = (int)(sl->flash_size/sl->flash_pgsz); for (i = 0; i < num_pages; i++) { /* addr must be an addr inside the page */ stm32_addr_t addr = (stm32_addr_t) sl->flash_base + i * (stm32_addr_t) sl->flash_pgsz; @@ -1981,6 +2308,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* wait for completion */ wait_flash_busy_progress(sl); + check_flash_error(sl); + /* relock the flash */ lock_flash(sl); @@ -2039,7 +2368,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, stlink_read_mem32(sl, address + (uint32_t) off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); return -1; } } @@ -2134,7 +2463,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of pagesize, not supported\n"); + ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, check page start address and compare with flash module organisation in related ST reference manual of your device.\n", sl->flash_pgsz); return -1; } @@ -2143,17 +2472,15 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* erase each page */ int page_count = 0; for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t) off)) { - /* addr must be an addr inside the page */ + // addr must be an addr inside the page if (stlink_erase_flash_page(sl, addr + (uint32_t) off) == -1) { ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } - fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - fflush(stdout); page_count++; } - fprintf(stdout,"\n"); ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); @@ -2180,7 +2507,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id != STLINK_CHIPID_STM32_L496X) && (sl->chip_id != STLINK_CHIPID_STM32_L4RX)) { - if( sl->version.stlink_v == 1 ) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); } @@ -2213,8 +2540,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* set programming mode */ set_flash_cr_pg(sl); - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for(off = 0; off < len;) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; printf("size: %u\n", (unsigned int)size); @@ -2295,8 +2622,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* todo: check write operation */ /* disable pecr protection */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); /* check pecr.pelock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2306,8 +2633,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } /* unlock program memory */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); /* check pecr.prglock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2334,7 +2661,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off/sl->flash_pgsz), - (unsigned int)(len/sl->flash_pgsz)); + (unsigned int)(len/sl->flash_pgsz)); fflush(stdout); } @@ -2398,11 +2725,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t // note: length not checked static uint8_t stlink_parse_hex(const char* hex) { uint8_t d[2]; - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) { char c = *(hex + i); - if(c >= '0' && c <= '9') d[i] = c - '0'; - else if(c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; - else if(c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; + if (c >= '0' && c <= '9') d[i] = c - '0'; + else if (c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; + else if (c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; else return 0; // error } return (d[0] << 4) | (d[1]); @@ -2415,15 +2742,15 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t end = 0; bool eof_found = false; - for(int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it - if(scan == 1) { - if(!eof_found) { + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { ELOG("No EoF recond\n"); res = -1; break; } - if(*begin >= end) { + if (*begin >= end) { ELOG("No data found in file\n"); res = -1; break; @@ -2431,7 +2758,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, *size = (end - *begin) + 1; data = calloc(*size, 1); // use calloc to get NULL if out of memory - if(!data) { + if (!data) { ELOG("Cannot allocate %d bytes\n", *size); res = -1; break; @@ -2441,7 +2768,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } FILE* file = fopen(path, "r"); - if(!file) { + if (!file) { ELOG("Cannot open file\n"); res = -1; break; @@ -2450,17 +2777,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t lba = 0; char line[1 + 5*2 + 255*2 + 2]; - while(fgets(line, sizeof(line), file)) { - if(line[0] == '\n' || line[0] == '\r') continue; // skip empty lines - if(line[0] != ':') { // no marker - wrong file format + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') continue; // skip empty lines + if (line[0] != ':') { // no marker - wrong file format ELOG("Wrong file format - no marker\n"); res = -1; break; } size_t l = strlen(line); - while(l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL - if((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format + while (l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL + if ((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format ELOG("Wrong file format - wrong line length\n"); res = -1; break; @@ -2468,17 +2795,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, // check sum uint8_t chksum = 0; - for(size_t i = 1; i < l; i += 2) { + for (size_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } - if(chksum != 0) { + if (chksum != 0) { ELOG("Wrong file format - checksum mismatch\n"); res = -1; break; } uint8_t reclen = stlink_parse_hex(line + 1); - if(((uint32_t)reclen + 5)*2 + 1 != l) { + if (((uint32_t)reclen + 5)*2 + 1 != l) { ELOG("Wrong file format - record length mismatch\n"); res = -1; break; @@ -2489,17 +2816,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, switch(rectype) { case 0: // data - if(scan == 0) { + if (scan == 0) { uint32_t b = lba + offset; uint32_t e = b + reclen - 1; - if(b < *begin) *begin = b; - if(e > end) end = e; + if (b < *begin) *begin = b; + if (e > end) end = e; } else { - for(uint8_t i = 0; i < reclen; ++i) { + for (uint8_t i = 0; i < reclen; ++i) { uint8_t b = stlink_parse_hex(line + 9 + i*2); uint32_t addr = lba + offset + i; - if(addr >= *begin && addr <= end) { + if (addr >= *begin && addr <= end) { data[addr - *begin] = b; } } @@ -2519,7 +2846,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, break; case 4: // Extended Linear Address - if(reclen == 2) { + if (reclen == 2) { lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); } else { @@ -2535,13 +2862,13 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, ELOG("Wrong file format - unexpected record type %d\n", rectype); res = -1; } - if(res != 0) break; + if (res != 0) break; } fclose(file); } - if(res == 0) { + if (res == 0) { *mem = data; } else { @@ -2564,17 +2891,31 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); - idx = (unsigned int)length; - for(num_empty = 0; num_empty != length; ++num_empty) { - if (data[--idx] != erased_pattern) { - break; + /* + * This optimization may cause unexpected garbage data remaining + * Turned off by default + */ + if (sl->opt) { + idx = (unsigned int)length; + for (num_empty = 0; num_empty != length; ++num_empty) { + if (data[--idx] != erased_pattern) { + break; + } } - } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } + /* Round down to words */ + num_empty -= (num_empty & 3); + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + } else { + num_empty = 0; + } + /* + * TODO: investigate: + * a kind of weird behaviour here: + * if the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, data, (num_empty == length) ? (uint32_t) length : (uint32_t) length - num_empty, num_empty == length); stlink_fwrite_finalize(sl, addr); return err; @@ -2599,17 +2940,31 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return -1; } - idx = (unsigned int) mf.len; - for(num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { - break; + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + if (sl->opt) { + idx = (unsigned int) mf.len; + for (num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } } - } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } + /* Round down to words */ + num_empty -= (num_empty & 3); + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + } else { + num_empty = 0; + } + /* + * TODO: investigate: + * a kind of weird behaviour here: + * if the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); @@ -2623,62 +2978,17 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; - - if(len != 4) { - ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); - return -1; - } - - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); - - /* Check if chip is supported and for correct address */ - if(sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && - sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { - ELOG("Option bytes writing is currently only supported for the STM32G0\n"); - return -1; - } - - /* Unlock flash if necessary (ref manuel page 52) */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { - - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0xCDEF89AB); - - // check that the lock is no longer set. - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - /* Unlock option bytes if necessary (ref manuel page 61) */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { - - /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x08192A3B); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x4C5D6E7F); - - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { - ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } + int ret = 0; + (void) len; /* Write options bytes */ uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - WLOG("Writing option bytes 0x%04x\n", data); - //stlink_write_debug32(sl, addr, data); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); /* Set Options Start bit */ @@ -2686,84 +2996,16 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + wait_flash_busy(sl); - /* apply options bytes immediate */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + ret = check_flash_error(sl); - /* Re-lock option bytes */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1u << STM32Gx_FLASH_CR_OPTLOCK); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Re-lock flash. */ + /* Reload options */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1u << STM32Gx_FLASH_CR_LOCK); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - return 0; -} - - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32_t len) { - - uint32_t val; - - if(len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); - return -1; - } - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_PELOCK_BIT) { - WLOG("Unlocking flash\n"); - //Unlock data EEPROM and the FLASH_PECR register (reference page 74) - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x89ABCDEF); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x02030405); - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_PELOCK_BIT) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if ((val & (STM32L0_FLASH_OPTLOCK_BIT))) { - WLOG("Unlocking options\n"); - //Unlock the Option bytes area (reference page 76) - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0xFBEAD9C8); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0x24252627); - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_OPTLOCK_BIT) { - ELOG("Options unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - /* Write options bytes */ - uint32_t data; - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32_L0_CAT2_OPTION_BYTES_BASE, data); - - /* Reload options */ - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - val |= (STM32L0_FLASH_OBL_LAUNCH_BIT); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, val); - - return 0; + return ret; } /** @@ -2773,85 +3015,39 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32 * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) +{ + uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; - - if(len != 4 && len != 8) { - ELOG("Wrong length for writting option bytes, must be 4 or 8 is %d\n", len); - return -1; - } - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_PELOCK_BIT) { - WLOG("Unlocking flash\n"); - //Unlock data EEPROM and the FLASH_PECR register (reference page 74) - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x89ABCDEF); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x02030405); - - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_PELOCK_BIT) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if ((val & (STM32L1_FLASH_OPTLOCK_BIT))) { - WLOG("Unlocking options\n"); - //Unlock the Option bytes area (reference page 76) - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0xFBEAD9C8); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0x24252627); - - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_OPTLOCK_BIT) { - ELOG("Options unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - + int ret = 0; /* Clear errors */ - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); + stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); - stlink_read_debug32(sl, addr, &val); - WLOG("Option bytes 0x%08x is 0x%08x\n",addr,val); + while (len != 0) { + /* Write options bytes */ + write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - if( data != val ) { - WLOG("Writing option bytes 0x%04x\n", data); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, addr, &val); - WLOG("Option bytes is 0x%08x\n",val); - } - - - if(len==8) { - /* Clear errors */ - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); - - stlink_read_debug32(sl, addr+4, &val); - WLOG("2nd option bytes 0x%08x is 0x%08x\n",addr,val); + wait_flash_busy(sl); - /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base+4)); - if( data != val ) { - WLOG("Writing 2nd option bytes 0x%04x\n", data); - stlink_write_debug32(sl, addr+4, data); + if ((ret = check_flash_error(sl))) + break; - stlink_read_debug32(sl, addr+4, &val); - WLOG("2nd option bytes is 0x%08x\n",val); - } + len-=4; + addr+=4; + base+=4; } /* Reload options */ - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - val |= (STM32L1_FLASH_OBL_LAUNCH_BIT); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, val); + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - return 0; + return ret; } /** @@ -2861,46 +3057,13 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; + int ret = 0; - if(len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); - return -1; - } - - /* Unlock flash if necessary */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1u << STM32L4_FLASH_CR_LOCK))) { - - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, 0xCDEF89AB); - - // check that the lock is no longer set. - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1u << STM32L4_FLASH_CR_LOCK))) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - /* Unlock option bytes if necessary (ref manuel page 61) */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1 << STM32L4_FLASH_CR_OPTLOCK))) { - - /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, 0x08192A3B); - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, 0x4C5D6E7F); - - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1 << STM32L4_FLASH_CR_OPTLOCK))) { - ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } + (void) addr; + (void) len; /* Write options bytes */ uint32_t data; @@ -2914,25 +3077,16 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t stlink_write_debug32(sl, STM32L4_FLASH_CR, val); /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32L4_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + wait_flash_busy(sl); + + ret = check_flash_error(sl); /* apply options bytes immediate */ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - /* Re-lock option bytes */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1u << STM32L4_FLASH_CR_OPTLOCK); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - /* Re-lock flash. */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1u << STM32L4_FLASH_CR_LOCK); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - return 0; + return ret; } @@ -2942,98 +3096,35 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { - uint32_t val; +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); + (void) addr; + (void) len; - stlink_write_debug32(sl, FLASH_F2_OPT_CR, option_byte & 0x0FFFFFFC); + write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - stlink_write_debug32(sl, FLASH_F2_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F4_OPTCR, (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); + wait_flash_busy(sl); - stlink_read_debug32(sl, FLASH_F2_SR, &val); - WLOG("wait BSY flag to be 0\n"); - - while(val & 0x00010000){ - stlink_read_debug32(sl, FLASH_F2_SR, &val); - } - WLOG("BSY flag is 0\n"); + ret = check_flash_error(sl); - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); + /* option bytes are reloaded at reset only, no obl. */ - DLOG("STM32 F2 option bytes are written\n"); - - return 0; + return ret; } /** - * Write option bytes + * Read option bytes * @param sl * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - - stlink_write_debug32(sl, FLASH_F4_OPT_CR, option_byte & 0x0FFFFFFC); - - stlink_write_debug32(sl, FLASH_F4_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); - - - stlink_read_debug32(sl, FLASH_F4_SR, &val); - WLOG("wait BSY flag to be 0\n"); - - while(val & 0x00010000){ - stlink_read_debug32(sl, FLASH_F4_SR, &val); - } - WLOG("BSY flag is 0\n"); - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); - - DLOG("STM32 F4 option bytes are written\n"); - - return 0; +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } /** @@ -3043,63 +3134,66 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); - WLOG("option bytes CR = %x\n",option_byte); - - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); - - return 0; + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } /** * Read option bytes * @param sl - * @param option_byte value to write + * @param option_byte value to read * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { - uint32_t val; + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +} +/** + * Read first option bytes +* @param sl +* @param option_byte option value +* @return 0 on success, -ve on failure. +*/ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_debug32(sl, sl->option_base, option_byte); +} - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; } - stlink_read_debug32(sl, FLASH_F4_OPT_CR, option_byte); - WLOG("option bytes CR = %x\n",option_byte); - - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } +} - return 0; +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) +{ + WLOG("About to write option byte %#10x to target.\n", option_byte); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } /** @@ -3109,33 +3203,66 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { - - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); - - WLOG("Option bytes write chip_id 0x%08x addr 0x%08x\n",sl->chip_id,addr); +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) +{ + int ret = -1; - /* Check if chip is supported and for correct address */ - if(((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || - (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_g0x(sl, base, len); + if (sl->option_base == 0) { + ELOG("Option bytes writing is currently not supported for connected chip\n"); + return -1; } - else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_l0_cat2(sl, base, len); + + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return -1; } - else if((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_l496x(sl, base, len); + + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return -1; } - else if( ( (sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) - && ( (addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4) ) ) { - return stlink_write_option_bytes_l1(sl, base, addr, len); + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; } - else { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0, STM32L496x/L4A6x, STM32L1 and STM32L0\n"); + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); return -1; } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; } /** @@ -3155,28 +3282,12 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return -1; } + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); return err; } - -/** - * Write the given 32-bit value with option byte - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) { - - if(sl->chip_id == STLINK_CHIPID_STM32_F2){ - return stlink_write_option_bytes_f2(sl, val); - }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ - return stlink_write_option_bytes_f4(sl, val); - } - else - { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32F4, STM32G0 and STM32L0\n"); - return -1; - } -} diff --git a/src/flash_loader.c b/src/flash_loader.c index f88a42eca..a2c5879ce 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -1,210 +1,182 @@ -#include "stlink.h" - #include #include #include +#include + #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 -/* from openocd, contrib/loaders/flash/stm32.s */ -static const uint8_t loader_code_stm32vl[] = { - 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ - 0x1c, 0x44, /* add r4, r3 */ - /* write_half_word: */ - 0x01, 0x23, /* movs r3, #0x01 */ - 0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */ - 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ - 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ - /* busy: */ - 0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */ - 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ - 0xfb, 0xd0, /* beq busy */ - 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ - 0x01, 0xd1, /* bne exit */ - 0x01, 0x3a, /* subs r2, r2, #0x01 */ - 0xf0, 0xd1, /* bne write_half_word */ - /* exit: */ - 0x00, 0xbe, /* bkpt #0x00 */ - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ +/* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ + + /* flashloaders/stm32f0.s -- compiled with thumb2 */ + static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { -#if 1 - /* - * These two NOPs here are a safety precaution, added by Pekka Nikander - * while debugging the STM32F05x support. They may not be needed, but - * there were strange problems with simpler programs, like a program - * that had just a breakpoint or a program that first moved zero to register r2 - * and then had a breakpoint. So, it appears safest to have these two nops. - * - * Feel free to remove them, if you dare, but then please do test the result - * rigorously. Also, if you remove these, it may be a good idea first to - * #if 0 them out, with a comment when these were taken out, and to remove - * these only a few months later... But YMMV. - */ - 0x00, 0x30, // nop /* add r0,#0 */ - 0x00, 0x30, // nop /* add r0,#0 */ -#endif - 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE - 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - 0x04, 0x26, // mov r6, #4 /* PGERR */ - // write_half_word: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0x2B, 0x43, // orr r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ - 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ - // busy: - 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ - 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ - 0xFC, 0xD0, // beq busy - - 0x33, 0x42, // tst r3, r6 /* PGERR */ - 0x04, 0xD1, // bne exit - - 0x02, 0x30, // add r0, r0, #2 /* sram += 2 */ - 0x02, 0x31, // add r1, r1, #2 /* flash += 2 */ - 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ - 0x00, 0x2A, // cmp r2, #0 - 0xF0, 0xD1, // bne write_half_word - // exit: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0xAB, 0x43, // bic r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - 0x00, 0xBE, // bkpt #0x00 - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l[] = { // flashloaders/stm32lx.s - 0x04, 0xe0, // b test_done ; Go to compare - // write_word: - 0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0 - 0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1 - 0x04, 0x30, // adds r0, #4 ; Increment r0 - 0x04, 0x31, // adds r1, #4 ; Increment r1 - 0x01, 0x3a, // subs r2, #1 ; Decrement r2 - // test_done: - 0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0 - 0xf8, 0xd8, // bhi write_word ; Loop if above 0 - 0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit - 0x00, 0x00 + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, }; static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s - 0x07, 0x4b, - - 0x62, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0x92, 0x00, - - 0x08, 0x4b, - 0x62, 0xb1, - 0x04, 0x78, - 0x0c, 0x70, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x01, 0x00, - 0x01, 0xf1, 0x01, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - 0x00, 0xbf, - - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l4[] = { // flashloaders/stm32l4.s - 0x08, 0x4b, // start: ldr r3, [pc, #32] ; - 0x72, 0xb1, // next: cbz r2, - 0x04, 0x68, // ldr r4, [r0, #0] - 0x45, 0x68, // ldr r5, [r0, #4] - 0x0c, 0x60, // str r4, [r1, #0] - 0x4d, 0x60, // str r5, [r1, #4] - 0x5c, 0x8a, // wait: ldrh r4, [r3, #18] - 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 - 0xfb, 0xd1, // bne.n - 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 - 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 - 0xef, 0xe7, // b.n - 0x00, 0xbe, // done: bkpt 0x0000 - 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7[] = { // flashloaders/stm32f7.s - 0x08, 0x4b, - 0x72, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - 0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xef, 0xe7, - 0x00, 0xbe, // bkpt #0x00 - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0x92, 0x00, // lsls r2, r2, #2 - 0x09, 0x4b, // ldr r3, [pc, #36] ; (0x20000028 ) - // next: - 0x72, 0xb1, // cbz r2, 24 - 0x04, 0x78, // ldrb r4, [r0, #0] - 0x0c, 0x70, // strb r4, [r1, #0] - 0xbf, 0xf3, 0x4f, 0x8f, // dsb sy - // wait: - 0xdc, 0x89, // ldrh r4, [r3, #14] - 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 - 0xfb, 0xd1, // bne.n e - 0x00, 0xf1, 0x01, 0x00, // add r0, r0, #1 - 0x01, 0xf1, 0x01, 0x01, // add r1, r1, #1 - 0xa2, 0xf1, 0x01, 0x02, // sub r2, r2, #1 - 0xef, 0xe7, // b next - // done: - 0x00, 0xbe, // bkpt - 0x00, 0xbf, // nop - // flash_base: - 0x00, 0x3c, 0x02, 0x40 // .word 0x40023c00 + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size; + size_t size = 0; /* allocate the loader in sram */ if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { @@ -226,7 +198,7 @@ static int loader_v_dependent_assignment(stlink_t *sl, { int retval = 0; - if( sl->version.stlink_v == 1 ) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -330,7 +302,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } memcpy(sl->q_buf, loader_code, loader_size); - stlink_write_mem32(sl, sl->sram_base, loader_size); + int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); + if (ret) + return ret; *addr = sl->sram_base; *size = loader_size; @@ -384,10 +358,20 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* run loader */ stlink_run(sl); -#define WAIT_ROUNDS 10000 +// This piece of code used to try to spin for .1 second by waiting +// doing 10000 rounds of 10 microseconds. But because this usually runs +// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" +// (actually almost two ticks) of the system. 1 milisecond. Thus, the +// ten thousand attempts, when "something goes wrong" that requires +// the error message "flash loader run error" would wait for something +// like 20 seconds before coming up with the error. +// by increasing the sleep-per-round to the same order-of-magnitude as +// the tick-rounding that the OS uses, the wait until the error message is +// reduced to the same order of magnitude as what was intended. -- REW. +#define WAIT_ROUNDS 100 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(10); + usleep(1000); if (stlink_is_core_halted(sl)) break; } diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt deleted file mode 100644 index 2393690ce..000000000 --- a/src/gdbserver/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -set(STUTIL_SOURCE - gdb-remote.c - gdb-remote.h - gdb-server.c - gdb-server.h - semihosting.c - semihosting.h) - -if (MSVC) - # We need a getopt from somewhere... - set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c") -endif() - -add_executable(st-util ${STUTIL_SOURCE}) - -if (WIN32 OR APPLE) - target_link_libraries(st-util ${STLINK_LIB_STATIC}) -else() - target_link_libraries(st-util ${STLINK_LIB_SHARED}) -endif() - -install(TARGETS st-util - RUNTIME DESTINATION bin -) diff --git a/src/getopt/LICENSE.txt b/src/getopt/LICENSE.txt index 340303a96..4e4ed8bd5 100644 --- a/src/getopt/LICENSE.txt +++ b/src/getopt/LICENSE.txt @@ -1,3 +1,5 @@ +BSD 3-Clause License + Copyright (c) 2012, Kim Gräsman All rights reserved. diff --git a/src/getopt/getopt.c b/src/getopt/getopt.c index 72dce14d6..5dd45bff7 100644 --- a/src/getopt/getopt.c +++ b/src/getopt/getopt.c @@ -1,8 +1,8 @@ -#include "getopt.h" - #include #include +#include "getopt.h" + #if !defined(_MSC_VER) const int no_argument = 0; const int required_argument = 1; @@ -19,8 +19,8 @@ static char* optcursor = NULL; /* Implemented based on [1] and [2] for optional arguments. optopt is handled FreeBSD-style, per [3]. - Other GNU and FreeBSD extensions are purely accidental. - + Other GNU and FreeBSD extensions are purely accidental. + [1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html [2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html [3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE @@ -37,22 +37,22 @@ int getopt(int argc, char* const argv[], const char* optstring) { if (optind >= argc) goto no_more_optchars; - /* If, when getopt() is called argv[optind] is a null pointer, getopt() + /* If, when getopt() is called argv[optind] is a null pointer, getopt() shall return -1 without changing optind. */ if (argv[optind] == NULL) goto no_more_optchars; - /* If, when getopt() is called *argv[optind] is not the character '-', + /* If, when getopt() is called *argv[optind] is not the character '-', getopt() shall return -1 without changing optind. */ if (*argv[optind] != '-') goto no_more_optchars; - /* If, when getopt() is called argv[optind] points to the string "-", + /* If, when getopt() is called argv[optind] points to the string "-", getopt() shall return -1 without changing optind. */ if (strcmp(argv[optind], "-") == 0) goto no_more_optchars; - /* If, when getopt() is called argv[optind] points to the string "--", + /* If, when getopt() is called argv[optind] points to the string "--", getopt() shall return -1 after incrementing optind. */ if (strcmp(argv[optind], "--") == 0) { ++optind; @@ -64,12 +64,12 @@ int getopt(int argc, char* const argv[], const char* optstring) { optchar = *optcursor; - /* FreeBSD: The variable optopt saves the last known option character + /* FreeBSD: The variable optopt saves the last known option character returned by getopt(). */ optopt = optchar; - /* The getopt() function shall return the next option character (if one is - found) from argv that matches a character in optstring, if there is + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is one that matches. */ optdecl = strchr(optstring, optchar); if (optdecl) { @@ -79,15 +79,15 @@ int getopt(int argc, char* const argv[], const char* optstring) { optarg = ++optcursor; if (*optarg == '\0') { /* GNU extension: Two colons mean an option takes an - optional arg; if there is text in the current argv-element - (i.e., in the same word as the option name itself, for example, + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, "-oarg"), then it is returned in optarg, otherwise optarg is set to zero. */ if (optdecl[2] != ':') { /* If the option was the last character in the string pointed to by an element of argv, then optarg shall contain the next element of argv, and optind shall be incremented by 2. If the resulting - value of optind is greater than argc, this indicates a missing + value of optind is greater than argc, this indicates a missing option-argument, and getopt() shall return an error indication. Otherwise, optarg shall point to the string following the @@ -97,7 +97,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { if (++optind < argc) { optarg = argv[optind]; } else { - /* If it detects a missing option-argument, it shall return the + /* If it detects a missing option-argument, it shall return the colon character ( ':' ) if the first character of optstring was a colon, or a question-mark character ( '?' ) otherwise. */ @@ -112,7 +112,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { optcursor = NULL; } } else { - /* If getopt() encounters an option character that is not contained in + /* If getopt() encounters an option character that is not contained in optstring, it shall return the question-mark ( '?' ) character. */ optchar = '?'; } @@ -131,7 +131,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ -int getopt_long(int argc, char* const argv[], const char* optstring, +int getopt_long(int argc, char* const argv[], const char* optstring, const struct option* longopts, int* longindex) { const struct option* o = longopts; const struct option* match = NULL; @@ -165,7 +165,7 @@ int getopt_long(int argc, char* const argv[], const char* optstring, if (longindex) *longindex = (match - longopts); - /* If flag is NULL, then getopt_long() shall return val. + /* If flag is NULL, then getopt_long() shall return val. Otherwise, getopt_long() returns 0, and flag shall point to a variable which shall be set to val if the option is found, but left unchanged if the option is not found. */ @@ -190,7 +190,7 @@ int getopt_long(int argc, char* const argv[], const char* optstring, retval = ':'; } } else if (strchr(argv[optind], '=')) { - /* An argument was provided to a non-argument option. + /* An argument was provided to a non-argument option. I haven't seen this specified explicitly, but both GNU and BSD-based implementations show this behavior. */ diff --git a/src/libusb_settings.h b/src/libusb_settings.h new file mode 100644 index 000000000..c2e2df923 --- /dev/null +++ b/src/libusb_settings.h @@ -0,0 +1,46 @@ +#ifndef LIBUSB_SETTINGS_H +#define LIBUSB_SETTINGS_H + +#include + +/* + + libusb ver | LIBUSB_API_VERSION +-------------+-------------------- + v1.0.13 | 0x01000100 + v1.0.14 | 0x010000FF + v1.0.15 | 0x01000101 + v1.0.16 | 0x01000102 + v1.0.17 | 0x01000102 + v1.0.18 | 0x01000102 + v1.0.19 | 0x01000103 + v1.0.20 | 0x01000104 + v1.0.21 | 0x01000105 + v1.0.22 | 0x01000106 + v1.0.23 | 0x01000107 + +*/ + +#if defined (__FreeBSD__) + #if !defined ( LIBUSBX_API_VERSION ) + #define LIBUSBX_API_VERSION LIBUSB_API_VERSION + #elif !defined (LIBUSB_API_VERSION) + #error unsupported libusb version + #endif +#endif + +#if defined (__FreeBSD__) + #define MINIMAL_API_VERSION 0x01000102 // v1.0.16 +#elif defined (__linux__) + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 +#elif defined (__APPLE__) + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 +#elif defined (_WIN32) + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 +#endif + +#if ( LIBUSB_API_VERSION < MINIMAL_API_VERSION ) + #error unsupported libusb version +#endif + +#endif // STLINKUSB_H diff --git a/src/logging.c b/src/logging.c index d4fb96b2e..ad144f6a4 100644 --- a/src/logging.c +++ b/src/logging.c @@ -9,9 +9,9 @@ #include #include -#include "stlink/logging.h" +#include "logging.h" -static int max_level = UINFO; +static int max_level = UDEBUG; int ugly_init(int maximum_threshold) { max_level = maximum_threshold; @@ -54,3 +54,24 @@ int ugly_log(int level, const char *tag, const char *format, ...) { va_end(args); return 1; } + + +/* + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr +*/ +int ugly_libusb_log_level(enum ugly_loglevel v) +{ + switch (v) { + case UDEBUG: return 4; + case UINFO: return 3; + case UWARN: return 2; + case UERROR: return 1; + }; + + return 2; +} diff --git a/include/stlink/logging.h b/src/logging.h similarity index 96% rename from include/stlink/logging.h rename to src/logging.h index da5f7d19d..1083b2c55 100644 --- a/include/stlink/logging.h +++ b/src/logging.h @@ -18,6 +18,7 @@ enum ugly_loglevel { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); +int ugly_libusb_log_level(enum ugly_loglevel v); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ diff --git a/src/md5.c b/src/md5.c new file mode 100755 index 000000000..521c52969 --- /dev/null +++ b/src/md5.c @@ -0,0 +1,340 @@ +/* + * Retrieved from https://github.com/WaterJuice/WjCryptLib + */ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// WjCryptLib_Md5 +// +// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining +// Public Domain license. +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "md5.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// INTERNAL FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// F, G, H, I +// +// The basic MD5 functions. F and G are optimised compared to their RFC 1321 definitions for architectures that lack +// an AND-NOT instruction, just like in Colin Plumb's implementation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define F( x, y, z ) ( (z) ^ ((x) & ((y) ^ (z))) ) +#define G( x, y, z ) ( (y) ^ ((z) & ((x) ^ (y))) ) +#define H( x, y, z ) ( (x) ^ (y) ^ (z) ) +#define I( x, y, z ) ( (y) ^ ((x) | ~(z)) ) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STEP +// +// The MD5 transformation for all four rounds. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define STEP( f, a, b, c, d, x, t, s ) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TransformFunction +// +// This processes one or more 64-byte data blocks, but does NOT update the bit counters. There are no alignment +// requirements. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void* + TransformFunction + ( + Md5Context* ctx, + void const* data, + uintmax_t size + ) +{ + uint8_t* ptr; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t saved_a; + uint32_t saved_b; + uint32_t saved_c; + uint32_t saved_d; + + #define GET(n) (ctx->block[(n)]) + #define SET(n) (ctx->block[(n)] = \ + ((uint32_t)ptr[(n)*4 + 0] << 0) \ + | ((uint32_t)ptr[(n)*4 + 1] << 8 ) \ + | ((uint32_t)ptr[(n)*4 + 2] << 16) \ + | ((uint32_t)ptr[(n)*4 + 3] << 24) ) + + ptr = (uint8_t*)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do + { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + // Round 1 + STEP( F, a, b, c, d, SET(0), 0xd76aa478, 7 ) + STEP( F, d, a, b, c, SET(1), 0xe8c7b756, 12 ) + STEP( F, c, d, a, b, SET(2), 0x242070db, 17 ) + STEP( F, b, c, d, a, SET(3), 0xc1bdceee, 22 ) + STEP( F, a, b, c, d, SET(4), 0xf57c0faf, 7 ) + STEP( F, d, a, b, c, SET(5), 0x4787c62a, 12 ) + STEP( F, c, d, a, b, SET(6), 0xa8304613, 17 ) + STEP( F, b, c, d, a, SET(7), 0xfd469501, 22 ) + STEP( F, a, b, c, d, SET(8 ), 0x698098d8, 7 ) + STEP( F, d, a, b, c, SET(9 ), 0x8b44f7af, 12 ) + STEP( F, c, d, a, b, SET(10 ), 0xffff5bb1, 17 ) + STEP( F, b, c, d, a, SET(11 ), 0x895cd7be, 22 ) + STEP( F, a, b, c, d, SET(12 ), 0x6b901122, 7 ) + STEP( F, d, a, b, c, SET(13 ), 0xfd987193, 12 ) + STEP( F, c, d, a, b, SET(14 ), 0xa679438e, 17 ) + STEP( F, b, c, d, a, SET(15 ), 0x49b40821, 22 ) + + // Round 2 + STEP( G, a, b, c, d, GET(1), 0xf61e2562, 5 ) + STEP( G, d, a, b, c, GET(6), 0xc040b340, 9 ) + STEP( G, c, d, a, b, GET(11), 0x265e5a51, 14 ) + STEP( G, b, c, d, a, GET(0), 0xe9b6c7aa, 20 ) + STEP( G, a, b, c, d, GET(5), 0xd62f105d, 5 ) + STEP( G, d, a, b, c, GET(10), 0x02441453, 9 ) + STEP( G, c, d, a, b, GET(15), 0xd8a1e681, 14 ) + STEP( G, b, c, d, a, GET(4), 0xe7d3fbc8, 20 ) + STEP( G, a, b, c, d, GET(9), 0x21e1cde6, 5 ) + STEP( G, d, a, b, c, GET(14), 0xc33707d6, 9 ) + STEP( G, c, d, a, b, GET(3), 0xf4d50d87, 14 ) + STEP( G, b, c, d, a, GET(8), 0x455a14ed, 20 ) + STEP( G, a, b, c, d, GET(13), 0xa9e3e905, 5 ) + STEP( G, d, a, b, c, GET(2), 0xfcefa3f8, 9 ) + STEP( G, c, d, a, b, GET(7), 0x676f02d9, 14 ) + STEP( G, b, c, d, a, GET(12), 0x8d2a4c8a, 20 ) + + // Round 3 + STEP( H, a, b, c, d, GET(5), 0xfffa3942, 4 ) + STEP( H, d, a, b, c, GET(8), 0x8771f681, 11 ) + STEP( H, c, d, a, b, GET(11), 0x6d9d6122, 16 ) + STEP( H, b, c, d, a, GET(14), 0xfde5380c, 23 ) + STEP( H, a, b, c, d, GET(1), 0xa4beea44, 4 ) + STEP( H, d, a, b, c, GET(4), 0x4bdecfa9, 11 ) + STEP( H, c, d, a, b, GET(7), 0xf6bb4b60, 16 ) + STEP( H, b, c, d, a, GET(10), 0xbebfbc70, 23 ) + STEP( H, a, b, c, d, GET(13), 0x289b7ec6, 4 ) + STEP( H, d, a, b, c, GET(0), 0xeaa127fa, 11 ) + STEP( H, c, d, a, b, GET(3), 0xd4ef3085, 16 ) + STEP( H, b, c, d, a, GET(6), 0x04881d05, 23 ) + STEP( H, a, b, c, d, GET(9), 0xd9d4d039, 4 ) + STEP( H, d, a, b, c, GET(12), 0xe6db99e5, 11 ) + STEP( H, c, d, a, b, GET(15), 0x1fa27cf8, 16 ) + STEP( H, b, c, d, a, GET(2), 0xc4ac5665, 23 ) + + // Round 4 + STEP( I, a, b, c, d, GET(0), 0xf4292244, 6 ) + STEP( I, d, a, b, c, GET(7), 0x432aff97, 10 ) + STEP( I, c, d, a, b, GET(14), 0xab9423a7, 15 ) + STEP( I, b, c, d, a, GET(5), 0xfc93a039, 21 ) + STEP( I, a, b, c, d, GET(12), 0x655b59c3, 6 ) + STEP( I, d, a, b, c, GET(3), 0x8f0ccc92, 10 ) + STEP( I, c, d, a, b, GET(10), 0xffeff47d, 15 ) + STEP( I, b, c, d, a, GET(1), 0x85845dd1, 21 ) + STEP( I, a, b, c, d, GET(8), 0x6fa87e4f, 6 ) + STEP( I, d, a, b, c, GET(15), 0xfe2ce6e0, 10 ) + STEP( I, c, d, a, b, GET(6), 0xa3014314, 15 ) + STEP( I, b, c, d, a, GET(13), 0x4e0811a1, 21 ) + STEP( I, a, b, c, d, GET(4), 0xf7537e82, 6 ) + STEP( I, d, a, b, c, GET(11), 0xbd3af235, 10 ) + STEP( I, c, d, a, b, GET(2), 0x2ad7d2bb, 15 ) + STEP( I, b, c, d, a, GET(9), 0xeb86d391, 21 ) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while ( size -= 64 ); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + #undef GET + #undef SET + + return ptr; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Initialise +// +// Initialises an MD5 Context. Use this to initialise/reset a context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Initialise + ( + Md5Context* Context // [out] + ) +{ + Context->a = 0x67452301; + Context->b = 0xefcdab89; + Context->c = 0x98badcfe; + Context->d = 0x10325476; + + Context->lo = 0; + Context->hi = 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Update +// +// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on +// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Update + ( + Md5Context* Context, // [in out] + void const* Buffer, // [in] + uint32_t BufferSize // [in] + ) +{ + uint32_t saved_lo; + uint32_t used; + uint32_t free; + + saved_lo = Context->lo; + if ( (Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo ) + { + Context->hi++; + } + Context->hi += (uint32_t)( BufferSize >> 29 ); + + used = saved_lo & 0x3f; + + if ( used ) + { + free = 64 - used; + + if ( BufferSize < free ) + { + memcpy( &Context->buffer[used], Buffer, BufferSize ); + return; + } + + memcpy( &Context->buffer[used], Buffer, free ); + Buffer = (uint8_t*)Buffer + free; + BufferSize -= free; + TransformFunction(Context, Context->buffer, 64); + } + + if ( BufferSize >= 64 ) + { + Buffer = TransformFunction( Context, Buffer, BufferSize & ~(unsigned long)0x3f ); + BufferSize &= 0x3f; + } + + memcpy( Context->buffer, Buffer, BufferSize ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Finalise +// +// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After +// calling this, Md5Initialised must be used to reuse the context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Finalise + ( + Md5Context* Context, // [in out] + MD5_HASH* Digest // [in] + ) +{ + uint32_t used; + uint32_t free; + + used = Context->lo & 0x3f; + + Context->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) + { + memset( &Context->buffer[used], 0, free ); + TransformFunction( Context, Context->buffer, 64 ); + used = 0; + free = 64; + } + + memset( &Context->buffer[used], 0, free - 8 ); + + Context->lo <<= 3; + Context->buffer[56] = (uint8_t)( Context->lo ); + Context->buffer[57] = (uint8_t)( Context->lo >> 8 ); + Context->buffer[58] = (uint8_t)( Context->lo >> 16 ); + Context->buffer[59] = (uint8_t)( Context->lo >> 24 ); + Context->buffer[60] = (uint8_t)( Context->hi ); + Context->buffer[61] = (uint8_t)( Context->hi >> 8 ); + Context->buffer[62] = (uint8_t)( Context->hi >> 16 ); + Context->buffer[63] = (uint8_t)( Context->hi >> 24 ); + + TransformFunction( Context, Context->buffer, 64 ); + + Digest->bytes[0] = (uint8_t)( Context->a ); + Digest->bytes[1] = (uint8_t)( Context->a >> 8 ); + Digest->bytes[2] = (uint8_t)( Context->a >> 16 ); + Digest->bytes[3] = (uint8_t)( Context->a >> 24 ); + Digest->bytes[4] = (uint8_t)( Context->b ); + Digest->bytes[5] = (uint8_t)( Context->b >> 8 ); + Digest->bytes[6] = (uint8_t)( Context->b >> 16 ); + Digest->bytes[7] = (uint8_t)( Context->b >> 24 ); + Digest->bytes[8] = (uint8_t)( Context->c ); + Digest->bytes[9] = (uint8_t)( Context->c >> 8 ); + Digest->bytes[10] = (uint8_t)( Context->c >> 16 ); + Digest->bytes[11] = (uint8_t)( Context->c >> 24 ); + Digest->bytes[12] = (uint8_t)( Context->d ); + Digest->bytes[13] = (uint8_t)( Context->d >> 8 ); + Digest->bytes[14] = (uint8_t)( Context->d >> 16 ); + Digest->bytes[15] = (uint8_t)( Context->d >> 24 ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Calculate +// +// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Calculate + ( + void const* Buffer, // [in] + uint32_t BufferSize, // [in] + MD5_HASH* Digest // [in] + ) +{ + Md5Context context; + + Md5Initialise( &context ); + Md5Update( &context, Buffer, BufferSize ); + Md5Finalise( &context, Digest ); +} diff --git a/src/md5.h b/src/md5.h new file mode 100755 index 000000000..5ef252221 --- /dev/null +++ b/src/md5.h @@ -0,0 +1,100 @@ +/* + * Retrieved from https://github.com/WaterJuice/WjCryptLib + */ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// WjCryptLib_Md5 +// +// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining +// Public Domain license. +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Md5Context - This must be initialised using Md5Initialised. Do not modify the contents of this structure directly. +typedef struct +{ + uint32_t lo; + uint32_t hi; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint8_t buffer[64]; + uint32_t block[16]; +} Md5Context; + +#define MD5_HASH_SIZE ( 128 / 8 ) + +typedef struct +{ + uint8_t bytes [MD5_HASH_SIZE]; +} MD5_HASH; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Initialise +// +// Initialises an MD5 Context. Use this to initialise/reset a context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Initialise + ( + Md5Context* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Update +// +// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on +// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Update + ( + Md5Context* Context, // [in out] + void const* Buffer, // [in] + uint32_t BufferSize // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Finalise +// +// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After +// calling this, Md5Initialised must be used to reuse the context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Finalise + ( + Md5Context* Context, // [in out] + MD5_HASH* Digest // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Calculate +// +// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Calculate + ( + void const* Buffer, // [in] + uint32_t BufferSize, // [in] + MD5_HASH* Digest // [in] + ); diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index 4cb917ac4..646fca238 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -27,11 +27,11 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; - if(fds[i].events & (POLLIN|POLLPRI)) { + if (fds[i].events & (POLLIN|POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } - if(fds[i].events & POLLOUT) { + if (fds[i].events & POLLOUT) { op = &ofds; FD_SET(fds[i].fd, op); } @@ -42,7 +42,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) #endif /* Set up the timeval structure for the timeout parameter */ - if(timo < 0) { + if (timo < 0) { toptr = 0; } else { toptr = &timeout; @@ -59,17 +59,17 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) printf("Exiting select rc=%d\n", rc); #endif - if(rc <= 0) + if (rc <= 0) return rc; - if(rc > 0) { + if (rc > 0) { for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; - if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + if (fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) fds[i].revents |= POLLIN; - if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + if (fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) fds[i].revents |= POLLOUT; - if(FD_ISSET(fd, &efds)) + if (FD_ISSET(fd, &efds)) /* Some error was detected ... should be some way to know. */ fds[i].revents |= POLLHUP; #ifdef DEBUG_POLL @@ -118,7 +118,7 @@ SOCKET win32_socket(int domain, int type, int protocol) { SOCKET fd = socket(domain, type, protocol); - if(fd == INVALID_SOCKET) { + if (fd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); } return fd; @@ -133,7 +133,7 @@ win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { int rc = connect(fd, addr, addr_len); assert(rc == 0 || rc == SOCKET_ERROR); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_connect_errno(WSAGetLastError()); } return rc; @@ -148,7 +148,7 @@ SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { SOCKET newfd = accept(fd, addr, addr_len); - if(newfd == INVALID_SOCKET) { + if (newfd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); newfd = (SOCKET)-1; } @@ -165,7 +165,7 @@ win32_shutdown(SOCKET fd, int mode) { int rc = shutdown(fd, mode); assert(rc == 0 || rc == SOCKET_ERROR); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -174,7 +174,7 @@ win32_shutdown(SOCKET fd, int mode) int win32_close_socket(SOCKET fd) { int rc = closesocket(fd); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -183,7 +183,7 @@ int win32_close_socket(SOCKET fd) ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -192,7 +192,7 @@ ssize_t win32_write_socket(SOCKET fd, void *buf, int n) ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { int rc = recv(fd, buf, n, 0); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index e3a7267a9..8f5b992fe 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -37,7 +37,7 @@ struct pollfd { short revents; /* returned events */ }; #endif -#define poll(x, y, z) win32_poll(x, y, z) +#define poll(x, y, z) win32_poll(x, y, z) /* These wrappers do nothing special except set the global errno variable if * an error occurs (winsock doesn't do this by default). They set errno @@ -45,12 +45,12 @@ struct pollfd { * outside of this file "shouldn't" have to worry about winsock specific error * handling. */ -#define socket(x, y, z) win32_socket(x, y, z) -#define connect(x, y, z) win32_connect(x, y, z) -#define accept(x, y, z) win32_accept(x, y, z) -#define shutdown(x, y) win32_shutdown(x, y) -#define read(x, y, z) win32_read_socket(x, y, z) -#define write(x, y, z) win32_write_socket(x, y, z) +#define socket(x, y, z) win32_socket(x, y, z) +#define connect(x, y, z) win32_connect(x, y, z) +#define accept(x, y, z) win32_accept(x, y, z) +#define shutdown(x, y) win32_shutdown(x, y) +#define read(x, y, z) win32_read_socket(x, y, z) +#define write(x, y, z) win32_write_socket(x, y, z) /* Winsock uses int instead of the usual socklen_t */ typedef int socklen_t; diff --git a/src/mmap.c b/src/mmap.c index 90ae5fc17..b76e4ad64 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -3,7 +3,7 @@ #include #include -#include "stlink/mmap.h" +#include "mmap.h" void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { diff --git a/include/stlink/mmap.h b/src/mmap.h similarity index 100% rename from include/stlink/mmap.h rename to src/mmap.h diff --git a/src/sg.c b/src/sg.c index e7ff5d14e..798cda9ab 100644 --- a/src/sg.c +++ b/src/sg.c @@ -82,8 +82,8 @@ #include #include -#include "stlink.h" -#include "stlink/logging.h" +#include +#include "logging.h" #define STLINK_OK 0x80 #define STLINK_FALSE 0x81 @@ -109,8 +109,7 @@ void _stlink_sg_close(stlink_t *sl) { } } -static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) -{ +static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) { unsigned char csw[13]; memset(csw, 0, sizeof(csw)); int transferred; @@ -229,9 +228,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint * @param endpoint_in * @param endpoint_out */ - static void -get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) -{ +static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { DLOG("Fetching sense...\n"); uint8_t cdb[16]; memset(cdb, 0, sizeof(cdb)); @@ -324,7 +321,6 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, return real_transferred; } - int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! @@ -385,7 +381,6 @@ int stlink_q(stlink_t *sl) { } // TODO thinking, cleanup - void stlink_stat(stlink_t *stl, char *txt) { if (stl->q_len <= 0) return; @@ -404,7 +399,6 @@ void stlink_stat(stlink_t *stl, char *txt) { } } - int _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); @@ -417,7 +411,6 @@ int _stlink_sg_version(stlink_t *stl) { // Get stlink mode: // STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE // usb dfu || usb mass || jtag or swd - int _stlink_sg_current_mode(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); @@ -431,11 +424,10 @@ int _stlink_sg_current_mode(stlink_t *stl) { } // Exit the mass mode and enter the swd debug mode. - int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard return stlink_q(sl); @@ -443,12 +435,11 @@ int _stlink_sg_enter_swd_mode(stlink_t *sl) { // Exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) - int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; return stlink_q(sl); @@ -525,11 +516,10 @@ int _stlink_sg_core_id(stlink_t *sl) { } // Arm-core reset -> halted state. - int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_RESETSYS; sl->q_len = 2; sg->q_addr = 0; if (stlink_q(sl)) @@ -545,7 +535,6 @@ int _stlink_sg_reset(stlink_t *sl) { } // Arm-core reset -> halted state. - int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -562,7 +551,6 @@ int _stlink_sg_jtag_reset(stlink_t *sl, int value) { } // Arm-core status: halted or running. - int _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -573,7 +561,6 @@ int _stlink_sg_status(stlink_t *sl) { } // Force the core into the debug mode -> halted state. - int _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -588,12 +575,11 @@ int _stlink_sg_force_debug(stlink_t *sl) { } // Read all arm-core registers. - int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READALLREGS; sl->q_len = 84; sg->q_addr = 0; if (stlink_q(sl)) @@ -634,7 +620,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READREG; sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; @@ -679,7 +665,7 @@ int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_WRITEREG; // 2: reg index // 3-6: reg content sg->cdb_cmd_blk[2] = idx; @@ -696,12 +682,11 @@ int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { // Write a register of the debug module of the core. // XXX ?(atomic writes) // TODO test - void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_write_dreg ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_WRITEDEBUGREG; // 2-5: address of reg of the debug module // 6-9: reg content write_uint32(sg->cdb_cmd_blk + 2, addr); @@ -713,7 +698,6 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { } // Force the core exit the debug mode. - int _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -729,7 +713,6 @@ int _stlink_sg_run(stlink_t *sl) { } // Step the arm-core. - int _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -750,7 +733,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_SETFP; // 2:The number of the flash patch used to set the breakpoint // 3-6: Address of the breakpoint (LSB) // 7: FP_ALL (0x02) / FP_UPPER (0x01) / FP_LOWER (0x00) @@ -764,13 +747,12 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { } // TODO test - // TODO make delegate! void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_clr_hw_bp ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_CLEARFP; sg->cdb_cmd_blk[2] = fp_nr; sl->q_len = 2; @@ -779,7 +761,6 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { } // Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) - int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -804,7 +785,6 @@ int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. - int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -833,7 +813,6 @@ int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. - int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -862,7 +841,6 @@ int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write one DWORD data to memory - int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -875,7 +853,6 @@ int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { } // Read one DWORD data from memory - int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -891,9 +868,7 @@ int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { } // Exit the jtag or swd mode and enter the mass mode. - -int _stlink_sg_exit_debug_mode(stlink_t *stl) -{ +int _stlink_sg_exit_debug_mode(stlink_t *stl) { if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); @@ -905,7 +880,6 @@ int _stlink_sg_exit_debug_mode(stlink_t *stl) return 0; } - // 1) open a sg device, switch the stlink from dfu to mass mode // 2) wait 5s until the kernel driver stops reseting the broken device // 3) reopen the device @@ -943,14 +917,13 @@ static stlink_backend_t _stlink_sg_backend = { }; static stlink_t* stlink_open(const int verbose) { - stlink_t *sl = malloc(sizeof (stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); - if(sl != NULL) + if (sl != NULL) free(sl); - if(slsg != NULL) + if (slsg != NULL) free(slsg); return NULL; } @@ -963,13 +936,10 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } -#if defined (__FreeBSD__) - #define LIBUSBX_API_VERSION LIBUSB_API_VERSION -#endif -#if LIBUSBX_API_VERSION < 0x01000106 - libusb_set_debug(slsg->libusb_ctx, 3); +#if LIBUSB_API_VERSION < 0x01000106 + libusb_set_debug(slsg->libusb_ctx, ugly_libusb_log_level(verbose)); #else - libusb_set_option(slsg->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, 3); + libusb_set_option(slsg->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); #endif slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); @@ -984,7 +954,6 @@ static stlink_t* stlink_open(const int verbose) { // TODO // Could read the interface config descriptor, and assert lots of the assumptions - // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); @@ -1045,7 +1014,7 @@ static stlink_t* stlink_open(const int verbose) { sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + sl->core_stat = TARGET_UNKNOWN; slsg->q_addr = 0; return sl; diff --git a/include/stlink/sg.h b/src/sg.h similarity index 50% rename from include/stlink/sg.h rename to src/sg.h index e521ba217..3a8a7a239 100644 --- a/include/stlink/sg.h +++ b/src/sg.h @@ -1,25 +1,17 @@ /* - * File: stlink/sg.h + * File: sg.h * Author: karl * * Created on October 1, 2011, 11:29 PM */ #ifndef STLINK_SG_H -#define STLINK_SG_H - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4200 4255 4668 4820) -#include -#pragma warning(pop) -#else -#include -#endif +#define STLINK_SG_H -#include "stlink.h" +#include "libusb_settings.h" +#include -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -49,33 +41,32 @@ extern "C" { - struct stlink_libsg { - libusb_context* libusb_ctx; - libusb_device_handle *usb_handle; - unsigned ep_rep; - unsigned ep_req; +struct stlink_libsg { + libusb_context* libusb_ctx; + libusb_device_handle *usb_handle; + unsigned ep_rep; + unsigned ep_req; - int sg_fd; - int do_scsi_pt_err; + int sg_fd; + int do_scsi_pt_err; - unsigned char cdb_cmd_blk[CDB_SL]; + unsigned char cdb_cmd_blk[CDB_SL]; - int q_data_dir; // Q_DATA_IN, Q_DATA_OUT - // the start of the query data in the device memory space - uint32_t q_addr; + int q_data_dir; // Q_DATA_IN, Q_DATA_OUT + // the start of the query data in the device memory space + uint32_t q_addr; - // Sense (error information) data - // obsolete, this was fed to the scsi tools - unsigned char sense_buf[SENSE_BUF_LEN]; + // Sense (error information) data + // obsolete, this was fed to the scsi tools + unsigned char sense_buf[SENSE_BUF_LEN]; - struct stlink_reg reg; - }; + struct stlink_reg reg; +}; - stlink_t* stlink_v1_open(const int verbose, int reset); +stlink_t* stlink_v1_open(const int verbose, int reset); #ifdef __cplusplus } #endif #endif /* STLINK_SG_H */ - diff --git a/src/gdbserver/gdb-remote.c b/src/st-util/gdb-remote.c similarity index 82% rename from src/gdbserver/gdb-remote.c rename to src/st-util/gdb-remote.c index e4aad312d..24636e8c9 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -8,6 +8,7 @@ #include #include #include + #if defined(__MINGW32__) || defined(_MSC_VER) #include #else @@ -15,6 +16,8 @@ #include #endif +#include "gdb-remote.h" + static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { @@ -27,7 +30,7 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; - for(unsigned int i = 0; i < data_length; i++) { + for (unsigned int i = 0; i < data_length; i++) { packet[i + 1] = data[i]; cksum += data[i]; } @@ -36,19 +39,19 @@ int gdb_send_packet(int fd, char* data) { packet[length - 2] = hex[cksum >> 4]; packet[length - 1] = hex[cksum & 0xf]; - while(1) { - if(write(fd, packet, length) != length) { + while (1) { + if (write(fd, packet, length) != length) { free(packet); return -2; } char ack; - if(read(fd, &ack, 1) != 1) { + if (read(fd, &ack, 1) != 1) { free(packet); return -2; } - if(ack == '+') { + if (ack == '+') { free(packet); return 0; } @@ -64,7 +67,7 @@ int gdb_recv_packet(int fd, char** buffer) { char* packet_buffer = malloc(packet_size); unsigned state; - if(packet_buffer == NULL) + if (packet_buffer == NULL) return -2; start: @@ -79,15 +82,15 @@ int gdb_recv_packet(int fd, char** buffer) { */ char c; - while(state != 4) { - if(read(fd, &c, 1) != 1) { + while (state != 4) { + if (read(fd, &c, 1) != 1) { free(packet_buffer); return -2; } switch(state) { case 0: - if(c != '$') { + if (c != '$') { // ignore } else { state = 1; @@ -95,16 +98,16 @@ int gdb_recv_packet(int fd, char** buffer) { break; case 1: - if(c == '#') { + if (c == '#') { state = 2; } else { packet_buffer[packet_idx++] = c; cksum += c; - if(packet_idx == packet_size) { + if (packet_idx == packet_size) { packet_size += ALLOC_STEP; void* p = realloc(packet_buffer, packet_size); - if(p != NULL) + if (p != NULL) packet_buffer = p; else { free(packet_buffer); @@ -127,9 +130,9 @@ int gdb_recv_packet(int fd, char** buffer) { } uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); - if(recv_cksum_int != cksum) { + if (recv_cksum_int != cksum) { char nack = '-'; - if(write(fd, &nack, 1) != 1) { + if (write(fd, &nack, 1) != 1) { free(packet_buffer); return -2; } @@ -137,7 +140,7 @@ int gdb_recv_packet(int fd, char** buffer) { goto start; } else { char ack = '+'; - if(write(fd, &ack, 1) != 1) { + if (write(fd, &ack, 1) != 1) { free(packet_buffer); return -2; } @@ -157,16 +160,15 @@ int gdb_check_for_interrupt(int fd) { pfd.fd = fd; pfd.events = POLLIN; - if(poll(&pfd, 1, 0) != 0) { + if (poll(&pfd, 1, 0) != 0) { char c; - if(read(fd, &c, 1) != 1) + if (read(fd, &c, 1) != 1) return -2; - if(c == '\x03') // ^C + if (c == '\x03') // ^C return 1; } return 0; } - diff --git a/src/gdbserver/gdb-remote.h b/src/st-util/gdb-remote.h similarity index 100% rename from src/gdbserver/gdb-remote.h rename to src/st-util/gdb-remote.h diff --git a/src/gdbserver/gdb-server.c b/src/st-util/gdb-server.c similarity index 80% rename from src/gdbserver/gdb-server.c rename to src/st-util/gdb-server.c index a874a81da..a7107ff88 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -14,6 +14,7 @@ #include #define __attribute__(x) #endif + #if defined(_WIN32) #include #else @@ -24,8 +25,7 @@ #endif #include -#include - +#include #include "gdb-remote.h" #include "gdb-server.h" #include "semihosting.h" @@ -59,7 +59,6 @@ static const char* current_memory_map = NULL; typedef struct _st_state_t { // things from command line, bleh - int stlink_version; int logging_level; int listen_port; int persistent; @@ -86,21 +85,13 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { - stlink_t *ret = NULL; - switch (st->stlink_version) { - case 2: - if(serial_specified){ - ret = stlink_open_usb(st->logging_level, st->reset, serialnumber); - } - else{ - ret = stlink_open_usb(st->logging_level, st->reset, NULL); - } - break; - case 1: - ret = stlink_v1_open(st->logging_level, st->reset); - break; + stlink_t *sl = NULL; + if (serial_specified) { + sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); + } else { + sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); } - return ret; + return sl; } @@ -108,8 +99,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", optional_argument, NULL, 'v'}, - {"stlink_version", required_argument, NULL, 's'}, - {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, @@ -123,7 +112,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -V, --version\t\tPrint the version\n" " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" - " -s X, --stlink_version=X\n" "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" " -1, --stlinkv1\tForce stlink version 1\n" " -p 4242, --listen_port=1234\n" @@ -139,7 +127,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { " --serial \n" "\t\t\tUse a specific serial number.\n" "\n" - "The STLINKv2 device to use can be specified in the environment\n" + "The STLINK device to use can be specified in the environment\n" "variable STLINK_DEVICE on the format :.\n" "\n" ; @@ -148,7 +136,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: break; @@ -163,17 +151,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->logging_level = DEBUG_LOGGING_LEVEL; } break; - case '1': - st->stlink_version = 1; - break; - case 's': - sscanf(optarg, "%i", &q); - if (q < 0 || q > 2) { - fprintf(stderr, "stlink version %d unknown!\n", q); - exit(EXIT_FAILURE); - } - st->stlink_version = q; - break; case 'p': sscanf(optarg, "%i", &q); if (q < 0) { @@ -199,8 +176,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(optarg); int length = j / 2; //the length of the destination-array - if(j % 2 != 0) return -1; - for(size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { + if (j % 2 != 0) return -1; + for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, optarg + j, 2); serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); @@ -225,16 +202,22 @@ int main(int argc, char** argv) { memset(&state, 0, sizeof(state)); // set defaults... - state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); - printf("st-util %s\n", STLINK_VERSION); + printf("st-util\n"); sl = do_connect(&state); - if(sl == NULL) return 1; + if (sl == NULL) { + return 1; + } + + if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); + return 1; + } connected_stlink = sl; signal(SIGINT, &cleanup); @@ -245,16 +228,14 @@ int main(int argc, char** argv) { stlink_reset(sl); } - - - ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; current_memory_map = make_memory_map(sl); #if defined(__MINGW32__) || defined(_MSC_VER) WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0){ goto winsock_error; } #endif @@ -531,27 +512,27 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { + if (sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { strcpy(map, memory_map_template_F4); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); - } else if(sl->core_id==STM32F7_CORE_ID) { + } else if (sl->core_id==STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F2) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F2) { snprintf(map, sz, memory_map_template_F2, (unsigned int)sl->flash_size, (unsigned int)sl->sram_size, (unsigned int)sl->flash_size - 0x20000, (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if((sl->chip_id==STLINK_CHIPID_STM32_L4) || + } else if ((sl->chip_id==STLINK_CHIPID_STM32_L4) || (sl->chip_id==STLINK_CHIPID_STM32_L43X) || (sl->chip_id==STLINK_CHIPID_STM32_L46X)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if(sl->chip_id==STLINK_CHIPID_STM32_L496X) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_L496X) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); } else { @@ -602,7 +583,7 @@ static void init_data_watchpoints(stlink_t *sl) { stlink_write_debug32(sl, 0xE000EDFC, data); // make sure all watchpoints are cleared - for(int i = 0; i < DATA_WATCH_NUM; i++) { + for (int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); } @@ -619,15 +600,15 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, mask = -1; i = len; - while(i) { + while (i) { i >>= 1; mask++; } - if((mask != (uint32_t)-1) && (mask < 16)) { - for(i = 0; i < DATA_WATCH_NUM; i++) { + if ((mask != (uint32_t)-1) && (mask < 16)) { + for (i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? - if(data_watches[i].fun == WATCHDISABLED) { + if (data_watches[i].fun == WATCHDISABLED) { DLOG("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); data_watches[i].fun = wf; @@ -658,8 +639,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { int i; - for(i = 0 ; i < DATA_WATCH_NUM; i++) { - if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { + for (i = 0 ; i < DATA_WATCH_NUM; i++) { + if ((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; @@ -697,7 +678,7 @@ static void init_code_breakpoints(stlink_t *sl) { ILOG("Found %i hw breakpoint registers\n", code_break_num); - for(int i = 0; i < code_break_num; i++) { + for (int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMP0 + i * 4, 0); } @@ -705,7 +686,7 @@ static void init_code_breakpoints(stlink_t *sl) { static int has_breakpoint(stm32_addr_t addr) { - for(int i = 0; i < code_break_num; i++) { + for (int i = 0; i < code_break_num; i++) { if (code_breaks[i].addr == addr) { return 1; } @@ -718,7 +699,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { uint32_t mask; int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - if(addr & 1) { + if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return -1; } @@ -730,16 +711,16 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { } int id = -1; - for(int i = 0; i < code_break_num; i++) { - if(fpb_addr == code_breaks[i].addr || + for (int i = 0; i < code_break_num; i++) { + if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } } - if(id == -1) { - if(set) return -1; // Free slot not found + if (id == -1) { + if (set) return -1; // Free slot not found else return 0; // Breakpoint is already removed } @@ -748,18 +729,18 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { bp->addr = fpb_addr; if (sl->core_id==STM32F7_CORE_ID) { - if(set) bp->type = type; + if (set) bp->type = type; else bp->type = 0; mask = (bp->addr) | 1; } else { - if(set) bp->type |= type; + if (set) bp->type |= type; else bp->type &= ~type; mask = (bp->addr) | 1 | (bp->type << 30); } - if(bp->type == 0) { + if (bp->type == 0) { DLOG("clearing hw break %d\n", id); stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); @@ -788,13 +769,13 @@ static struct flash_block* flash_root; static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { - if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { + if (addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { ELOG("flash_add_block: incorrect bounds\n"); return -1; } stlink_calculate_pagesize(sl, addr); - if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { + if (addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { ELOG("flash_add_block: unaligned block\n"); return -1; } @@ -814,7 +795,7 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned int fit_blocks = 0, fit_length = 0; - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { /* Block: ------X------Y-------- * Data: a-----b * a--b @@ -825,7 +806,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned X = fb->addr, Y = fb->addr + fb->length; unsigned a = addr, b = addr + length; - if(a < Y && b > X) { + if (a < Y && b > X) { // from start of the block unsigned start = (a > X ? a : X) - X; unsigned end = (b > Y ? Y : b) - X; @@ -837,12 +818,12 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { } } - if(fit_blocks == 0) { + if (fit_blocks == 0) { ELOG("Unfit data block %08x -> %04x\n", addr, length); return -1; } - if(fit_length != length) { + if (fit_length != length) { WLOG("data block %08x -> %04x truncated to %04x\n", addr, length, fit_length); WLOG("(this is not an error, just a GDB glitch)\n"); @@ -858,10 +839,10 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); stlink_force_debug(sl); - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); //Update FLASH_PAGE @@ -880,7 +861,7 @@ static int flash_go(stlink_t *sl) { error = 0; error: - for(struct flash_block* fb = flash_root, *next; fb; fb = next) { + for (struct flash_block* fb = flash_root, *next; fb; fb = next) { next = fb->next; free(fb->data); free(fb); @@ -955,7 +936,7 @@ static void init_cache (stlink_t *sl) { int i; /* Assume only F7 has a cache. */ - if(sl->core_id!=STM32F7_CORE_ID) + if (sl->core_id!=STM32F7_CORE_ID) return; stlink_read_debug32(sl, CLIDR, &clidr); @@ -971,14 +952,14 @@ static void init_cache (stlink_t *sl) { (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, cache_desc.dminline, cache_desc.iminline); - for(i = 0; i < 7; i++) + for (i = 0; i < 7; i++) { unsigned int ct = (clidr >> (3 * i)) & 0x07; cache_desc.dcache[i].width = 0; cache_desc.icache[i].width = 0; - if(ct == 2 || ct == 3 || ct == 4) + if (ct == 2 || ct == 3 || ct == 4) { /* Data. */ stlink_write_debug32(sl, CSSELR, i << 1); @@ -986,7 +967,7 @@ static void init_cache (stlink_t *sl) { read_cache_level_desc(sl, &cache_desc.dcache[i]); } - if(ct == 1 || ct == 3) + if (ct == 1 || ct == 3) { /* Instruction. */ stlink_write_debug32(sl, CSSELR, (i << 1) | 1); @@ -1034,7 +1015,7 @@ static void cache_sync(stlink_t *sl) { unsigned ccr; - if(sl->core_id!=STM32F7_CORE_ID) + if (sl->core_id!=STM32F7_CORE_ID) return; if (!cache_modified) return; @@ -1062,7 +1043,7 @@ static size_t unhexify(const char *in, char *out, size_t out_count) int serve(stlink_t *sl, st_state_t *st) { SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); - if(!IS_SOCK_VALID(sock)) { + if (!IS_SOCK_VALID(sock)) { perror("socket"); return 1; } @@ -1076,13 +1057,13 @@ int serve(stlink_t *sl, st_state_t *st) { serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(st->listen_port); - if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); close_socket(sock); return 1; } - if(listen(sock, 5) < 0) { + if (listen(sock, 5) < 0) { perror("listen"); close_socket(sock); return 1; @@ -1092,7 +1073,7 @@ int serve(stlink_t *sl, st_state_t *st) { SOCKET client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); - if(!IS_SOCK_VALID(client)) { + if (!IS_SOCK_VALID(client)) { perror("accept"); close_socket(sock); return 1; @@ -1114,12 +1095,17 @@ int serve(stlink_t *sl, st_state_t *st) { * emulate attaching and detaching to target. */ unsigned int attached = 1; - - while(1) { + /* + * If a critical error is detected, break from the loop + */ + int critical_error = 0; + int ret; + while (1) { + ret = 0; char* packet; int status = gdb_recv_packet(client, &packet); - if(status < 0) { + if (status < 0) { ELOG("cannot recv: %d\n", status); close_socket(client); return 1; @@ -1132,13 +1118,13 @@ int serve(stlink_t *sl, st_state_t *st) { switch(packet[0]) { case 'q': { - if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { + if (packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { reply = strdup(""); break; } char *separator = strstr(packet, ":"), *params = ""; - if(separator == NULL) { + if (separator == NULL) { separator = packet + strlen(packet); } else { params = separator + 1; @@ -1150,8 +1136,8 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); - if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STLINK_CHIPID_STM32_F4 + if (!strcmp(queryName, "Supported")) { + if (sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F4_HD || sl->core_id==STM32F7_CORE_ID) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); @@ -1159,7 +1145,7 @@ int serve(stlink_t *sl, st_state_t *st) { else { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } - } else if(!strcmp(queryName, "Xfer")) { + } else if (!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; char *annex __attribute__((unused)); @@ -1178,18 +1164,18 @@ int serve(stlink_t *sl, st_state_t *st) { const char* data = NULL; - if(!strcmp(type, "memory-map") && !strcmp(op, "read")) + if (!strcmp(type, "memory-map") && !strcmp(op, "read")) data = current_memory_map; - if(!strcmp(type, "features") && !strcmp(op, "read")) + if (!strcmp(type, "features") && !strcmp(op, "read")) data = target_description_F4; - if(data) { + if (data) { unsigned data_length = (unsigned int) strlen(data); - if(addr + length > data_length) + if (addr + length > data_length) length = data_length - addr; - if(length == 0) { + if (length == 0) { reply = strdup("l"); } else { reply = calloc(length + 2, 1); @@ -1197,11 +1183,11 @@ int serve(stlink_t *sl, st_state_t *st) { strncpy(&reply[1], data, length); } } - } else if(!strncmp(queryName, "Rcmd,",4)) { + } else if (!strncmp(queryName, "Rcmd,",4)) { // Rcmd uses the wrong separator separator = strstr(packet, ","); params = ""; - if(separator == NULL) { + if (separator == NULL) { separator = packet + strlen(packet); } else { params = separator + 1; @@ -1225,32 +1211,75 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(cmd, "resume", 6)) {// resume DLOG("Rcmd: resume\n"); cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Rcmd: resume failed\n"); + reply = strdup("E00"); + + } else { + reply = strdup("OK"); + } - reply = strdup("OK"); } else if (!strncmp(cmd, "halt", 4)) { //halt - reply = strdup("OK"); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: halt failed\n"); + reply = strdup("E00"); - stlink_force_debug(sl); + } else { + reply = strdup("OK"); + DLOG("Rcmd: halt\n"); + } - DLOG("Rcmd: halt\n"); } else if (!strncmp(cmd, "jtag_reset", 10)) { //jtag_reset reply = strdup("OK"); - stlink_jtag_reset(sl, 0); - stlink_jtag_reset(sl, 1); - stlink_force_debug(sl); + ret = stlink_jtag_reset(sl, 0); + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); + + } + + ret = stlink_jtag_reset(sl, 1); + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); + + } - DLOG("Rcmd: jtag_reset\n"); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: jtag_reset failed with force_debug\n"); + reply = strdup("E00"); + + } + if (strcmp(reply, "E00")) { + // no errors have been found + DLOG("Rcmd: jtag_reset\n"); + } } else if (!strncmp(cmd, "reset", 5)) { //reset - reply = strdup("OK"); - stlink_force_debug(sl); - stlink_reset(sl); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: reset failed with force_debug\n"); + reply = strdup("E00"); + } + + ret = stlink_reset(sl); + if (ret) { + DLOG("Rcmd: reset failed with reset\n"); + reply = strdup("E00"); + } + init_code_breakpoints(sl); init_data_watchpoints(sl); - DLOG("Rcmd: reset\n"); + if (reply == NULL) { + reply = strdup("OK"); + DLOG("Rcmd: reset\n"); + } + } else if (!strncmp(cmd, "semihosting ", 12)) { DLOG("Rcmd: got semihosting cmd '%s'", cmd); char *arg = cmd + 12; @@ -1279,7 +1308,7 @@ int serve(stlink_t *sl, st_state_t *st) { free(cmd); } - if(reply == NULL) + if (reply == NULL) reply = strdup(""); free(queryName); @@ -1293,7 +1322,7 @@ int serve(stlink_t *sl, st_state_t *st) { cmdName++; // vCommand -> Command - if(!strcmp(cmdName, "FlashErase")) { + if (!strcmp(cmdName, "FlashErase")) { char *__s_addr, *s_length; char *tok = params; @@ -1306,12 +1335,12 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("FlashErase: addr:%08x,len:%04x\n", addr, length); - if(flash_add_block(addr, length, sl) < 0) { + if (flash_add_block(addr, length, sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } - } else if(!strcmp(cmdName, "FlashWrite")) { + } else if (!strcmp(cmdName, "FlashWrite")) { char *__s_addr, *data; char *tok = params; @@ -1326,8 +1355,8 @@ int serve(stlink_t *sl, st_state_t *st) { // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); unsigned dec_index = 0; - for(unsigned int i = 0; i < data_length; i++) { - if(data[i] == 0x7d) { + for (unsigned int i = 0; i < data_length; i++) { + if (data[i] == 0x7d) { i++; decoded[dec_index++] = data[i] ^ 0x20; } else { @@ -1336,31 +1365,31 @@ int serve(stlink_t *sl, st_state_t *st) { } // Fix alignment - if(dec_index % 2 != 0) + if (dec_index % 2 != 0) dec_index++; DLOG("binary packet %d -> %d\n", data_length, dec_index); - if(flash_populate(addr, decoded, dec_index) < 0) { + if (flash_populate(addr, decoded, dec_index) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } free(decoded); - } else if(!strcmp(cmdName, "FlashDone")) { - if(flash_go(sl) < 0) { + } else if (!strcmp(cmdName, "FlashDone")) { + if (flash_go(sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } - } else if(!strcmp(cmdName, "Kill")) { + } else if (!strcmp(cmdName, "Kill")) { attached = 0; reply = strdup("OK"); } - if(reply == NULL) + if (reply == NULL) reply = strdup(""); break; @@ -1368,25 +1397,30 @@ int serve(stlink_t *sl, st_state_t *st) { case 'c': cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Semihost: run failed\n"); + } - while(1) { + while (1) { status = gdb_check_for_interrupt(client); - if(status < 0) { + if (status < 0) { ELOG("cannot check for int: %d\n", status); close_socket(client); return 1; } - if(status == 1) { + if (status == 1) { stlink_force_debug(sl); break; } - stlink_status(sl); - if(sl->core_stat == STLINK_CORE_HALTED) { + ret = stlink_status(sl); + if (ret) { + DLOG("Semihost: status failed\n"); + } + if(sl->core_stat == TARGET_HALTED) { struct stlink_reg reg; - int ret; stm32_addr_t pc; stm32_addr_t addr; int offset = 0; @@ -1396,7 +1430,10 @@ int serve(stlink_t *sl, st_state_t *st) { break; } - stlink_read_all_regs (sl, ®); + ret = stlink_read_all_regs (sl, ®); + if (ret) { + DLOG("Semihost: read_all_regs failed\n"); + } /* Read PC */ pc = reg.r[15]; @@ -1420,17 +1457,29 @@ int serve(stlink_t *sl, st_state_t *st) { if (insn == 0xBEAB && !has_breakpoint(addr)) { - do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + ret = do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + if (ret) { + DLOG("Semihost: do_semihosting failed\n"); + } /* Write return value */ - stlink_write_reg(sl, reg.r[0], 0); + ret = stlink_write_reg(sl, reg.r[0], 0); + if (ret) { + DLOG("Semihost: write_reg failed for return value\n"); + } /* Jump over the break instruction */ - stlink_write_reg(sl, reg.r[15] + 2, 15); + ret = stlink_write_reg(sl, reg.r[15] + 2, 15); + if (ret) { + DLOG("Semihost: write_reg failed for jumping over break\n"); + } /* continue execution */ cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Semihost: continue execution failed with stlink_run\n"); + } } else { break; } @@ -1443,14 +1492,21 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 's': - cache_sync(sl); - stlink_step(sl); + cache_sync(sl); + ret = stlink_step(sl); + if (ret) { + // have problem sending step packet + ELOG("Step: cannot send step request\n"); + reply = strdup("E00"); + critical_error = 1; // absolutely critical + } else { + reply = strdup("S05"); // TRAP + } - reply = strdup("S05"); // TRAP break; case '?': - if(attached) { + if (attached) { reply = strdup("S05"); // TRAP } else { /* Stub shall reply OK if not attached. */ @@ -1459,10 +1515,13 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 'g': - stlink_read_all_regs(sl, ®p); + ret = stlink_read_all_regs(sl, ®p); + if (ret) { + DLOG("g packet: read_all_regs failed\n"); + } reply = calloc(8 * 16 + 1, 1); - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); break; @@ -1471,42 +1530,49 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned id = (unsigned int) strtoul(&packet[1], NULL, 16); unsigned myreg = 0xDEADDEAD; - if(id < 16) { - stlink_read_reg(sl, id, ®p); + if (id < 16) { + ret = stlink_read_reg(sl, id, ®p); myreg = htonl(regp.r[id]); - } else if(id == 0x19) { - stlink_read_reg(sl, 16, ®p); + } else if (id == 0x19) { + ret = stlink_read_reg(sl, 16, ®p); myreg = htonl(regp.xpsr); - } else if(id == 0x1A) { - stlink_read_reg(sl, 17, ®p); + } else if (id == 0x1A) { + ret = stlink_read_reg(sl, 17, ®p); myreg = htonl(regp.main_sp); - } else if(id == 0x1B) { - stlink_read_reg(sl, 18, ®p); + } else if (id == 0x1B) { + ret = stlink_read_reg(sl, 18, ®p); myreg = htonl(regp.process_sp); - } else if(id == 0x1C) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id == 0x1C) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.control); - } else if(id == 0x1D) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id == 0x1D) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.faultmask); - } else if(id == 0x1E) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id == 0x1E) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.basepri); - } else if(id == 0x1F) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id == 0x1F) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.primask); - } else if(id >= 0x20 && id < 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id >= 0x20 && id < 0x40) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.s[id-0x20]); - } else if(id == 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); + } else if (id == 0x40) { + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.fpscr); } else { + ret = 1; reply = strdup("E00"); } + if (ret) { + DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); + } - reply = calloc(8 + 1, 1); - sprintf(reply, "%08x", myreg); + if (reply == NULL) { + // if reply is set to "E00", skip + reply = calloc(8 + 1, 1); + sprintf(reply, "%08x", myreg); + } break; } @@ -1518,31 +1584,36 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned reg = (unsigned int) strtoul(s_reg, NULL, 16); unsigned value = (unsigned int) strtoul(s_value, NULL, 16); - if(reg < 16) { - stlink_write_reg(sl, ntohl(value), reg); - } else if(reg == 0x19) { - stlink_write_reg(sl, ntohl(value), 16); - } else if(reg == 0x1A) { - stlink_write_reg(sl, ntohl(value), 17); - } else if(reg == 0x1B) { - stlink_write_reg(sl, ntohl(value), 18); - } else if(reg == 0x1C) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1D) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1E) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1F) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg >= 0x20 && reg < 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + + if (reg < 16) { + ret = stlink_write_reg(sl, ntohl(value), reg); + } else if (reg == 0x19) { + ret = stlink_write_reg(sl, ntohl(value), 16); + } else if (reg == 0x1A) { + ret = stlink_write_reg(sl, ntohl(value), 17); + } else if (reg == 0x1B) { + ret = stlink_write_reg(sl, ntohl(value), 18); + } else if (reg == 0x1C) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1D) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1E) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1F) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg >= 0x20 && reg < 0x40) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x40) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else { + ret = 1; reply = strdup("E00"); } - - if(!reply) { + if (ret) { + DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); + } + if (reply == NULL) { + // note that NULL may not be zero reply = strdup("OK"); } @@ -1550,11 +1621,14 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'G': - for(int i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) { char str[9] = {0}; strncpy(str, &packet[1 + i * 8], 8); uint32_t reg = (uint32_t) strtoul(str, NULL, 16); - stlink_write_reg(sl, ntohl(reg), i); + ret = stlink_write_reg(sl, ntohl(reg), i); + if (ret) { + DLOG("G packet: stlink_write_reg failed"); + } } reply = strdup("OK"); @@ -1582,7 +1656,7 @@ int serve(stlink_t *sl, st_state_t *st) { } reply = calloc(count * 2 + 1, 1); - for(unsigned int i = 0; i < count; i++) { + for (unsigned int i = 0; i < count; i++) { reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } @@ -1599,10 +1673,10 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned count = (unsigned int) strtoul(s_count, NULL, 16); int err = 0; - if(start % 4) { + if (start % 4) { unsigned align_count = 4 - start % 4; if (align_count > count) align_count = count; - for(unsigned int i = 0; i < align_count; i ++) { + for (unsigned int i = 0; i < align_count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1614,10 +1688,10 @@ int serve(stlink_t *sl, st_state_t *st) { hexdata += 2*align_count; } - if(count - count % 4) { + if (count - count % 4) { unsigned aligned_count = count - count % 4; - for(unsigned int i = 0; i < aligned_count; i ++) { + for (unsigned int i = 0; i < aligned_count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1629,8 +1703,8 @@ int serve(stlink_t *sl, st_state_t *st) { hexdata += 2*aligned_count; } - if(count) { - for(unsigned int i = 0; i < count; i ++) { + if (count) { + for (unsigned int i = 0; i < count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1649,7 +1723,7 @@ int serve(stlink_t *sl, st_state_t *st) { switch (packet[1]) { case '1': - if(update_code_breakpoint(sl, addr, 1) < 0) { + if (update_code_breakpoint(sl, addr, 1) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); @@ -1660,15 +1734,15 @@ int serve(stlink_t *sl, st_state_t *st) { case '3': // insert read watchpoint case '4': { // insert access watchpoint enum watchfun wf; - if(packet[1] == '2') { + if (packet[1] == '2') { wf = WATCHWRITE; - } else if(packet[1] == '3') { + } else if (packet[1] == '3') { wf = WATCHREAD; } else { wf = WATCHACCESS; } - if(add_data_watchpoint(sl, wf, addr, len) < 0) { + if (add_data_watchpoint(sl, wf, addr, len) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); @@ -1696,7 +1770,7 @@ int serve(stlink_t *sl, st_state_t *st) { case '2' : // remove write watchpoint case '3' : // remove read watchpoint case '4' : // remove access watchpoint - if(delete_data_watchpoint(sl, addr) < 0) { + if (delete_data_watchpoint(sl, addr) < 0) { reply = strdup("E00"); break; } else { @@ -1728,9 +1802,13 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'R': { + /* Reset the core. */ - stlink_reset(sl); + ret = stlink_reset(sl); + if (ret) { + DLOG("R packet : stlink_reset failed\n"); + } init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1742,18 +1820,29 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'k': /* Kill request - reset the connection itself */ - stlink_run(sl); - stlink_exit_debug_mode(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Kill: stlink_run failed\n"); + } + + ret = stlink_exit_debug_mode(sl); + if (ret) { + DLOG("Kill: stlink_exit_debug_mode failed\n"); + } stlink_close(sl); sl = do_connect(st); - if(sl == NULL) cleanup(0); + if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) + cleanup(0); connected_stlink = sl; if (st->reset) { stlink_reset(sl); } - stlink_force_debug(sl); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Kill: stlink_force_debug failed\n"); + } init_cache(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1766,11 +1855,11 @@ int serve(stlink_t *sl, st_state_t *st) { reply = strdup(""); } - if(reply) { + if (reply) { DLOG("send: %s\n", reply); int result = gdb_send_packet(client, reply); - if(result != 0) { + if (result != 0) { ELOG("cannot send: %d\n", result); free(reply); free(packet); @@ -1781,6 +1870,11 @@ int serve(stlink_t *sl, st_state_t *st) { free(reply); } + if (critical_error) { + close_socket(client); + return 1; + } + free(packet); } diff --git a/src/gdbserver/gdb-server.h b/src/st-util/gdb-server.h similarity index 100% rename from src/gdbserver/gdb-server.h rename to src/st-util/gdb-server.h diff --git a/src/gdbserver/semihosting.c b/src/st-util/semihosting.c similarity index 95% rename from src/gdbserver/semihosting.c rename to src/st-util/semihosting.c index 9e92cf3bd..fed66ab60 100644 --- a/src/gdbserver/semihosting.c +++ b/src/st-util/semihosting.c @@ -5,10 +5,9 @@ #include #include -#include "semihosting.h" - #include -#include +#include +#include "semihosting.h" static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { @@ -100,7 +99,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) // the requested bytes. (perhaps reading the whole area is faster??). // // If 16 and 8 bit writes are available, then they could be used instead. - + // Just return when the length is zero avoiding unneeded work. if (len == 0) return 0; @@ -178,7 +177,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_OPEN error: " "cannot read args from target memory\n"); *ret = -1; @@ -215,7 +214,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, name_address, name, name_len) != 0 ) { + if (mem_read(sl, name_address, name, name_len) != 0){ free(name); *ret = -1; DLOG("Semihosting SYS_OPEN error: " @@ -238,7 +237,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t args[1]; int fd; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_CLOSE error: " "cannot read args from target memory\n"); *ret = -1; @@ -263,7 +262,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t buffer_len; void *buffer; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_WRITE error: " "cannot read args from target memory\n"); *ret = -1; @@ -289,7 +288,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, buffer_address, buffer, buffer_len) != 0 ) { + if (mem_read(sl, buffer_address, buffer, buffer_len) != 0){ DLOG("Semihosting SYS_WRITE error: " "cannot read buffer from target memory\n"); free(buffer); @@ -322,7 +321,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { void *buffer; ssize_t read_result; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_READ error: " "cannot read args from target memory\n"); *ret = -1; @@ -357,7 +356,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (read_result == -1) { *ret = buffer_len; } else { - if (mem_write(sl, buffer_address, buffer, read_result) != 0 ) { + if (mem_write(sl, buffer_address, buffer, read_result) != 0){ DLOG("Semihosting SYS_READ error: " "cannot write buffer to target memory\n"); free(buffer); @@ -385,7 +384,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_REMOVE error: " "cannot read args from target memory\n"); *ret = -1; @@ -414,7 +413,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, name_address, name, name_len) != 0 ) { + if (mem_read(sl, name_address, name, name_len) != 0){ free(name); *ret = -1; DLOG("Semihosting SYS_REMOVE error: " @@ -438,7 +437,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { int fd; off_t offset; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_SEEK error: " "cannot read args from target memory\n"); *ret = -1; @@ -482,7 +481,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint8_t buf[WRITE0_BUFFER_SIZE]; while (true) { - if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0 ) { + if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0){ DLOG("Semihosting WRITE0: " "cannot read target memory at 0x%08x\n", r1); return -1; diff --git a/src/gdbserver/semihosting.h b/src/st-util/semihosting.h similarity index 100% rename from src/gdbserver/semihosting.h rename to src/st-util/semihosting.h diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt new file mode 100644 index 000000000..8c36e5a1f --- /dev/null +++ b/src/stlink-gui/CMakeLists.txt @@ -0,0 +1,41 @@ +### +# Build GUI +### + +if (NOT WIN32) + ## GUI-Building requires the presence of a GTK3 toolset + if (NOT GTK3_FOUND) + message(STATUS "GTK3 not found!") + return() # no GTK3 present => no GUI build + else (GTK3_FOUND) + message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") + include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) + + # Install desktop application entry + install(FILES stlink-gui.desktop + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) + + # Install icons + install(FILES icons/stlink-gui.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) + + set(GUI_SOURCES gui.c gui.h) + + ## stlink-gui-local + add_executable(stlink-gui-local ${GUI_SOURCES}) + file(COPY stlink-gui.ui DESTINATION ${CMAKE_BINARY_DIR}/bin) + set_target_properties(stlink-gui-local PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_BINARY_DIR}/bin") + target_link_libraries(stlink-gui-local ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + + ## stlink-gui + add_executable(stlink-gui ${GUI_SOURCES}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) + set_target_properties(stlink-gui PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") + target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + endif () +endif () diff --git a/src/tools/gui/stlink-gui.c b/src/stlink-gui/gui.c similarity index 62% rename from src/tools/gui/stlink-gui.c rename to src/stlink-gui/gui.c index c1cf26b76..7ae591f2d 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/stlink-gui/gui.c @@ -1,11 +1,11 @@ -#include -#include #include +#include +#include #include #include #include -#include "stlink-gui.h" +#include "gui.h" #define MEM_READ_SIZE 1024 @@ -15,30 +15,21 @@ G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); -static void -stlink_gui_dispose (GObject *gobject) -{ +static void stlink_gui_dispose (GObject *gobject) { G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); } -static void -stlink_gui_finalize (GObject *gobject) -{ +static void stlink_gui_finalize (GObject *gobject) { G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); } -static void -stlink_gui_class_init (STlinkGUIClass *klass) -{ +static void stlink_gui_class_init (STlinkGUIClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = stlink_gui_dispose; gobject_class->finalize = stlink_gui_finalize; } -static void -stlink_gui_init (STlinkGUI *self) -{ +static void stlink_gui_init (STlinkGUI *self) { self->sl = NULL; self->filename = NULL; @@ -54,9 +45,7 @@ stlink_gui_init (STlinkGUI *self) self->file_mem.base = 0; } -static gboolean -set_info_error_message_idle (STlinkGUI *gui) -{ +static gboolean set_info_error_message_idle (STlinkGUI *gui) { if (gui->error_message != NULL) { gchar *markup; @@ -72,40 +61,31 @@ set_info_error_message_idle (STlinkGUI *gui) return FALSE; } -static void -stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) -{ +static void stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) { gui->error_message = g_strdup (message); g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); } -static void -stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) -{ +static void stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) { gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); - if (sensitivity && gui->sl) gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); - if (sensitivity && !gui->sl) gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); - if (sensitivity && gui->sl && gui->filename) gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); - gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), sensitivity && (gui->sl != NULL)); } -static void -mem_view_init_headers (GtkTreeView *view) -{ +static void mem_view_init_headers (GtkTreeView *view) { GtkCellRenderer *renderer; gint i; g_return_if_fail (view != NULL); renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, + gtk_tree_view_insert_column_with_attributes ( + view, -1, "Address", renderer, @@ -133,26 +113,24 @@ mem_view_init_headers (GtkTreeView *view) } } -static void -mem_view_add_as_hex (GtkListStore *store, - GtkTreeIter *iter, - gint column, - guint32 value) -{ +static void mem_view_add_as_hex ( + GtkListStore *store, + GtkTreeIter *iter, + gint column, + guint32 value) { gchar *hex_str; hex_str = g_strdup_printf ("0x%08X", value); - gtk_list_store_set (store, iter, column, hex_str, -1); + gtk_list_store_set(store, iter, column, hex_str, -1); g_free (hex_str); } -static void -mem_view_add_buffer (GtkListStore *store, - GtkTreeIter *iter, - guint32 address, - guchar *buffer, - gint len) -{ +static void mem_view_add_buffer ( + GtkListStore *store, + GtkTreeIter *iter, + guint32 address, + guchar *buffer, + gint len) { guint32 *word; gint i, step; gint column = 0; @@ -174,61 +152,41 @@ mem_view_add_buffer (GtkListStore *store, } } -static guint32 -hexstr_to_guint32 (const gchar *str, GError **err) -{ +static guint32 hexstr_to_guint32 (const gchar *str, GError **err) { guint32 val; gchar *end_ptr; val = (guint32) strtoul (str, &end_ptr, 16); if ((errno == ERANGE && val == UINT_MAX) || (errno != 0 && val == 0)) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 1, - "Invalid hexstring"); + g_set_error (err, g_quark_from_string ("hextou32"), 1, "Invalid hexstring"); return UINT32_MAX; } if (end_ptr == str) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 2, - "Invalid hexstring"); + g_set_error (err, g_quark_from_string ("hextou32"), 2, "Invalid hexstring"); return UINT32_MAX; } return val; } - -static void -stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { +static void stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - mem_view_add_buffer (store, - &iter, - mem->base, - mem->memory, - (gint) mem->size); + mem_view_add_buffer (store, &iter, mem->base, mem->memory, (gint) mem->size); gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); gtk_progress_bar_set_fraction (gui->progress.bar, 0); stlink_gui_set_sensitivity (gui, TRUE); } -static gboolean -stlink_gui_update_devmem_view (STlinkGUI *gui) -{ +static gboolean stlink_gui_update_devmem_view (STlinkGUI *gui) { stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); return FALSE; } - - -static gpointer -stlink_gui_populate_devmem_view (gpointer data) -{ +static gpointer stlink_gui_populate_devmem_view (gpointer data) { guint off; stm32_addr_t addr; @@ -240,23 +198,21 @@ stlink_gui_populate_devmem_view (gpointer data) addr = gui->sl->flash_base; - if (gui->flash_mem.memory) { + if (gui->flash_mem.memory) g_free (gui->flash_mem.memory); - } gui->flash_mem.memory = g_malloc (gui->sl->flash_size); gui->flash_mem.size = gui->sl->flash_size; gui->flash_mem.base = gui->sl->flash_base; for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; + guint n_read = MEM_READ_SIZE; if (off + MEM_READ_SIZE > gui->sl->flash_size) { n_read = (guint) gui->sl->flash_size - off; /* align if needed */ - if (n_read & 3) { + if (n_read & 3) n_read = (n_read + 4) & ~(3); - } } /* reads to sl->q_buf */ stlink_read_mem32(gui->sl, addr + off, n_read); @@ -270,29 +226,22 @@ stlink_gui_populate_devmem_view (gpointer data) gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; } g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); - return NULL; } -static gboolean -stlink_gui_update_filemem_view (STlinkGUI *gui) -{ +static gboolean stlink_gui_update_filemem_view (STlinkGUI *gui) { gchar *basename; basename = g_path_get_basename (gui->filename); gtk_notebook_set_tab_label_text (gui->notebook, - GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), - basename); + GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), basename); g_free (basename); stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); - return FALSE; } -static gpointer -stlink_gui_populate_filemem_view (gpointer data) -{ +static gpointer stlink_gui_populate_filemem_view (gpointer data) { guchar buffer[MEM_READ_SIZE]; GFile *file; GFileInfo *file_info; @@ -306,81 +255,73 @@ stlink_gui_populate_filemem_view (gpointer data) g_return_val_if_fail (gui != NULL, NULL); g_return_val_if_fail (gui->filename != NULL, NULL); - if (g_str_has_suffix (gui->filename, ".hex")) { - // If the file has prefix .hex - try to interpret it as Intel-HEX. - // It's difficult to merge the world of standard functions and GLib, - // so do it simple - load whole file into buffer and copy the data - // to the destination afterwards. - // We loose meanwhile the displaying of the progress and need - // double memory. - - uint8_t* mem = NULL; - size_t size = 0; - uint32_t begin = 0; - int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); - - if (res == 0) { - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = size; - gui->file_mem.memory = g_malloc (size); - gui->file_mem.base = begin; - - memcpy (gui->file_mem.memory, mem, size); - } - else { - stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); - } - - free(mem); - } - else { - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out; - } - - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - - for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) { - n_read = (guint) gui->file_mem.size - off; - } - - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; - } - -out_input: - g_object_unref (input_stream); -out: - g_object_unref (file); - } - - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + if (g_str_has_suffix (gui->filename, ".hex")) { + // If the file has prefix .hex - try to interpret it as Intel-HEX. + // It's difficult to merge the world of standard functions and GLib, + // so do it simple - load whole file into buffer and copy the data to the + // destination afterwards. + // We loose meanwhile the displaying of the progress and need double memory. + + uint8_t* mem = NULL; + size_t size = 0; + uint32_t begin = 0; + int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); + + if (res == 0) { + if (gui->file_mem.memory) + g_free (gui->file_mem.memory); + gui->file_mem.size = size; + gui->file_mem.memory = g_malloc (size); + gui->file_mem.base = begin; + + memcpy (gui->file_mem.memory, mem, size); + } else { + stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); + } + + free(mem); + } else { + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) + g_free (gui->file_mem.memory); + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) + n_read = (guint) gui->file_mem.size - off; + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } + + out_input: g_object_unref (input_stream); + out: g_object_unref (file); + } + + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); return NULL; } @@ -388,29 +329,23 @@ static void mem_jmp (GtkTreeView *view, GtkEntry *entry, guint32 base_addr, gsize size, - GError **err) -{ + GError **err) { GtkTreeModel *model; guint32 jmp_addr; GtkTreeIter iter; jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); - if (err && *err) { + if (err && *err) return; - } if (jmp_addr < base_addr || jmp_addr > base_addr + size) { - g_set_error (err, - g_quark_from_string ("mem_jmp"), - 1, - "Invalid address"); + g_set_error (err, g_quark_from_string ("mem_jmp"), 1, "Invalid address"); return; } model = gtk_tree_view_get_model (view); - if (!model) { + if (!model) return; - } if (gtk_tree_model_get_iter_first (model, &iter)) { do { @@ -429,24 +364,17 @@ static void mem_jmp (GtkTreeView *view, path = gtk_tree_model_get_path (model, &iter); gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (view, - path, - NULL, - TRUE, - 0.0, - 0.0); + gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.0, 0.0); gtk_tree_path_free (path); } } } - g_value_unset (&value); + g_value_unset(&value); } while (gtk_tree_model_iter_next (model, &iter)); } } -static void -devmem_jmp_cb (GtkWidget *widget, gpointer data) -{ +static void devmem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; (void) widget; @@ -465,9 +393,7 @@ devmem_jmp_cb (GtkWidget *widget, gpointer data) } } -static void -filemem_jmp_cb (GtkWidget *widget, gpointer data) -{ +static void filemem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; (void) widget; @@ -488,9 +414,7 @@ filemem_jmp_cb (GtkWidget *widget, gpointer data) } } -static gchar * -dev_format_chip_id (guint32 chip_id) -{ +static gchar *dev_format_chip_id (guint32 chip_id) { const struct stlink_chipid_params *params; params = stlink_chipid_get_params(chip_id); @@ -500,31 +424,25 @@ dev_format_chip_id (guint32 chip_id) return g_strdup (params->description); } -static gchar * -dev_format_mem_size (gsize flash_size) -{ +static gchar *dev_format_mem_size (gsize flash_size) { return g_strdup_printf ("%u kB", (unsigned int)(flash_size / 1024)); } -static void -stlink_gui_set_connected (STlinkGUI *gui) -{ +static void stlink_gui_set_connected (STlinkGUI *gui) { gchar *tmp_str; GtkListStore *store; GtkTreeIter iter; gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Connected"); + gtk_statusbar_get_context_id (gui->statusbar, "conn"), "Connected"); gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); - if (gui->filename) { + if (gui->filename) gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); - } tmp_str = dev_format_chip_id (gui->sl->chip_id); gtk_label_set_text (gui->chip_id_label, tmp_str); @@ -548,9 +466,8 @@ stlink_gui_set_connected (STlinkGUI *gui) g_free (tmp_str); store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); @@ -560,9 +477,7 @@ stlink_gui_set_connected (STlinkGUI *gui) g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); } -static void -connect_button_cb (GtkWidget *widget, gpointer data) -{ +static void connect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; gint i; (void) widget; @@ -574,11 +489,11 @@ connect_button_cb (GtkWidget *widget, gpointer data) /* try version 1 then version 2 */ gui->sl = stlink_v1_open(0, 1); + if (gui->sl == NULL) + gui->sl = stlink_open_usb(0, 1, NULL, 0); if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0, 1, NULL); - } - if (gui->sl == NULL) { - stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; + stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); + return; } /* code below taken from flash/main.c, refactoring might be in order */ @@ -601,8 +516,7 @@ connect_button_cb (GtkWidget *widget, gpointer data) stlink_gui_set_connected (gui); } -static void stlink_gui_set_disconnected (STlinkGUI *gui) -{ +static void stlink_gui_set_disconnected (STlinkGUI *gui) { gtk_statusbar_push (gui->statusbar, gtk_statusbar_get_context_id (gui->statusbar, "conn"), "Disconnected"); @@ -614,9 +528,7 @@ static void stlink_gui_set_disconnected (STlinkGUI *gui) gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); } -static void -disconnect_button_cb (GtkWidget *widget, gpointer data) -{ +static void disconnect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; (void) widget; @@ -631,9 +543,7 @@ disconnect_button_cb (GtkWidget *widget, gpointer data) } -static void -stlink_gui_open_file (STlinkGUI *gui) -{ +static void stlink_gui_open_file (STlinkGUI *gui) { GtkWidget *dialog; GtkListStore *store; GtkTreeIter iter; @@ -646,13 +556,11 @@ stlink_gui_open_file (STlinkGUI *gui) NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - gui->filename = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + gui->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); @@ -663,37 +571,30 @@ stlink_gui_open_file (STlinkGUI *gui) gtk_widget_destroy (dialog); } -static void -open_button_cb (GtkWidget *widget, gpointer data) -{ +static void open_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; (void) widget; gui = STLINK_GUI (data); - stlink_gui_open_file (gui); } -static gboolean -stlink_gui_write_flash_update (STlinkGUI *gui) -{ +static gboolean stlink_gui_write_flash_update (STlinkGUI *gui) { stlink_gui_set_sensitivity (gui, TRUE); gui->progress.activity_mode = FALSE; gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - return FALSE; } -static gpointer -stlink_gui_write_flash (gpointer data) -{ +static gpointer stlink_gui_write_flash (gpointer data) { g_return_val_if_fail (STLINK_IS_GUI (data), NULL); STlinkGUI *gui = (STlinkGUI *)data; g_return_val_if_fail ((gui->sl != NULL), NULL); g_return_val_if_fail ((gui->filename != NULL), NULL); - if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { + if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, + (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { stlink_gui_set_info_error_message (gui, "Failed to write to flash"); } @@ -701,9 +602,7 @@ stlink_gui_write_flash (gpointer data) return NULL; } -static void -flash_button_cb (GtkWidget *widget, gpointer data) -{ +static void flash_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; gchar *tmp_str; guint32 address; @@ -722,47 +621,38 @@ flash_button_cb (GtkWidget *widget, gpointer data) result = gtk_dialog_run (gui->flash_dialog); if (result == GTK_RESPONSE_OK) { - address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), - &err); + address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), &err); if (err) { stlink_gui_set_info_error_message (gui, err->message); } else { - if (address > gui->sl->flash_base + gui->sl->flash_size || - address < gui->sl->flash_base) { + if (address > gui->sl->flash_base + gui->sl->flash_size || address < gui->sl->flash_base) { stlink_gui_set_info_error_message (gui, "Invalid address"); - } - else if (address + gui->file_mem.size > - gui->sl->flash_base + gui->sl->flash_size) { + } else if (address + gui->file_mem.size > gui->sl->flash_base + gui->sl->flash_size) { stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); } else { stlink_gui_set_sensitivity (gui, FALSE); - gtk_progress_bar_set_text (gui->progress.bar, - "Writing to flash"); + gtk_progress_bar_set_text (gui->progress.bar, "Writing to flash"); gui->progress.activity_mode = TRUE; gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - g_thread_new ("flash", - (GThreadFunc) stlink_gui_write_flash, gui); + g_thread_new ("flash", (GThreadFunc) stlink_gui_write_flash, gui); } } } } -int export_to_file(const char*filename, const struct mem_t flash_mem) -{ +int export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); FILE * f=fopen(filename, "w"); - if(f==NULL) + if (f == NULL) return -1; - for(gsize i=0;iflash_mem)!=0) + if (export_to_file (filename, gui->flash_mem) != 0) { stlink_gui_set_info_error_message(gui, "Failed to export flash"); - else + } else { stlink_gui_set_info_error_message(gui, "Export successful"); + } g_free (filename); } gtk_widget_destroy (dialog); } -static gboolean -progress_pulse_timeout (STlinkGUI *gui) { +static gboolean progress_pulse_timeout (STlinkGUI *gui) { if (gui->progress.activity_mode) { gtk_progress_bar_pulse (gui->progress.bar); } else { @@ -802,12 +691,11 @@ progress_pulse_timeout (STlinkGUI *gui) { return TRUE; } -static void -notebook_switch_page_cb (GtkNotebook *notebook, - GtkWidget *widget, - guint page_num, - gpointer data) -{ +static void notebook_switch_page_cb ( + GtkNotebook *notebook, + GtkWidget *widget, + guint page_num, + gpointer data) { STlinkGUI *gui; (void) notebook; (void) widget; @@ -815,22 +703,20 @@ notebook_switch_page_cb (GtkNotebook *notebook, gui = STLINK_GUI (data); if (page_num == 1) { - if (gui->filename == NULL) { + if (gui->filename == NULL) stlink_gui_open_file (gui); - } } } -static void -dnd_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint target_type, - guint timestamp, - gpointer data) -{ +static void dnd_received_cb ( + GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint target_type, + guint timestamp, + gpointer data) { GFile *file_uri; gchar **file_list; const guchar *file_data; @@ -841,14 +727,12 @@ dnd_received_cb (GtkWidget *widget, (void) x; (void) y; - if (selection_data != NULL && - gtk_selection_data_get_length (selection_data) > 0) { + if (selection_data != NULL && gtk_selection_data_get_length (selection_data) > 0) { switch (target_type) { case TARGET_FILENAME: - if (gui->filename) { + if (gui->filename) g_free (gui->filename); - } file_data = gtk_selection_data_get_data (selection_data); file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); @@ -859,11 +743,9 @@ dnd_received_cb (GtkWidget *widget, g_strfreev (file_list); g_object_unref (file_uri); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); @@ -873,39 +755,33 @@ dnd_received_cb (GtkWidget *widget, break; } } - gtk_drag_finish (context, - TRUE, - gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - timestamp); + gtk_drag_finish ( + context, + TRUE, + gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, + timestamp); } -void -stlink_gui_init_dnd (STlinkGUI *gui) -{ - GtkTargetEntry target_list[] = { - { "text/uri-list", 0, TARGET_FILENAME }, - }; - - gtk_drag_dest_set (GTK_WIDGET (gui->window), - GTK_DEST_DEFAULT_ALL, - target_list, - G_N_ELEMENTS (target_list), - GDK_ACTION_COPY); - - g_signal_connect (gui->window, "drag-data-received", - G_CALLBACK (dnd_received_cb), gui); +void stlink_gui_init_dnd (STlinkGUI *gui) { + GtkTargetEntry target_list[] = { { "text/uri-list", 0, TARGET_FILENAME }, }; + + gtk_drag_dest_set( + GTK_WIDGET (gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS (target_list), + GDK_ACTION_COPY); + + g_signal_connect (gui->window, "drag-data-received", G_CALLBACK (dnd_received_cb), gui); } -static void -stlink_gui_build_ui (STlinkGUI *gui) { +static void stlink_gui_build_ui (STlinkGUI *gui) { GtkBuilder *builder; GtkListStore *devmem_store; GtkListStore *filemem_store; gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { - ui_file = "stlink-gui.ui"; - } + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) ui_file = "stlink-gui.ui"; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { g_printerr ("Failed to load UI file: %s\n", ui_file); @@ -913,37 +789,25 @@ stlink_gui_build_ui (STlinkGUI *gui) { } gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); - g_signal_connect (G_OBJECT (gui->window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); + g_signal_connect (G_OBJECT (gui->window), "destroy", G_CALLBACK (gtk_main_quit), NULL); /* set up toolutton clicked callbacks */ - gui->open_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); - g_signal_connect (G_OBJECT (gui->open_button), "clicked", - G_CALLBACK (open_button_cb), gui); - - gui->connect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); - g_signal_connect (G_OBJECT (gui->connect_button), "clicked", - G_CALLBACK (connect_button_cb), gui); - - gui->disconnect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); - g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", - G_CALLBACK (disconnect_button_cb), gui); - - gui->flash_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); - g_signal_connect (G_OBJECT (gui->flash_button), "clicked", - G_CALLBACK (flash_button_cb), gui); - - gui->export_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); - g_signal_connect (G_OBJECT (gui->export_button), "clicked", - G_CALLBACK (export_button_cb), gui); - - gui->devmem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); + gui->open_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); + g_signal_connect (G_OBJECT (gui->open_button), "clicked", G_CALLBACK (open_button_cb), gui); + + gui->connect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); + g_signal_connect (G_OBJECT (gui->connect_button), "clicked", G_CALLBACK (connect_button_cb), gui); + + gui->disconnect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); + g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", G_CALLBACK (disconnect_button_cb), gui); + + gui->flash_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); + g_signal_connect (G_OBJECT (gui->flash_button), "clicked", G_CALLBACK (flash_button_cb), gui); + + gui->export_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); + g_signal_connect (G_OBJECT (gui->export_button), "clicked", G_CALLBACK (export_button_cb), gui); + + gui->devmem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); mem_view_init_headers (gui->devmem_treeview); devmem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -954,8 +818,7 @@ stlink_gui_build_ui (STlinkGUI *gui) { gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); g_object_unref (devmem_store); - gui->filemem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); + gui->filemem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); mem_view_init_headers (gui->filemem_treeview); filemem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -966,75 +829,43 @@ stlink_gui_build_ui (STlinkGUI *gui) { gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); g_object_unref (filemem_store); - gui->core_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); - - gui->chip_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + gui->core_id_label = GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); + gui->chip_id_label = GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + gui->flash_size_label = GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + gui->ram_size_label = GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + gui->device_frame = GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); - gui->flash_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + gui->notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); + g_signal_connect (gui->notebook, "switch-page", G_CALLBACK (notebook_switch_page_cb), gui); - gui->ram_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + gui->devmem_box = GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); + gui->filemem_box = GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - gui->device_frame = - GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); + gui->devmem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); + g_signal_connect (gui->devmem_jmp_entry, "activate", G_CALLBACK (devmem_jmp_cb), gui); - gui->notebook = - GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); - g_signal_connect (gui->notebook, "switch-page", - G_CALLBACK (notebook_switch_page_cb), gui); - - gui->devmem_box = - GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); - - gui->filemem_box = - GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - - gui->devmem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); - g_signal_connect (gui->devmem_jmp_entry, "activate", - G_CALLBACK (devmem_jmp_cb), gui); - - gui->filemem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); - g_signal_connect (gui->filemem_jmp_entry, "activate", - G_CALLBACK (filemem_jmp_cb), gui); + gui->filemem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); + g_signal_connect (gui->filemem_jmp_entry, "activate", G_CALLBACK (filemem_jmp_cb), gui); gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); - gui->progress.bar = - GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); + gui->progress.bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); - gui->progress.timer = g_timeout_add (100, - (GSourceFunc) progress_pulse_timeout, - gui); + gui->progress.timer = g_timeout_add (100, (GSourceFunc) progress_pulse_timeout, gui); - gui->statusbar = - GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + gui->statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); - gui->infobar = - GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); + gui->infobar = GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); gtk_info_bar_add_button (gui->infobar, "_OK", GTK_RESPONSE_OK); gui->infolabel = GTK_LABEL (gtk_label_new ("")); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), - GTK_WIDGET (gui->infolabel)); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), GTK_WIDGET (gui->infolabel)); g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); /* flash dialog */ - gui->flash_dialog = - GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); - g_signal_connect_swapped (gui->flash_dialog, "response", - G_CALLBACK (gtk_widget_hide), gui->flash_dialog); - - gui->flash_dialog_ok = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); - - gui->flash_dialog_cancel = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); - - gui->flash_dialog_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); + gui->flash_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); + g_signal_connect_swapped (gui->flash_dialog, "response", G_CALLBACK (gtk_widget_hide), gui->flash_dialog); + gui->flash_dialog_ok = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); + gui->flash_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); + gui->flash_dialog_entry = GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); /* make it so */ gtk_widget_show_all (GTK_WIDGET (gui->window)); @@ -1044,9 +875,7 @@ stlink_gui_build_ui (STlinkGUI *gui) { stlink_gui_set_disconnected (gui); } -int -main (int argc, char **argv) -{ +int main (int argc, char **argv) { STlinkGUI *gui; gtk_init (&argc, &argv); @@ -1056,6 +885,5 @@ main (int argc, char **argv) stlink_gui_init_dnd (gui); gtk_main (); - return 0; } diff --git a/src/tools/gui/stlink-gui.h b/src/stlink-gui/gui.h similarity index 98% rename from src/tools/gui/stlink-gui.h rename to src/stlink-gui/gui.h index 30c503fd3..c83e638f6 100644 --- a/src/tools/gui/stlink-gui.h +++ b/src/stlink-gui/gui.h @@ -39,8 +39,7 @@ struct mem_t { guint32 base; }; -struct _STlinkGUI -{ +struct _STlinkGUI { GObject parent_instance; /*< private >*/ @@ -82,8 +81,7 @@ struct _STlinkGUI stlink_t *sl; }; -struct _STlinkGUIClass -{ +struct _STlinkGUIClass { GObjectClass parent_class; /* class members */ diff --git a/src/stlink-gui/icons/export-icons.sh b/src/stlink-gui/icons/export-icons.sh new file mode 100644 index 000000000..f36cb5598 --- /dev/null +++ b/src/stlink-gui/icons/export-icons.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# create the XPM icon and all resolutions below hicolor as PNG + +APPNAME="stlink-gui" +ORIGIN="stlink-gui_icon.svg" +OUTDIR="hicolor" + +# possible size options are --export-dpi / --export-width / --export-height +OPTS="-z --export-id-only" +ID="scalable-icon" +RESOLUTIONS="16 22 24 32 48 64 128 256" + +if ! [ -d $OUTDIR ]; then + echo "output directory missing. Create it..." + mkdir $OUTDIR + for RES in $RESOLUTIONS; do + mkdir -p $OUTDIR/${RES}x${RES}/apps + done +fi + +# create single app icon +inkscape $OPTS --export-width=32 --export-id=$ID --export-png=$APPNAME.png $ORIGIN +if [ $? != 0 ]; then + exit 1; +fi +convert $APPNAME.png $APPNAME.xpm + +# create all the resolutions +ALL="" +for RES in $RESOLUTIONS; do + inkscape $OPTS --export-width=$RES --export-id=$ID --export-png=$OUTDIR/${RES}x${RES}/apps/$APPNAME.png $ORIGIN + ALL="$ALL $OUTDIR/${RES}x${RES}/apps/$APPNAME.png" +done + +# this is for windows... +#echo "build Windows icon from $ALL" +#convert $ALL $APPNAME.ico + +exit 0 diff --git a/src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/128x128/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/128x128/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/16x16/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/16x16/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/22x22/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/22x22/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/24x24/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/24x24/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/24x24/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/24x24/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/256x256/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/256x256/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/256x256/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/256x256/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/32x32/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/32x32/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/48x48/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/48x48/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/64x64/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/64x64/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/64x64/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/64x64/apps/stlink-gui.png diff --git a/src/tools/gui/art/stlink-gui.png b/src/stlink-gui/icons/stlink-gui.png similarity index 100% rename from src/tools/gui/art/stlink-gui.png rename to src/stlink-gui/icons/stlink-gui.png diff --git a/src/tools/gui/art/stlink-gui.svg b/src/stlink-gui/icons/stlink-gui.svg similarity index 100% rename from src/tools/gui/art/stlink-gui.svg rename to src/stlink-gui/icons/stlink-gui.svg diff --git a/src/tools/gui/art/stlink-gui.xpm b/src/stlink-gui/icons/stlink-gui.xpm similarity index 100% rename from src/tools/gui/art/stlink-gui.xpm rename to src/stlink-gui/icons/stlink-gui.xpm diff --git a/src/tools/gui/art/stlink-gui_48.png b/src/stlink-gui/icons/stlink-gui_48.png similarity index 100% rename from src/tools/gui/art/stlink-gui_48.png rename to src/stlink-gui/icons/stlink-gui_48.png diff --git a/src/tools/gui/stlink-gui.desktop b/src/stlink-gui/stlink-gui.desktop similarity index 75% rename from src/tools/gui/stlink-gui.desktop rename to src/stlink-gui/stlink-gui.desktop index 54cb40349..72bc26ac6 100644 --- a/src/tools/gui/stlink-gui.desktop +++ b/src/stlink-gui/stlink-gui.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=stlink GenericName=Stlink Tools -Comment=STM32 discovery line Linux programmer +Comment=Open source STM32 MCU programming toolset Exec=stlink-gui Icon=stlink-gui Terminal=false diff --git a/src/tools/gui/stlink-gui.ui b/src/stlink-gui/stlink-gui.ui similarity index 100% rename from src/tools/gui/stlink-gui.ui rename to src/stlink-gui/stlink-gui.ui diff --git a/src/tools/flash.c b/src/tools/flash.c index f87b65940..3a83daf8a 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -2,7 +2,6 @@ // TODO - this should be done as just a simple flag to the st-util command line... - #include #include #include @@ -10,7 +9,7 @@ #include #include -#include +#include static stlink_t *connected_stlink = NULL; @@ -29,17 +28,15 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); - puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); - puts(" Use hex format for addr, and ."); - puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); - puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); - puts(" ./st-flash [--version]"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); + puts(" , and : Use hex format."); + puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); + puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); + puts("print tool version info: ./st-flash [--version]"); puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); - puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); + puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); } int main(int ac, char** av) @@ -59,13 +56,16 @@ int main(int ac, char** av) printf("st-flash %s\n", STLINK_VERSION); - if (o.devname != NULL) /* stlinkv1 */ - sl = stlink_v1_open(o.log_level, 1); - else /* stlinkv2 */ - sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); + sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); - if (sl == NULL) + if (sl == NULL) { return -1; + } + + if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + printf("Failed to connect to target\n"); + return -1; + } if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; @@ -73,6 +73,7 @@ int main(int ac, char** av) } sl->verbose = o.log_level; + sl->opt = o.opt; connected_stlink = sl; signal(SIGINT, &cleanup); @@ -133,7 +134,7 @@ int main(int ac, char** av) if (o.cmd == FLASH_CMD_WRITE) /* write */ { size_t size = 0; - if(o.format == FLASH_FORMAT_IHEX) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { printf("Cannot parse %s as Intel-HEX file\n", o.filename); @@ -142,7 +143,7 @@ int main(int ac, char** av) } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if(o.format == FLASH_FORMAT_IHEX) + if (o.format == FLASH_FORMAT_IHEX) err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -154,7 +155,7 @@ int main(int ac, char** av) } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if(o.format == FLASH_FORMAT_IHEX) + if (o.format == FLASH_FORMAT_IHEX) err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -164,7 +165,8 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ + else if ((o.addr >= sl->option_base) && + (o.addr < sl->option_base + sl->option_size)) { err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { @@ -173,10 +175,15 @@ int main(int ac, char** av) } } else if (o.area == FLASH_OPTION_BYTES){ - err = stlink_fwrite_option_bytes_32bit(sl, o.val); + if (o.val == 0) { + printf("attempting to set option byte to 0, abort.\n"); + goto on_error; + } + + err = stlink_write_option_bytes32(sl, o.val); if (err == -1) { - printf("stlink_fwrite_option_bytes() == -1\n"); + printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } } @@ -210,16 +217,13 @@ int main(int ac, char** av) else /* read */ { if(o.area == FLASH_OPTION_BYTES){ - if(sl->chip_id == STLINK_CHIPID_STM32_F2){ - uint32_t option_byte = 0; - err = stlink_read_option_bytes_f2(sl,&option_byte); - printf("%x\n",option_byte); - }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ - uint32_t option_byte = 0; - err = stlink_read_option_bytes_f4(sl,&option_byte); + uint32_t option_byte; + err = stlink_read_option_bytes32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else { printf("%x\n",option_byte); - }else{ - printf("This format is available for STM32F2 and STM32F4 Only\n"); } }else{ if ((o.addr >= sl->flash_base) && (o.size == 0) && @@ -231,11 +235,12 @@ int main(int ac, char** av) o.size = sl->sram_size; } err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); - } - if (err == -1) - { - printf("stlink_fread() == -1\n"); - goto on_error; + + if (err == -1) + { + printf("stlink_fread() == -1\n"); + goto on_error; + } } } diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 3f74ac057..c8d7841de 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -1,28 +1,97 @@ -#include - #include #include #include +#include + static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - if(strlen(str) < n) return false; + if (strlen(str) < n) return false; return (0 == strncmp(str, prefix, n)); } -int flash_get_opts(struct flash_opts* o, int ac, char** av) -{ - bool serial_specified = false; +// support positive integer from 0 to UINT64_MAX +// support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 +// negative numbers are not supported +// return 0 if success else return -1 +static int get_long_integer_from_char_array (const char *const str, uint64_t *read_value) { + uint64_t value; + char *tail; - // defaults + // hexadecimal + if (starts_with (str, "0x") || starts_with (str, "0X")) { + value = strtoul (str + 2, &tail, 16); + } + // binary + else if (starts_with (str, "0b") || starts_with (str, "0B")) { + value = strtoul (str + 2, &tail, 2); + } + // octal + else if (starts_with (str, "0")) { + value = strtoul (str + 1, &tail, 8); + } + // decimal + else { + value = strtoul (str, &tail, 10); + } + + if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { + value = value * 1024; + } + else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + value = value * 1024 * 1024; + } + else if (tail[0] == '\0') { + // value not change + } + else { + return -1; + } + *read_value = value; + return 0; +} + +// support positive integer from 0 to UINT32_MAX +// support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 +// negative numbers are not supported +// return 0 if success else return -1 +static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { + uint64_t value; + int result = get_long_integer_from_char_array (str, &value); + if (result != 0) { + return result; + } + else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ +cannot convert to int32_t\n"); + return -1; + } + else { + *read_value = (uint32_t)value; + return 0; + } +} +static int invalid_args(const char *expected) { + fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); + return -1; +} + +static int bad_arg(const char *arg) { + fprintf(stderr, "*** Error: Invalid value for %s\n", arg); + return -1; +} + +int flash_get_opts(struct flash_opts* o, int ac, char** av) { + + // defaults memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; // options - - while(ac >= 1) { + int result; + while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); @@ -30,12 +99,15 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; } + else if (strcmp(av[0], "--opt") == 0) { + o->opt = ENABLE_OPT; + } else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; - if(strcmp(av[0], "--serial") == 0) { + if (strcmp(av[0], "--serial") == 0) { ac--; av++; if (ac < 1) return -1; @@ -44,23 +116,19 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; //the length of the destination-array - if(j % 2 != 0) return -1; - - for(size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { + int length = j / 2; // the length of the destination-array + if (j % 2 != 0) return -1; + for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - - serial_specified = true; } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; - if(strcmp(av[0], "--area") == 0) { + if (strcmp(av[0], "--area") == 0) { ac--; av++; if (ac < 1) return -1; @@ -81,9 +149,59 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) return -1; } + else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + const char* freq; + if (strcmp(av[0], "--freq") == 0) { + ac--; + av++; + if (ac < 1) return -1; + freq = av[0]; + } + else { + freq = av[0] + strlen("--freq="); + } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { + o->freq = 5; + } + else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + o->freq = 15; + } + else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + o->freq = 25; + } + else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + o->freq = 50; + } + else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + o->freq = 100; + } + else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + o->freq = 125; + } + else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + o->freq = 240; + } + else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + o->freq = 480; + } + else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + o->freq = 950; + } + else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + o->freq = 1200; + } + else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + o->freq = 1800; + } + else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + o->freq = 4000; + } + else + return -1; + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; - if(strcmp(av[0], "--format") == 0) { + if (strcmp(av[0], "--format") == 0) { ac--; av++; if (ac < 1) return -1; @@ -92,38 +210,25 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else { format = av[0] + strlen("--format="); } - if (strcmp(format, "binary") == 0) o->format = FLASH_FORMAT_BINARY; else if (strcmp(format, "ihex") == 0) o->format = FLASH_FORMAT_IHEX; else - return -1; + return bad_arg("format"); + } + else if ( starts_with(av[0], "--flash=") ) { + const char *arg = av[0] + strlen("--flash="); + + uint32_t flash_size; + result = get_integer_from_char_array(arg, &flash_size); + if (result != 0) return bad_arg ("--flash"); + else o->flash_size = (size_t) flash_size; + } + else if (strcmp(av[0],"--connect-under-reset")== 0){ + o->connect_under_reset = true; } - else if ( starts_with(av[0], "--flash=") ) { - const char *arg = av[0] + strlen("--flash="); - char *ep = 0; - - o->flash_size = (uint32_t)strtoul(arg,&ep,0); - while ( *ep ) { - switch ( *ep++ ) { - case 0: - break; - case 'k': - case 'K': - o->flash_size *= 1024u; - break; - case 'm': - case 'M': - o->flash_size *= 1024u * 1024u; - break; - default: - fprintf(stderr,"Invalid --flash=%s\n",arg); - return -1; - } - } - } - else { + else { break; // non-option found } @@ -132,8 +237,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) } // command and (optional) device name - - while(ac >= 1) { // looks like for stlinkv1 the device name and command may be swaped - check both positions in all cases + while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = FLASH_CMD_ERASE; @@ -150,10 +254,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = CMD_RESET; } - else if(starts_with(av[0], "/dev/")) { - if (o->devname) return -1; - o->devname = av[0]; - } else { break; } @@ -162,58 +262,60 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) av++; } - char * tail; switch(o->cmd) { case FLASH_CMD_NONE: // no command found return -1; case FLASH_CMD_ERASE: // no more arguments expected - if(ac != 0) return -1; + if (ac != 0) return -1; break; case FLASH_CMD_READ: // expect filename, addr and size - if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; + if ((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; + if (ac != 3) return invalid_args("read "); if (ac != 3) return -1; - o->filename = av[0]; - o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return -1; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) address; - o->size = strtoul(av[2], &tail, 16); - if(tail[0] != '\0') return -1; + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); + else o->size = (size_t) size; break; case FLASH_CMD_WRITE: - if(o->area == FLASH_OPTION_BYTES){ - if(ac != 1) return -1; + if (o->area == FLASH_OPTION_BYTES){ + if (ac != 1) return -1; - o->val = (uint32_t)strtoul(av[0], &tail, 16); - } - else if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr - if (ac != 2) return -1; + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + if (ac != 2) return invalid_args("write "); o->filename = av[0]; - o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return -1; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; } - else if(o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) return -1; - + else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + if (ac != 1) return invalid_args("write "); o->filename = av[0]; } else { - return -1; + return -1; // should have been caught during format parsing } break; default: break ; } - // some constistence checks - - if(serial_specified && o->devname != NULL) return -1; // serial not supported for v1 - return 0; } - diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt deleted file mode 100644 index c619a0547..000000000 --- a/src/tools/gui/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -if (NOT gtk_FOUND) - return() -endif() - -set(GUI_SOURCES stlink-gui.c stlink-gui.h) -set(INSTALLED_UI_DIR share/stlink) - -include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) - -add_executable(stlink-gui-local ${GUI_SOURCES}) -set_target_properties(stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) - - -add_executable(stlink-gui ${GUI_SOURCES}) -set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}") -target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) - -install(TARGETS stlink-gui - RUNTIME DESTINATION bin) -install(FILES stlink-gui.ui - DESTINATION ${INSTALLED_UI_DIR}) -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # Install desktop entry - install(FILES stlink-gui.desktop - DESTINATION share/applications) - # Install icon - install(FILES art/stlink-gui.svg - DESTINATION share/icons/hicolor/scalable/apps) -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - diff --git a/src/tools/gui/art/export-icons.sh b/src/tools/gui/art/export-icons.sh deleted file mode 100755 index 9d61719b9..000000000 --- a/src/tools/gui/art/export-icons.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# create the XPM icon and all resolutions below hicolor as PNG - -APPNAME="stlink-gui" -ORIGIN="stlink-gui_icon.svg" -OUTDIR="hicolor" - -## possible size options are --export-dpi / --export-width / --export-height -OPTS="-z --export-id-only" -ID="scalable-icon" -RESOLUTIONS="16 22 24 32 48 64 128 256" - - if ! [ -d $OUTDIR ]; then - echo "output directory missing. Create it..." - mkdir $OUTDIR - for RES in $RESOLUTIONS; do - mkdir -p $OUTDIR/${RES}x${RES}/apps - done - fi - - # create single app icon - inkscape $OPTS --export-width=32 --export-id=$ID --export-png=$APPNAME.png $ORIGIN - if [ $? != 0 ]; then exit 1; fi - convert $APPNAME.png $APPNAME.xpm - - # create all the resolutions - ALL="" - for RES in $RESOLUTIONS; do - inkscape $OPTS --export-width=$RES --export-id=$ID --export-png=$OUTDIR/${RES}x${RES}/apps/$APPNAME.png $ORIGIN - ALL="$ALL $OUTDIR/${RES}x${RES}/apps/$APPNAME.png" - done - - # this is for windows... - #echo "build Windows icon from $ALL" - #convert $ALL $APPNAME.ico - -exit 0 diff --git a/src/tools/info.c b/src/tools/info.c index 2ad8f2c09..8464d8632 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -8,14 +8,14 @@ static void usage(void) { puts("st-info --version"); - puts("st-info --flash"); - puts("st-info --sram"); - puts("st-info --descr"); - puts("st-info --pagesize"); - puts("st-info --chipid"); + puts("st-info --probe"); puts("st-info --serial"); puts("st-info --hla-serial"); - puts("st-info --probe"); + puts("st-info --flash [--connect-under-reset]"); + puts("st-info --pagesize [--connect-under-reset]"); + puts("st-info --sram [--connect-under-reset]"); + puts("st-info --chipid [--connect-under-reset]"); + puts("st-info --descr [--connect-under-reset]"); } /* Print normal or OpenOCD hla_serial with newline */ @@ -45,20 +45,20 @@ static void stlink_print_info(stlink_t *sl) if (!sl) return; - printf(" serial: "); + printf(" serial: "); stlink_print_serial(sl, false); - printf("openocd: "); + printf(" hla-serial: "); stlink_print_serial(sl, true); - printf(" flash: %u (pagesize: %u)\n", - (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); + printf(" flash: %u (pagesize: %u)\n", + (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); - printf(" sram: %u\n", (unsigned int)sl->sram_size); - printf(" chipid: 0x%.4x\n", sl->chip_id); + printf(" sram: %u\n", (unsigned int)sl->sram_size); + printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); if (params) - printf(" descr: %s\n", params->description); + printf(" descr: %s\n", params->description); } static void stlink_probe(void) @@ -76,19 +76,25 @@ static void stlink_probe(void) stlink_probe_usb_free(&stdevs, size); } -static stlink_t *stlink_open_first(void) +static stlink_t *stlink_open_first(bool under_reset) { stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); - + if (sl == NULL) { + if (under_reset) { + sl = stlink_open_usb(0, 2, NULL, 0); + } else { + sl = stlink_open_usb(0, 1, NULL, 0); + } + } + return sl; } -static int print_data(char **av) +static int print_data(int ac, char **av) { stlink_t* sl = NULL; + bool under_reset = false; // Probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { @@ -99,7 +105,16 @@ static int print_data(char **av) return 0; } - sl = stlink_open_first(); + if (ac == 3) { + if (strcmp(av[2],"--connect-under-reset") == 0) { + under_reset = true; + } else { + usage(); + return -1; + } + } + + sl = stlink_open_first(under_reset); if (sl == NULL) { return -1; @@ -113,18 +128,18 @@ static int print_data(char **av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - if (strcmp(av[1], "--flash") == 0) + if (strcmp(av[1], "--serial") == 0) + stlink_print_serial(sl, false); + else if (strcmp(av[1], "--hla-serial") == 0) + stlink_print_serial(sl, true); + else if (strcmp(av[1], "--flash") == 0) printf("0x%x\n", (unsigned int)sl->flash_size); - else if (strcmp(av[1], "--sram") == 0) - printf("0x%x\n", (unsigned int)sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) printf("0x%x\n", (unsigned int)sl->flash_pgsz); + else if (strcmp(av[1], "--sram") == 0) + printf("0x%x\n", (unsigned int)sl->sram_size); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--serial") == 0) - stlink_print_serial(sl, false); - else if (strcmp(av[1], "--hla-serial") == 0) - stlink_print_serial(sl, true); else if (strcmp(av[1], "--descr") == 0) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) @@ -149,7 +164,7 @@ int main(int ac, char** av) return -1; } - err = print_data(av); + err = print_data(ac,av); return err; } diff --git a/src/usb.c b/src/usb.c index 9df9d7296..a711749da 100644 --- a/src/usb.c +++ b/src/usb.c @@ -2,33 +2,26 @@ #include #include #include +#include #if !defined(_MSC_VER) #include #endif #include -#include -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4200 4255 4668 4820) -#include -#pragma warning(pop) -#else -#include -#endif #include #include -#include "stlink.h" +#if defined(__MINGW32__) || defined(_MSC_VER) +#include +#endif +#include enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; -static inline uint32_t le_to_h_u32(const uint8_t* buf) -{ +static inline uint32_t le_to_h_u32(const uint8_t* buf) { return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); } -static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) -{ +static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { unsigned int i; int speed_index = -1; int speed_diff = INT_MAX; @@ -36,122 +29,98 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u bool match = true; for (i = 0; i < map_size; i++) { - if (!map[i]) - continue; - last_valid_speed = i; - if (khz == map[i]) { - speed_index = i; - break; - } else { - int current_diff = khz - map[i]; - /* get abs value for comparison */ - current_diff = (current_diff > 0) ? current_diff : -current_diff; - if ((current_diff < speed_diff) && khz >= map[i]) { - speed_diff = current_diff; - speed_index = i; - } - } + if (!map[i]) continue; + last_valid_speed = i; + if (khz == map[i]) { + speed_index = i; + break; + } else { + int current_diff = khz - map[i]; + // Get abs value for comparison + current_diff = (current_diff > 0) ? current_diff : -current_diff; + if ((current_diff < speed_diff) && khz >= map[i]) { + speed_diff = current_diff; + speed_index = i; + } + } } if (speed_index == -1) { - /* this will only be here if we cannot match the slow speed. - * use the slowest speed we support.*/ - speed_index = last_valid_speed; - match = false; - } else if (i == map_size) - match = false; - + // This will only be here if we cannot match the slow speed. Use the slowest speed we support. + speed_index = last_valid_speed; + match = false; + } else if (i == map_size) { + match = false; + } if (!match) { - ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \ - khz, map[speed_index]); + ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); } return speed_index; } void _stlink_usb_close(stlink_t* sl) { - if (!sl) - return; + if (!sl) return; struct stlink_libusb * const handle = sl->backend_data; - // maybe we couldn't even get the usb device? + // Maybe we couldn't even get the usb device? if (handle != NULL) { - if (handle->usb_handle != NULL) { - libusb_close(handle->usb_handle); - } - + if (handle->usb_handle != NULL) libusb_close(handle->usb_handle); libusb_exit(handle->libusb_ctx); free(handle); } } ssize_t send_recv(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize, - unsigned char* rxbuf, size_t rxsize) { - /* note: txbuf and rxbuf can point to the same area */ + unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, size_t rxsize) { + /* Note: txbuf and rxbuf can point to the same area */ int res = 0; int t; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, - txbuf, - (int) txsize, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int) txsize, &res, 3000); if (t) { printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); return -1; } else if ((size_t)res != txsize) { printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - rxbuf, - (int) rxsize, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int) rxsize, &res, 3000); if (t) { - printf("[!] send_recv read reply failed: %s\n", - libusb_error_name(t)); + printf("[!] send_recv read reply failed: %s\n", libusb_error_name(t)); return -1; } } if ((handle->protocoll == 1) && terminate) { - /* Read the SG reply */ + // Read the SG reply unsigned char sg_buf[13]; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - sg_buf, - 13, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { - printf("[!] send_recv read storage failed: %s\n", - libusb_error_name(t)); + printf("[!] send_recv read storage failed: %s\n", libusb_error_name(t)); return -1; } - /* The STLink doesn't seem to evaluate the sequence number */ + // The STLink doesn't seem to evaluate the sequence number. handle->sg_transfer_idx++; } return res; } -static inline int send_only -(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize) { +static inline int send_only(struct stlink_libusb* handle, int terminate, + unsigned char* txbuf, size_t txsize) { return (int) send_recv(handle, terminate, txbuf, txsize, NULL, 0); } -static int fill_command -(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) { +static int fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; int i = 0; memset(cmd, 0, sizeof (sl->c_buf)); - if(slu->protocoll == 1) { + if (slu->protocoll == 1) { cmd[i++] = 'U'; cmd[i++] = 'S'; cmd[i++] = 'B'; @@ -159,9 +128,9 @@ static int fill_command write_uint32(&cmd[i], slu->sg_transfer_idx); write_uint32(&cmd[i + 4], len); i += 8; - cmd[i++] = (dir == SG_DXFER_FROM_DEV)?0x80:0; - cmd[i++] = 0; /* Logical unit */ - cmd[i++] = 0xa; /* Command length */ + cmd[i++] = (dir == SG_DXFER_FROM_DEV) ? 0x80 : 0; + cmd[i++] = 0; // Logical unit + cmd[i++] = 0xa; // Command length } return i; } @@ -189,7 +158,7 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_APIV3_GET_VERSION_EX; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - if (size != rep_len) { + if (size != (ssize_t)rep_len) { printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); return (int) size; } @@ -243,6 +212,7 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { return (int) size; } *data = read_uint32(rdata, 4); + return 0; } @@ -267,6 +237,29 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { return 0; } +int _stlink_usb_get_rw_status(stlink_t *sl) { + if (sl->version.jtag_api == STLINK_JTAG_API_V1) return -1; + + unsigned char* const rdata = sl->q_buf; + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + int i; + int16_t ret = 0; + + i = fill_command(sl, SG_DXFER_FROM_DEV, 12); + cmd[i++] = STLINK_DEBUG_COMMAND; + if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12); + } else { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2); + } + if (ret < 0) return -1; + + return 0; +} + int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -279,14 +272,11 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) - return ret; + if (ret == -1) return ret; + ret = send_only(slu, 0, data, len); + if (ret == -1) return ret; - ret = send_only(slu, 1, data, len); - if (ret == -1) - return ret; - - return 0; + return _stlink_usb_get_rw_status(sl); } int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -301,12 +291,9 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) - return ret; - + if (ret == -1) return ret; ret = send_only(slu, 1, data, len); - if (ret == -1) - return ret; + if (ret == -1) return ret; return 0; } @@ -326,6 +313,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { printf("[!] send_recv STLINK_GET_CURRENT_MODE\n"); return -1; } + return sl->q_buf[0]; } @@ -334,23 +322,53 @@ int _stlink_usb_core_id(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int rep_len = 4; + int rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READCOREID; - + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_READCOREID; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; + } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READCOREID\n"); return -1; } - sl->core_id = read_uint32(data, 0); + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + sl->core_id = read_uint32(data, 0); + } else { + sl->core_id = read_uint32(data, 4); + } return 0; } +int _stlink_usb_status_v2(stlink_t *sl) +{ + int result; + uint32_t status = 0; + + result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); + DLOG("core status: %08X\n", status); + if (result != 0) { + sl->core_stat = TARGET_UNKNOWN; + } else { + if (status & S_HALT) { + sl->core_stat = TARGET_HALTED; + } else if (status & S_RESET_ST) { + sl->core_stat = TARGET_RESET; + } else { + sl->core_stat = TARGET_RUNNING; + } + } + + return result; +} int _stlink_usb_status(stlink_t * sl) { + if (sl->version.jtag_api != STLINK_JTAG_API_V1) return _stlink_usb_status_v2(sl); + struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -360,13 +378,20 @@ int _stlink_usb_status(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_GETSTATUS\n"); return (int) size; } sl->q_len = (int) size; + if (sl->q_len > 1) { + if (sl->q_buf[0] == STLINK_CORE_RUNNING) + sl->core_stat = TARGET_RUNNING; + else if (sl->q_buf[0] == STLINK_CORE_HALTED) + sl->core_stat = TARGET_HALTED; + else + sl->core_stat = TARGET_UNKNOWN; + } return 0; } @@ -399,18 +424,18 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = sl->version.stlink_v > 1? STLINK_DEBUG_APIV2_ENTER : STLINK_DEBUG_ENTER; + // Select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). + cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - if (rep_len == 0) { - size = send_only(slu, 1, cmd, slu->cmd_len); + size = send_only(slu, 1, cmd, slu->cmd_len); } else { - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); } if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_ENTER\n"); - return (int) size; + printf("[!] send_recv STLINK_DEBUG_ENTER\n"); + return (int) size; } return 0; @@ -424,7 +449,6 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_COMMAND; cmd[i++] = STLINK_DFU_EXIT; - size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv STLINK_DFU_EXIT\n"); @@ -444,7 +468,11 @@ int _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_RESETSYS; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; + } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -452,12 +480,11 @@ int _stlink_usb_reset(stlink_t * sl) { return (int) size; } - // Reset through AIRCR so NRST does not need to be connected - return stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); + // Reset through AIRCR so that NRST does not need to be connected. + return stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); } - int _stlink_usb_jtag_reset(stlink_t * sl, int value) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -469,7 +496,6 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_DRIVE_NRST; cmd[i++] = value; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_JTAG_DRIVE_NRST\n"); @@ -490,7 +516,6 @@ int _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_STEPCORE\n"); @@ -506,6 +531,15 @@ int _stlink_usb_step(stlink_t* sl) { */ int _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + + int res; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY|C_DEBUGEN); + return res; + } + + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -514,7 +548,6 @@ int _stlink_usb_run(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_RUNCORE\n"); @@ -532,6 +565,7 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { ssize_t size; int rep_len = 2; int i; + // clock speed only supported by stlink/v2 and for firmware >= 22 if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); @@ -540,7 +574,6 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; cmd[i++] = clk_divisor & 0xFF; cmd[i++] = (clk_divisor >> 8) & 0xFF; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n"); @@ -550,13 +583,12 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { return 0; } else if (sl->version.stlink_v == 3) { int speed_index; - uint32_t map[STLINK_V3_MAX_FREQ_NB]; + uint32_t map[STLINK_V3_MAX_FREQ_NB]; i = fill_command(sl, SG_DXFER_FROM_DEV, 16); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); if (size == -1) { printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); @@ -565,17 +597,14 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) - speeds_size = STLINK_V3_MAX_FREQ_NB; + if (speeds_size > STLINK_V3_MAX_FREQ_NB) speeds_size = STLINK_V3_MAX_FREQ_NB; - for (i = 0; i < speeds_size; i++) - map[i] = le_to_h_u32(&data[12 + 4 * i]); + for (i = 0; i < speeds_size; i++) map[i] = le_to_h_u32(&data[12 + 4 * i]); - /* set to zero all the next entries */ - for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) - map[i] = 0; + // Set to zero all the next entries + for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; - speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); i = fill_command(sl, SG_DXFER_FROM_DEV, 16); @@ -583,12 +612,12 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = STLINK_APIV3_SET_COM_FREQ; cmd[i++] = 0; // SWD mode cmd[i++] = 0; - cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); if (size == -1) { printf("[!] send_recv STLINK_APIV3_SET_COM_FREQ\n"); return (int) size; @@ -628,16 +657,16 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_READMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READMEM_32BIT\n"); return (int) size; } sl->q_len = (int) size; - stlink_print_data(sl); + return 0; } @@ -646,33 +675,44 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - uint32_t rep_len = 84; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 84 : 88; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READALLREGS; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_READALLREGS; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; + } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); return (int) size; } + + /* V1: regs data from offset 0 */ + /* V2: status at offset 0, regs data from offset 4 */ + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; sl->q_len = (int) size; stlink_print_data(sl); - for(i=0; i<16; i++) - regp->r[i]= read_uint32(sl->q_buf, i*4); - regp->xpsr = read_uint32(sl->q_buf, 64); - regp->main_sp = read_uint32(sl->q_buf, 68); - regp->process_sp = read_uint32(sl->q_buf, 72); - regp->rw = read_uint32(sl->q_buf, 76); - regp->rw2 = read_uint32(sl->q_buf, 80); - if (sl->verbose < 2) - return 0; - DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); - DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); - DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); - DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); - DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); + for(i=reg_offset; i<16; i++) regp->r[i]= read_uint32(sl->q_buf, i*4); + regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); + regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); + regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); + regp->rw = read_uint32(sl->q_buf, reg_offset + 76); + regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); + + if (sl->verbose < 2) return 0; + + DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); + DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); + DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 72)); + DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 76)); + DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 80)); return 0; } @@ -683,20 +723,29 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t r; - uint32_t rep_len = 4; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READREG; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_READREG; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READREG; + } + cmd[i++] = (uint8_t) r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READREG\n"); return (int) size; } + sl->q_len = (int) size; stlink_print_data(sl); - r = read_uint32(sl->q_buf, 0); + r = read_uint32(sl->q_buf, reg_offset); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { @@ -710,10 +759,10 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { regp->process_sp = r; break; case 19: - regp->rw = r; /* XXX ?(primask, basemask etc.) */ + regp->rw = r; // XXX ?(primask, basemask etc.) break; case 20: - regp->rw2 = r; /* XXX ?(primask, basemask etc.) */ + regp->rw2 = r; // XXX ?(primask, basemask etc.) break; default: regp->r[r_idx] = r; @@ -728,34 +777,30 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg int ret; sl->q_buf[0] = (unsigned char) r_idx; - for (int i = 1; i < 4; i++) { - sl->q_buf[i] = 0; - } + for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 0x14: - regp->primask = (uint8_t) (r & 0xFF); - regp->basepri = (uint8_t) ((r>>8) & 0xFF); - regp->faultmask = (uint8_t) ((r>>16) & 0xFF); - regp->control = (uint8_t) ((r>>24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; + case 0x14: + regp->primask = (uint8_t) (r & 0xFF); + regp->basepri = (uint8_t) ((r>>8) & 0xFF); + regp->faultmask = (uint8_t) ((r>>16) & 0xFF); + regp->control = (uint8_t) ((r>>24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; } return 0; @@ -765,17 +810,14 @@ int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) int ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; for (int i = 0; i < 32; i++) { ret = _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; } return 0; @@ -788,24 +830,35 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ /* These are held in the same register */ ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; val = (uint8_t) (val>>24); switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); - break; + case 0x1C: /* control */ + val = (((uint32_t) val) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) val) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) val) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) val); + break; } r_idx = 0x14; @@ -814,8 +867,7 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str write_uint32(sl->q_buf, val); ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; sl->q_buf[0] = (unsigned char) r_idx; sl->q_buf[1] = 0; @@ -834,15 +886,22 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_WRITEREG; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_WRITEREG; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; + } + cmd[i++] = idx; write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_WRITEREG\n"); return (int) size; } -sl->q_len = (int) size; + sl->q_len = (int) size; stlink_print_data(sl); return 0; @@ -878,8 +937,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]) -{ +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -887,112 +945,97 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST sl = calloc(1, sizeof (stlink_t)); slu = calloc(1, sizeof (struct stlink_libusb)); - if (sl == NULL) - goto on_malloc_error; - if (slu == NULL) - goto on_malloc_error; + + if (sl == NULL) goto on_malloc_error; + if (slu == NULL) goto on_malloc_error; ugly_init(verbose); sl->backend = &_stlink_usb_backend; sl->backend_data = slu; - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + sl->core_stat = TARGET_UNKNOWN; if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; } +#if LIBUSB_API_VERSION < 0x01000106 + libusb_set_debug(slu->libusb_ctx, ugly_libusb_log_level(verbose)); +#else + libusb_set_option(slu->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); +#endif + libusb_device **list; - /** @todo We should use ssize_t and use it as a counter if > 0. As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) */ + /* @TODO: We should use ssize_t and use it as a counter if > 0. + * As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) + */ int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; - int devBus =0; - int devAddr=0; - - /* @TODO: Reading a environment variable in a usb open function is not very nice, this - should be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink - serial string should be passed to this function. Probably people are using this but this is very odd because - as programmer can change to multiple busses and it is better to detect them based on serial. */ + int devBus = 0; + int devAddr = 0; + + /* @TODO: Reading a environment variable in a usb open function is not very nice, this should be refactored + * and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink serial string should + * be passed to this function. Probably people are using this but this is very odd because as programmer + * can change to multiple busses and it is better to detect them based on serial. + */ char *device = getenv("STLINK_DEVICE"); if (device) { char *c = strchr(device,':'); - if (c==NULL) { + if (c == NULL) { WLOG("STLINK_DEVICE must be : format\n"); goto on_error; } - devBus=atoi(device); - *c++=0; - devAddr=atoi(c); + devBus = atoi(device); + *c++ = 0; + devAddr = atoi(c); ILOG("bus %03d dev %03d\n",devBus, devAddr); } while (cnt--) { - libusb_get_device_descriptor( list[cnt], &desc ); - if (desc.idVendor != STLINK_USB_VID_ST) - continue; + struct libusb_device_handle *handle; + + libusb_get_device_descriptor(list[cnt], &desc); + if (desc.idVendor != STLINK_USB_VID_ST) continue; if (devBus && devAddr) { - if ((libusb_get_bus_number(list[cnt]) != devBus) - || (libusb_get_device_address(list[cnt]) != devAddr)) { + if ((libusb_get_bus_number(list[cnt]) != devBus) || (libusb_get_device_address(list[cnt]) != devAddr)) { continue; } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || - (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || - (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { - struct libusb_device_handle *handle; - - ret = libusb_open(list[cnt], &handle); - if (ret) - continue; + ret = libusb_open(list[cnt], &handle); + if (ret) continue; // could not open device + + sl->serial_size = libusb_get_string_descriptor_ascii( + handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); - sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, - (unsigned char *)sl->serial, sizeof(sl->serial)); - libusb_close(handle); + libusb_close(handle); - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) - || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) - || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + if (sl->serial_size < 0) continue; // could not read serial + + // if no serial provided, or if serial match device, fixup version and protocol + if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { + if (STLINK_V1_USB_PID(desc.idProduct)) { + slu->protocoll = 1; + sl->version.stlink_v = 1; + } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { sl->version.stlink_v = 2; - } else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { + } else if (STLINK_V3_USB_PID(desc.idProduct)) { sl->version.stlink_v = 3; } - - if ((serial == NULL) || (*serial == 0)) - break; - - if (sl->serial_size < 0) - continue; - - if (memcmp(serial, &sl->serial, sl->serial_size) == 0) - break; - - continue; - } - - if (desc.idProduct == STLINK_USB_PID_STLINK) { - slu->protocoll = 1; - sl->version.stlink_v = 1; break; } } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); + WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched":"any"); goto on_error; } else { ret = libusb_open(list[cnt], &slu->usb_handle); if (ret != 0) { - WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", - ret, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, strerror (errno), + sl->version.stlink_v, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); libusb_free_device_list(list, 1); goto on_error; } @@ -1032,6 +1075,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || + desc.idProduct == STLINK_USB_PID_STLINK_V2_1 || desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || @@ -1042,80 +1086,121 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } slu->sg_transfer_idx = 0; - // TODO - never used at the moment, always CMD_SIZE - slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; + slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE: STLINK_CMD_SIZE; + + // Initialize stlink version (sl->version) + stlink_version(sl); // Initialize stlink version (sl->version) stlink_version(sl); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - ILOG("-- exit_dfu_mode\n"); + // This seems to work, and is unnecessary information for the user. + // Demoted to debug -- REW + DLOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } - // set the speed before entering the mode - // as the chip discovery phase should be done at this speed too + sl->freq = freq; + // set the speed before entering the mode as the chip discovery phase + // should be done at this speed too // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + DLOG("JTAG/SWD freq set to %d\n", freq); + switch (freq) { + case 5: + stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); + break; + case 15: + stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); + break; + case 25: + stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); + break; + case 50: + stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); + break; + case 100: + stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); + break; + case 125: + stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); + break; + case 240: + stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); + break; + case 480: + stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); + break; + case 950: + stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); + break; + case 1200: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); + break; + case 0: case 1800: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + break; + case 4000: + stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); + break; + } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + if (reset == 2) { + stlink_jtag_reset(sl,0); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + stlink_force_debug(sl); + stlink_jtag_reset(sl,1); + usleep(10000); } - if (reset) { - if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + + if (reset == 1) { + if ( sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); } - ret = stlink_load_device_params(sl); + stlink_load_device_params(sl); + return sl; -on_libusb_error: - if (ret == -1) { + on_libusb_error: stlink_close(sl); return NULL; - } - - return sl; -on_error: - if (slu->libusb_ctx) - libusb_exit(slu->libusb_ctx); + on_error: + if (slu->libusb_ctx) libusb_exit(slu->libusb_ctx); -on_malloc_error: - if (sl != NULL) - free(sl); - if (slu != NULL) - free(slu); - - return NULL; + on_malloc_error: + if (sl != NULL) free(sl); + if (slu != NULL) free(slu); + return NULL; } static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { stlink_t **_sldevs; libusb_device *dev; int i = 0; - int ret = 0; size_t slcnt = 0; size_t slcur = 0; /* Count stlink */ while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - int r = libusb_get_device_descriptor(dev, &desc); - if (r < 0) { - WLOG("failed to get libusb device descriptor\n"); + int ret = libusb_get_device_descriptor(dev, &desc); + + if (ret < 0) { + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO && - desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER && - desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID && - desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID && - desc.idProduct != STLINK_USB_PID_STLINK_V3_2VCP_PID) + if (desc.idVendor != STLINK_USB_VID_ST) continue; + + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { + WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); continue; + } slcnt++; } @@ -1131,51 +1216,46 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { i = 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - ret = libusb_get_device_descriptor(dev, &desc); + int ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { - WLOG("failed to get libusb device descriptor\n"); + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) - continue; + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) continue; struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_MAX_SIZE]; - memset(serial, 0, sizeof(serial)); + char serial[STLINK_SERIAL_MAX_SIZE] = {0,}; ret = libusb_open(dev, &handle); + if (ret < 0) { - WLOG("failed to get libusb device descriptor\n"); + if (ret == LIBUSB_ERROR_ACCESS) { + ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct, ret); + } else { + ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); + } break; } - ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); - if (ret < 0) - *serial = 0; libusb_close(handle); - stlink_t *sl = NULL; - sl = stlink_open_usb(0, 1, serial); - if (!sl) - continue; + if (ret < 0) continue; - _sldevs[slcur] = sl; - slcur++; - } + stlink_t *sl = stlink_open_usb(0, 1, serial, 0); + if (!sl) { + ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); + continue; + } - /* Something went wrong */ - if (ret < 0) { - free(_sldevs); - *sldevs = NULL; - return 0; + _sldevs[slcur++] = sl; } *sldevs = _sldevs; - return slcnt; + + return slcur; } size_t stlink_probe_usb(stlink_t **stdevs[]) { @@ -1187,12 +1267,10 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { ssize_t cnt; r = libusb_init(NULL); - if (r < 0) - return 0; + if (r < 0) return 0; cnt = libusb_get_device_list(NULL, &devs); - if (cnt < 0) - return 0; + if (cnt < 0) return 0; slcnt = stlink_probe_usb_devs(devs, &sldevs); libusb_free_device_list(devs, 1); @@ -1200,15 +1278,13 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { libusb_exit(NULL); *stdevs = sldevs; + return slcnt; } void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { - if (stdevs == NULL || *stdevs == NULL || size == 0) - return; - - for (size_t n = 0; n < size; n++) - stlink_close((*stdevs)[n]); + if (stdevs == NULL || *stdevs == NULL || size == 0) return; + for (size_t n = 0; n < size; n++) stlink_close((*stdevs)[n]); free(*stdevs); *stdevs = NULL; } diff --git a/include/stlink/usb.h b/src/usb.h similarity index 56% rename from include/stlink/usb.h rename to src/usb.h index 4bf28c355..5c1f5b7ca 100644 --- a/include/stlink/usb.h +++ b/src/usb.h @@ -1,5 +1,5 @@ /* - * File: stlink/usb.h + * File: usb.h * Author: karl * * Created on October 1, 2011, 11:29 PM @@ -9,10 +9,10 @@ #define STLINK_USB_H #include -#include -#include "stlink.h" -#include "stlink/logging.h" +#include +#include "libusb_settings.h" +#include "logging.h" #ifdef __cplusplus extern "C" { @@ -23,11 +23,30 @@ extern "C" { #define STLINK_USB_PID_STLINK_32L 0x3748 #define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a #define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_PID_STLINK_V2_1 0x3752 #define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d #define STLINK_USB_PID_STLINK_V3E_PID 0x374e #define STLINK_USB_PID_STLINK_V3S_PID 0x374f #define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 +#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK ) + +#define STLINK_V2_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_32L || \ + (pid) == STLINK_USB_PID_STLINK_32L_AUDIO || \ + (pid) == STLINK_USB_PID_STLINK_NUCLEO) + +#define STLINK_V2_1_USB_PID(pid) ( (pid) == STLINK_USB_PID_STLINK_V2_1 ) + +#define STLINK_V3_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V3_USBLOADER || \ + (pid) == STLINK_USB_PID_STLINK_V3E_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3S_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID ) + +#define STLINK_SUPPORTED_USB_PID(pid) ( STLINK_V1_USB_PID(pid) || \ + STLINK_V2_USB_PID(pid) || \ + STLINK_V2_1_USB_PID(pid) || \ + STLINK_V3_USB_PID(pid)) + #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 @@ -49,7 +68,7 @@ extern "C" { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/src/win32/unistd.h b/src/win32/unistd.h index 4c94aed34..5b2798b41 100644 --- a/src/win32/unistd.h +++ b/src/win32/unistd.h @@ -1,9 +1,9 @@ #ifndef _UNISTD_H #define _UNISTD_H 1 -/* This file intended to serve as a drop-in replacement for - * unistd.h on Windows - * Please add functionality as neeeded +/* + * This file intended to serve as a drop-in replacement for unistd.h on Windows + * Please add functionality as neeeded. */ #include @@ -16,19 +16,18 @@ #if defined(_MSC_VER) #pragma warning(pop) #endif -#include /* getopt at: https://gist.github.com/ashelly/7776712 */ -#include /* for getpid() and the exec..() family */ -#include /* for _getcwd() and _chdir() */ +#include // getopt at: https://gist.github.com/ashelly/7776712 +#include // for getpid() and the exec..() family +#include // for _getcwd() and _chdir() #define srandom srand #define random rand -/* Values for the second argument to access. - These may be OR'd together. */ -#define R_OK 4 /* Test for read permission. */ -#define W_OK 2 /* Test for write permission. */ -//#define X_OK 1 /* execute permission - unsupported in windows*/ -#define F_OK 0 /* Test for existence. */ +/* Values for the second argument to access. These may be OR'd together. */ +#define R_OK 4 // Test for read permission +#define W_OK 2 // Test for write permission +// #define X_OK 1 // execute permission - unsupported in windows +#define F_OK 0 // Test for existence #define access _access #define dup2 _dup2 @@ -40,7 +39,9 @@ #define chdir _chdir #define isatty _isatty #define lseek _lseek -/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */ +/* read, write, and close are NOT being defined here, + * because while there are file handle specific versions for Windows, they probably don't work for sockets. + * You need to look at your app and consider whether to call e.g. closesocket(). */ #define ssize_t int @@ -49,7 +50,7 @@ #define STDERR_FILENO 2 /* should be in some equivalent to */ typedef __int8 int8_t; -typedef __int16 int16_t; +typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; @@ -61,4 +62,4 @@ typedef unsigned __int64 uint64_t; int usleep(unsigned int waitTime); #endif -#endif /* unistd.h */ +#endif /* unistd.h */ diff --git a/stlinkv1_macosx_driver/Makefile b/stlinkv1_macos_driver/Makefile similarity index 74% rename from stlinkv1_macosx_driver/Makefile rename to stlinkv1_macos_driver/Makefile index 9947ff672..e6ba6309b 100644 --- a/stlinkv1_macosx_driver/Makefile +++ b/stlinkv1_macos_driver/Makefile @@ -1,15 +1,17 @@ -# make ... for both stlink v1 and stlink v2 support -## +### +# Makefile for STlink-v1 support +### + VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c +SOURCES_LIB=common.c usb.c sg.c logging.c OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test_usb test_sg +TEST_PROGRAMS=test-flash test-sg test-usb LDFLAGS=-L. -lstlink -lusb-1.0 CFLAGS+=-g CFLAGS+=-DDEBUG=1 -CFLAGS+=-std=gnu99 +CFLAGS+=-std=gnu11 CFLAGS+=-Wall -Wextra @@ -20,8 +22,8 @@ all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) $(LIBRARY): $(OBJS_LIB) @echo "objs are $(OBJS_LIB)" $(AR) -cr $@ $^ - @echo "done making library" - + @echo "Compilation of library completed." + test_sg: test_sg.o $(LIBRARY) @echo "building test_sg" @@ -40,18 +42,17 @@ test_usb: test_usb.o $(LIBRARY) clean: rm -rf $(OBJS_LIB) rm -rf $(LIBRARY) - rm -rf test_usb* - rm -rf test_sg* + rm -rf test-flash* test-sg* test-usb* $(MAKE) -C flash clean $(MAKE) -C gdbserver clean - + flash: $(MAKE) -C flash gdbserver: $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" -osx_stlink_shield: - ./osx/install.sh +macos_stlink_shield: + ./install.sh .PHONY: clean all flash gdbserver diff --git a/stlinkv1_macos_driver/README.md b/stlinkv1_macos_driver/README.md new file mode 100644 index 000000000..e0f9256e8 --- /dev/null +++ b/stlinkv1_macos_driver/README.md @@ -0,0 +1,39 @@ +# Installation instructions for STLINK/v1 driver + +When connecting to the STLINK/v1 on macOS via USB, the system claims the programmer as a SCSI device. Thus libusb is not able to initialise and establish a connection to it. To solve this issue Marco Cassinerio (marco.cassinerio@gmail.com) has created a so called "codeless driver" which claims the device. It is of higher priority then the default apple mass storage driver, what allows the device to be accessed through libusb. + +To make use of this alternative approach one needs to go through the following steps: + +1) Configure System Integrity Protection (SIP) + +The above system security setting introduced by Apple with OS X El Capitan (10.11) in 2015 is active per default +and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). +Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, +until SIP is fully deactivated. Without SIP-deactivation, st-util would fail to detect a STLINK/v1 device later on. + +In order to deactivate SIP, boot into the recovery mode and run ```csrutil disable``` in a terminal console window. + +2) Reboot the system. + +3) Install the macOS Kernel Extension (kext) (ST-Link-v1 driver): + - Open a terminal console and navigate to this subdirectory `/stlinkv1_macos_driver` + - Use the command ```sudo sh ./install.sh``` to install the appropiate kext for your system version. + This should result in the following output: + +``` +Requesting load of /Library/Extensions/stlink_shield.kext. +/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). +``` +4) Reboot the system. + +5) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` +You should then see a similar output like in this example: + +``` +INFO common.c: Loading device parameters.... +INFO common.c: Device connected is: F1 High-density device, id 0x10036414 +INFO common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 2048 bytes +INFO sg.c: Successfully opened a stlink v1 debugger +INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. +INFO gdb-server.c: Listening at *:4242... +``` diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh new file mode 100644 index 000000000..19e9f141d --- /dev/null +++ b/stlinkv1_macos_driver/install.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +ISMACOS=$(sw_vers -productVersion) +case $ISMACOS in +10.13*) + KEXT="stlink_shield_10_13.kext" + ;; +10.14*) + KEXT="stlink_shield_10_14.kext" + ;; +10.15*) + KEXT="stlink_shield_10_15.kext" + ;; +*) + echo "OS X version not supported." + exit 1 + ;; +esac +chown -R root:wheel $KEXT/ +cp -R $KEXT /Library/Extensions/stlink_shield.kext +kextload -v /Library/Extensions/stlink_shield.kext +touch /Library/Extensions diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist new file mode 100644 index 000000000..fc759b362 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.13 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 new file mode 100644 index 000000000..161c0a829 Binary files /dev/null and b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 differ diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo new file mode 100644 index 000000000..bdab95bcc --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo @@ -0,0 +1 @@ +KEXT???? \ No newline at end of file diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..d5d0fd744 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources @@ -0,0 +1,115 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist new file mode 100644 index 000000000..d43deca2b --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.14 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 new file mode 100644 index 000000000..a49757ef1 Binary files /dev/null and b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 differ diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo new file mode 100644 index 000000000..bdab95bcc --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo @@ -0,0 +1 @@ +KEXT???? \ No newline at end of file diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..d5d0fd744 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources @@ -0,0 +1,115 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist new file mode 100644 index 000000000..a2a5f8ac2 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.15 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 new file mode 100644 index 000000000..4e64961ae Binary files /dev/null and b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 differ diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/PkgInfo b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/PkgInfo new file mode 100644 index 000000000..bdab95bcc --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/PkgInfo @@ -0,0 +1 @@ +KEXT???? \ No newline at end of file diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/_CodeSignature/CodeResources b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..d5d0fd744 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/_CodeSignature/CodeResources @@ -0,0 +1,115 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist b/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist new file mode 100644 index 000000000..b0a0228d8 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleVersion + 1.0.0 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj new file mode 100644 index 000000000..23dc192d8 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj @@ -0,0 +1,613 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXFileReference section */ + 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_13.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_14.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* NanosMouse */ = { + isa = PBXGroup; + children = ( + 089C167CFE841241C02AAC07 /* Resources */, + 19C28FB6FE9D52B211CA2CBB /* Products */, + ); + name = NanosMouse; + sourceTree = ""; + usesTabs = 0; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8CD33C31149BB80D0033D618 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 19C28FB6FE9D52B211CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */, + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */, + 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8F9084E924786F0B009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F524786F0F009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850124786F39009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8F9084E724786F0B009109AD /* stlink_shield_10_13 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F9084EE24786F0B009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_13" */; + buildPhases = ( + 8F9084E824786F0B009109AD /* ShellScript */, + 8F9084E924786F0B009109AD /* Headers */, + 8F9084EA24786F0B009109AD /* Resources */, + 8F9084EC24786F0B009109AD /* Sources */, + 8F9084ED24786F0B009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_13; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */; + buildPhases = ( + 8F9084F424786F0F009109AD /* ShellScript */, + 8F9084F524786F0F009109AD /* Headers */, + 8F9084F624786F0F009109AD /* Resources */, + 8F9084F824786F0F009109AD /* Sources */, + 8F9084F924786F0F009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_14; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; + buildPhases = ( + 8F90850024786F39009109AD /* ShellScript */, + 8F90850124786F39009109AD /* Headers */, + 8F90850224786F39009109AD /* Resources */, + 8F90850424786F39009109AD /* Sources */, + 8F90850524786F39009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_15; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F90850924786F39009109AD /* stlink_shield_10_15.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = "stlink-org"; + }; + buildConfigurationList = 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 089C166AFE841209C02AAC07 /* NanosMouse */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8F9084E724786F0B009109AD /* stlink_shield_10_13 */, + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */, + 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8F9084EA24786F0B009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F624786F0F009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850224786F39009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8F9084E824786F0B009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi\n"; + }; + 8F9084ED24786F0B009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi\n"; + }; + 8F9084F424786F0F009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F9084F924786F0F009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F90850024786F39009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F90850524786F39009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8F9084EC24786F0B009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F824786F0F009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850424786F39009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3EEA308808D71E4B002CBB49 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; + APPLY_RULES_IN_COPY_FILES = YES; + APPLY_RULES_IN_COPY_HEADERS = YES; + CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_GCD_PERFORMANCE = YES; + CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_STATIC_ANALYZER_MODE = deep; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CXX0X_EXTENSIONS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_FLOAT_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; + CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_INTERFACE_IVARS = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + COPY_HEADERS_RUN_UNIFDEF = YES; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DONT_GENERATE_INFOPLIST_FILE = NO; + DRIVERKIT_DEPLOYMENT_TARGET = 19.0; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; + GCC_ENABLE_KERNEL_DEVELOPMENT = YES; + GCC_ENABLE_TRIGRAPHS = YES; + GCC_FAST_MATH = YES; + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_SHORT_ENUMS = YES; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + GENERATE_PKGINFO_FILE = YES; + GENERATE_PROFILING_CODE = YES; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INFOPLIST_OUTPUT_FORMAT = XML; + INFOPLIST_PREPROCESS = YES; + INLINE_PRIVATE_FRAMEWORKS = YES; + KEEP_PRIVATE_EXTERNS = YES; + LD_GENERATE_MAP_FILE = YES; + LINKER_DISPLAYS_MANGLED_NAMES = YES; + MODULE_NAME = com.libusb.stlink_shield; + MODULE_VERSION = 1.0; + PLIST_FILE_OUTPUT_FORMAT = XML; + PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; + RUN_CLANG_STATIC_ANALYZER = YES; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SEPARATE_SYMBOL_EDIT = YES; + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = Pedantic; + VALIDATE_PRODUCT = YES; + VALIDATE_WORKSPACE = YES; + VERSIONING_SYSTEM = "apple-generic"; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + 3EEA308908D71E4B002CBB49 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; + APPLY_RULES_IN_COPY_FILES = YES; + APPLY_RULES_IN_COPY_HEADERS = YES; + CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_GCD_PERFORMANCE = YES; + CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_STATIC_ANALYZER_MODE = deep; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CXX0X_EXTENSIONS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_FLOAT_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; + CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_INTERFACE_IVARS = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + COPY_HEADERS_RUN_UNIFDEF = YES; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DONT_GENERATE_INFOPLIST_FILE = NO; + DRIVERKIT_DEPLOYMENT_TARGET = 19.0; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; + GCC_ENABLE_KERNEL_DEVELOPMENT = YES; + GCC_ENABLE_TRIGRAPHS = YES; + GCC_FAST_MATH = YES; + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_SHORT_ENUMS = YES; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + GENERATE_PKGINFO_FILE = YES; + GENERATE_PROFILING_CODE = YES; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INFOPLIST_OUTPUT_FORMAT = XML; + INFOPLIST_PREPROCESS = YES; + INLINE_PRIVATE_FRAMEWORKS = YES; + KEEP_PRIVATE_EXTERNS = YES; + LD_GENERATE_MAP_FILE = YES; + LINKER_DISPLAYS_MANGLED_NAMES = YES; + MODULE_NAME = com.libusb.stlink_shield; + MODULE_VERSION = 1.0; + PLIST_FILE_OUTPUT_FORMAT = XML; + PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; + RUN_CLANG_STATIC_ANALYZER = YES; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SEPARATE_SYMBOL_EDIT = YES; + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = Pedantic; + VALIDATE_PRODUCT = YES; + VALIDATE_WORKSPACE = YES; + VERSIONING_SYSTEM = "apple-generic"; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; + 8F9084EF24786F0B009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F9084F024786F0B009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 8F9084FB24786F0F009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F9084FC24786F0F009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 8F90850724786F39009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F90850824786F39009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3EEA308808D71E4B002CBB49 /* Debug */, + 3EEA308908D71E4B002CBB49 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F9084EE24786F0B009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_13" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F9084EF24786F0B009109AD /* Debug */, + 8F9084F024786F0B009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F9084FB24786F0F009109AD /* Debug */, + 8F9084FC24786F0F009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F90850724786F39009109AD /* Debug */, + 8F90850824786F39009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000..b06818d2f Binary files /dev/null and b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..e097e4fe6 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,22 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildIntermediatesPath + Build/Intermediates.noindex + CustomBuildLocationType + RelativeToDerivedData + CustomBuildProductsPath + Build/Products + DerivedDataLocationStyle + Default + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + SharedBuildFolderName + Build + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme new file mode 100644 index 000000000..d98dd9b97 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme new file mode 100644 index 000000000..79299d7a5 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme new file mode 100644 index 000000000..e72a90366 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 000000000..d23112ec9 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,67 @@ + + + + + SchemeUserState + + stlink_shield 10.7.xcscheme_^#shared#^_ + + orderHint + 2 + + stlink_shield copy copy.xcscheme_^#shared#^_ + + orderHint + 3 + + stlink_shield copy.xcscheme_^#shared#^_ + + orderHint + 2 + + stlink_shield.xcscheme_^#shared#^_ + + orderHint + 1 + + stlink_shield_10.13.xcscheme_^#shared#^_ + + orderHint + 0 + + stlink_shield_10.14 copy.xcscheme_^#shared#^_ + + orderHint + 4 + + stlink_shield_10.14.xcscheme_^#shared#^_ + + orderHint + 1 + + stlink_shield_10.15.xcscheme_^#shared#^_ + + orderHint + 2 + + + SuppressBuildableAutocreation + + 8F9084E724786F0B009109AD + + primary + + + 8F9084F324786F0F009109AD + + primary + + + 8F9084FF24786F39009109AD + + primary + + + + + diff --git a/stlinkv1_macosx_driver/README.md b/stlinkv1_macosx_driver/README.md deleted file mode 100644 index b2a68442c..000000000 --- a/stlinkv1_macosx_driver/README.md +++ /dev/null @@ -1,47 +0,0 @@ -from: marco.cassinerio@gmail.com - -to: texane@gmail.com - -Hi, - -i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can add it in your package. -The problem is that os x claims the device as scsi and libusb won't be able to connect to it. -I've created what is called a codeless driver which claims the device and has a higher priority then the default apple mass storage driver, so the device can be accessed through libusb. - -I tested this codeless driver under OS X 10.6.8 and 10.7.2. -I assume it works with any 10.6.x and 10.7.x version as well. - -Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which invoke the `install.sh`. - -First, unpack the `osx.tar.gz` contents: -```bash -tar xzvf osx.tar.gz -``` - -Then, install the driver using: -```bash -sudo make osx_stlink_shield -``` - -no reboot required. - -P.S. If error `OS X version not supported` occurs. For the latest versions of Mac OS X you may need to change the `osx/install.sh` as follows: -```bash -< ISOSXLION=$(sw_vers -productVersion) ---- -> ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') -``` - -### OS X 10.10 Yosemite - -For OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions - -```bash -sudo nvram boot-args="kext-dev-mode=1" -``` - -reboot the system! - -### OS X 10.11 El Capitan - -For OS X 10.11 El Capitan: the Yosemite kext seems to work (tested on 10.11.04). diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz deleted file mode 100644 index 57bc31466..000000000 Binary files a/stlinkv1_macosx_driver/osx.tar.gz and /dev/null differ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8df28ce7e..6e60fdd5a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,15 +1,16 @@ -set(TESTS - usb - sg -) +### +# Build test executables +### -foreach(test ${TESTS}) - add_executable(${test} ${test}.c) - add_dependencies(${test} ${STLINK_LIB_STATIC}) - target_link_libraries(${test} ${STLINK_LIB_STATIC}) - add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) -endforeach() +set(TESTEXEC usb sg) -add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") -target_link_libraries(flash ${STLINK_LIB_STATIC}) -add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash) +foreach (test ${TESTEXEC}) + add_executable(test-${test} ${test}.c) + add_dependencies(test-${test} ${STLINK_LIB_SHARED}) + target_link_libraries(test-${test} ${STLINK_LIB_SHARED} ${SSP_LIB}) + add_test(test-${test} ${CMAKE_BINARY_DIR}/bin/test-${test}) +endforeach () + +add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") +target_link_libraries(test-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) +add_test(test-flash ${CMAKE_BINARY_DIR}/bin/test-flash) diff --git a/tests/flash.c b/tests/flash.c index 6c8b8ed9b..d47b3564d 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -3,9 +3,10 @@ #include #include -#include +#include + #if defined(_MSC_VER) -#include + #include #endif struct Test { @@ -15,50 +16,57 @@ struct Test { }; static bool cmp_strings(const char * s1, const char * s2) { - if(s1 == NULL || s2 == NULL) return (s1 == s2); - else return (0 == strcmp(s1, s2)); + if (s1 == NULL || s2 == NULL) { + return (s1 == s2); + } else { + return (0 == strcmp(s1, s2)); + } } static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { - if(s1 == NULL || s2 == NULL) return (s1 == s2); - else return (0 == memcmp(s1, s2, size)); + if (s1 == NULL || s2 == NULL) { + return (s1 == s2); + } else { + return (0 == memcmp(s1, s2, size)); + } } static bool execute_test(const struct Test * test) { int ac = 0; char* av[32]; - // parse (tokenize) the test command line -#if defined(_MSC_VER) - char *cmd_line = alloca(strlen(test->cmd_line)); -#else - char cmd_line[strlen(test->cmd_line)]; -#endif - strcpy(cmd_line, test->cmd_line); + /* parse (tokenize) the test command line */ + #if defined(_MSC_VER) + char *cmd_line = alloca(strlen(test->cmd_line) + 1); + #else + char cmd_line[strlen(test->cmd_line) + 1]; + #endif - for(char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { - if((size_t)ac >= sizeof(av)/sizeof(av[0])) return false; + strcpy(cmd_line, test->cmd_line); + for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { + if ((size_t)ac >= sizeof(av)/sizeof(av[0])) + return false; av[ac] = tok; ++ac; } - // call + /* call */ struct flash_opts opts; int res = flash_get_opts(&opts, ac, av); - // compare results + /* compare results */ bool ret = (res == test->res); - if(ret && (res == 0)) { + if (ret && (res == 0)) { ret &= (opts.cmd == test->opts.cmd); - ret &= cmp_strings(opts.devname, test->opts.devname); ret &= cmp_mem(opts.serial, test->opts.serial, sizeof(opts.serial)); ret &= cmp_strings(opts.filename, test->opts.filename); ret &= (opts.addr == test->opts.addr); ret &= (opts.size == test->opts.size); ret &= (opts.reset == test->opts.reset); ret &= (opts.log_level == test->opts.log_level); + ret &= (opts.freq == test->opts.freq); ret &= (opts.format == test->opts.format); } @@ -68,46 +76,171 @@ static bool execute_test(const struct Test * test) { static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, - { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER }, - { "/dev/sg0 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = { 0 }, .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = NULL, .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0x1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 15K --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 15, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=6k --reset write test.bin 0x80000000", -1, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 6, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --reset read test.bin 0x80000000 1000", 0, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --reset read test.bin 0x80000000 1k", 0, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1024, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --reset read test.bin 0x80000000 1M", 0, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1048576, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, { "erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = { 0 }, .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .serial = { 0 }, + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset --format=ihex write test.hex", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.hex", - .addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } }, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.hex", + .addr = 0, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_IHEX } + }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, + { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .serial = "\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, { "--serial=A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .serial = "\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, }; -int main() -{ +int main() { bool allOk = true; - for(size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { - if(!execute_test(&tests[i])) allOk = false; + for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { + if (!execute_test(&tests[i])) + allOk = false; } - return (allOk ? 0 : 1); } - diff --git a/tests/sg.c b/tests/sg.c index a014717d7..1af177174 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -1,16 +1,17 @@ -/* +/* * File: test_main.c - * + * * main() ripped out of old stlink-hw.c */ #include #include #include + #include #if defined(_MSC_VER) -#define __attribute__(x) + #define __attribute__(x) #endif static void __attribute__((unused)) mark_buf(stlink_t *sl) { @@ -24,24 +25,22 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { sl->q_buf[16] = 0x33; sl->q_buf[63] = 0x44; sl->q_buf[64] = 0x69; - sl->q_buf[1024 * 6 - 1] = 0x42; //6kB - sl->q_buf[1024 * 8 - 1] = 0x42; //8kB + sl->q_buf[1024 * 6 - 1] = 0x42; // 6kB + sl->q_buf[1024 * 8 - 1] = 0x42; // 8kB } -int main(void) -{ +int main(void) { /* Avoid unused parameter warning */ // set scpi lib debug level: 0 for no debug info, 10 for lots - - fputs( - "\nUsage: stlink-access-test [anything at all] ...\n" - "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** Because we just use libusb, we can just tell the kernel's\n" - "*** driver to simply ignore the device...\n" - "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", - stderr); + fputs( + "\nUsage: stlink-access-test [anything at all] ...\n" + "\n*** Notice: The stlink firmware violates the USB standard.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" + "*** Unplug the stlink and execute once as root:\n" + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", + stderr); stlink_t *sl = stlink_v1_open(99, 1); if (sl == NULL) @@ -51,8 +50,6 @@ int main(void) stlink_enter_swd_mode(sl); stlink_current_mode(sl); stlink_core_id(sl); - //---------------------------------------------------------------------- - stlink_status(sl); //stlink_force_debug(sl); stlink_reset(sl); @@ -67,19 +64,19 @@ int main(void) #if 0 stlink_read_mem32(sl, 0xe000edf0, 4); DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); - stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif + #if 0 - // happy new year 2011: let blink all the leds + // let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" -#define GPIOC 0x40011000 // port C -#define GPIOC_CRH (GPIOC + 0x04) // port configuration register high -#define GPIOC_ODR (GPIOC + 0x0c) // port output data register -#define LED_BLUE (1<<8) // pin 8 -#define LED_GREEN (1<<9) // pin 9 + #define GPIOC 0x40011000 // port C + #define GPIOC_CRH (GPIOC + 0x04) // port configuration register high + #define GPIOC_ODR (GPIOC + 0x0c) // port output data register + #define LED_BLUE (1<<8) // pin 8 + #define LED_GREEN (1<<9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); DLOG("GPIOC_CRH = 0x%08x\n", io_conf); @@ -92,8 +89,8 @@ int main(void) for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); - /* stlink_read_mem32(sl, 0x4001100c, 4); */ - /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ + //stlink_read_mem32(sl, 0x4001100c, 4); + //DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); usleep(100 * 1000); memset(sl->q_buf, 0, sizeof(sl->q_buf)); @@ -101,8 +98,8 @@ int main(void) usleep(100 * 1000); } write_uint32(sl->q_buf, io_conf); // set old state - #endif + #if 0 // TODO rtfm: stlink doesn't have flash write routines // writing to the flash area confuses the fw for the next read access @@ -119,18 +116,19 @@ int main(void) stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif + #if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); //stlink_write_mem8(sl, 0x20000000, 16); - //stlink_write_mem8(sl, 0x20000000, 1); //stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif + #if 0 // a not aligned mem32 access doesn't work indeed fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); @@ -149,6 +147,7 @@ int main(void) stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif + #if 0 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); @@ -162,26 +161,30 @@ int main(void) stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif + #if 0 stlink_run(sl); stlink_status(sl); - stlink_force_debug(sl); stlink_status(sl); #endif + #if 0 /* read the system bootloader */ fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif + #if 0 /* read the flash memory */ fputs("\n+++++++ read flash memory\n\n", stderr); /* mark_buf(sl); */ stlink_read_mem32(sl, 0x08000000, 4); #endif + #if 0 /* flash programming */ fputs("\n+++++++ program flash memory\n\n", stderr); stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif + #if 0 /* check file contents */ fputs("\n+++++++ check flash memory\n\n", stderr); { @@ -189,6 +192,7 @@ int main(void) printf("_____ stlink_fcheck_flash() == %d\n", res); } #endif + #if 0 fputs("\n+++++++ sram write and execute\n\n", stderr); stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); @@ -198,13 +202,13 @@ int main(void) #if 0 stlink_run(sl); stlink_status(sl); - //---------------------------------------------------------------------- // back to mass mode, just in case ... stlink_exit_debug_mode(sl); stlink_current_mode(sl); stlink_close(sl); #endif - //fflush(stderr); fflush(stdout); + //fflush(stderr); + //fflush(stdout); return EXIT_SUCCESS; } diff --git a/tests/usb.c b/tests/usb.c index 06fd73429..ce72e24a5 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,15 +1,32 @@ #include + #include +#include -int main(int ac, char** av) +static void usage(void) { - (void)ac; - (void)av; + puts("test-usb --reset"); + puts("test-usb --no-reset"); +} + +int main(int ac, char** av) { stlink_t* sl; struct stlink_reg regs; + int reset = 0; - sl = stlink_open_usb(10, 1, NULL); + if (ac == 2) { + if (strcmp(av[1], "--reset") == 0) + reset = 2; + if (strcmp(av[1], "--no-reset") == 0) + reset = 1; + } + if (reset == 0) { + usage(); + return 0; + } + + sl = stlink_open_usb(10, reset, NULL, 0); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); @@ -30,9 +47,12 @@ int main(int ac, char** av) printf("-- core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + if (stlink_cpu_id(sl, &cpuid)) { + printf("Failed reading stlink_cpu_id\n"); + } else { + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + } printf("-- read_sram\n"); static const uint32_t sram_base = STM32_SRAM_BASE; @@ -43,12 +63,12 @@ int main(int ac, char** av) printf("FP_CTRL\n"); stlink_read_mem32(sl, STLINK_REG_CM3_FP_CTRL, 4); - // no idea what reg this is.. */ - // stlink_read_mem32(sl, 0xe000ed90, 4); + // no idea what reg this is... + //stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... - // stlink_read_mem32(sl, 0xe000edf0, 4); + //stlink_read_mem32(sl, 0xe000edf0, 4); // offset 0xC into TIM11 register? TIMx_DIER? - // stlink_read_mem32(sl, 0x4001100c, 4); */ + //stlink_read_mem32(sl, 0x4001100c, 4); /* Test 32 bit Write */ write_uint32(sl->q_buf,0x01234567); @@ -72,14 +92,13 @@ int main(int ac, char** av) printf("-- reset\n"); stlink_reset(sl); stlink_force_debug(sl); - /* Test reg write*/ + /* Test reg write */ stlink_write_reg(sl, 0x01234567, 3); stlink_write_reg(sl, 0x89abcdef, 4); stlink_write_reg(sl, 0x12345678, 15); for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); - stlink_read_all_regs(sl, ®s); printf("-- status\n"); @@ -96,6 +115,5 @@ int main(int ac, char** av) stlink_close(sl); } - return 0; }