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.md b/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 000000000..2d565a3f7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -0,0 +1,38 @@
+---
+name: Bug Report
+about: Create a report to help us improve
+title: "[Your device name]: [Title]"
+labels: bug/needs-investigation
+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
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
similarity index 89%
rename from .github/ISSUE_TEMPLATE/feature_request.md
rename to .github/ISSUE_TEMPLATE/feature-request.md
index bf626eb97..2aa7a5c7f 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -1,4 +1,11 @@
-# Feature Request
+---
+name: Feature Request
+about: Suggest an idea for this project
+title: "[feature] "
+labels: code/feature-request
+assignees: ''
+
+---
Thank you for giving feedback to the stlink project.
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..23e7ddc07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
build
+build-mingw
obj-*
*.user*
diff --git a/.travis.sh b/.travis.sh
index 05568d37d..5291ec95b 100755
--- a/.travis.sh
+++ b/.travis.sh
@@ -5,15 +5,42 @@ ls -1 /usr/bin/clang*
ls -1 /usr/bin/scan-build*
echo "----"
+echo "WORK DIR:$DIR"
+DIR=$PWD
+
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")
+
+ 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 && make package && cd -
+
+ echo "--> Building Release..."
+ 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 && make package && cd -
+
+# echo "--> Building Binary..."
+# mkdir -p build/Binary && cd build/Binary
+# cho "-DCMAKE_BUILD_TYPE=Binary -DCMAKE_INSTALL_PREFIX=$PWD/_install"
+# cmake -DCMAKE_BUILD_TYPE=Binary -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../
+# make && make package && cd -
+else [ "$TRAVIS_OS_NAME" == "osx" ];
brew install libusb
-fi
-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 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 && 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 -
+ echo "--> Building Release..."
+ 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 && make package && cd -
+fi
diff --git a/.travis.yml b/.travis.yml
index b0f985012..b7ff93ff9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,106 @@
-
-compiler:
- - gcc
- - clang
-
language: c
-os:
- - linux
- - osx
+matrix:
+ include:
+ ### 64-bit builds ###
+ - os: linux
+ arch: x64
+ compiler: gcc-5
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x64
+ compiler: gcc-7
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x64
+ compiler: gcc-9
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x64
+ 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']
+ - os: linux
+ arch: x64
+ 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']
+# - os: linux
+# arch: x64
+# 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']
+# env: CFLAGS=-m32 LDFLAGS=-m32
+
+ ### 32-bit builds ###
+ - os: linux
+ arch: x86
+ compiler: gcc-5
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x86
+ compiler: gcc-7
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x86
+ compiler: gcc-9
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev']
+ - os: linux
+ arch: x86
+ 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']
+ - os: linux
+ arch: x86
+ 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']
-addons:
- apt:
- sources:
- - sourceline: 'ppa:ubuntu-toolchain-r/test'
- packages:
- - clang
- - g++-6
- - gcc-6
- - libusb-1.0.0-dev
+ ### macOS ###
+ - os: osx
+ compiler: gcc
+ addons:
+ homebrew:
+ packages:
+ - gcc
+ - libusb
+ - gtk+3
+ - os: osx
+ compiler: clang
+ addons:
+ homebrew:
+ packages:
+ - clang
+ - libusb
+ - gtk+3
script:
- git fetch --tags
diff --git a/.version b/.version
index dc1e644a1..ce6a70b9d 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-1.6.0
+1.6.0
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba4c46d08..9ad6b6497 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,71 @@
-Stlink ChangeLog
+stlink ChangeLog
================
+v1.6.1
+======
+
+Release date: (TBD)
+
+This release drops support for some older operating systems. Check project README for details.
+
+Features:
+
+- Support for STM32L1, SM32L4 option bytes write (#596, #844, #847)
+- CMake now creates an uninstall target (#619, #907)
+- Added CMAKEFLAGS and install target (#804, #935)
+- Support for STM32G4 (#822)
+- Add aliased SRAM2 region in the L496 memory map (#824)
+- Improved support for STM32G0 (#825, #850, #856, #857)
+- Added postinst script with 'depmod -a' for 'make package' (#845, #931)
+- Calculate checksums for flash operations (#862, #924)
+- Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards (#900)
+- STM32G0/G4 improvements (#910)
+ - Enable mass erase with a flash programming check
+ - Handle G4 Cat3 devices with configurable dual bank flash by using a helper
+- Display programmer serial when no target is connected (#432, #933, #943)
+
+Updates & changes:
+
+- Improved argument parsing for CLI tools (#378, #922)
+- [doc] Updated tutorial: macOS ST-Link-v1 detection (#574, #587)
+- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895)
+- [doc] Verify correct udev configuration for device access (#764)
+- Added more error info to WLOGs during probe (#883)
+- Added check for libssp during compilation (#885)
+- Silence unnecessary messages (#886)
+- Set up a libusb log level accordingly to verbosity (commit 49f887d5247fdd28f163b6317790c4f087e652cc)
+- [doc] Define libusb & cmake version compatibility (#896, #897, #899, commit 27aa88821197d3ffe82baff4e971c3488ec39899)
+- Update for STM32G471/473/474/483/484 devices (#901)
+- [doc] st-flash --flash=n[k][m] command line option to override device model (#902)
+- [doc] Update compiling instructions (#113, commit 10ae5294cd03aacfc07312010f026d3cb12ea56c)
+- [doc] Defined version compatibility and installation instructions for macOS (commit 23c071edea45f6e8852fef52d884a680973d6d8f)
+- Deprecated old appveyor-mingw script (commit 97484422008df0f75c978627054776f35842a075)
+- Enhanced error log with file path for map_file() (#650, #879, #921)
+- Refactoring: Overall option code rework (#927)
+- Refactoring: Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929)
+- Reconfiguration of package build process (#931, #936, #940, commit 9b19f9225460472af9d98959b7217d0a840ee972)
+
+Fixes:
+
+- Fixed wait-loop for flash_loader_run() (#290)
+- Clear the PG bit before setting the PER bit (#579, #876)
+- Fixed compilation issues with int length on 32-bit platforms (#629, #908)
+- Fixed st-info --probe mechanism (#679, #918)
+- Fixed sign-compare (size != rep_len) in usb.c (Regression) (#772, #869, #872, #891)
+- Avoid re-define of O_BINARY on Windows (#788)
+- Fixed st-flash manpage read example (#858)
+- Fixed stlink support with no mass storage (#861)
+- Make Version.cmake more error-resistant (#872)
+- Error return in failed probe (#887, #890)
+- Fixed formatting for options display in st-flash & st-info (commits c783d0e777ccc83a7a8be26a4f4d3414e0478560 and 562cd2496e696dbd22950925866aac662d81ee5f)
+- Fixed dead loop after an unexpected unplug (#780, #812, #913)
+- Fixed broken build on 32-bit systems (#919, #920)
+- st-flash: minor usage fix and make cmdline parsing more user friendly (#925)
+- Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922)
+- Restored functionality of make test builds (Regression) (#926, #929)
+- Fixed compilation error due to uninitialized cpuid (#937, #938)
+
+
v1.6.0
======
@@ -8,50 +73,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))
-* 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 ([#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))
+* Working 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:
-* 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 ([#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) ([#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
======
@@ -59,29 +127,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
======
@@ -90,16 +162,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
======
@@ -108,21 +186,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
======
@@ -131,16 +216,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
======
@@ -149,36 +237,49 @@ Release date: 2017-01-28
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](/~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` ([#459](/~https://github.com/texane/stlink/pull/541))
-* 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:
-* 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 (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)
+* 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
======
@@ -191,15 +292,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)
@@ -209,18 +307,23 @@ 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)
+* 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 b0eef1189..fd79ac10e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,225 +1,287 @@
-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)
+
+
+###
+# 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(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools")
+include(GNUInstallDirs) # Define GNU standard installation directories
+
+set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory")
+set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory")
set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib")
-if( IS_DIRECTORY ${LIB_INSTALL_DIR})
+option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON)
+option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON)
+option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF)
+
+# 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(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+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()
+else ()
set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory")
- set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" )
-endif()
+ set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}")
+endif ()
-if( IS_DIRECTORY ${INCLUDE_INSTALL_DIR})
+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)
+
+if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
+ find_package(PkgConfig)
+ pkg_check_modules(GTK3 gtk+-3.0)
endif ()
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 ()
+
+include(CheckLibraryExists)
+
+CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists)
+if (_stack_chk_fail_exists)
+ set(SSP_LIB ssp)
+else ()
+ set(SSP_LIB "")
+endif ()
if (CMAKE_BUILD_TYPE STREQUAL "")
- set(CMAKE_BUILD_TYPE "Debug")
-endif()
+ set(CMAKE_BUILD_TYPE "Debug")
+endif ()
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
- include(CTest)
-endif()
+ include(CTest)
+endif ()
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/usb.h
+ include/stlink/sg.h
+ include/stlink/logging.h
+ include/stlink/mmap.h
+ include/stlink/chipid.h
+ include/stlink/flash_loader.h
+ )
set(STLINK_SOURCE
- src/chipid.c
- src/common.c
- src/usb.c
- src/sg.c
- src/logging.c
- src/flash_loader.c
-)
+ src/chipid.c
+ src/common.c
+ src/usb.c
+ src/sg.c
+ src/logging.c
+ src/flash_loader.c
+ src/md5.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")
+if (WIN32 OR MINGW OR MSYS)
+ set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c")
+ set(STLINK_HEADERS "${STLINK_HEADERS};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 ()
+
###
# 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})
-
-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()
-
-set_target_properties(${STLINK_LIB_SHARED}
- PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}
- VERSION ${STLINK_SHARED_VERSION}
-)
-
-# Link shared library with apple OS libraries
+ set(STLINK_LIB_SHARED ${PROJECT_NAME})
+else (WIN32)
+ 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(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 macOS 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()
+ find_library(ObjC objc)
+ find_library(CoreFoundation CoreFoundation)
+ find_library(IOKit IOKit)
+ target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB})
+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()
+if (WIN32 OR MINGW OR MSYS)
+ target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB})
+else ()
+ target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB})
+endif ()
+install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check 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}
-)
+add_library(
+ ${STLINK_LIB_STATIC} STATIC
+ ${STLINK_HEADERS} # header files for ide projects generated by cmake
+ ${STLINK_SOURCE}
+ )
-# Link shared library with apple OS libraries
+# Link static library with Apple macOS 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()
-
-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()
+ find_library(ObjC objc)
+ find_library(CoreFoundation CoreFoundation)
+ find_library(IOKit IOKit)
+ target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB})
+endif ()
+
+if (WIN32 OR MINGW OR MSYS) ### TODO: MinGW OR MSYS on Linux
+ target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB})
+else ()
+ target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB})
+endif ()
set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
if (STLINK_STATIC_LIB)
- install(TARGETS ${STLINK_LIB_STATIC}
- ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}
- )
-endif()
+ install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check path
+endif ()
+
###
# Tools
###
-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()
+add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c)
add_executable(st-info src/tools/info.c)
+
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})
+else ()
+ target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB})
+ target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB})
+endif ()
-install(TARGETS st-flash st-info
- RUNTIME DESTINATION bin
-)
+install(TARGETS st-flash st-info RUNTIME DESTINATION bin) ### TODO: Check path
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()
+ 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)
+add_subdirectory(src/stlink-gui)
+
###
# Others
###
-add_subdirectory(usr/lib/pkgconfig)
-add_subdirectory(include)
+
+add_subdirectory(include) ### TODO: Check path
add_subdirectory(doc/man)
add_subdirectory(tests)
-include(cmake/CPackConfig.cmake)
-include(CPack)
+# ====
+
+
+###
+# Package build
+###
+
+add_subdirectory(cmake/packaging)
+include(cmake/packaging/cpack_config.cmake)
+
+
+###
+# 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/LICENSE.md b/LICENSE.md
index 3d464ca1e..9c3b59f0f 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, The stlink project (github.com/stlink-org/stlink) & "Capt'ns Missing Link" authors.
+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..444f1920b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,49 +1,57 @@
##
-# This Makefile is used to drive building of Debug and Release
-# targets of CMake
+# This Makefile is used to drive building of Debug and Release targets of CMake
##
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 " 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
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
+ @$(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) -Wno-dev ../../
clean:
- @echo "[CLEAN]"
- @rm -Rf build
+ @echo "[CLEAN]"
+ @rm -Rf build
.PHONY: clean
diff --git a/README.md b/README.md
index 594e0fae9..735712329 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,81 @@
-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)
+[![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0.svg)](/~https://github.com/stlink-org/stlink/releases/develop)
+[![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total.svg)](/~https://github.com/stlink-org/stlink/releases)
+[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink)
+[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?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)**.
+The source files **stm32l0x.s** and **stm32lx.s** found in the subdirectory `/flashloaders/`
+are licensed under the **General Public License (GPL v2+)**.
-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
-* **STLINKv1:**
+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:
+
+* **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
+Currently known working combinations of programmers and targets are listed in [devices_boards.md](doc/devices_boards.md).
-## Supported hardware combinations
+Supported operating systems are listed in [version_support.md](doc/version_support.md).
-Currently known working combinations of programmers and targets are listed in [doc/tested-boards.md](doc/tested-boards.md).
+
+## Tutorial & HOWTO
+
+Our [tutorial.md](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**:
+
+Please compile and install from source as described in our [compiling manual](doc/compiling.md#Windows).
+
+Long awaited binaries will be available soon...
-**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**:
@@ -54,9 +90,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)
@@ -69,197 +104,20 @@ 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.
-
-
-## 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+.
+* **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.
# 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))
+* 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/Find7zip.cmake b/cmake/modules/Find7zip.cmake
new file mode 100644
index 000000000..83eb912d4
--- /dev/null
+++ b/cmake/modules/Find7zip.cmake
@@ -0,0 +1,7 @@
+# Find7zip.cmake
+# Detect 7zip file archiver on Windows systems to extract (zip-)archives
+
+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..13f70d7b7
--- /dev/null
+++ b/cmake/modules/Findlibusb.cmake
@@ -0,0 +1,154 @@
+# Findlibusb.cmake
+# 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) # Windows
+ # 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 (NOT EXISTS "/etc/debian_version")
+ 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 OR EXISTS "/etc/debian_version")
+ # Preparations for installing libusb library
+ find_package(7zip REQUIRED)
+ set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version
+ 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}/3rdparty/libusb-${LIBUSB_WIN_VERSION})
+
+ # 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
+ if (${ZIP_EXECUTABLE} MATCHES "p7zip")
+ execute_process(
+ COMMAND ${ZIP_EXECUTABLE} -d ${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}
+ ) # <-- Note the absence of a space character following the -o option!
+ endif ()
+
+ # 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)
+ 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)
+ 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 82%
rename from cmake/CFlags.cmake
rename to cmake/modules/c_flags.cmake
index b76856d24..d6b12403b 100644
--- a/cmake/CFlags.cmake
+++ b/cmake/modules/c_flags.cmake
@@ -11,10 +11,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 +34,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..da9d76eba
--- /dev/null
+++ b/cmake/modules/get_version.cmake
@@ -0,0 +1,109 @@
+# Determine project version
+# * Using Git
+# * 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/packaging/CMakeLists.txt b/cmake/packaging/CMakeLists.txt
new file mode 100644
index 000000000..e831f611f
--- /dev/null
+++ b/cmake/packaging/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_subdirectory(debian)
+add_subdirectory(fedora)
+add_subdirectory(opensuse)
+add_subdirectory(windows)
diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake
new file mode 100644
index 000000000..522fb7f11
--- /dev/null
+++ b/cmake/packaging/cpack_config.cmake
@@ -0,0 +1,85 @@
+###
+# Configure package
+###
+
+set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
+set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+set(CPACK_SET_DESTDIR "ON")
+set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist")
+
+if (APPLE)
+ set(CPACK_GENERATOR "ZIP")
+ set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64")
+ set(CPACK_INSTALL_PREFIX "")
+elseif (WIN32) ### TODO: Binary build config for windows...
+ set(CPACK_GENERATOR "ZIP")
+ set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32")
+ set(CPACK_INSTALL_PREFIX "")
+
+ # Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system.
+ # Typical usage:
+ # *) install cross compiler: `sudo apt-get install mingw-w64`
+ # *) cd build
+ # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake ..
+ # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake ..
+
+ #set(CMAKE_SYSTEM_NAME Windows)
+ #set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
+ #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)
+
+elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version")
+ message(STATUS "Debian-based Linux OS detected")
+
+ ### Debian-specific
+ set(CPACK_GENERATOR "DEB")
+ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Open source STM32 MCU programming toolset")
+ set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "/~https://github.com/stlink-org/stlink")
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi")
+ set(CPACK_PACKAGE_CONTACT "bluca@debian.org")
+
+ ## Set debian_revision number
+ # Convention: Restart the debian_revision at 1 each time the upstream_version is increased.
+ set(CPACK_DEBIAN_PACKAGE_RELEASE "0")
+
+ ## Debian package name
+ # CPack DEB generator generates package file name in deb format:
+ # _-_.deb
+ set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
+
+ ## Add CHANGELOG in Debian-specific format
+ ### TODO
+
+ ## Add license file
+ ### TODO
+
+ # Include a postinst-script
+ set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/packaging/debian/postinst")
+
+ ### rpm-specific ### TODO: Package config for opensuse should go here...
+
+else ()
+ ### TODO: Package config for fedora should go here...
+endif ()
+
+
+###
+# Build package
+###
+
+include(CPack)
diff --git a/cmake/packaging/debian/CMakeLists.txt b/cmake/packaging/debian/CMakeLists.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/cmake/packaging/debian/changelog b/cmake/packaging/debian/changelog
new file mode 100644
index 000000000..b4e942d7c
--- /dev/null
+++ b/cmake/packaging/debian/changelog
@@ -0,0 +1,226 @@
+stlink (1.6.0) unstable; urgency=medium
+
+Release date: 2020-02-20
+
+Major changes and added features:
+
+* Initial support for STM32L41X
+* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477
+* Added preliminary support for some STM32G0 chips
+* Added support for mass erasing second bank on STM32F10x_XL
+* Added call to clear PG bit after writing to flash
+* Added support to write option bytes for the STM32G0
+* Added support for STM32WB55 chips
+* Added STLink V3SET VID:PIDs to the udev rules
+* Support for "STM32+Audio" v2-1 firmware
+* Build for Windows under Debian/Ubuntu
+* Allow for 64 bytes serials
+* Added full support for STLINK CHIP ID L4RX
+* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752)
+* Added support for writing option bytes on STM32L0xx
+* Added support to read and write option bytes for STM32F2 series
+* Added support to read and write option bytes for STM32F446
+
+Updates and fixes:
+
+* Fixed "unkown chip id", piped output and st-util -v
+* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git
+* Updated STM32F3xx chip ID that covers a few different devices
+* Made udev rules and modprobe conf installation optional
+* Fixed case when __FILE__ don't contain "/" nor "\\"
+* Fixed double dash issue in doc/man
+* Compiling documentation: package is called libusb-1.0-0-dev on Debian
+* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices
+* Added O_BINARY option to open file
+* Fixed versioning when compiling from the checked out git-repo
+* win32: move usleep definition to unistd.h
+* Fixed relative path to the UI files needed by stlink-gui-local (GUI)
+* Added howto for sending NRST signal through GDB
+* Fixed package name "devscripts" in doc/compiling.md
+* Fixed few potential memory/resource leaks
+* Updated Linux source repositories in README.md: Debian and Ubuntu
+* Do not issue JTAG reset on stlink-v1
+* Fixed flash size of STM32 Discovery vl
+* Updated documentation on software structure
+
+General project updates:
+
+* Updated README.md, CHANGELOG.md and issue templates
+* Fixed travis build config file
+* Added CODE_OF_CONDUCT
+* Archived page from github project wiki to doc/wiki_old.md
+
+-- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000
+
+
+stlink (1.5.1) unstable; urgency=medium
+
+Release date: 2018-09-13
+
+Major changes and added features:
+
+* Added reset through AIRCR
+* Added creation of icons for .desktop file
+* Added desktop file for linux
+* Added button to export STM32 flash memory to a file
+* Updated libusb to 1.0.22
+* Added icons for STLink GUI
+* Added support for STM32L4R9 target
+* Added memory map for STM32F411RE target
+* Implemented intel hex support for GTK GUI
+
+Updates and fixes:
+
+* Fixed missing flash_loader for STM32L0x
+* Fix for stlink library calls exit() or _exit()
+* Added semihosting parameter documentation in doc/man
+* Fixed reference to non-exisiting st-term tool in doc/man
+* Fixed serial number size mismatch with stlink_open_usb()
+* Debian packaging, CMake and README.md fixes
+* Disabled static library installation by default
+* Fix for libusb deprecation
+* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX
+* Regression: stlink installation under Linux (Debian 9) is broken since #695
+* Fixed flash memory map for STM32F72xxx target
+* Proper flash page size calculation for STM32F412xx target
+* Return correct value on EOF for Semihosting SYS_READ
+* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION
+
+-- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100
+
+
+stlink (1.5.0) unstable; urgency=medium
+
+Release date: 2018-02-16
+
+Major changes and added features:
+
+* Added support of STM32L496xx/4A6xx devices
+* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe
+* Added support for STM32F72xx (chip-ID: 0x452) devices
+
+Updates and fixes:
+
+* Fixed verification of flash error for STM32L496x device
+* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS
+* Updated changelog in debian package
+* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems
+* Fixed write for microcontroller with RAM size less or equal to 32K
+* Fixed memory map for STM32L496xx boards
+* Fixed __FILE__ base name extraction
+* Added debian/triggers to run ldconfig
+* Fixed build on Fedora with GCC 8
+
+-- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000
+
+
+stlink (1.4.0) unstable; urgency=low
+
+Release date: 2017-07-01
+
+Major changes and added features:
+
+* Allow building of debian package with CPack
+* Added support for STM32L011 target
+* Added support for flashing second bank on STM32F10x_XL
+* Initial support to compile with Microsoft Visual Studio 2017
+* Added support for STM32L452 target
+
+Updates and fixes:
+
+* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints
+* Added --flash=n[k][m] command line option to override device model
+* Updated libusb to 1.0.21 for Windows
+* Fixed low-voltage flashing on STM32F7 devices
+* Fixed building with mingw64
+* Fixed possible memory leak
+* Fixed installation path for shared objects
+* Fixed a few -Wformat warnings
+* Removed unused defines in mimgw.h
+* Skip GTK detection when cross-compiling
+* Fixed compilation with GCC 7
+* Fixed flashing to 'f0 device' targets
+* Fixed wrong counting when flashing
+
+-- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000
+
+
+stlink (1.3.1) unstable; urgency=low
+
+Release date: 2017-02-25
+
+Major changes and added features:
+
+* Added support for Semihosting `SYS_READC`
+* Added support for STM32F413
+* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457)
+
+Updates and fixes:
+
+* cmake/CPackConfig.cmake: Fixup OSX zip filename
+* Updated source repositories in README.md: Windows, macOS, Alpine Linux
+* Compilation fixes
+* Stripped full paths to source files in log
+* Fixed incorrect release folder name in docs
+* Fixed compilation when path includes spaces
+
+-- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000
+
+
+stlink (1.3.0) unstable; urgency=low
+
+Release date: 2017-01-28
+
+Major changes and added features:
+
+* Deprecation of autotools (autoconf, automake) and fixed build with MinGW
+* Added intel hex file reading for `st-flash`
+* Added support for ARM semihosting to `st-util`
+* Added manpages (generated with pandoc from Markdown)
+* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature
+* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers
+* Merge st-probe tool into st-info
+* Added support for native debian packaging
+* Rewritten commandline parsing for `st-flash`
+* Added `--reset` command to `st-flash`
+* st-util should detect when USB commands fail
+
+Chip support added for:
+
+* STM32F401XE: Added memory map for device
+* STM32F410RBTx
+* STM32F412
+* STM32F7xx
+* STM32F7x7x
+* STM32L0xx Cat2 devices (chip-ID: 0x425)
+* STM32L0xx Cat5 devices (chip-ID: 0x447)
+* STM32L4xx
+* STM32L432
+
+Updates and fixes:
+
+* Fixed "unaligned addr or size" when trying to write a program in RAM
+* Fixed flashing on STM32_F3_SMALL
+* Fixed STM32L-problem with flash loader
+* Don't read the target voltage on startup, because it crashes STM32F100
+* Added a useful error message instead of "[!] send_recv"
+* Do a JTAG reset prior to reading CPU information when processor is in deep sleep
+* Fixed STM32F030 erase error
+* Fixed memory map for STM32F7xx
+* Redesign of `st-flash` commandline options parsing
+* Set SWDCLK and fixed jtag_reset bug
+* doc/compiling.md: Add note about installation and ldconfig
+* Fixed Release target to generate the man-pages with pandoc
+* Fixed Cygwin build
+* Reset flash mass erase (MER) bit after mass erase for safety
+* Wrong extract command in FindLibUSB.cmake
+* Fixed compilation error on Ubuntu 16.10
+
+-- 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/copyright b/cmake/packaging/debian/copyright
similarity index 98%
rename from debian/copyright
rename to cmake/packaging/debian/copyright
index 941a4a011..7a6d585c5 100644
--- a/debian/copyright
+++ b/cmake/packaging/debian/copyright
@@ -1,7 +1,7 @@
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
+Upstream-Contact: Luca Bocassi
+Source: /~https://github.com/stlink-org/stlink
Files: *
Copyright: 2011-2018 agpanarin
diff --git a/cmake/packaging/debian/postinst b/cmake/packaging/debian/postinst
new file mode 100644
index 000000000..bc74428ae
--- /dev/null
+++ b/cmake/packaging/debian/postinst
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This `DEBIAN/postinst` script is run post-installation
+
+depmod -a
diff --git a/cmake/packaging/fedora/CMakeLists.txt b/cmake/packaging/fedora/CMakeLists.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/cmake/packaging/opensuse/CMakeLists.txt b/cmake/packaging/opensuse/CMakeLists.txt
new file mode 100644
index 000000000..e69de29bb
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_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/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/control b/debian/control
index e33fc757c..3c1e9700f 100644
--- a/debian/control
+++ b/debian/control
@@ -1,12 +1,12 @@
Source: stlink
Priority: optional
-Maintainer: Andrew 'Necromant' Andrianov
+Maintainer: Luca Bocassi
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
+Homepage: /~https://github.com/stlink-org/stlink
+Vcs-Git: /~https://github.com/stlink-org/stlink.git
+Vcs-Browser: /~https://github.com/stlink-org/stlink
Package: libstlink-dev
Section: libdevel
diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install
index 0c3543cd9..18fd98b03 100644
--- a/debian/libstlink-dev.install
+++ b/debian/libstlink-dev.install
@@ -1,5 +1,4 @@
usr/include/*
usr/lib/*/lib*.a
-usr/lib/*/pkgconfig/*
+usr/lib/*/pkg-config/*
usr/lib/*/lib*.so
-
diff --git a/debian/pkg-config/CMakeLists.txt b/debian/pkg-config/CMakeLists.txt
new file mode 100644
index 000000000..fa3a326a8
--- /dev/null
+++ b/debian/pkg-config/CMakeLists.txt
@@ -0,0 +1,15 @@
+#set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}")
+#set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}")
+#set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}")
+#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"
+# )
+
+#install(
+# FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
+# DESTINATION ${STLINK_LIBRARY_PATH}/debian/
+# )
diff --git a/usr/lib/pkgconfig/pkg-config.pc.cmake b/debian/pkg-config/pkg-config.pc.cmake
similarity index 99%
rename from usr/lib/pkgconfig/pkg-config.pc.cmake
rename to debian/pkg-config/pkg-config.pc.cmake
index 4170bf84b..c00eb070e 100644
--- a/usr/lib/pkgconfig/pkg-config.pc.cmake
+++ b/debian/pkg-config/pkg-config.pc.cmake
@@ -8,4 +8,3 @@ includedir=${PKG_CONFIG_INCLUDEDIR}
libdir=${PKG_CONFIG_LIBDIR}
Libs: ${PKG_CONFIG_LIBS}
Cflags: ${PKG_CONFIG_CFLAGS}
-
diff --git a/debian/rules b/debian/rules
index e228a7087..e183fffb7 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,7 +1,7 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
-#DH_VERBOSE = 1
+DH_VERBOSE = 1
# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
DPKG_EXPORT_BUILDFLAGS = 1
diff --git a/debian/watch b/debian/watch
index cc653ca9f..20ad1260e 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,3 +1,3 @@
version=3
opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \
- /~https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz
+ /~https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz
diff --git a/doc/app-example/CMakeLists.txt b/doc/app-example/CMakeLists.txt
index 0e91bed6f..a7697720c 100644
--- a/doc/app-example/CMakeLists.txt
+++ b/doc/app-example/CMakeLists.txt
@@ -1,12 +1,11 @@
-# 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)
find_package(PkgConfig)
@@ -14,15 +13,10 @@ pkg_check_modules(STLINK REQUIRED stlink)
set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror")
-include_directories(
- ${STLINK_INCLUDE_DIRS}
-)
+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 bin)
diff --git a/doc/compiling.md b/doc/compiling.md
index 555dce487..15d8b4fc2 100644
--- a/doc/compiling.md
+++ b/doc/compiling.md
@@ -1,202 +1,210 @@
-# Compiling
+# Compiling from sources
-## Build from sources
+## Microsoft Windows (10, 8.1)
+### Common Requirements
-* CMake (minimal v2.8.7)
-* C compiler (gcc, clang, mingw)
-* Libusb 1.0 (minimal v1.0.9)
-* (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:
+* `7zip`
+* `git`
+* `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 `7zip` from
+2. Install `git` from
+3. Install `cmake` from
+ Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant.
+4. Install
+ - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
+ - _OR_: **Visual Studio 2017 CE** (other versions will likely work as well, but are untested; the Community edition is free for open source
+ development)
+5. Create a new destination folder at a place of your choice
+6. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\`
+7. 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
-You could install to a user folder e.g `$HOME`:
-```
-$ cd build/Release; make install DESTDIR=$HOME
-```
-
-Or system wide:
+### Building
+#### MinGW-w64
-```
-$ cd build/Release; sudo make install
-```
+1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\`
+2. Execute `./mingw64-build.bat`
-## Linux
+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.
-## Common requirements
-* 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
+#### Visual Studio (32 bit)
-### Fixing cannot open shared object file
+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 ..`).
-When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`.
+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).
-## Permissions with udev
+NOTE:
+This solution will link to the dll version of libusb-1.0.y
+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\3rdparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`.
-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.
+## Linux
+### Common requirements
-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):
+Install the following packages from your package repository:
-```
-$ udevadm control --reload-rules
-$ udevadm trigger
-```
+* `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)
+* `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)
-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.
+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`
-### Note for STLINKv1 usage
+(Replace gcc with the intended C-compiler if necessary or leave out any optional package not needed.)
-The STLINKv1's SCSI emulation is very broken, so the best thing to do
-is tell your operating system to completely ignore it.
-Options (do one of these before you plug it in)
+### Installation
-* `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`
+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`
-### Build Debian Package
-To build the debian package you need the following extra packages: `devscripts debhelper`.
+### Building
-```
-$ 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
-```
+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.
-## Mac OS X
+The top level Makefile is just a handy wrapper for:
-When compiling on a mac you need the following:
+##### MinGW64:
-* A compiler toolchain (XCode)
-* CMake
-* Libusb 1.0
+```sh
+$ mkdir build && cd build
+$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake -S ..
+$ make
+```
-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:
+##### MinGW32:
+```sh
+$ mkdir build && cd build
+$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S ..
+$ make
```
-brew install libusb cmake
-```
-
-Compile as described in the first section of this document.
-## Build using different directories for udev and modprobe
+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`.
-To put the udev or the modprobe configuration files into a different directory
-during installation you can use the following cmake options:
+When installing system-wide, the dynamic library cache needs to be updated with the command `ldconfig`.
-```
-$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \
- -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" ..
-```
-## Build using different directory for shared libs
+### Build a Debian Package
-To put the compiled shared libs into a different directory during installation
-you can use the following cmake option:
+To build the debian package you need the following extra packages: `devscripts debhelper`.
-```
-$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..
+```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
```
-## Windows (MinGW64)
-### Prequistes
+### Set permissions with udev
-* 7Zip
-* CMake 2.8 or higher
-* MinGW64 GCC toolchain (5.3.0)
+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`.
-### Installation
+The rules are located in the subdirectory `etc/udev/rules.d` within the sourcefolder.
+Copy them to the directory path `/etc/udev/rules.d` and subsequently reload the udev rules:
-1. Install 7Zip from
-2. Install CMake from
-3. Install MinGW64 from (mingw-w64-install.exe)
-4. Git clone or download stlink sourcefiles zip
+```sh
+$ cp etc/udev/rules.d /etc/udev/rules.d
+$ udevadm control --reload-rules
+$ udevadm trigger
+```
-### Building
+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.
-Check and execute (in the script folder) `\scripts\mingw64-build.bat`
-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`
+### Note on the use of STLink-v1 programmers:
-## Windows (Visual Studio)
+At the time of writing the STLink-v1 has mostly been replaced with the newer generation STLink-v2 programmers and thus is only rarely used.
+As there are some caveats as well, we recommend to use the STLink-v2 programmers if possible.
-### Prerequisites
+To be more precise, the STLINKv1's SCSI emulation is somehow broken, so the best advice possibly is to tell your operating system to completely ignore it.
-* 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)
+Choose on of the following options _before_ connecting the device to your computer:
-### Installation
+* `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`
-1. Install 7Zip from
-2. Install CMake from
-3. Git clone or download stlink sourcefiles zip
-### Building
+## macOS
+### Common requirements
-These instructions are for a 32bit version.
+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/).
-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 ..`).
+Then install the following dependencies from the package repository:
-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).
+* `git`
+* `gcc` or `llvm` (for clang) (C-compiler)
+* `cmake`
+* `pkg-config`
+* `libusb`
+* `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`)
-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 do this with only one simple command, type:
-## Linux (MinGW64)
+* 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 llvm-9.0 cmake libusb gtk3` or
+ - with clang: `sudo port install git gcc9 cmake libusb gtk3`
-### Prequistes
-* 7Zip
-* CMake 2.8 or higher
-* MinGW64 GCC toolchain (5.3.0)
+### Installation
-### Installation (Debian / Ubuntu)
+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`
-sudo apt install p7zip mingw-w64
### 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.
-```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
-```
+
+## Build using a different directory for shared libs
+
+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" ..`.
+
+
+Author: nightwalker-87
diff --git a/doc/devices_boards.md b/doc/devices_boards.md
new file mode 100644
index 000000000..00acdd2cf
--- /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]:
+* 32VL-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/man/CMakeLists.txt b/doc/man/CMakeLists.txt
index 949cd2fcf..090a2237e 100644
--- a/doc/man/CMakeLists.txt
+++ b/doc/man/CMakeLists.txt
@@ -1,37 +1,32 @@
-set(MANPAGES
- st-util
- st-flash
- st-info
-)
+set(MANPAGES st-util st-flash st-info)
# 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()
+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_PREFIX}/share/man/man1)
+ unset(f)
+ endif ()
+endforeach ()
diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1
index 6bd206069..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 4096
+$ 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 ae6c88f46..b787e8dd7 100644
--- a/doc/man/st-flash.md
+++ b/doc/man/st-flash.md
@@ -45,6 +45,9 @@ reset
\--reset
: TODO
+\--opt
+: Enable ignore ending empty bytes optimization
+
\--serial *iSerial*
: TODO
@@ -61,7 +64,7 @@ Flash `firmware.bin` to device
Read firmware from device (4096 bytes)
- $ st-flash read firmware.bin 0x8000000 4096
+ $ st-flash read firmware.bin 0x8000000 0x1000
Erase firmware from device
diff --git a/doc/man/st-info.md b/doc/man/st-info.md
index 67d9373d7..ca2579785 100644
--- a/doc/man/st-info.md
+++ b/doc/man/st-info.md
@@ -12,7 +12,7 @@ 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.
# OPTIONS
@@ -20,29 +20,29 @@ Serial code, openocd, flash, sram, page size, chipid, description.
\--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/release.md b/doc/release.md
index c2dca87b2..ae8b864ee 100644
--- a/doc/release.md
+++ b/doc/release.md
@@ -1,7 +1,7 @@
Release
=======
-This document describes the steps takes for developers to create a release
+This document describes the steps it takes 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
diff --git a/doc/tested-boards.md b/doc/tested-boards.md
deleted file mode 100644
index 27d09cc34..000000000
--- a/doc/tested-boards.md
+++ /dev/null
@@ -1,54 +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)
-
-No information:
-
-* everything else!
-
-STLink v2 (as found on the 32L and F4 Discovery boards), known working targets:
-
-* STM32F030F4P6 (custom board)
-* STM32F0Discovery (STM32F0 Discovery board)
-* STM32F100xx (Medium Density VL, as on the 32VL Discovery board)
-* STM32L1xx (STM32L Discovery 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)
-* STM32F103VET6 (HY-STM32 board)
-* STM32F105RCT6 (DecaWave EVB1000 board)
-* STM32F303xx (STM32F3 Discovery board)
-* STM32F407xx (STM32F4 Discovery board)
-* STM32F429I-DISCO (STM32F4 Discovery board with LCD)
-* STM32F439VIT6 (discovery board reseated CPU)
-* STM32L052K8T6 (custom board)
-* STM32L151CB (custom board)
-* STM32L152RB (STM32L-Discovery board, custom board)
-* STM32F051R8T6 (STM320518-EVAL board)
-* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio)
-
-STLink v2-1 (as found on the Nucleo boards), known working targets:
-
-* STM32F401xx (STM32 Nucleo-F401RE board)
-* STM32F030R8T6 (STM32 Nucleo-F030R8 board)
-* STM32F072RBT6 (STM32 Nucleo-F072RB board)
-* STM32F103RB (STM32 Nucleo-F103RB board)
-* STM32F303RET6 (STM32 Nucleo-F303RE board)
-* STM32F334R8 (STM32 Nucleo-F334R8 board)
-* STM32F411RET6 (STM32 Nucleo-F411RE board)
-* STM32F756NGHx (STMF7 evaluation board)
-* STM32L053R8 (STM32 Nucleo-L053R8 board)
-* STM32F769NI (STM32F7 discovery board)
-* Nucleo-L152RE board
-* [Nucleo-L476RG board](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html)
-* STM32L452RET6 (STM32 Nucleo-L452RE board)
-* STM32F042K6 (STM32 Nucleo-32 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..75e03f1bc 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1,68 +1,159 @@
-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.
+## Useful tool options
-Installing a GNU toolchain
-==========================
+### st-flash
-Any toolchain supporting the cortex m3 should do. You can find the
-necessary to install such a toolchain here:
+#### --flash=n[k][m]
+
+(since v1.4.0)
+
+You can specify `--flash=128k` for example, to override the STM32F103C8T6 to assume 128k of flash instead of the default of 64k.
+This option accepts decimal (128k), octal 0200k, or hex 0x80k.
+Obviously leaving the multiplier out is equally valid, for example: `--flash=0x20000`.
+The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively.
+
+#### 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).
+
+
+## Solutions to common problems
+### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only)
+#### Problem:
+
+st-util fails to detect a STLINK/v1 device:
```
-/~https://github.com/esden/summon-arm-toolchain
+st-util -1
+st-util $VERSION-STRING$
+WARN src/sg.c: Failed to find an stlink v1 by VID:PID
+ERROR src/sg.c: Could not open stlink device
```
-Details for the installation are provided in the topmost `README` file.
-This documentation assumes the toolchains is installed in a
-`$TOOLCHAIN_PATH`.
+#### Solution (clean setup):
-Installing STLINK
-=================
+1) Configure System Integrity Protection (SIP)
-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.
+The root of this problem is a system security setting introduced by Apple with OS X El Capitan (10.11) in 2015.
+The so called System Integrity Protection (SIP) 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,
+while SIP is fully activated (as is per default).
+Action needs to be taken here by booting into the recovery mode where a terminal console window needs to be opened.
-Before continuing, the following dependencies must be met:
+For macOS 10.11 - 10.13 it is not recommended to disable SIP completely as with the command `csrutil disable`,
+because this leaves the system more vulnerable to common threats.
+Instead there is a more adequate and reasonable option implemented by Apple.
+Running `csrutil enable --without kext`, allows to load unsigned kernel extensions
+while leaving SIP active with all other security features.
+Unfortunately this option has been removed in macOS 10.14, which leaves the only option to disable SIP completely.
-- libusb-1.0
-- cmake
+So who ever intends to run the STLINK/v1 programmer on macOS please take this into account.
-Also make sure `gtk+` version 3.0 is installed. (`sudo apt-get install gtk+-3.0` or similiar)
+Further details can be found here: https://forums.developer.apple.com/thread/17452
-STLINK should run on any system meeting the above constraints.
+2) Install the ST-Link-v1 driver from the subdirectory `/stlinkv1_macosx_driver`
+ by referring to the instructions in the README file available there.
-The STLINK software source code is retrieved using:
+3) Move the $OS_VERSION$.kext file to `/System/Library/Extensions`.
+
+4) Load the Kernel Extension (kext): `$ sudo kextload -v /System/Library/Extensions/stlink_shield10_x.kext`
```
-$> git clone /~https://github.com/texane/stlink.git
+Requesting load of /System/Library/Extensions/stlink_shield10_x.kext.
+/System/Library/Extensions/stlink_shield10_x.kext loaded successfully (or already loaded).
```
-Everything can be built from the top directory:
+5) Enter the command `$ sudo touch /System/Library/Extensions`
+
+
+7) 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:
```
-$> cd stlink
-$> make
-$> cd build/Release && make install DESTDIR=_install
+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...
```
-It includes:
+### b) Verify if udev rules are set correctly (by Dave Hylands)
+
+To investigate, start by plugging your STLINK device into the usb port. Then run `lsusb`. You should see an entry something like the following:
-- a communication library (libstlink.a),
-- a GDB server (st-util),
-- a flash manipulation tool (st-flash).
-- a programmer and chip information tool (st-info)
+```
+Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB)
+```
-Using the GDB server
-====================
-
+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).
+
+On my system I see the following:
+
+```
+crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017
+```
+
+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:
+
+```
+# 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.
+```
+
+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:
+
+```
+sudo udevadm control --reload-rules
+sudo udevadm trigger
+```
+
+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
+
+Any toolchain supporting the cortex m3 should do. You can find the
+necessary to install such a toolchain here:
+
+```
+/~https://github.com/esden/summon-arm-toolchain
+```
+
+Details for the installation are provided in the topmost `README` file.
+This documentation assumes the toolchains is installed in a
+`$TOOLCHAIN_PATH`.
+
+## 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
@@ -85,11 +176,11 @@ the discovery kit you are using, you must run one of the 2 commands:
$> ./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
-```
+```
Then, GDB can be used to interact with the kit:
@@ -113,7 +204,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,8 +218,8 @@ 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
@@ -154,7 +245,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,21 +258,234 @@ $> [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
+ -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
+```
+
+
+## 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
```
+
+## 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
+```
+
+## Installation of openOCD on Mac OS X with STlink-v2:
+
+`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
+
+
+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.
+
+Q: How can I install stlink and flash binaries on Mac OS X ?
+
+A: 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/stlink-org/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
+
+ST-Link/V2 debugger with downgraded V2.14.3 firmware:
+
+https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k
+
+After downgrading the firmware, flashing works 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!
+
+
References
==========
@@ -192,5 +496,4 @@ References
documentation related to the STM32L discovery kit
-
- libopencm3, a project providing a firmware library, with solid
- examples for Cortex M3, M4 and M0 processors from any vendor.
+ libopencm3, a project providing a firmware library, with solid examples for Cortex M3, M4 and M0 processors from any vendor.
diff --git a/doc/version_support.md b/doc/version_support.md
new file mode 100644
index 000000000..75def2e66
--- /dev/null
+++ b/doc/version_support.md
@@ -0,0 +1,80 @@
+
+_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) |
+
+
+### 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/etc/udev/rules.d/49-stlinkv2-1.rules b/etc/udev/rules.d/49-stlinkv2-1.rules
index 15a797a05..b89b84012 100644
--- a/etc/udev/rules.d/49-stlinkv2-1.rules
+++ b/etc/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/include/CMakeLists.txt b/include/CMakeLists.txt
index a0c649532..6e5e3c279 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,14 +1,8 @@
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 ${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 f9de94fd4..05618e35f 100644
--- a/include/stlink.h
+++ b/include/stlink.h
@@ -118,7 +118,6 @@ enum target_state {
#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 {
@@ -129,6 +128,7 @@ enum target_state {
STLINK_FLASH_TYPE_L4,
STLINK_FLASH_TYPE_F1_XL,
STLINK_FLASH_TYPE_G0,
+ STLINK_FLASH_TYPE_G4,
STLINK_FLASH_TYPE_WB
};
@@ -202,6 +202,7 @@ typedef struct flash_loader {
// 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()
@@ -210,6 +211,8 @@ typedef struct flash_loader {
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
+ 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()
@@ -218,9 +221,13 @@ typedef struct flash_loader {
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)
+ // 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()
@@ -261,8 +268,6 @@ typedef struct flash_loader {
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);
@@ -284,8 +289,12 @@ typedef struct flash_loader {
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);
+
+ 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 "stlink/sg.h"
#include "stlink/usb.h"
@@ -294,6 +303,7 @@ typedef struct flash_loader {
#include "stlink/chipid.h"
#include "stlink/flash_loader.h"
#include "stlink/version.h"
+#include "stlink/logging.h"
#ifdef __cplusplus
}
diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h
index a4f4be4c0..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,9 +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, /* G070/G071/081 */
STLINK_CHIPID_STM32_F413 = 0x463,
- STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board
- STLINK_CHIPID_STM32_G0X1 = 0x460,
+ 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_WB55 = 0x495
};
@@ -82,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/logging.h b/include/stlink/logging.h
index da5f7d19d..1083b2c55 100644
--- a/include/stlink/logging.h
+++ b/include/stlink/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/include/stlink/sg.h b/include/stlink/sg.h
index e521ba217..98efd4e58 100644
--- a/include/stlink/sg.h
+++ b/include/stlink/sg.h
@@ -6,20 +6,12 @@
*/
#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 "stlinkusb.h"
#include "stlink.h"
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -49,29 +41,29 @@ 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
}
diff --git a/include/stlink/stlinkusb.h b/include/stlink/stlinkusb.h
new file mode 100644
index 000000000..633d82bd0
--- /dev/null
+++ b/include/stlink/stlinkusb.h
@@ -0,0 +1,46 @@
+#ifndef STLINKUSB_H
+#define STLINKUSB_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/include/stlink/tools/flash.h b/include/stlink/tools/flash.h
index 6851ede8b..15e020b35 100644
--- a/include/stlink/tools/flash.h
+++ b/include/stlink/tools/flash.h
@@ -5,7 +5,8 @@
#include
#define DEBUG_LOG_LEVEL 100
-#define STND_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 +14,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 +24,11 @@ struct flash_opts
enum flash_area area;
uint32_t val;
size_t flash_size; /* --flash=n[k][m] */
+ int opt;
};
-#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}
int flash_get_opts(struct flash_opts* o, int ac, char** av);
#endif // STLINK_FLASH_H_
-
diff --git a/include/stlink/usb.h b/include/stlink/usb.h
index a69101c1f..1448481be 100644
--- a/include/stlink/usb.h
+++ b/include/stlink/usb.h
@@ -9,9 +9,9 @@
#define STLINK_USB_H
#include
-#include
#include "stlink.h"
+#include "stlinkusb.h"
#include "stlink/logging.h"
#ifdef __cplusplus
@@ -19,14 +19,33 @@ extern "C" {
#endif
#define STLINK_USB_VID_ST 0x0483
-#define STLINK_USB_PID_STLINK 0x3744
-#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_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_USB_PID_STLINK 0x3744
+#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
@@ -58,4 +77,3 @@ extern "C" {
#endif
#endif /* STLINK_USB_H */
-
diff --git a/include/stm32.h b/include/stm32.h
index 8f8e7eba1..c71718653 100644
--- a/include/stm32.h
+++ b/include/stm32.h
@@ -15,6 +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_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800)
+#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000)
+
#endif /* STM32_H */
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
index 3f92ae8e0..15ec21cd0 100644
--- a/scripts/mingw64-build.bat
+++ b/scripts/mingw64-build.bat
@@ -1,5 +1,8 @@
@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%
+cd ..
+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
diff --git a/src/chipid.c b/src/chipid.c
index d627849a3..60d0787e9 100644
--- a/src/chipid.c
+++ b/src/chipid.c
@@ -5,7 +5,7 @@ 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,7 +47,7 @@ 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,
@@ -67,7 +67,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 +77,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 +87,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 +97,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 +107,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 +117,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 +127,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 +139,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 +149,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 +159,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 +169,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 +191,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 +201,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,7 +212,7 @@ 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,
@@ -221,7 +223,7 @@ static const struct stlink_chipid_params devices[] = {
{
// 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 +235,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 +247,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 +257,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 +267,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 +279,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 +291,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 +303,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 +315,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 +325,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 +337,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 +349,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 +360,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 +372,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 +426,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 +438,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 +447,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 +467,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 +481,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 +490,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 +506,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 +527,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,
@@ -521,21 +535,70 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base = 0x1ff00000,
.bootrom_size = 0x2000
},
+ {
+ // STM32G030/031/041 (from RM0454 & RM0444)
+ .chip_id = STLINK_CHIPID_STM32_G0_CAT1,
+ .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)
+ .option_base = STM32_G0_OPTION_BYTES_BASE,
+ .option_size = 4,
+ },
{
// STM32G071/081 (from RM0444)
- .chip_id = STLINK_CHIPID_STM32_G0X1,
- .description = "G071/G081 device",
+ .chip_id = STLINK_CHIPID_STM32_G0_CAT2,
+ .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 = 0x7800 // 30K (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",
+ .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)
+ .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
diff --git a/src/common.c b/src/common.c
index db0ab445e..32c892420 100644
--- a/src/common.c
+++ b/src/common.c
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include
#include
@@ -14,10 +15,12 @@
#include "stlink.h"
#include "stlink/mmap.h"
#include "stlink/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
@@ -74,15 +77,20 @@
#define FLASH_L1_FPRG 10
#define FLASH_L1_PROG 3
+// Flash registers common to STM32G0 and STM32G4 series.
+#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000)
+#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)
-#define STM32G0_FLASH_REGS_ADDR ((uint32_t)0x40022000)
-#define STM32G0_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00)
-#define STM32G0_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08)
-#define STM32G0_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c)
-#define STM32G0_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10)
-#define STM32G0_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14)
-#define STM32G0_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18)
-#define STM32G0_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20)
+// Mostly the same as G4 chips, but the notation
+// varies a bit after the 'OPTR' register.
+#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR)
#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24)
#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28)
#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C)
@@ -91,21 +99,46 @@
#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38)
#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80)
-// GO FLASH control register
-#define STM32G0_FLASH_CR_PG 0 /* Program */
-#define STM32G0_FLASH_CR_PER 1 /* Page erase */
-#define STM32G0_FLASH_CR_MER1 2 /* Mass erase */
-#define STM32G0_FLASH_CR_PNB 3 /* Page number (5 bits) */
-#define STM32G0_FLASH_CR_STRT 16 /* Start */
-#define STM32G0_FLASH_CR_OPTSTRT 17 /* Start of modification of option bytes */
-#define STM32G0_FLASH_CR_FSTPG 18 /* Fast programming */
-#define STM32G0_FLASH_CR_EOPIE 24 /* End of operation interrupt enable */
-#define STM32G0_FLASH_CR_ERRIE 25 /* Error interrupt enable */
-#define STM32G0_FLASH_CR_OBL_LAUNCH 27 /* Forces the option byte loading */
-#define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */
-#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock */
-// GO FLASH status register
-#define STM32G0_FLASH_SR_BSY 16 /* FLASH_SR Busy */
+// G4 (RM0440 Table 17, sec 3.7.19)
+// Mostly the same as STM32G0 chips, but there are a few extra
+// registers because 'cat 3' devices can have two Flash banks.
+#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR)
+#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04)
+#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24)
+#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28)
+#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C)
+#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30)
+#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44)
+#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48)
+#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C)
+#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50)
+#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70)
+#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74)
+
+// G0/G4 FLASH control register
+#define STM32Gx_FLASH_CR_PG (0) /* Program */
+#define STM32Gx_FLASH_CR_PER (1) /* Page erase */
+#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */
+#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 */
+#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */
+#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */
+#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)
@@ -137,6 +170,7 @@
//32L4 register base is at FLASH_REGS_ADDR (0x40022000)
#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08)
+#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C)
#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10)
#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14)
#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20)
@@ -145,19 +179,22 @@
#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */
#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */
+#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */
#define STM32L4_FLASH_CR_PG 0 /* Program */
#define STM32L4_FLASH_CR_PER 1 /* Page erase */
#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */
#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */
#define STM32L4_FLASH_CR_STRT 16 /* Start command */
+#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */
#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */
#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */
+#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<flash_type == STLINK_FLASH_TYPE_L4)
reg = STM32L4_FLASH_CR;
- else if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- reg = STM32G0_FLASH_CR;
+ else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4)
+ reg = STM32Gx_FLASH_CR;
else if (sl->flash_type == STLINK_FLASH_TYPE_WB)
reg = STM32WB_FLASH_CR;
else
@@ -302,8 +344,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) {
cr_lock_shift = FLASH_F4_CR_LOCK;
else if (sl->flash_type == STLINK_FLASH_TYPE_L4)
cr_lock_shift = STM32L4_FLASH_CR_LOCK;
- else if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- cr_lock_shift = STM32G0_FLASH_CR_LOCK;
+ else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4)
+ cr_lock_shift = STM32Gx_FLASH_CR_LOCK;
else if (sl->flash_type == STLINK_FLASH_TYPE_WB)
cr_lock_shift = STM32WB_FLASH_CR_LOCK;
else
@@ -323,8 +366,9 @@ static void unlock_flash(stlink_t *sl) {
key_reg = FLASH_F4_KEYR;
else if (sl->flash_type == STLINK_FLASH_TYPE_L4)
key_reg = STM32L4_FLASH_KEYR;
- else if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- key_reg = STM32G0_FLASH_KEYR;
+ 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)
key_reg = STM32WB_FLASH_KEYR;
else
@@ -362,9 +406,10 @@ static void lock_flash(stlink_t *sl) {
} 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) {
- cr_reg = STM32G0_FLASH_CR;
- cr_lock_shift = STM32G0_FLASH_CR_LOCK;
+ } 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) {
cr_reg = STM32WB_FLASH_CR;
cr_lock_shift = STM32WB_FLASH_CR_LOCK;
@@ -395,8 +440,9 @@ static void set_flash_cr_pg(stlink_t *sl) {
cr_reg = STM32L4_FLASH_CR;
x &= ~STM32L4_FLASH_CR_OPBITS;
x |= 1 << STM32L4_FLASH_CR_PG;
- } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) {
- cr_reg = STM32G0_FLASH_CR;
+ } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4) {
+ cr_reg = STM32Gx_FLASH_CR;
x |= (1 << FLASH_CR_PG);
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
@@ -416,8 +462,9 @@ static void clear_flash_cr_pg(stlink_t *sl) {
cr_reg = FLASH_F4_CR;
else if (sl->flash_type == STLINK_FLASH_TYPE_L4)
cr_reg = STM32L4_FLASH_CR;
- else if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- cr_reg = STM32G0_FLASH_CR;
+ else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4)
+ cr_reg = STM32Gx_FLASH_CR;
else if (sl->flash_type == STLINK_FLASH_TYPE_WB)
cr_reg = STM32WB_FLASH_CR;
else
@@ -430,8 +477,9 @@ static void clear_flash_cr_pg(stlink_t *sl) {
static void set_flash_cr_per(stlink_t *sl) {
uint32_t cr_reg, val;
- if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- cr_reg = STM32G0_FLASH_CR;
+ if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4)
+ cr_reg = STM32Gx_FLASH_CR;
else if (sl->flash_type == STLINK_FLASH_TYPE_WB)
cr_reg = STM32WB_FLASH_CR;
else
@@ -450,8 +498,9 @@ static void set_flash_cr2_per(stlink_t *sl) {
static void clear_flash_cr_per(stlink_t *sl) {
uint32_t cr_reg;
- if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- cr_reg = STM32G0_FLASH_CR;
+ if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4)
+ cr_reg = STM32Gx_FLASH_CR;
else if (sl->flash_type == STLINK_FLASH_TYPE_WB)
cr_reg = STM32WB_FLASH_CR;
else
@@ -472,9 +521,13 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) {
cr_reg = STM32L4_FLASH_CR;
cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2);
cr_pg = 1 << STM32L4_FLASH_CR_PG;
- } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) {
- cr_reg = STM32G0_FLASH_CR;
- cr_mer = (1 << FLASH_CR_MER);
+ } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4) {
+ cr_reg = STM32Gx_FLASH_CR;
+ 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;
@@ -493,7 +546,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;
@@ -542,9 +595,10 @@ static void set_flash_cr_strt(stlink_t *sl) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_L4) {
cr_reg = STM32L4_FLASH_CR;
cr_strt = 1 << STM32L4_FLASH_CR_STRT;
- } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) {
- cr_reg = STM32G0_FLASH_CR;
- cr_strt = 1 << STM32G0_FLASH_CR_STRT;
+ } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4) {
+ cr_reg = STM32Gx_FLASH_CR;
+ cr_strt = 1 << STM32Gx_FLASH_CR_STRT;
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
cr_strt = 1 << STM32WB_FLASH_CR_STRT;
@@ -573,8 +627,9 @@ static inline uint32_t read_flash_sr(stlink_t *sl) {
sr_reg = FLASH_F4_SR;
else if (sl->flash_type == STLINK_FLASH_TYPE_L4)
sr_reg = STM32L4_FLASH_SR;
- else if (sl->flash_type == STLINK_FLASH_TYPE_G0)
- sr_reg = STM32G0_FLASH_SR;
+ 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)
sr_reg = STM32WB_FLASH_SR;
else
@@ -599,8 +654,9 @@ static inline unsigned int is_flash_busy(stlink_t *sl) {
sr_busy_shift = FLASH_F4_SR_BSY;
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)
- sr_busy_shift = STM32G0_FLASH_SR_BSY;
+ 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)
sr_busy_shift = STM32WB_FLASH_SR_BSY;
else
@@ -636,6 +692,22 @@ static void wait_flash_busy_progress(stlink_t *sl) {
fprintf(stdout, "\n");
}
+static int check_flash_error(stlink_t *sl)
+{
+ uint32_t res = 0;
+ if ((sl->flash_type == STLINK_FLASH_TYPE_G0) ||
+ (sl->flash_type == STLINK_FLASH_TYPE_G4)) {
+ res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK;
+ }
+
+ 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);
}
@@ -684,12 +756,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;
@@ -787,7 +863,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;
@@ -823,13 +901,15 @@ int stlink_load_device_params(stlink_t *sl) {
flash_size = flash_size >>16;
flash_size = flash_size & 0xffff;
- if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) {
- sl->flash_size = 128 * 1024;
+ if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM ||
+ sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW ||
+ sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) {
+ sl->flash_size = 128 * 1024;
} else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) {
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;
@@ -837,23 +917,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);
+#else
+ ILOG("%s: %d KiB SRAM, %d KiB flash in %d %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;
}
@@ -892,8 +992,7 @@ int stlink_status(stlink_t *sl) {
* @param sl stlink context, assumed to contain valid data in the buffer
* @param slv output parsed version object
*/
-void _parse_version(stlink_t *sl, stlink_version_t *slv)
-{
+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
@@ -1011,7 +1110,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();
@@ -1117,8 +1216,6 @@ int stlink_current_mode(stlink_t *sl) {
}
-
-
// End of delegates.... Common code below here...
// Endianness
@@ -1218,13 +1315,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;
}
@@ -1275,6 +1378,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*/
@@ -1311,7 +1438,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;
}
@@ -1330,7 +1457,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);
}
@@ -1355,6 +1482,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) {
@@ -1374,7 +1504,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;
}
@@ -1393,7 +1523,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);
}
@@ -1477,7 +1607,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);
@@ -1487,26 +1617,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;
@@ -1527,9 +1657,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];
@@ -1539,11 +1669,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));
@@ -1560,11 +1690,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 {
@@ -1604,18 +1734,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;
}
@@ -1630,7 +1760,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;
@@ -1641,26 +1771,33 @@ 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){
- if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) ||
- (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) ||
- (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) ||
+ if ((sl->chip_id == STLINK_CHIPID_STM32_F2) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F4) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F411RE) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F446) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) ||
(sl->chip_id == STLINK_CHIPID_STM32_F412)) {
uint32_t sector=calculate_F4_sectornum(flashaddr);
if (sector>= 12) {
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) {
+ 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;
@@ -1674,7 +1811,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){
*/
int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
{
- if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L4) {
+ if (sl->flash_type == STLINK_FLASH_TYPE_F4 ||
+ sl->flash_type == STLINK_FLASH_TYPE_L4) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);
@@ -1693,7 +1831,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr));
write_flash_cr_bker_pnb(sl, page);
- } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) {
+ } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) {
// calculate the actual page from the address
uint32_t sector=calculate_F7_sectornum(flashaddr);
@@ -1728,7 +1867,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
uint32_t val;
uint32_t flash_regs_base;
- if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) {
+ if (sl->chip_id == STLINK_CHIPID_STM32_L0 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L011) {
flash_regs_base = STM32L0_FLASH_REGS_ADDR;
} else {
flash_regs_base = STM32L_FLASH_REGS_ADDR;
@@ -1736,7 +1878,7 @@ 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);
@@ -1773,7 +1915,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 */
@@ -1793,7 +1935,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
val |= (1 << 0) | (1 << 1) | (1 << 2);
stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val);
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB ||
- sl->flash_type == STLINK_FLASH_TYPE_G0) {
+ sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4) {
uint32_t val;
// Wait for any ongoing Flash operation to finish.
wait_flash_busy(sl);
@@ -1804,7 +1947,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.
@@ -1813,11 +1956,19 @@ 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);
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
+ 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 = ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER );
- stlink_write_debug32(sl, STM32G0_FLASH_CR, val);
+ 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) / (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);
+ val |= ((flash_page & 0x7F) << 3) | ( 1 << FLASH_CR_PER );
+ stlink_write_debug32(sl, STM32Gx_FLASH_CR, val);
}
// Set the 'start operation' bit.
@@ -1828,13 +1979,17 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
clear_flash_cr_per(sl);
// Re-lock the flash.
lock_flash(sl);
- } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) {
+ } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) ||
+ ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);
/* 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);
@@ -1881,10 +2036,11 @@ 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, WB series. */
- if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_WB) {
+ /* 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_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;
@@ -1920,6 +2076,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);
@@ -1995,7 +2153,10 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin
uint32_t flash_regs_base;
flash_loader_t fl;
- if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) {
+ if (sl->chip_id == STLINK_CHIPID_STM32_L0 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L011) {
flash_regs_base = STM32L0_FLASH_REGS_ADDR;
} else {
flash_regs_base = STM32L_FLASH_REGS_ADDR;
@@ -2114,7 +2275,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);
}
@@ -2148,7 +2309,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
set_flash_cr_pg(sl);
size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000;
- for(off = 0; off < len;) {
+ for (off = 0; off < len;) {
size_t size = len - off > buf_size ? buf_size : len - off;
printf("size: %u\n", (unsigned int)size);
@@ -2167,7 +2328,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
} //STM32F4END
else if (sl->flash_type == STLINK_FLASH_TYPE_WB ||
- sl->flash_type == STLINK_FLASH_TYPE_G0) {
+ sl->flash_type == STLINK_FLASH_TYPE_G0 ||
+ sl->flash_type == STLINK_FLASH_TYPE_G4) {
fprintf(stdout, "Writing\r\n");
fflush(stdout);
// Wait for any ongoing operations to finish.
@@ -2214,7 +2376,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
uint32_t flash_regs_base;
uint32_t pagesize;
- if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) {
+ if (sl->chip_id == STLINK_CHIPID_STM32_L0 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L011) {
flash_regs_base = STM32L0_FLASH_REGS_ADDR;
pagesize = L0_WRITE_BLOCK_SIZE;
} else {
@@ -2328,11 +2493,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]);
@@ -2345,15 +2510,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;
@@ -2361,7 +2526,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;
@@ -2371,7 +2536,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;
@@ -2380,17 +2545,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;
@@ -2398,17 +2563,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;
@@ -2419,17 +2584,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;
}
}
@@ -2449,7 +2614,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 {
@@ -2465,13 +2630,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 {
@@ -2494,17 +2659,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;
@@ -2529,17 +2708,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);
@@ -2553,42 +2746,29 @@ 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_g0x1(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 writting option bytes, must be 4 is %d\n", len);
- return -1;
- }
-
- /* Unlock flash if necessary (ref manuel page 52) */
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- if ((val & (1u << STM32G0_FLASH_CR_LOCK))) {
-
- /* disable flash write protection. */
- stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123);
- stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB);
+ (void) addr;
+ (void) len;
- // check that the lock is no longer set.
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- if ((val & (1u << STM32G0_FLASH_CR_LOCK))) {
- ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n");
- return -1;
- }
+ if (unlock_flash_if(sl)) {
+ 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, STM32G0_FLASH_CR, &val);
- if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) {
+ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
+ if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) {
/* disable option byte write protection. */
- stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x08192A3B);
- stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x4C5D6E7F);
+ 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, STM32G0_FLASH_CR, &val);
- if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) {
+ 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;
}
@@ -2597,32 +2777,34 @@ static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t
/* 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, STM32G0_FLASH_OPTR, data);
+ WLOG("Writing option bytes %#10x to %#10x\n", data, addr);
+ //stlink_write_debug32(sl, addr, data);
+ stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data);
/* Set Options Start bit */
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- val |= (1 << STM32G0_FLASH_CR_OPTSTRT);
- stlink_write_debug32(sl, STM32G0_FLASH_CR, val);
+ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
+ 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, STM32G0_FLASH_SR, &val);
- } while ((val & (1 << 16)) != 0);
+ stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val);
+ } while ((val & (1 << STM32Gx_FLASH_SR_BSY)) != 0);
+
+ check_flash_error(sl);
/* apply options bytes immediate */
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- val |= (1 << STM32G0_FLASH_CR_OBL_LAUNCH);
- stlink_write_debug32(sl, STM32G0_FLASH_CR, val);
+ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
+ val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH);
+ stlink_write_debug32(sl, STM32Gx_FLASH_CR, val);
/* Re-lock option bytes */
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- val |= (1u << STM32G0_FLASH_CR_OPTLOCK);
- stlink_write_debug32(sl, STM32G0_FLASH_CR, val);
+ 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. */
- stlink_read_debug32(sl, STM32G0_FLASH_CR, &val);
- val |= (1u << STM32G0_FLASH_CR_LOCK);
- stlink_write_debug32(sl, STM32G0_FLASH_CR, val);
+ lock_flash(sl);
return 0;
}
@@ -2635,14 +2817,12 @@ static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t
* @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) {
+static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) {
uint32_t val;
+ (void) addr;
+ (void) len;
- 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");
@@ -2675,7 +2855,7 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32
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);
+ stlink_write_debug32(sl, STM32_L0_CATx_OPTION_BYTES_BASE, data);
/* Reload options */
stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val);
@@ -2685,14 +2865,187 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32
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_l1(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) {
+
+ uint32_t val;
+ uint32_t data;
+
+ 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;
+ }
+ }
+
+
+ /* Clear errors */
+ stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00);
+
+ stlink_read_debug32(sl, addr, &val);
+ WLOG("Option bytes 0x%08x is 0x%08x\n",addr,val);
+
+ /* Write options bytes */
+ write_uint32((unsigned char*) &data, *(uint32_t*) (base));
+ if ( data != val ) {
+ WLOG("Writing option bytes 0x%04x\n", data);
+ 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);
+
+ /* 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);
+ stlink_read_debug32(sl, addr+4, &val);
+ WLOG("2nd option bytes is 0x%08x\n",val);
+ }
+ }
+
+ /* 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);
+
+ 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_l496x(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) {
+
+ uint32_t val;
+
+ (void) addr;
+ (void) len;
+
+ /* 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;
+ }
+ }
+
+ /* 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, STM32L4_FLASH_OPTR, data);
+
+ /* Set Options Start bit */
+ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val);
+ val |= (1 << STM32L4_FLASH_CR_OPTSTRT);
+ 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);
+
+ /* 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;
+}
+
+
/**
* Write option bytes
* @param sl
* @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) {
+static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_t addr, size_t len) {
uint32_t val;
+ uint32_t option_byte;
+
+ (void) addr; /* todo: add sanitary check */
+
+ if(len != 4) {
+ ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len);
+ return -1;
+ }
+
+ option_byte = *(uint32_t*) (base);
stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val);
if (val & FLASH_F2_OPT_LOCK_BIT) {
@@ -2720,7 +3073,7 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) {
stlink_read_debug32(sl, FLASH_F2_SR, &val);
WLOG("wait BSY flag to be 0\n");
- while(val & 0x00010000){
+ while (val & 0x00010000){
stlink_read_debug32(sl, FLASH_F2_SR, &val);
}
WLOG("BSY flag is 0\n");
@@ -2741,8 +3094,18 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) {
* @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) {
+static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) {
uint32_t val;
+ uint32_t option_byte;
+
+ (void) addr; /* todo: add sanitary check */
+
+ if(len != 4) {
+ ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len);
+ return -1;
+ }
+
+ option_byte = *(uint32_t*) (base);
stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
if (val & FLASH_F4_OPT_LOCK_BIT) {
@@ -2766,11 +3129,10 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) {
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){
+ while (val & 0x00010000){
stlink_read_debug32(sl, FLASH_F4_SR, &val);
}
WLOG("BSY flag is 0\n");
@@ -2785,6 +3147,19 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) {
return 0;
}
+/**
+ * Read option bytes
+ * @param sl
+ * @param option_byte value to write
+ * @return 0 on success, -ve on failure.
+ */
+int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte)
+{
+ uint32_t ret = stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte);
+ WLOG("option bytes CR = %#010x\n", *option_byte);
+ return ret;
+}
+
/**
* Read option bytes
* @param sl
@@ -2821,7 +3196,7 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* 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) {
@@ -2843,13 +3218,62 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) {
}
stlink_read_debug32(sl, FLASH_F4_OPT_CR, option_byte);
- WLOG("option bytes CR = %x\n",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);
return 0;
}
+/**
+* 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);
+}
+
+/**
+ * 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;
+ }
+ 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);
+ }
+}
+
+/**
+ * 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);
+}
/**
* Write option bytes
@@ -2858,23 +3282,45 @@ 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);
-
- /* Check if chip is supported and for correct address */
- if((sl->chip_id == STLINK_CHIPID_STM32_G0X1) && (addr == STM32_G0_OPTION_BYTES_BASE)) {
- return stlink_write_option_bytes_g0x1(sl, base, len);
+int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t 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 {
- ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n");
+
+ if (addr + len > sl->option_base + sl->option_size) {
+ ELOG("Option bytes data too long\n");
return -1;
}
+ switch (sl->chip_id) {
+ case STLINK_CHIPID_STM32_F2:
+ return stlink_write_option_bytes_f2(sl, base, addr, len);
+ case STLINK_CHIPID_STM32_F446:
+ return stlink_write_option_bytes_f4(sl, base, addr, len);
+ case STLINK_CHIPID_STM32_L0_CAT2:
+ return stlink_write_option_bytes_l0_cat2(sl, base, addr, len);
+ case STLINK_CHIPID_STM32_L496X:
+ return stlink_write_option_bytes_l496x(sl, base, addr, len);
+ case STLINK_CHIPID_STM32_L152_RE:
+ case STLINK_CHIPID_STM32_L1_HIGH:
+ return stlink_write_option_bytes_l1(sl, base, addr, len);
+ 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_write_option_bytes_gx(sl, base, addr, len);
+ default:
+ ELOG("Option bytes writing is currently not implemented for connected chip\n");
+ return -1;
+ }
+
}
/**
@@ -2894,28 +3340,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 eaf81019e..6d3d83fdb 100644
--- a/src/flash_loader.c
+++ b/src/flash_loader.c
@@ -226,7 +226,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;
@@ -255,32 +255,37 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
const uint8_t* loader_code;
size_t loader_size;
- if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2
- || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH
- || sl->chip_id == STLINK_CHIPID_STM32_L152_RE || sl->chip_id == STLINK_CHIPID_STM32_L011
- || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */
+ if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM ||
+ sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS ||
+ sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH ||
+ sl->chip_id == STLINK_CHIPID_STM32_L152_RE ||
+ sl->chip_id == STLINK_CHIPID_STM32_L011 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 ||
+ sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
- } else if (sl->core_id == STM32VL_CORE_ID
- || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM
- || sl->chip_id == STLINK_CHIPID_STM32_F3
- || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL
- || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH
- || sl->chip_id == STLINK_CHIPID_STM32_F37x
- || sl->chip_id == STLINK_CHIPID_STM32_F334) {
+ } else if (sl->core_id == STM32VL_CORE_ID ||
+ sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM ||
+ sl->chip_id == STLINK_CHIPID_STM32_F3 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL ||
+ sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH ||
+ sl->chip_id == STLINK_CHIPID_STM32_F37x ||
+ sl->chip_id == STLINK_CHIPID_STM32_F334) {
loader_code = loader_code_stm32vl;
loader_size = sizeof(loader_code_stm32vl);
- } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 ||
- sl->chip_id == STLINK_CHIPID_STM32_F4 ||
- sl->chip_id == STLINK_CHIPID_STM32_F4_DE ||
- sl->chip_id == STLINK_CHIPID_STM32_F4_LP ||
- sl->chip_id == STLINK_CHIPID_STM32_F4_HD ||
- sl->chip_id == STLINK_CHIPID_STM32_F4_DSI ||
- sl->chip_id == STLINK_CHIPID_STM32_F410 ||
- sl->chip_id == STLINK_CHIPID_STM32_F411RE ||
- sl->chip_id == STLINK_CHIPID_STM32_F412 ||
- sl->chip_id == STLINK_CHIPID_STM32_F413 ||
- sl->chip_id == STLINK_CHIPID_STM32_F446
+ } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F4 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F4_DE ||
+ sl->chip_id == STLINK_CHIPID_STM32_F4_LP ||
+ sl->chip_id == STLINK_CHIPID_STM32_F4_HD ||
+ sl->chip_id == STLINK_CHIPID_STM32_F4_DSI ||
+ sl->chip_id == STLINK_CHIPID_STM32_F410 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F411RE ||
+ sl->chip_id == STLINK_CHIPID_STM32_F412 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F413 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F446
) {
int retval;
retval = loader_v_dependent_assignment(sl,
@@ -290,8 +295,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
if (retval == -1) {
return retval;
}
- } else if (sl->core_id == STM32F7_CORE_ID ||
- sl->chip_id == STLINK_CHIPID_STM32_F7 ||
+ } else if (sl->core_id == STM32F7_CORE_ID ||
+ sl->chip_id == STLINK_CHIPID_STM32_F7 ||
sl->chip_id == STLINK_CHIPID_STM32_F7XXXX ||
sl->chip_id == STLINK_CHIPID_STM32_F72XXX
) {
@@ -303,15 +308,19 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
if (retval == -1) {
return retval;
}
- } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) {
+ } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F04 ||
+ sl->chip_id == STLINK_CHIPID_STM32_F0_CAN ||
+ sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL ||
+ sl->chip_id == STLINK_CHIPID_STM32_F09X) {
loader_code = loader_code_stm32f0;
loader_size = sizeof(loader_code_stm32f0);
} else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) ||
- (sl->chip_id == STLINK_CHIPID_STM32_L41X) ||
- (sl->chip_id == STLINK_CHIPID_STM32_L43X) ||
- (sl->chip_id == STLINK_CHIPID_STM32_L46X) ||
- (sl->chip_id == STLINK_CHIPID_STM32_L4RX) ||
- (sl->chip_id == STLINK_CHIPID_STM32_L496X))
+ (sl->chip_id == STLINK_CHIPID_STM32_L41X) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_L43X) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_L46X) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_L4RX) ||
+ (sl->chip_id == STLINK_CHIPID_STM32_L496X))
{
loader_code = loader_code_stm32l4;
loader_size = sizeof(loader_code_stm32l4);
@@ -347,11 +356,13 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
return -1;
}
- if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
+ if ((sl->flash_type == STLINK_FLASH_TYPE_F0) ||
+ (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
count = size / sizeof(uint16_t);
if (size % sizeof(uint16_t))
++count;
- } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) {
+ } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 ||
+ sl->flash_type == STLINK_FLASH_TYPE_L0) {
count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t))
++count;
@@ -375,10 +386,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
index 2393690ce..ff9bde165 100644
--- a/src/gdbserver/CMakeLists.txt
+++ b/src/gdbserver/CMakeLists.txt
@@ -4,21 +4,20 @@ set(STUTIL_SOURCE
gdb-server.c
gdb-server.h
semihosting.c
- semihosting.h)
+ semihosting.h
+ )
if (MSVC)
# We need a getopt from somewhere...
set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c")
-endif()
+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()
+ target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB})
+else ()
+ target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB})
+endif ()
-install(TARGETS st-util
- RUNTIME DESTINATION bin
-)
+install(TARGETS st-util RUNTIME DESTINATION bin)
diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c
index e4aad312d..3b1794f3e 100644
--- a/src/gdbserver/gdb-remote.c
+++ b/src/gdbserver/gdb-remote.c
@@ -27,7 +27,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 +36,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 +64,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 +79,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 +95,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 +127,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 +137,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,13 +157,13 @@ 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;
}
diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c
index 2dfbc7454..dadb3f56e 100644
--- a/src/gdbserver/gdb-server.c
+++ b/src/gdbserver/gdb-server.c
@@ -89,10 +89,10 @@ static stlink_t* do_connect(st_state_t *st) {
stlink_t *ret = NULL;
switch (st->stlink_version) {
case 2:
- if(serial_specified){
+ if (serial_specified){
ret = stlink_open_usb(st->logging_level, st->reset, serialnumber);
}
- else{
+ else {
ret = stlink_open_usb(st->logging_level, st->reset, NULL);
}
break;
@@ -199,8 +199,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);
@@ -234,7 +234,14 @@ int main(int argc, char** argv) {
printf("st-util %s\n", STLINK_VERSION);
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 +252,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
@@ -449,7 +454,7 @@ static const char* const memory_map_template_L496 =
""
" " // code = sram, bootrom or flash; flash is bigger
" " // SRAM2 (64 KB)
- " " // SRAM1 (256 KB)
+ " " // SRAM1 + aliased SRAM2 (256+64=320 KB)
" "
" 0x800"
" "
@@ -531,27 +536,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 +607,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 +624,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 +663,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 +702,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 +710,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 +723,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 +735,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 +753,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 +793,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 +819,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 +830,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 +842,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 +863,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 +885,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 +960,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 +976,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 +991,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 +1039,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 +1067,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 +1081,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 +1097,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 +1119,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 +1142,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 +1160,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 +1169,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 +1188,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 +1207,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 +1235,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");
+
+ }
- DLOG("Rcmd: jtag_reset\n");
+ ret = stlink_jtag_reset(sl, 1);
+ if (ret) {
+ DLOG("Rcmd: jtag_reset failed with jtag_reset\n");
+ reply = strdup("E00");
+
+ }
+
+ 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 +1332,7 @@ int serve(stlink_t *sl, st_state_t *st) {
free(cmd);
}
- if(reply == NULL)
+ if (reply == NULL)
reply = strdup("");
free(queryName);
@@ -1293,7 +1346,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 +1359,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 +1379,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 +1389,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 +1421,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);
+ 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 +1454,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 +1481,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 +1516,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 +1539,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 +1554,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 +1608,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 +1645,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 +1680,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 +1697,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 +1712,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 +1727,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 +1747,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 +1758,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 +1794,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 +1826,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 +1844,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 +1879,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 +1894,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/semihosting.c b/src/gdbserver/semihosting.c
index 9e92cf3bd..40758b61d 100644
--- a/src/gdbserver/semihosting.c
+++ b/src/gdbserver/semihosting.c
@@ -178,7 +178,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 +215,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 +238,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 +263,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 +289,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 +322,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 +357,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 +385,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 +414,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 +438,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 +482,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/logging.c b/src/logging.c
index d2ca11f2a..c00c172ae 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -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/src/md5.c b/src/md5.c
new file mode 100755
index 000000000..e2b526c7d
--- /dev/null
+++ b/src/md5.c
@@ -0,0 +1,339 @@
+/*
+ * 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 "md5.h"
+#include
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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/sg.c b/src/sg.c
index 4e8349bc2..8e6bb34e8 100644
--- a/src/sg.c
+++ b/src/sg.c
@@ -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,7 +424,6 @@ 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);
@@ -443,7 +435,6 @@ 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");
@@ -525,7 +516,6 @@ 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);
@@ -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,7 +575,6 @@ 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;
@@ -696,7 +682,6 @@ 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");
@@ -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);
@@ -764,7 +747,6 @@ 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;
@@ -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);
diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt
new file mode 100644
index 000000000..74b71cecd
--- /dev/null
+++ b/src/stlink-gui/CMakeLists.txt
@@ -0,0 +1,35 @@
+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}")
+endif ()
+
+set(GUI_SOURCES gui.c gui.h)
+set(INSTALLED_UI_DIR share/stlink) ### TODO: Check Path
+
+include_directories(SYSTEM ${GTK3_INCLUDE_DIRS})
+
+# stlink-gui-local
+add_executable(stlink-gui-local ${GUI_SOURCES})
+set_target_properties(
+ stlink-gui-local PROPERTIES
+ COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ### TODO: Check Path
+ )
+target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB})
+
+# stlink-gui
+add_executable(stlink-gui ${GUI_SOURCES})
+set_target_properties(
+ stlink-gui PROPERTIES
+ COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" ### TODO: Check Path
+ )
+target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB})
+
+install(TARGETS stlink-gui RUNTIME DESTINATION bin) ### TODO: Check Path
+install(FILES gui.ui DESTINATION ${INSTALLED_UI_DIR}) ### TODO: Check Path
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop entry
+ install(FILES icons/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) # Install icon
+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..f90196c06 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);
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,34 @@ 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";
+ gchar *ui_file = STLINK_UI_DIR "/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 = "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 +790,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 +819,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 +830,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 +876,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 +886,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/tools/gui/stlink-gui.ui b/src/stlink-gui/gui.ui
similarity index 100%
rename from src/tools/gui/stlink-gui.ui
rename to src/stlink-gui/gui.ui
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 100%
rename from src/tools/gui/stlink-gui.desktop
rename to src/stlink-gui/stlink-gui.desktop
diff --git a/src/tools/flash.c b/src/tools/flash.c
index a8d937930..3a9cc3674 100644
--- a/src/tools/flash.c
+++ b/src/tools/flash.c
@@ -29,17 +29,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=] {read|write} [addr] [size]");
+ puts("command line: ./st-flash [--debug] [--serial ] erase");
+ puts("command line: ./st-flash [--debug] [--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 +57,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);
- 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 +74,7 @@ int main(int ac, char** av)
}
sl->verbose = o.log_level;
+ sl->opt = o.opt;
connected_stlink = sl;
signal(SIGINT, &cleanup);
@@ -133,7 +135,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 +144,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 +156,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 +166,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){
+ 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 +176,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 +218,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);
+ 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 if(sl->chip_id == STLINK_CHIPID_STM32_F446){
- uint32_t option_byte = 0;
- err = stlink_read_option_bytes_f4(sl,&option_byte);
- 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 +236,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..085d278db 100644
--- a/src/tools/flash_opts.c
+++ b/src/tools/flash_opts.c
@@ -6,23 +6,29 @@
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;
+static int invalid_args(const char *expected) {
+ fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected);
+ return -1;
+}
- // defaults
+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) {
+ while (ac >= 1) {
if (strcmp(av[0], "--version") == 0) {
printf("v%s\n", STLINK_VERSION);
exit(EXIT_SUCCESS);
@@ -30,12 +36,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 +53,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;
@@ -83,7 +88,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av)
}
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 +97,37 @@ 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=");
- 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 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 {
break; // non-option found
}
@@ -132,8 +136,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 +153,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;
}
@@ -168,52 +167,42 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av)
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;
-
+ if (tail[0] != '\0') return bad_arg("addr");
o->size = strtoul(av[2], &tail, 16);
- if(tail[0] != '\0') return -1;
-
+ if (tail[0] != '\0') return bad_arg("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;
-
+ 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;
+ if (tail[0] != '\0') return bad_arg("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..3ebbba8de 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 --probe");
+ puts("st-info --serial");
+ puts("st-info --hla-serial");
puts("st-info --flash");
- puts("st-info --sram");
- puts("st-info --descr");
puts("st-info --pagesize");
+ puts("st-info --sram");
puts("st-info --chipid");
- puts("st-info --serial");
- puts("st-info --hla-serial");
- puts("st-info --probe");
+ puts("st-info --descr");
}
/* 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)
@@ -113,18 +113,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)
diff --git a/src/usb.c b/src/usb.c
index 12945d6d2..0edf35e46 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -2,19 +2,12 @@
#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
@@ -36,34 +29,34 @@ 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;
+ /* 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;
+ 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;
@@ -151,7 +144,7 @@ static int fill_command
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';
@@ -189,7 +182,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;
}
@@ -470,8 +463,8 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) {
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;
@@ -988,6 +981,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
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) */
int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list);
@@ -1013,6 +1012,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
}
while (cnt--) {
+ struct libusb_device_handle *handle;
+
libusb_get_device_descriptor( list[cnt], &desc );
if (desc.idVendor != STLINK_USB_VID_ST)
continue;
@@ -1024,61 +1025,54 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
}
}
- 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);
- sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber,
- (unsigned char *)sl->serial, sizeof(sl->serial));
- 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)) {
- 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)) {
- sl->version.stlink_v = 3;
- }
+ /* could not open device, continue */
+ if (ret)
+ continue;
- if ((serial == NULL) || (*serial == 0))
- break;
- if (sl->serial_size < 0)
- continue;
+ sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber,
+ (unsigned char *)sl->serial, sizeof(sl->serial));
- if (memcmp(serial, &sl->serial, sl->serial_size) == 0)
- break;
+ if ((serial == NULL) || (*serial == 0))
+ break;
+ if (sl->serial_size < 0)
continue;
- }
- if (desc.idProduct == STLINK_USB_PID_STLINK) {
- slu->protocoll = 1;
- sl->version.stlink_v = 1;
+ if (memcmp(serial, &sl->serial, sl->serial_size) == 0)
break;
- }
+
+ libusb_close(handle);
+
+ /* could not read serial, continue */
+ if (sl->serial_size < 0)
+ continue;
+
+ /* 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 (STLINK_V3_USB_PID(desc.idProduct)) {
+ sl->version.stlink_v = 3;
+ }
+
+ 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;
}
@@ -1116,26 +1110,31 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
// TODO - could use the scanning techniq from stm8 code here...
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_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.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 ||
+ desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) {
slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT;
} else {
slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
}
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);
}
@@ -1149,20 +1148,19 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
}
if (reset) {
- if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2);
+ 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) {
- stlink_close(sl);
- return NULL;
- }
+ stlink_close(sl);
+ return NULL;
- return sl;
on_error:
if (slu->libusb_ctx)
@@ -1181,28 +1179,25 @@ 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)
- continue;
+ 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++;
}
@@ -1217,51 +1212,47 @@ 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)
+ if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) {
continue;
-
- struct libusb_device_handle* handle;
- char serial[STLINK_SERIAL_MAX_SIZE];
- memset(serial, 0, sizeof(serial));
-
- ret = libusb_open(dev, &handle);
- if (ret < 0) {
- WLOG("failed to get libusb device descriptor\n");
- 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)
+ }
+
+ struct libusb_device_handle* handle;
+ char serial[STLINK_SERIAL_MAX_SIZE] = {0,};
+
+ ret = libusb_open(dev, &handle);
+ if (ret < 0) {
+ 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));
+
+ libusb_close(handle);
+
+ if (ret < 0) {
+ continue;
+ }
+
+ stlink_t *sl = stlink_open_usb(0, 1, serial);
+ if (!sl) {
+ ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct);
continue;
+ }
- _sldevs[slcur] = sl;
- slcur++;
- }
-
- /* 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[]) {
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/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8df28ce7e..c6b04ddb3 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,15 +1,12 @@
-set(TESTS
- usb
- sg
-)
+set(TESTS usb sg)
-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()
+foreach (test ${TESTS})
+ add_executable(${test} ${test}.c)
+ add_dependencies(${test} ${STLINK_LIB_STATIC})
+ target_link_libraries(${test} ${STLINK_LIB_STATIC} ${SSP_LIB})
+ add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test})
+endforeach ()
add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c")
-target_link_libraries(flash ${STLINK_LIB_STATIC})
+target_link_libraries(flash ${STLINK_LIB_STATIC} ${SSP_LIB})
add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash)
diff --git a/tests/flash.c b/tests/flash.c
index 6c8b8ed9b..53032474a 100644
--- a/tests/flash.c
+++ b/tests/flash.c
@@ -4,8 +4,9 @@
#include
#include
+
#if defined(_MSC_VER)
-#include
+ #include
#endif
struct Test {
@@ -15,44 +16,50 @@ 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);
@@ -68,46 +75,97 @@ 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,
+ .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,
+ .format = FLASH_FORMAT_BINARY }
+ },
+ { "--debug --reset read test.bin 0x80000000 0x1000", 0,
+ { .cmd = FLASH_CMD_READ,
+ .serial = { 0 },
+ .filename = "test.bin",
+ .addr = 0x80000000,
+ .size = 0x1000,
+ .reset = 1,
+ .log_level = DEBUG_LOG_LEVEL,
+ .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,
+ .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,
+ .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,
+ .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,
+ .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,
+ .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..32ef55b69 100644
--- a/tests/sg.c
+++ b/tests/sg.c
@@ -1,6 +1,6 @@
-/*
+/*
* File: test_main.c
- *
+ *
* main() ripped out of old stlink-hw.c
*/
@@ -10,7 +10,7 @@
#include
#if defined(_MSC_VER)
-#define __attribute__(x)
+ #define __attribute__(x)
#endif
static void __attribute__((unused)) mark_buf(stlink_t *sl) {
@@ -24,24 +24,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 +49,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 +63,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 +88,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 +97,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 +115,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 +146,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 +160,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 +191,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 +201,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..a2c3ef8cd 100644
--- a/tests/usb.c
+++ b/tests/usb.c
@@ -1,10 +1,9 @@
#include
#include
-int main(int ac, char** av)
-{
- (void)ac;
- (void)av;
+int main(int ac, char** av) {
+ (void)ac;
+ (void)av;
stlink_t* sl;
struct stlink_reg regs;
@@ -30,9 +29,13 @@ 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 +46,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 +75,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 +98,5 @@ int main(int ac, char** av)
stlink_close(sl);
}
-
return 0;
}
diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt
deleted file mode 100644
index a656ff623..000000000
--- a/usr/lib/pkgconfig/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}")
-set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}")
-set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}")
-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"
-)
-
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
- DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/
-)