Merge branch 'testing' into 'develop'

develop
nightwalker-87 2024-10-03 23:24:18 +02:00
commit bfcc1e2628
70 zmienionych plików z 862 dodań i 615 usunięć

1
.gitignore vendored
Wyświetl plik

@ -2,6 +2,7 @@ build
build-mingw build-mingw
build-mingw-32 build-mingw-32
build-mingw-64 build-mingw-64
3rdparty
.project .project
.cmake/ .cmake/

Wyświetl plik

@ -1,5 +1,46 @@
# stlink Changelog # stlink Changelog
# v1.8.1
Release date: 2024-09-01
This release drops support for some older operating systems. Check project README for details.
Updated system requirements:
- C-Standard: C17 (ISO/IEC 9899:2018)
- `cmake` >= 3.16.3
- `libusb` >= 1.0.23
- `libgtk-dev` >= 3.24.18
Features:
- Added support for STLINK-V3PWR ([#1388](https://github.com/stlink-org/stlink/pull/1388), [#1389](https://github.com/stlink-org/stlink/pull/1389))
- Dynamic SRAM size for F4 memory map ([#1390](https://github.com/stlink-org/stlink/pull/1390))
- Modifications to allow building of toolset in OpenBSD ([#1392](https://github.com/stlink-org/stlink/pull/1392))
- --mass-erase for st-flash write commands ([#1397](https://github.com/stlink-org/stlink/pull/1397))
- Support for setting option bytes to STM32L41x_L42x (according to RM0394) ([#1405](https://github.com/stlink-org/stlink/pull/1405), [#1412](https://github.com/stlink-org/stlink/pull/1412), [#1413](https://github.com/stlink-org/stlink/pull/1413))
- Improvements for stlink-gui ([#1411](https://github.com/stlink-org/stlink/pull/1411))
- [STM32U575/585]: Added support for OTP bytes ([#1419](https://github.com/stlink-org/stlink/pull/1419))
- [STM32Gx]: Added erase support for multi-bank products ([#1420](https://github.com/stlink-org/stlink/pull/1420))
Updates & changes:
- Debian 11 x64 doesn't work with v1.8.0 because of incompatible glibc ([#1376](https://github.com/stlink-org/stlink/pull/1376), commit [#ece34ef](https://github.com/stlink-org/stlink/commit/ece34efbce579ca7d367c58f903ffa6dc7bd96e6))
- [STM32L4R5ZI]: gdb-multiarch uses wrong osabi ([#1386](https://github.com/stlink-org/stlink/pull/1386), [#1387](https://github.com/stlink-org/stlink/pull/1387), [#1394](https://github.com/stlink-org/stlink/pull/1394))
- [doc] STM32H573 reports chipid 0x000 ([#1398](https://github.com/stlink-org/stlink/pull/1398), commit [#3655871](https://github.com/stlink-org/stlink/commit/3655871f8dd97294bbee191c1c7341c8a129af2f))
Fixes:
- Cmake minimal version mismatch ([#1374](https://github.com/stlink-org/stlink/pull/1374), [#1375](https://github.com/stlink-org/stlink/pull/1375), commit [#1ee7f6b](https://github.com/stlink-org/stlink/commit/1ee7f6b6c05e305112bb070ae571ebbe26c55946))
- Added a graceful way to terminate st-util ([#1395](https://github.com/stlink-org/stlink/pull/1395), [#1396](https://github.com/stlink-org/stlink/pull/1396))
- [st-trace] Bug in function static bool read_trace( ) ([#1400](https://github.com/stlink-org/stlink/pull/1400), commit [#32ce4bf](https://github.com/stlink-org/stlink/commit/32ce4bf88a816fb6a9841a33e6c5f6b593a9b927))
- Fixed STM32H7 FLASH_OPTCR unlock sequence ([#1401](https://github.com/stlink-org/stlink/pull/1401), [#1416](https://github.com/stlink-org/stlink/pull/1416))
- Restored support for STM32G4 Cat4 device STM32G491 ([#1403](https://github.com/stlink-org/stlink/pull/1403), [#1414](https://github.com/stlink-org/stlink/pull/1414))
- Fixed STM32H7 option byte programming ([#1417](https://github.com/stlink-org/stlink/pull/1417))
- Latest release stlink-1.8.0-win32 doesn't run ([#1364](https://github.com/stlink-org/stlink/pull/1364), [#1410](https://github.com/stlink-org/stlink/pull/1410), commit [#e493109](https://github.com/stlink-org/stlink/commit/e4931097f887d8a048d1d188388b82ced918cf08))
- Make path to .chip files relative to installation directory on Windows ([#1421](https://github.com/stlink-org/stlink/pull/1421))
- Replaced deprecated cmd to fix package uninstall ([#1426](https://github.com/stlink-org/stlink/pull/1426))
- Fixed compilation error -Wshorten-64-to-32 in stlink-lib/usb.c ([#1427](https://github.com/stlink-org/stlink/pull/1427))
- st-util cannot parse -V and -F options and --freq option results in a segmentation fault ([#1428](https://github.com/stlink-org/stlink/pull/1428), [#1429](https://github.com/stlink-org/stlink/pull/1429))
# v1.8.0 # v1.8.0
Release date: 2024-02-01 Release date: 2024-02-01
@ -8,6 +49,7 @@ This release drops support for macOS and some older operating systems. Check pro
Removed Travis CI integration as it is no longer functional. Removed Travis CI integration as it is no longer functional.
Updated system requirements: Updated system requirements:
- C-Standard: C11 (ISO/IEC 9899:2011)
- `cmake` >= 3.13.0 - `cmake` >= 3.13.0
- `libusb` >= 1.0.22 - `libusb` >= 1.0.22
- `libgtk-dev` >= 3.22.30 - `libgtk-dev` >= 3.22.30

Wyświetl plik

@ -2,14 +2,14 @@
# General cmake settings # General cmake settings
### ###
cmake_minimum_required(VERSION 3.10.2) cmake_minimum_required(VERSION 3.16.3)
cmake_policy(SET CMP0042 NEW) cmake_policy(SET CMP0042 NEW)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON) set(CMAKE_C_EXTENSIONS ON)
@ -256,35 +256,22 @@ add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} ${STLINK_SOURCE})
set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}")
message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}")
message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}")
set_target_properties(${STLINK_LIB_SHARED} PROPERTIES set_target_properties(${STLINK_LIB_SHARED} PROPERTIES
SOVERSION ${PROJECT_VERSION_MAJOR} SOVERSION ${PROJECT_VERSION_MAJOR}
VERSION ${STLINK_SHARED_VERSION} VERSION ${STLINK_SHARED_VERSION}
OUTPUT_NAME ${PROJECT_NAME} OUTPUT_NAME ${PROJECT_NAME}
) )
# Link shared library # Link shared library
if (WIN32) # ... with Windows libraries if (WIN32)
target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32)
else () else ()
target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB})
endif() endif()
install(TARGETS ${STLINK_LIB_SHARED} install(TARGETS ${STLINK_LIB_SHARED} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Copy libusb DLL-library to binary output folder
if (WIN32)
file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll
DESTINATION ${CMAKE_INSTALL_BINDIR})
file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR})
endif()
### ###
@ -302,17 +289,16 @@ add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} ${STLINK_SOURCE})
set(STLINK_STATIC_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) set(STLINK_STATIC_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}") message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}")
message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}")
message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") message(STATUS "VERSION: ${STLINK_STATIC_VERSION}")
set_target_properties(${STLINK_LIB_STATIC} PROPERTIES set_target_properties(${STLINK_LIB_STATIC} PROPERTIES
SOVERSION ${PROJECT_VERSION_MAJOR} SOVERSION ${PROJECT_VERSION_MAJOR}
VERSION ${STLINK_STATIC_VERSION} VERSION ${STLINK_STATIC_VERSION}
OUTPUT_NAME ${STLINK_LIB_STATIC_OUTPUT_NAME} OUTPUT_NAME ${STLINK_LIB_STATIC_OUTPUT_NAME}
) )
# Link static library # Link static library
if (WIN32) # ... with Windows libraries if (WIN32)
target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32)
else () else ()
target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB})
@ -343,15 +329,15 @@ add_executable(st-util ${ST-UTIL_SOURCES})
add_executable(st-trace ${ST-TRACE_SOURCES}) add_executable(st-trace ${ST-TRACE_SOURCES})
if (WIN32) if (WIN32)
target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-flash ${STLINK_LIB_STATIC})
target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_STATIC})
target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_STATIC})
target_link_libraries(st-trace ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-trace ${STLINK_LIB_STATIC})
else () else ()
target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-flash ${STLINK_LIB_SHARED})
target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_SHARED})
target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_SHARED})
target_link_libraries(st-trace ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-trace ${STLINK_LIB_SHARED})
endif() endif()
install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR})
@ -384,8 +370,8 @@ endif()
if (WIN32) if (WIN32)
set(CMAKE_CHIPS_DIR ./config/chips) set(CMAKE_CHIPS_DIR ./config/chips)
else () else ()
set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/chips) set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/config/chips)
endif () endif()
add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" ) add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" )
file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip)
install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR})
@ -398,6 +384,7 @@ add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI
add_subdirectory(tests) # contains subordinate CMakeLists to build test executables add_subdirectory(tests) # contains subordinate CMakeLists to build test executables
add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages
### ###
# Uninstall target # Uninstall target
### ###

Wyświetl plik

@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at texane@gmail.com. All reported by contacting the project team [here](https://github.com/stlink-org/stlink/discussions). All
complaints will be reviewed and investigated and will result in a response that complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. obligated to maintain confidentiality with regard to the reporter of an incident.

Wyświetl plik

@ -17,7 +17,7 @@ Report a bug by [opening a new issue]() with one of the available templates. It'
1) If using a ST-Link-v2 programmer: Convince yourself that it is recognised as an USB device by your computer, thus reporting device and manufacturer ID. Use a diagnostic tool to probe for enumerated USB devices, e.g [`lsusb -v`](https://linux.die.net/man/8/lsusb) on unix-based systems. 1) If using a ST-Link-v2 programmer: Convince yourself that it is recognised as an USB device by your computer, thus reporting device and manufacturer ID. Use a diagnostic tool to probe for enumerated USB devices, e.g [`lsusb -v`](https://linux.die.net/man/8/lsusb) on unix-based systems.
2) **Use the [ST-Link firmware upgrade tool](https://www.st.com/en/development-tools/stsw-link007.html) based on Java to read out the current firmware version and update to the latest available version. This also works for _non-genuine_ ST programmers and boards.** 2) **Use the [ST-Link firmware upgrade tool](https://www.st.com/en/development-tools/stsw-link007.html) based on Java to read out the current firmware version and update to the latest available version. This also works for _non-genuine_ ST programmers and boards.**
3) Try to make sure you have a working toolchain before starting to build. 3) Try to make sure you have a working toolchain before starting to build.
4) **Update to the _latest_ release version or maybe even use the `develop` branch.** 4) **Update to the _latest_ release version or maybe even use the `testing` branch.**
5) Search for your problem in the available open issues, _before_ opening a new ticket. 5) Search for your problem in the available open issues, _before_ opening a new ticket.
6) Make sure to **use the available issue templates** to submit a bug-report or a feature-request. **Do not replace the prepared text, edit the placeholders instead. _Describe_ your problem.** 6) Make sure to **use the available issue templates** to submit a bug-report or a feature-request. **Do not replace the prepared text, edit the placeholders instead. _Describe_ your problem.**
7) Avoid to add new comments to closed issues unless they confirm a solution already available. 7) Avoid to add new comments to closed issues unless they confirm a solution already available.

Wyświetl plik

@ -10,41 +10,49 @@
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system
FIND_PATH( # libusb header file
LIBUSB_INCLUDE_DIR NAMES libusb.h FIND_PATH(LIBUSB_INCLUDE_DIR
NAMES libusb.h
HINTS /usr/include HINTS /usr/include
) )
# libusb library
set(LIBUSB_NAME usb) set(LIBUSB_NAME usb)
find_library( find_library(LIBUSB_LIBRARY
LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} NAMES ${LIBUSB_NAME}
HINTS /usr /usr/local /opt HINTS /usr /usr/local /opt
) )
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR)
mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
if (NOT LIBUSB_FOUND) if (NOT LIBUSB_FOUND)
message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.")
endif() endif()
elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD; libusb-1.0 is available from ports elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD; libusb is available from ports
FIND_PATH( # libusb header file
LIBUSB_INCLUDE_DIR NAMES libusb.h FIND_PATH(LIBUSB_INCLUDE_DIR
NAMES libusb.h
HINTS /usr/local/include HINTS /usr/local/include
PATH_SUFFIXES libusb-1.0 PATH_SUFFIXES libusb-1.0
) )
# libusb library
set(LIBUSB_NAME usb-1.0) set(LIBUSB_NAME usb-1.0)
find_library( find_library(LIBUSB_LIBRARY
LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} NAMES ${LIBUSB_NAME}
HINTS /usr/local HINTS /usr/local
) )
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR)
mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
if (NOT LIBUSB_FOUND) if (NOT LIBUSB_FOUND)
message(FATAL_ERROR "No libusb-1.0 library found on your system! Install libusb-1.0 from ports or packages.") message(FATAL_ERROR "No libusb-1.0 library found on your system! Install libusb-1.0 from ports or packages.")
endif() endif()
elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian elseif (WIN32 OR (MINGW AND EXISTS "/etc/debian_version")) # Windows OR cross-build with MinGW-toolchain on Debian
# MinGW/MSYS/MSVC: 64-bit or 32-bit? # MinGW: 64-bit or 32-bit?
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "=== Building for Windows (x86-64) ===") message(STATUS "=== Building for Windows (x86-64) ===")
set(ARCH 64) set(ARCH 64)
@ -53,26 +61,20 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to
set(ARCH 32) set(ARCH 32)
endif() endif()
if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... if (NOT LIBUSB_FOUND)
# Preparations for installing libusb library # Preparations for installing libusb library
set(LIBUSB_WIN_VERSION 1.0.25) # set libusb version set(LIBUSB_WIN_VERSION 1.0.27) # set libusb version
set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}.7z)
if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION})
set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE})
set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION})
elseif (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian
set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/${LIBUSB_WIN_ARCHIVE})
set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/3rdparty/libusb-${LIBUSB_WIN_VERSION})
endif()
# Get libusb package # Get libusb package
if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there
message(STATUS "libusb archive already in build folder") message(STATUS "libusb archive already in build folder")
else () # ... download the package else () # ... download the package
message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}")
file(DOWNLOAD file(DOWNLOAD
https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/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 aabe177bde869bfad34278335eaf8955 ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 c72153fc5a32f3b942427b0671897a1a
) )
endif() endif()
@ -84,9 +86,9 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to
WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}
) )
# Find path to libusb library # libusb header file
FIND_PATH( FIND_PATH(LIBUSB_INCLUDE_DIR
LIBUSB_INCLUDE_DIR NAMES libusb.h NAMES libusb.h
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include
PATH_SUFFIXES libusb-1.0 PATH_SUFFIXES libusb-1.0
NO_DEFAULT_PATH NO_DEFAULT_PATH
@ -94,40 +96,46 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to
) )
if (MINGW OR MSYS) if (MINGW OR MSYS)
set(LIBUSB_NAME usb-1.0) # libusb library (static)
find_library( set(LIBUSB_NAME libusb-1.0)
LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} find_library(LIBUSB_LIBRARY
NAMES ${LIBUSB_NAME}
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static
NO_DEFAULT_PATH NO_DEFAULT_PATH
NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_FIND_ROOT_PATH
) )
else (MSVC)
elseif (MSVC) # libusb library
set(LIBUSB_NAME libusb-1.0.lib) set(LIBUSB_NAME libusb-1.0)
find_library( find_library(LIBUSB_LIBRARY
LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} NAMES ${LIBUSB_NAME}
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/dll
NO_DEFAULT_PATH NO_DEFAULT_PATH
NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_FIND_ROOT_PATH
) )
endif() endif()
message(STATUS "Missing libusb library has been installed")
endif() 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_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
FIND_PATH( mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
LIBUSB_INCLUDE_DIR NAMES libusb.h message(STATUS "Missing libusb library has been installed")
HINTS /usr /usr/local /opt
else () # all other OS (unix-based)
# libusb header file
FIND_PATH(LIBUSB_INCLUDE_DIR
NAMES libusb.h
HINTS /usr/include
PATH_SUFFIXES libusb-1.0 PATH_SUFFIXES libusb-1.0
) )
# libusb library
set(LIBUSB_NAME usb-1.0) set(LIBUSB_NAME usb-1.0)
find_library( find_library(LIBUSB_LIBRARY
LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} NAMES ${LIBUSB_NAME}
HINTS /usr /usr/local /opt HINTS /usr /usr/local
) )
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)
if (NOT LIBUSB_FOUND) if (NOT LIBUSB_FOUND)

Wyświetl plik

@ -40,7 +40,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
add_cflag_if_supported("-Wredundant-decls") add_cflag_if_supported("-Wredundant-decls")
endif() endif()
if (NOT (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW))) if (NOT (WIN32 OR (MINGW AND EXISTS "/etc/debian_version")))
add_cflag_if_supported("-fPIC") add_cflag_if_supported("-fPIC")
endif() endif()

Wyświetl plik

@ -25,7 +25,7 @@ elseif (WIN32) # Wi
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}")
set(CPACK_INSTALL_PREFIX "") set(CPACK_INSTALL_PREFIX "")
elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is available on Debian/Ubuntu only elseif (EXISTS "/etc/debian_version" AND (NOT EXISTS WIN32)) # Package-build on Debian/Ubuntu
message(STATUS "Debian-based Linux OS detected") message(STATUS "Debian-based Linux OS detected")
set(CPACK_GENERATOR "DEB;RPM") # RPM requires package `rpm` set(CPACK_GENERATOR "DEB;RPM") # RPM requires package `rpm`

Wyświetl plik

@ -2,4 +2,4 @@ add_subdirectory(deb)
add_subdirectory(rpm) add_subdirectory(rpm)
add_subdirectory(windows) add_subdirectory(windows)
include(cpack_config.cmake) include(${CMAKE_MODULE_PATH}/cpack_config.cmake)

Wyświetl plik

@ -7,15 +7,22 @@ string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files}) foreach (file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}") message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") if (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program("@CMAKE_COMMAND@" execute_process(
ARGS "-E remove \"$ENV{DESTDIR}${file}\"" # remove deprecated: use rm instead,
OUTPUT_VARIABLE rm_out # because it does not check the file path, even return an error.
RETURN_VALUE rm_retval COMMAND "@CMAKE_COMMAND@" -E rm "$ENV{DESTDIR}${file}"
RESULT_VARIABLE rm_retval
ERROR_VARIABLE rm_err
) )
if (NOT "${rm_retval}" STREQUAL 0) if (NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}\n${rm_err}")
# Detect whether the file has been removed.
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(FATAL_ERROR "File has not been removed.\n${rm_err}")
else ()
message(STATUS "File has been removed.")
endif () endif ()
else (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") else ()
message(STATUS "File $ENV{DESTDIR}${file} does not exist.") message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif () endif ()
endforeach () endforeach ()

Wyświetl plik

@ -9,6 +9,6 @@ flash_pagesize 0x20000 // 128 KB
sram_size 0x20000 // 128 KB "DTCM" sram_size 0x20000 // 128 KB "DTCM"
bootrom_base 0x1ff00000 bootrom_base 0x1ff00000
bootrom_size 0x20000 // 128 KB bootrom_size 0x20000 // 128 KB
option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE option_base 0x52002020 // STM32_H7_OPTION_BYTES_BASE
option_size 0x2c // 44 B option_size 0x2c // 44 B
flags swo flags swo

Wyświetl plik

@ -9,6 +9,6 @@ flash_pagesize 0x20000 // 128 KB
sram_size 0x20000 // 128 KB "DTCM" sram_size 0x20000 // 128 KB "DTCM"
bootrom_base 0x1ff00000 bootrom_base 0x1ff00000
bootrom_size 0x20000 // 128 KB bootrom_size 0x20000 // 128 KB
option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE option_base 0x52002020 // STM32_H7_OPTION_BYTES_BASE
option_size 0x2c // 44 B /* FLASH_OPTSR_CUR to FLASH_BOOT_PRGR */ option_size 0x2c // 44 B /* FLASH_OPTSR_CUR to FLASH_BOOT_PRGR */
flags swo dualbank flags swo dualbank

Wyświetl plik

@ -5,10 +5,10 @@ ref_manual_id 0455
chip_id 0x480 // STM32_CHIPID_H7Ax chip_id 0x480 // STM32_CHIPID_H7Ax
flash_type H7 flash_type H7
flash_size_reg 0x08fff80c flash_size_reg 0x08fff80c
flash_pagesize 0x2000 // 8 KB flash_pagesize 0x20000 // 128 KB
sram_size 0x20000 // 128 KB "DTCM" sram_size 0x20000 // 128 KB "DTCM"
bootrom_base 0x1ff00000 bootrom_base 0x1ff00000
bootrom_size 0x20000 // 128 KB bootrom_size 0x20000 // 128 KB
option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE option_base 0x52002020 // STM32_H7_OPTION_BYTES_BASE
option_size 0x2c // 44 B option_size 0x2c // 44 B
flags swo dualbank flags swo dualbank

Wyświetl plik

@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB
sram_size 0xa000 // 40 KB sram_size 0xa000 // 40 KB
bootrom_base 0x1fff0000 bootrom_base 0x1fff0000
bootrom_size 0x7000 // 28 KB bootrom_size 0x7000 // 28 KB
option_base 0x0 option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE
option_size 0x0 option_size 0x4 // 4 B
flags swo flags swo

Wyświetl plik

@ -12,3 +12,5 @@ bootrom_size 0x10000 // 64 KB
option_base 0x0 option_base 0x0
option_size 0x0 option_size 0x0
flags swo dualbank flags swo dualbank
otp_base 0x0BFA0000
otp_size 0x200

Wyświetl plik

@ -27,7 +27,12 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374e", \
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374f", \ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374f", \
MODE:="0666", \ MODE:="0666", \
SYMLINK+="stlinkv3_%n" SYMLINK+="stlinkv3_%n"
# STLink V3PWR
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3757", \
MODE:="0666", \
SYMLINK+="stlinkv3_%n"
# If you share your linux system with other users, or just don't like the # 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 # idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with # OWNER:="yourusername" to create the device owned by you, or with

10
debian/changelog vendored
Wyświetl plik

@ -1,3 +1,13 @@
stlink (1.8.0-1) unstable; urgency=medium
* Switch to gbp workflow, binary OSX blobs no longer included upstream
* Merge tag 'upstream/1.8.0' into debian
* Drop cross.patch, merged upstream
* Install chips definitions in stlink-tools
* Update symbols files for 1.8.0
-- Luca Boccassi <bluca@debian.org> Thu, 08 Feb 2024 19:28:19 +0000
stlink (1.7.0+ds-1) unstable; urgency=medium stlink (1.7.0+ds-1) unstable; urgency=medium
* Merge tag 'v1.7.0' into debian. (Closes: #984356) * Merge tag 'v1.7.0' into debian. (Closes: #984356)

22
debian/control vendored
Wyświetl plik

@ -1,47 +1,43 @@
Source: stlink Source: stlink
Priority: optional Priority: optional
Maintainer: Luca Boccassi <bluca@debian.org> Maintainer: Luca Boccassi <bluca@debian.org>
Build-Depends: debhelper-compat (= 13), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev Build-Depends: debhelper-compat (= 13), cmake, libusb-1.0-0-dev, libgtk-3-dev, pkgconf, systemd-dev
Standards-Version: 4.5.1 Standards-Version: 4.6.2
Rules-Requires-Root: no Rules-Requires-Root: no
Section: electronics Section: electronics
Homepage: https://github.com/stlink-org/stlink Homepage: https://github.com/stlink-org/stlink
Vcs-Git: https://github.com/bluca/stlink.git -b debian Vcs-Git: https://github.com/bluca/stlink.git -b debian
Vcs-Browser: https://github.com/bluca/stlink Vcs-Browser: https://github.com/bluca/stlink
Package: stlink-lib-dev Package: libstlink-dev
Section: libdevel Section: libdevel
Architecture: linux-any Architecture: linux-any
Multi-Arch: same Multi-Arch: same
Depends: stlink-lib (= ${binary:Version}), ${misc:Depends} Depends: libstlink1 (= ${binary:Version}), ${misc:Depends}
Replaces: libstlink-dev (<< 1.7.0+ds-1)
Breaks: libstlink-dev (<< 1.7.0+ds-1)
Description: Open source version of the STMicroelectronics STLINK Tools Description: Open source version of the STMicroelectronics STLINK Tools
. .
This package contains development files for stlink. This package contains the development files for stlink.
Package: stlink-lib Package: libstlink1
Section: libs Section: libs
Architecture: linux-any Architecture: linux-any
Multi-Arch: same Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends} Depends: ${shlibs:Depends}, ${misc:Depends}
Replaces: libstlink1 (<< 1.7.0+ds-1)
Breaks: libstlink1 (<< 1.7.0+ds-1)
Description: Open source version of the STMicroelectronics STLINK Tools Description: Open source version of the STMicroelectronics STLINK Tools
. .
This package contains the shared library for stlink. This package contains the shared library for stlink.
Package: stlink-tools Package: stlink-tools
Architecture: linux-any Architecture: linux-any
Depends: stlink-lib (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Description: Open source version of the STMicroelectronics STLINK Tools Description: Open source version of the STMicroelectronics STLINK Tools
. .
This package contains commandline utilities for stlink, as well as modprobe This package contains commandline utilities for stlink, and modprobe
and udev rules. and udev rules.
Package: stlink-gui Package: stlink-gui
Architecture: linux-any Architecture: linux-any
Depends: stlink-lib (= ${binary:Version}), stlink-tools (= ${binary:Version}), Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}),
${shlibs:Depends}, ${misc:Depends} ${shlibs:Depends}, ${misc:Depends}
Description: Open source version of the STMicroelectronics STLINK Tools Description: Open source version of the STMicroelectronics STLINK Tools
. .

3
debian/copyright vendored
Wyświetl plik

@ -2,9 +2,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: stlink Upstream-Name: stlink
Upstream-Contact: Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Upstream-Contact: Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com>
Source: https://github.com/stlink-org/stlink Source: https://github.com/stlink-org/stlink
Comment: Upstream tarball has been repackaged to remove binary OSX kernel
drivers that are of unknown license and of no use to Debian.
Files-Excluded: stlinkv1_macos_driver
Files: * Files: *
Copyright: 2011-2021 The stlink project maintainers Copyright: 2011-2021 The stlink project maintainers

11
debian/gbp.conf vendored
Wyświetl plik

@ -1,7 +1,12 @@
[buildpackage] [DEFAULT]
upstream-tag = %(version)s
debian-branch = debian debian-branch = debian
upstream-branch = upstream
pristine-tar = True
sign-tags = True
[import-orig]
upstream-vcs-tag = v%(version)s
[dch] [dch]
git-log = --first-parent
customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py
git-log = --first-parent

3
debian/rules vendored
Wyświetl plik

@ -10,12 +10,15 @@ include /usr/share/dpkg/default.mk
# see FEATURE AREAS in dpkg-buildflags(1) # see FEATURE AREAS in dpkg-buildflags(1)
export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export deb_udevdir = $(shell pkg-config --variable=udevdir udev | sed s,^/,,)
%: %:
dh $@ --buildsystem cmake dh $@ --buildsystem cmake
override_dh_auto_configure: override_dh_auto_configure:
dh_auto_configure -- \ dh_auto_configure -- \
-DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d'
-DSTLINK_UDEV_RULES_DIR=/$(deb_udevdir)/rules.d
override_dh_auto_install: override_dh_auto_install:
dh_auto_install dh_auto_install

Wyświetl plik

@ -1,4 +1,4 @@
stlink-lib.so.1 stlink-lib #MINVER# libstlink.so.1 libstlink1 #MINVER#
Md5Calculate@Base 1.6.1 Md5Calculate@Base 1.6.1
Md5Finalise@Base 1.6.1 Md5Finalise@Base 1.6.1
Md5Initialise@Base 1.6.1 Md5Initialise@Base 1.6.1
@ -62,13 +62,32 @@ stlink-lib.so.1 stlink-lib #MINVER#
calculate_F7_sectornum@Base 1.5.0 calculate_F7_sectornum@Base 1.5.0
calculate_H7_sectornum@Base 1.7.0 calculate_H7_sectornum@Base 1.7.0
calculate_L4_page@Base 1.5.0 calculate_L4_page@Base 1.5.0
check_file@Base 1.8.0
check_flash_error@Base 1.8.0
clear_flash_cr_pg@Base 1.8.0
clear_flash_error@Base 1.8.0
dump_a_chip@Base 1.8.0
get_stm32l0_flash_base@Base 1.8.0
init_chipids@Base 1.8.0
#MISSING: 1.7.0# is_bigendian@Base 1.5.0 #MISSING: 1.7.0# is_bigendian@Base 1.5.0
is_flash_busy@Base 1.8.0
lock_flash@Base 1.8.0
lock_flash_option@Base 1.8.0
map_file@Base 1.8.0
md5_calculate@Base 1.8.0
process_chipfile@Base 1.8.0
read_flash_cr@Base 1.8.0
read_flash_sr@Base 1.8.0
read_uint16@Base 1.5.0 read_uint16@Base 1.5.0
read_uint32@Base 1.5.0 read_uint32@Base 1.5.0
send_recv@Base 1.5.0 send_recv@Base 1.5.0
send_usb_data_only@Base 1.5.0 send_usb_data_only@Base 1.5.0
send_usb_mass_storage_command@Base 1.5.0 send_usb_mass_storage_command@Base 1.5.0
stlink_calculate_pagesize@Base 1.5.0 stlink_calculate_pagesize@Base 1.5.0
stlink_check_address_alignment@Base 1.8.0
stlink_check_address_range_validity@Base 1.8.0
stlink_check_address_range_validity_otp@Base 1.8.0
stlink_checksum@Base 1.8.0
stlink_chip_id@Base 1.5.0 stlink_chip_id@Base 1.5.0
stlink_chipid_get_params@Base 1.5.0 stlink_chipid_get_params@Base 1.5.0
stlink_close@Base 1.5.0 stlink_close@Base 1.5.0
@ -80,6 +99,7 @@ stlink-lib.so.1 stlink-lib #MINVER#
stlink_enter_swd_mode@Base 1.5.0 stlink_enter_swd_mode@Base 1.5.0
stlink_erase_flash_mass@Base 1.5.0 stlink_erase_flash_mass@Base 1.5.0
stlink_erase_flash_page@Base 1.5.0 stlink_erase_flash_page@Base 1.5.0
stlink_erase_flash_section@Base 1.8.0
stlink_exit_debug_mode@Base 1.5.0 stlink_exit_debug_mode@Base 1.5.0
stlink_exit_dfu_mode@Base 1.5.0 stlink_exit_dfu_mode@Base 1.5.0
stlink_fcheck_flash@Base 1.5.0 stlink_fcheck_flash@Base 1.5.0
@ -91,6 +111,7 @@ stlink-lib.so.1 stlink-lib #MINVER#
stlink_flashloader_write@Base 1.7.0 stlink_flashloader_write@Base 1.7.0
stlink_force_debug@Base 1.5.0 stlink_force_debug@Base 1.5.0
stlink_fread@Base 1.5.0 stlink_fread@Base 1.5.0
stlink_fwrite_finalize@Base 1.8.0
stlink_fwrite_flash@Base 1.5.0 stlink_fwrite_flash@Base 1.5.0
stlink_fwrite_option_bytes@Base 1.6.0 stlink_fwrite_option_bytes@Base 1.6.0
#MISSING: 1.6.1# stlink_fwrite_option_bytes_32bit@Base 1.6.0 #MISSING: 1.6.1# stlink_fwrite_option_bytes_32bit@Base 1.6.0
@ -112,20 +133,24 @@ stlink-lib.so.1 stlink-lib #MINVER#
stlink_read_debug32@Base 1.5.0 stlink_read_debug32@Base 1.5.0
stlink_read_mem32@Base 1.5.0 stlink_read_mem32@Base 1.5.0
stlink_read_option_bytes32@Base 1.6.1 stlink_read_option_bytes32@Base 1.6.1
stlink_read_option_bytes_Gx@Base 1.6.1 #MISSING: 1.8.0# stlink_read_option_bytes_Gx@Base 1.6.1
stlink_read_option_bytes_boot_add32@Base 1.7.0 stlink_read_option_bytes_boot_add32@Base 1.7.0
stlink_read_option_bytes_boot_add_f7@Base 1.7.0 stlink_read_option_bytes_boot_add_f7@Base 1.7.0
stlink_read_option_bytes_f2@Base 1.6.0 stlink_read_option_bytes_f2@Base 1.6.0
stlink_read_option_bytes_f4@Base 1.6.0 stlink_read_option_bytes_f4@Base 1.6.0
stlink_read_option_bytes_f7@Base 1.7.0 stlink_read_option_bytes_f7@Base 1.7.0
stlink_read_option_bytes_generic@Base 1.6.1 stlink_read_option_bytes_generic@Base 1.6.1
stlink_read_option_bytes_gx@Base 1.8.0
stlink_read_option_control_register1_32@Base 1.7.0 stlink_read_option_control_register1_32@Base 1.7.0
stlink_read_option_control_register1_f7@Base 1.7.0 stlink_read_option_control_register1_f7@Base 1.7.0
stlink_read_option_control_register32@Base 1.7.0 stlink_read_option_control_register32@Base 1.7.0
stlink_read_option_control_register_Gx@Base 1.7.0 #MISSING: 1.8.0# stlink_read_option_control_register_Gx@Base 1.7.0
stlink_read_option_control_register_f0@Base 1.8.0
stlink_read_option_control_register_f2@Base 1.7.0 stlink_read_option_control_register_f2@Base 1.7.0
stlink_read_option_control_register_f4@Base 1.7.0 stlink_read_option_control_register_f4@Base 1.7.0
stlink_read_option_control_register_f7@Base 1.7.0 stlink_read_option_control_register_f7@Base 1.7.0
stlink_read_option_control_register_gx@Base 1.8.0
stlink_read_option_control_register_wb@Base 1.8.0
stlink_read_reg@Base 1.5.0 stlink_read_reg@Base 1.5.0
stlink_read_unsupported_reg@Base 1.5.0 stlink_read_unsupported_reg@Base 1.5.0
stlink_reset@Base 1.5.0 stlink_reset@Base 1.5.0
@ -140,9 +165,9 @@ stlink-lib.so.1 stlink-lib #MINVER#
stlink_step@Base 1.5.0 stlink_step@Base 1.5.0
stlink_target_connect@Base 1.7.0 stlink_target_connect@Base 1.7.0
stlink_target_voltage@Base 1.5.0 stlink_target_voltage@Base 1.5.0
stlink_trace_disable@Base 1.7.0 #MISSING: 1.8.0# stlink_trace_disable@Base 1.7.0
stlink_trace_enable@Base 1.7.0 #MISSING: 1.8.0# stlink_trace_enable@Base 1.7.0
stlink_trace_read@Base 1.7.0 #MISSING: 1.8.0# stlink_trace_read@Base 1.7.0
stlink_v1_open@Base 1.5.0 stlink_v1_open@Base 1.5.0
stlink_v1_open_inner@Base 1.5.0 stlink_v1_open_inner@Base 1.5.0
stlink_verify_write_flash@Base 1.5.0 stlink_verify_write_flash@Base 1.5.0
@ -157,6 +182,7 @@ stlink-lib.so.1 stlink-lib #MINVER#
stlink_write_option_bytes_boot_add32@Base 1.7.0 stlink_write_option_bytes_boot_add32@Base 1.7.0
stlink_write_option_control_register1_32@Base 1.7.0 stlink_write_option_control_register1_32@Base 1.7.0
stlink_write_option_control_register32@Base 1.7.0 stlink_write_option_control_register32@Base 1.7.0
stlink_write_otp@Base 1.8.0
stlink_write_reg@Base 1.5.0 stlink_write_reg@Base 1.5.0
stlink_write_unsupported_reg@Base 1.5.0 stlink_write_unsupported_reg@Base 1.5.0
stm32l1_write_half_pages@Base 1.5.0 stm32l1_write_half_pages@Base 1.5.0
@ -164,6 +190,11 @@ stlink-lib.so.1 stlink-lib #MINVER#
ugly_init@Base 1.5.0 ugly_init@Base 1.5.0
ugly_libusb_log_level@Base 1.6.1 ugly_libusb_log_level@Base 1.6.1
ugly_log@Base 1.5.0 ugly_log@Base 1.5.0
unlock_flash_if@Base 1.8.0
unlock_flash_option_if@Base 1.8.0
unmap_file@Base 1.8.0
wait_flash_busy@Base 1.8.0
write_buffer_to_sram@Base 1.5.0 write_buffer_to_sram@Base 1.5.0
write_flash_cr_psiz@Base 1.8.0
write_uint16@Base 1.5.0 write_uint16@Base 1.5.0
write_uint32@Base 1.5.0 write_uint32@Base 1.5.0

Wyświetl plik

@ -1,3 +1,4 @@
/usr/bin/st-* /usr/bin/st-*
lib/udev/rules.d/*.rules ${env:deb_udevdir}/rules.d/*.rules
etc/modprobe.d/*.conf etc/modprobe.d/*.conf
usr/share/stlink/chips

2
debian/stlink.pc.in vendored
Wyświetl plik

@ -3,7 +3,7 @@ includedir=${prefix}/include/stlink
libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@ libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@
Name: stlink Name: stlink
Description: Open source version of the STMicroelectronics STLINK Tools Description: Open source version of the STMicroelectronics ST-LINK Tools
Version: @VERSION@ Version: @VERSION@
Requires: libusb-1.0 Requires: libusb-1.0
Libs: -L${libdir} -lstlink Libs: -L${libdir} -lstlink

4
debian/upstream/metadata vendored 100644
Wyświetl plik

@ -0,0 +1,4 @@
---
Bug-Database: https://github.com/stlink-org/stlink/issues
Bug-Submit: https://github.com/stlink-org/stlink/issues/new
Repository-Browse: https://github.com/stlink-org/stlink

2
debian/watch vendored
Wyświetl plik

@ -1,3 +1,3 @@
version=3 version=3
opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/stlink-$1\.tar\.gz/ \ opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/stlink-$1\.tar\.gz/ \
https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz

Wyświetl plik

@ -1,5 +1,6 @@
# Compiling from sources # Compiling from sources
## Microsoft Windows (10, 11) ## Microsoft Windows (10, 11)
### Common Requirements ### Common Requirements
@ -7,52 +8,36 @@
On Windows users should ensure that the following software is installed: On Windows users should ensure that the following software is installed:
- `git` (_optional, but recommended_) - `git` (_optional, but recommended_)
- `7zip`
- `cmake` - `cmake`
- `7-zip` - `MSYS2`
- `MinGW-w64`
### Installation ### Installation
1. Install `git` from <https://git-scm.com/download/win> 1. Install `git` from <https://git-scm.com/download/win>
2. Install `cmake` from <https://cmake.org/download><br /> 2. Install `cmake` from <https://cmake.org/download/#latest> --> Binary distributions --> Windows x64 Installer<br />
Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant.
3. Install MinGW-w64<br /> 3. Install `MSYS2` from <https://www.msys2.org/><br />
Download **MinGW-w64** from <https://github.com/niXman/mingw-builds-binaries/releases/download/13.2.0-rt_v11-rev1/x86_64-13.2.0-release-win32-seh-msvcrt-rt_v11-rev1.7z>. Extract content to `C:\mingw-w64\` and add `C:\mingw-w64\bin\` to PATH-Variable.<br /> Follow the installation instructions on the website.
4. Install `mingw-w64` via the MSYS2 UCRT64 Shell: `pacman -S mingw-w64-x86_64-make`
4. Create a new destination folder at a place of your choice 5. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)<br />
5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` or download and extract (`7zip`) the stlink zip-sourcefolder from the Release page on GitHub.
6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)<br />
or download and extract the stlink zip-sourcefolder from the Release page on GitHub.
### Building ### Building
#### MinGW-w64 1. Open the command-line (cmd.exe) with administrator privileges
2. Move to the `stlink` directory with `cd C:\$Path-to-your-stlink-folder$\`
1. Open command-line with administrator privileges
2. Move to the `stlink` directory
3. Execute `mingw64-build.bat` 3. Execute `mingw64-build.bat`
NOTE:<br /> Depending on the flavour of compilation the final executables will be placed in the following directories:
Per default the build script (currently) uses `C:\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin`.<br /> - Local compilation: `<project_root>\build-mingw\bin`
When installing different toolchains make sure to update the path in the `mingw64-build.bat`.<br /> - Local installation: `C:\Program Files (x86)\stlink\bin`
This can be achieved by opening the .bat file with a common text editor. - Package Generation (portable): `C:\Users\swift\Desktop\stlink\build-mingw\dist`
Options: **NOTE:**
- `/m` - compilation runs in parallel utilizing multiple cores [ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for programmers to work with `stlink`.
- `/p:Configuration=Release` - generates _Release_, optimized build.
Directory `<project_root>\build\Release` contains final executables.
(`st-util.exe` is located in `<project_root>\build\src\gdbserver\Release`).
**NOTE 1:**
Executables link against libusb.dll library. It has to be placed in the same directory as binaries or in PATH.
It can be copied from: `<project_root>\build\3rdparty\libusb-{version}\MS{arch}\dll\libusb-1.0.dll`.
**NOTE 2:**
[ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for `stlink` to work.
## Linux ## Linux

Wyświetl plik

@ -2,7 +2,7 @@
# Generate manpages # Generate manpages
### ###
set(MANPAGES st-util st-flash st-info) set(MANPAGES st-info st-flash st-util)
# Only generate manpages with pandoc in Debug builds # Only generate manpages with pandoc in Debug builds
if (${STLINK_GENERATE_MANPAGES}) if (${STLINK_GENERATE_MANPAGES})
@ -12,7 +12,7 @@ if (${STLINK_GENERATE_MANPAGES})
${manpage}.1 ${manpage}.1
SOURCES ${manpage}.md SOURCES ${manpage}.md
PANDOC_DIRECTIVES -s -t man PANDOC_DIRECTIVES -s -t man
PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} PRODUCT_DIRECTORY ${CMAKE_INSTALL_FULL_DATADIR}
) )
endforeach () endforeach ()
else () else ()
@ -21,16 +21,16 @@ endif()
# Install from output folder or this folder # Install from output folder or this folder
foreach (manpage ${MANPAGES}) foreach (manpage ${MANPAGES})
if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) if (EXISTS ${CMAKE_INSTALL_FULL_DATADIR}/${manpage}.1)
set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") set(f "${CMAKE_INSTALL_FULL_DATADIR}/${manpage}.1")
elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") elseif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1)
set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1")
else() else ()
message(AUTHOR_WARNING "Manpage ${manpage} not generated") message(AUTHOR_WARNING "Manpage ${manpage} not generated")
endif() endif()
if (f AND NOT WIN32) if (f AND NOT WIN32)
install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1) install(FILES ${f} DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/man/man1)
unset(f) unset(f)
endif() endif()
endforeach () endforeach ()

Wyświetl plik

@ -1,6 +1,6 @@
% st-flash(1) Open Source STMicroelectronics Stlink Tools | stlink % st-flash(1) Open source version of the STMicroelectronics STLINK Tools | stlink
% %
% Feb 2018 % Feb 2023
# NAME # NAME

Wyświetl plik

@ -1,6 +1,6 @@
% st-flash(1) Open Source STMicroelectronics Stlink Tools | stlink % st-flash(1) Open source version of the STMicroelectronics STLINK Tools | stlink
% %
% Oct 2020 % Feb 2023
# NAME # NAME
st-info - Provides information about connected STLink and STM32 devices st-info - Provides information about connected STLink and STM32 devices

Wyświetl plik

@ -1,6 +1,6 @@
% st-util(1) Open Source STMicroelectronics Stlink Tools | stlink % st-util(1) Open source version of the STMicroelectronics STLINK Tools | stlink
% %
% Feb 2018 % Feb 2023
# NAME # NAME

Wyświetl plik

@ -34,9 +34,9 @@ More commonly these are:
| STM32H7 | M7F | | | STM32H7 | M7F | |
| STM32WB | M4F | | | STM32WB | M4F | |
| STM32WL | M4 | | | STM32WL | M4 | |
| STM32L5 | M33 | | | STM32L5 | M33 | *preliminary, limited and partial support only!* |
| STM32H5 | M33 | | | STM32H5 | M33 | *preliminary, limited and partial support only!* |
| STM32U5 | M33 | | | STM32U5 | M33 | *preliminary, limited and partial support only!* |
# Chinese Clone-Chips [may work, but without support!] # Chinese Clone-Chips [may work, but without support!]

Wyświetl plik

@ -251,16 +251,12 @@ There are a few options:
./st-util - usage: ./st-util - usage:
-h, --help Print this help -h, --help Print this help
-vXX, --verbose=XX Specify a specific verbosity level (0..99) -vXX, --verbose=XX Specify a specific verbosity level (0..99)
-v, --verbose Specify generally verbose logging -v, --verbose Specify general verbose logging
-p 4242, --listen_port=1234 -p 4242, --listen_port=1234 Set the listen port for the gdb server (default: 4242)-
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.
-m, --multi -n, --no-reset, --hot-plug Do not reset board on connection.
Set gdb server to extended mode.
st-util will continue listening for connections after disconnect.
-n, --no-reset, --hot-plug
Do not reset board on connection.
``` ```
The STLink device to use can be specified using the --serial parameter. The STLink device to use can be specified using the --serial parameter.

Wyświetl plik

@ -1,10 +1,8 @@
_Source:_ [pkgs.org](https://pkgs.org) - libusb, cmake, gtk, libgtk (as of Apr 2023)
## Supported Operating Systems ## Supported Operating Systems
### Microsoft Windows ### Microsoft Windows
On Windows users should ensure that cmake **3.13.0** or any later version is installed.<br /> On Windows users should ensure that cmake **3.16.3** or any later version is installed.<br />
Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`.
- Windows 10 - Windows 10
@ -12,85 +10,77 @@ Up on compiling c-make will **automatically** download and install the latest co
### Linux-/Unix-based: ### Linux-/Unix-based:
Maintained versions of: Actively maintained versions of:
- Debian - Debian
- Ubuntu - Ubuntu
- Fedora - Fedora
- openSUSE - openSUSE
- OpenMandriva - OpenMandriva
- Arch Linux - Arch Linux
- FreeBSD - FreeBSD [libusb 1.0.16-18 (API 0x01000102)]
- NetBSD - NetBSD
- OpenBSD - OpenBSD
Other Linux-/Unix-based Operating Systems: Other Linux-/Unix-based Operating Systems:
| Operating System | libusb | cmake | libgtk-dev | End of<br />OS-Support | | Operating System | libusb | cmake | libgtk-dev | End of<br />OS-Support |
| ------------------------ | ------------------------------ | ---------- | ----------- | ---------------------- | | ------------------------ | -------------------------- | ---------- | ----------- | ---------------------- |
| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | | KaOS [x64] | 1.0.27 | 3.30.2 | 3.24.43 | |
| Debian 11 (Bullseye) | 1.0.24 | 3.**18.4** | 3.24.24 | | | Void Linux [x64] | 1.0.27 | 3.30.1 | 3.24.42 | |
| Debian 10 (Buster) | 1.0.**22** | 3.**13.4** | 3.24.**5** | Jun 2024 | | CentOS 9 Stream [x64] | 1.0.26 (`libusbx`) | 3.26.5 | 3.24.31 | |
| | | | | | | Mageia 9 [x64] | 1.0.26 | 3.26.4 | 3.24.38 | |
| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.**16.3** | 3.24.**18** | May 2025 | | Solus [x64] | 1.0.26 | 3.24.1 | 3.24.38 | |
| | | | | | | ALT Linux P10 [x64] | 1.0.26 | 3.23.2 | 3.24.32 | |
| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | | PCLinuxOS [x64] | (?) | 3.30.2 | 3.24.38 | |
| | | | | | | | | | | |
| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | | Slackware 15 [x64] | 1.0.**24** | 3.24.1 | 3.24.31 | |
| NetBSD 8.x | 1.0.24 | 3.**19.7** | 3.24.27 | | | NetBSD 9.x | 1.0.**24** | 3.**21.2** | 3.24.**30** | |
| | | | | | | Adélie 1.0 | 1.0.**23** | 3.23.5 | 3.24.**30** | |
| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | | Ubuntu 20.04 LTS (Focal) | 1.0.**23** | 3.**16.3** | 3.24.**18** | May 2025 |
| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | May 2024 | | FreeBSD 13.x | 1.0.16-18 (API 0x01000102) | 3.**22.1** | 3.24.31 | Jan 2026 |
| | | | | |
| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | |
| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | |
| ALT Linux P9 | 1.0.**22** | 3.**16.3** | 3.24.29 | |
| | | | | |
| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | |
| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | |
| PCLinuxOS [x64] | (?) | 3.22.1 | 3.24.31 | |
| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | |
| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | |
| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | |
| Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | |
## Unsupported Operating Systems (as of Release v1.8.0)
## Unsupported Operating Systems (as of Release v1.8.1)
Systems with highlighted versions remain compatible with this toolset. Systems with highlighted versions remain compatible with this toolset.
| Operating System | libusb | cmake | End of<br />OS-Support | | Operating System | libusb | cmake | End of<br />OS-Support |
| ---------------------------------------- | ------------------------------ | ---------- | ---------------------- | | ---------------------------------------- | -------------------------- | ---------- | ---------------------- |
| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.**22.1** | Dec 2023 | | FreeBSD 12.x | 1.0.16-18 (API 0x01000102) | 3.**22.1** | Dec 2023 |
| Alpine 3.15 | 1.0.**24** | 3.**21.3** | Nov 2023 | | Alpine 3.15 | 1.0.**24** | 3.**21.3** | Nov 2023 |
| Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | | Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 |
| Alpine 3.14 | 1.0.**24** | 3.**20.3** | May 2023 | | Alpine 3.14 | 1.0.**24** | 3.**20.3** | May 2023 |
| CentOS / Rocky Linux / AlmaLinux 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | | Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 |
| Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 | | NetBSD 8.x | 1.0.**24** | 3.**19.7** | May 2024 |
| OpenMandriva Lx 4.2 | 1.0.**24** | 3.**19.3** | Mar 2023 | | OpenMandriva Lx 4.2 | 1.0.**24** | 3.**19.3** | Mar 2023 |
| Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 | | Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 |
| Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 | | Debian 11 (Bullseye) | 1.0.**24** | 3.**18.4** | Jun 2024 |
| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | | Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 |
| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | | Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 |
| Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | | CentOS / Rocky Linux / AlmaLinux 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 |
| openSUSE Leap 15.3 [x64] | 1.0.21 | 3.**17.0** | Dec 2022 | | CentOS 8 Stream [x64] | 1.0.**23** (`libusbx`) | 3.**20.2** | May 2024 |
| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | | Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 |
| openSUSE Leap 15.2 [x64] | 1.0.21 | 3.**17.0** | Dec 2021 | | Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 |
| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | | openSUSE Leap 15.3 [x64] | 1.0.21 | 3.**17.0** | Dec 2022 |
| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | | Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 |
| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | | openSUSE Leap 15.2 [x64] | 1.0.21 | 3.**17.0** | Dec 2021 |
| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | | Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 |
| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | | NetBSD 7.x | 1.0.22 | 3.16.1 | Jun 2020 |
| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | | Alpine 3.11 | 1.0.**23** | 3.15.5 | Nov 2021 |
| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | | FreeBSD 11.x | 1.0.16-18 (API 0x01000102) | 3.15.5 | Sep 2021 |
| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | | ALT Linux P9 | 1.0.22 | 3.**16.3** | |
| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | | Alpine 3.10 | 1.0.22 | 3.14.5 | May 2021 |
| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | | Fedora 31 [x64] | 1.0.22 (`libusbx`) | 3.14.5 | Nov 2020 |
| Ubuntu 18.04 LTS (Bionic) | 1.0.21 | 3.10.2 | Apr 2023 | | Mageia 7.1 | 1.0.22 | 3.14.3 | Jun 2021 |
| openSUSE Leap 15.1 [x64] | 1.0.21 | 3.10.2 | Jan 2021 | | Fedora 30 | 1.0.22 (`libusbx`) | 3.14.2 | May 2020 |
| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 | | Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.13.4 | Jul 2020 |
| Slackware 14.2 | 1.0.20 | 3.5.2 | | | Alpine 3.9 | 1.0.22 | 3.13.0 | Jan 2021 |
| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | | Debian 10 (Buster) | 1.0.22 | 3.13.4 | Jun 2024 |
| CentOS / Rocky Linux / AlmaLinux 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | | Ubuntu 18.04 LTS (Bionic) | 1.0.21 | 3.10.2 | Apr 2023 |
| openSUSE Leap 15.1 [x64] | 1.0.21 | 3.10.2 | Jan 2021 |
| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 |
| Slackware 14.2 | 1.0.20 | 3.5.2 | Jan 2024 |
| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | Jul 2019 |
| CentOS / Rocky Linux / AlmaLinux 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 |
_All other operating systems which are not listed are unsupported._ _All other operating systems which are not listed are unsupported._
Author: nightwalker-87

Wyświetl plik

@ -3,28 +3,26 @@
### ###
# Install this cross-compiler toolchain: # Install this cross-compiler toolchain:
#sudo apt-get install mingw-w64 # sudo apt-get install mingw-w64
# x86_64 # x86_64
mkdir build-mingw-64 mkdir build-mingw-64
cd build-mingw-64 cd build-mingw-64
cmake -DCMAKE_SYSTEM_NAME=Windows \ cmake -DCMAKE_SYSTEM_NAME=Windows \
-DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \
-DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake ..
make package make package
sudo cp dist/*.zip ../build/Release/dist sudo cp dist/*.zip ../build/Release/dist
make clean make clean
cd .. cd ..
rm -rf build-mingw-64
# i686 # i686
mkdir build-mingw-32 mkdir build-mingw-32
cd build-mingw-32 cd build-mingw-32
cmake -DCMAKE_SYSTEM_NAME=Windows \ cmake -DCMAKE_SYSTEM_NAME=Windows \
-DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \
-DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake ..
make package make package
sudo cp dist/*.zip ../build/Release/dist sudo cp dist/*.zip ../build/Release/dist
make clean make clean
cd .. cd ..
rm -rf build-mingw-32

Wyświetl plik

@ -142,37 +142,37 @@ enum stm32_chipids {
}; };
/* Constant STM32 option bytes base memory address */ /* Constant STM32 option bytes base memory address */
#define STM32_C0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) #define STM32_C0_OPTION_BYTES_BASE ((uint32_t) 0x1fff7800)
#define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) #define STM32_F4_OPTION_BYTES_BASE ((uint32_t) 0x40023c14)
#define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201c) #define STM32_H7_OPTION_BYTES_BASE ((uint32_t) 0x52002020)
#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1ff80000) #define STM32_L0_OPTION_BYTES_BASE ((uint32_t) 0x1ff80000)
#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1ff80000) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t) 0x1ff80000)
#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1fff0000) #define STM32_F7_OPTION_BYTES_BASE ((uint32_t) 0x1fff0000)
#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t) 0x1fff7800)
#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t) 0x1fff7800)
#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1fffc000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t) 0x1fffc000)
#define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_F0_OPTION_BYTES_BASE ((uint32_t) 0x1ffff800)
#define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_F1_OPTION_BYTES_BASE ((uint32_t) 0x1ffff800)
#define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_F3_OPTION_BYTES_BASE ((uint32_t) 0x1ffff800)
#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t) 0x1ffff800)
/* ============ */ /* ============ */
/* Old defines from common.c are below */ /* Old defines from common.c are below */
/* ============ */ /* ============ */
/* Constant STM32 memory address */ /* Constant STM32 memory address */
#define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_SRAM_BASE ((uint32_t) 0x20000000)
#define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_FLASH_BASE ((uint32_t) 0x08000000)
#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) #define STM32_F1_FLASH_BANK2_BASE ((uint32_t) 0x08080000)
#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) #define STM32_H7_FLASH_BANK2_BASE ((uint32_t) 0x08100000)
#define STM32F0_DBGMCU_CR 0xE0042004 #define STM32F0_DBGMCU_CR 0xE0042004
#define STM32F0_DBGMCU_CR_IWDG_STOP 8 #define STM32F0_DBGMCU_CR_IWDG_STOP 8

Wyświetl plik

@ -48,19 +48,19 @@
#define FLASH_CR_OPTWRE 9 #define FLASH_CR_OPTWRE 9
#define FLASH_CR_OBL_LAUNCH 13 #define FLASH_CR_OBL_LAUNCH 13
#define FLASH_ACR_OFF ((uint32_t)0x00) #define FLASH_ACR_OFF ((uint32_t) 0x00)
#define FLASH_PECR_OFF ((uint32_t)0x04) #define FLASH_PECR_OFF ((uint32_t) 0x04)
#define FLASH_PDKEYR_OFF ((uint32_t)0x08) #define FLASH_PDKEYR_OFF ((uint32_t) 0x08)
#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) #define FLASH_PEKEYR_OFF ((uint32_t) 0x0c)
#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) #define FLASH_PRGKEYR_OFF ((uint32_t) 0x10)
#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) #define FLASH_OPTKEYR_OFF ((uint32_t) 0x14)
#define FLASH_SR_OFF ((uint32_t)0x18) #define FLASH_SR_OFF ((uint32_t) 0x18)
#define FLASH_OBR_OFF ((uint32_t)0x1c) #define FLASH_OBR_OFF ((uint32_t) 0x1c)
#define FLASH_WRPR_OFF ((uint32_t)0x20) #define FLASH_WRPR_OFF ((uint32_t) 0x20)
// == STM32C0 == (RM0490) // == STM32C0 == (RM0490)
// C0 Flash registers // C0 Flash registers
#define FLASH_C0_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_C0_REGS_ADDR ((uint32_t) 0x40022000)
#define FLASH_C0_KEYR (FLASH_C0_REGS_ADDR + 0x08) #define FLASH_C0_KEYR (FLASH_C0_REGS_ADDR + 0x08)
#define FLASH_C0_OPT_KEYR (FLASH_C0_REGS_ADDR + 0x0C) #define FLASH_C0_OPT_KEYR (FLASH_C0_REGS_ADDR + 0x0C)
#define FLASH_C0_SR (FLASH_C0_REGS_ADDR + 0x10) #define FLASH_C0_SR (FLASH_C0_REGS_ADDR + 0x10)
@ -87,7 +87,7 @@
#define FLASH_F0_OPTKEY2 0xcdef89ab #define FLASH_F0_OPTKEY2 0xcdef89ab
// == STM32F2 == // == STM32F2 ==
#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F2_REGS_ADDR ((uint32_t) 0x40023c00)
#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) #define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04)
#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) #define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08)
#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) #define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c)
@ -107,7 +107,7 @@
// == STM32F4 == // == STM32F4 ==
// F4 Flash registers // F4 Flash registers
#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_REGS_ADDR ((uint32_t) 0x40023c00)
#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04)
#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) #define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08)
#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) #define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c)
@ -131,7 +131,7 @@
// == STM32F7 == // == STM32F7 ==
// F7 Flash registers // F7 Flash registers
#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F7_REGS_ADDR ((uint32_t) 0x40023c00)
#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) #define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04)
#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) #define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08)
#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) #define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c)
@ -165,7 +165,7 @@
// == STM32G0/G4 == // == STM32G0/G4 ==
// G0/G4 Flash registers (RM0440, p.146) // G0/G4 Flash registers (RM0440, p.146)
#define FLASH_Gx_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_Gx_REGS_ADDR ((uint32_t) 0x40022000)
#define FLASH_Gx_ACR (FLASH_Gx_REGS_ADDR + 0x00) #define FLASH_Gx_ACR (FLASH_Gx_REGS_ADDR + 0x00)
#define FLASH_Gx_KEYR (FLASH_Gx_REGS_ADDR + 0x08) #define FLASH_Gx_KEYR (FLASH_Gx_REGS_ADDR + 0x08)
#define FLASH_Gx_OPTKEYR (FLASH_Gx_REGS_ADDR + 0x0c) #define FLASH_Gx_OPTKEYR (FLASH_Gx_REGS_ADDR + 0x0c)
@ -181,6 +181,7 @@
#define FLASH_Gx_CR_PNB (3) /* Page number */ #define FLASH_Gx_CR_PNB (3) /* Page number */
#define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ #define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */
#define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ #define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */
#define FLASH_Gx_CR_BKER (13) /* Bank selection for erase operation */
#define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/ #define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/
#define FLASH_Gx_CR_STRT (16) /* Start */ #define FLASH_Gx_CR_STRT (16) /* Start */
#define FLASH_Gx_CR_OPTSTRT (17) /* Start of modification of option bytes */ #define FLASH_Gx_CR_OPTSTRT (17) /* Start of modification of option bytes */
@ -232,11 +233,10 @@
// == STM32H7 == // == STM32H7 ==
// H7 Flash registers // H7 Flash registers
#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) #define FLASH_H7_REGS_ADDR ((uint32_t) 0x52002000)
#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) #define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04)
#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) #define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104)
#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) #define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08)
#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108)
#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) #define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c)
#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) #define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c)
#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) #define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10)
@ -278,7 +278,7 @@
// == STM32L0/L1/L4/L5 == // == STM32L0/L1/L4/L5 ==
// Lx Flash registers // Lx Flash registers
#define FLASH_Lx_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_Lx_REGS_ADDR ((uint32_t) 0x40023c00)
#define FLASH_Lx_ACR (FLASH_Lx_REGS_ADDR + 0x00) #define FLASH_Lx_ACR (FLASH_Lx_REGS_ADDR + 0x00)
#define FLASH_Lx_PECR (FLASH_Lx_REGS_ADDR + 0x04) #define FLASH_Lx_PECR (FLASH_Lx_REGS_ADDR + 0x04)
#define FLASH_Lx_PDKEYR (FLASH_Lx_REGS_ADDR + 0x08) #define FLASH_Lx_PDKEYR (FLASH_Lx_REGS_ADDR + 0x08)
@ -300,7 +300,7 @@
#define FLASH_L0_OPTKEY1 0xFBEAD9C8 #define FLASH_L0_OPTKEY1 0xFBEAD9C8
#define FLASH_L0_OPTKEY2 0x24252627 #define FLASH_L0_OPTKEY2 0x24252627
#define FLASH_L0_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_L0_REGS_ADDR ((uint32_t) 0x40022000)
#define FLASH_L0_PELOCK (0) #define FLASH_L0_PELOCK (0)
#define FLASH_L0_OPTLOCK (2) #define FLASH_L0_OPTLOCK (2)
@ -352,16 +352,16 @@
#define FLASH_L4_CR_OBL_LAUNCH 27 /* Option bytes reload */ #define FLASH_L4_CR_OBL_LAUNCH 27 /* Option bytes reload */
// Bits requesting flash operations (useful when we want to clear them) // Bits requesting flash operations (useful when we want to clear them)
#define FLASH_L4_CR_OPBITS \ #define FLASH_L4_CR_OPBITS \
(uint32_t)((1lu << FLASH_L4_CR_PG) | (1lu << FLASH_L4_CR_PER) | \ (uint32_t) ((1lu << FLASH_L4_CR_PG) | (1lu << FLASH_L4_CR_PER) | \
(1lu << FLASH_L4_CR_MER1) | (1lu << FLASH_L4_CR_MER1)) (1lu << FLASH_L4_CR_MER1) | (1lu << FLASH_L4_CR_MER1))
// Page is fully specified by BKER and PNB // Page is fully specified by BKER and PNB
#define FLASH_L4_CR_PAGEMASK (uint32_t)(0x1fflu << FLASH_L4_CR_PNB) #define FLASH_L4_CR_PAGEMASK (uint32_t) (0x1fflu << FLASH_L4_CR_PNB)
#define FLASH_L4_OPTR_DUALBANK 21 #define FLASH_L4_OPTR_DUALBANK 21
// == STM32L5 == (RM0438, p.241) // == STM32L5 == (RM0438, p.241)
// L5 Flash registers // L5 Flash registers
#define FLASH_L5_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_L5_REGS_ADDR ((uint32_t) 0x40022000)
#define FLASH_L5_ACR (FLASH_L5_REGS_ADDR + 0x00) #define FLASH_L5_ACR (FLASH_L5_REGS_ADDR + 0x00)
#define FLASH_L5_NSKEYR (FLASH_L5_REGS_ADDR + 0x08) #define FLASH_L5_NSKEYR (FLASH_L5_REGS_ADDR + 0x08)
#define FLASH_L5_OPTKEYR (FLASH_L5_REGS_ADDR + 0x10) #define FLASH_L5_OPTKEYR (FLASH_L5_REGS_ADDR + 0x10)
@ -399,7 +399,7 @@
// == STM32WB == (RM0434) // == STM32WB == (RM0434)
// WB Flash registers // WB Flash registers
#define FLASH_WB_REGS_ADDR ((uint32_t)0x58004000) #define FLASH_WB_REGS_ADDR ((uint32_t) 0x58004000)
#define FLASH_WB_ACR (FLASH_WB_REGS_ADDR + 0x00) #define FLASH_WB_ACR (FLASH_WB_REGS_ADDR + 0x00)
#define FLASH_WB_KEYR (FLASH_WB_REGS_ADDR + 0x08) #define FLASH_WB_KEYR (FLASH_WB_REGS_ADDR + 0x08)
#define FLASH_WB_OPT_KEYR (FLASH_WB_REGS_ADDR + 0x0c) #define FLASH_WB_OPT_KEYR (FLASH_WB_REGS_ADDR + 0x0c)

Wyświetl plik

@ -2,7 +2,7 @@
mkdir build-mingw mkdir build-mingw
cd build-mingw cd build-mingw
set PATH=C:\Program Files\CMake\bin;C:\mingw-w64\x86_64-13.2.0-release-win32-seh-msvcrt-rt_v11-rev1\mingw64\bin;%PATH% set PATH=C:\Program Files\CMake\bin;C:\msys64\ucrt64\bin;C:\msys64\mingw64\bin;%PATH%
cmake -G "MinGW Makefiles" .. cmake -G "MinGW Makefiles" ..
mingw32-make mingw32-make
mingw32-make install mingw32-make install

Wyświetl plik

@ -44,25 +44,39 @@ static void cleanup(int32_t signum) {
} }
static void usage(void) { static void usage(void) {
puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] [--freq=<kHz>] [--area=<area>] {read|write} [path] [addr] [size]"); puts("usage: st-flash [options] read [file] [addr] [size]");
puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=<kHz>] [--serial <serial>] erase [addr] [size]"); puts(" st-flash [options] write <file> [addr] [size]");
puts("command line: ./st-flash [--debug] [--freq=<kHz>] [--serial <serial>] reset"); puts(" st-flash [options] write <value>");
puts(" <addr>, <serial> and <size>: Use hex format."); puts(" st-flash [options] erase <addr> <size>");
puts(" <fsize>: Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" st-flash [options] reset");
puts(" <format>: Can be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only."); puts("");
puts(" <area>: Can be 'main' (default), 'system', 'otp', 'optcr', 'optcr1', 'option' or 'option_boot_add'"); puts("options:");
puts("print tool version info: ./st-flash [--version]"); puts(" --freq <kHz> Frequency of JTAG/SWD, default 1800kHz.");
puts("example read option byte: ./st-flash --area=option read [path] [size]"); puts(" --serial <serial> STLink device to use.");
puts("example write option byte: ./st-flash --area=option write 0xXXXXXXXX"); puts(" --connect-under-reset Pull reset low while connecting.");
puts("On selected targets:"); puts(" --hot-plug Connect without reset.");
puts("example read boot_add option byte: ./st-flash --area=option_boot_add read"); puts(" --reset Reset after writing.");
puts("example write boot_add option byte: ./st-flash --area=option_boot_add write 0xXXXXXXXX"); puts(" --format {binary|ihex} Format of file to read or write. When writing");
puts("example read option control register byte: ./st-flash --area=optcr read"); puts(" with ihex specifying addr is not needed.");
puts("example write option control register1 byte: ./st-flash --area=optcr write 0xXXXXXXXX"); puts(" --flash <size> Specify size of flash, e.g. 128k, 1M.");
puts("example read option control register1 byte: ./st-flash --area=optcr1 read"); puts(" --area <area> Area to access, one of: main(default), system,");
puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); puts(" otp, option, option_boot_add, optcr, optcr1.");
puts("example read OTP area: ./st-flash --area=otp read [path]"); puts(" --opt Skip writing empty bytes at the tail end.");
puts("example write OTP area: ./st-flash --area=otp write [path] 0xXXXXXXXX"); puts(" --debug Output extra debug information.");
puts(" --version Print version information.");
puts(" --help Show this help.");
puts("");
puts("examples:");
puts(" st-flash --area=option read [file] [size]");
puts(" st-flash --area=option write 0xXXXXXXXX");
puts(" st-flash --area=option_boot_add read");
puts(" st-flash --area=option_boot_add write 0xXXXXXXXX");
puts(" st-flash --area=optcr read");
puts(" st-flash --area=optcr write 0xXXXXXXXX");
puts(" st-flash --area=optcr1 read");
puts(" st-flash --area=optcr1 write 0xXXXXXXXX");
puts(" st-flash --area=otp read <file>");
puts(" st-flash --area=otp write <file> 0xXXXXXXXX");
} }
int32_t main(int32_t ac, char** av) { int32_t main(int32_t ac, char** av) {
@ -70,14 +84,19 @@ int32_t main(int32_t ac, char** av) {
struct flash_opts o; struct flash_opts o;
int32_t err = -1; int32_t err = -1;
uint8_t * mem = NULL; uint8_t * mem = NULL;
int32_t getopt_ret;
o.size = 0; o.size = 0;
o.connect = CONNECT_NORMAL; o.connect = CONNECT_NORMAL;
if (flash_get_opts(&o, ac - 1, av + 1) == -1) { getopt_ret = flash_get_opts(&o, ac - 1, av + 1);
if (getopt_ret == -1) {
printf("invalid command line\n"); printf("invalid command line\n");
usage(); usage();
return (-1); return (-1);
} else if (getopt_ret == 1) {
usage();
return 0;
} }
printf("st-flash %s\n", STLINK_VERSION); printf("st-flash %s\n", STLINK_VERSION);
@ -100,6 +119,7 @@ int32_t main(int32_t ac, char** av) {
sl->verbose = o.log_level; sl->verbose = o.log_level;
sl->opt = o.opt; sl->opt = o.opt;
const enum erase_type_t erase_type = o.mass_erase ? MASS_ERASE : SECTION_ERASE;
connected_stlink = sl; connected_stlink = sl;
signal(SIGINT, &cleanup); signal(SIGINT, &cleanup);
@ -120,6 +140,14 @@ int32_t main(int32_t ac, char** av) {
if (o.cmd == FLASH_CMD_WRITE) { if (o.cmd == FLASH_CMD_WRITE) {
uint32_t size = 0; uint32_t size = 0;
if (erase_type == MASS_ERASE) {
err = stlink_erase_flash_mass(sl);
if (err == -1) {
printf("stlink_erase_flash_mass() == -1\n");
goto on_error;
}
}
// write // write
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); err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr);
@ -131,9 +159,9 @@ int32_t main(int32_t ac, char** av) {
} }
if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { 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, size, o.addr); err = stlink_mwrite_flash(sl, mem, size, o.addr, erase_type);
} else { } else {
err = stlink_fwrite_flash(sl, o.filename, o.addr); err = stlink_fwrite_flash(sl, o.filename, o.addr, erase_type);
} }
if (err == -1) { if (err == -1) {
@ -188,7 +216,7 @@ int32_t main(int32_t ac, char** av) {
printf("OTP Write NOT implemented\n"); printf("OTP Write NOT implemented\n");
goto on_error; goto on_error;
} }
err = stlink_fwrite_flash(sl, o.filename, o.addr); err = stlink_fwrite_flash(sl, o.filename, o.addr, NO_ERASE);
if (err == -1) { if (err == -1) {
printf("stlink_fwrite_flash() == -1\n"); printf("stlink_fwrite_flash() == -1\n");
@ -203,16 +231,21 @@ int32_t main(int32_t ac, char** av) {
} else if (o.cmd == FLASH_CMD_ERASE) { } else if (o.cmd == FLASH_CMD_ERASE) {
// erase // erase
if (o.size > 0 && o.addr > 0) { if ((erase_type == MASS_ERASE) || (o.size == 0 || o.addr == 0)) {
err = stlink_erase_flash_section(sl, o.addr, o.size, false); err = stlink_erase_flash_mass(sl);
if (err == -1) {
printf("stlink_erase_flash_mass() == -1\n");
goto on_error;
}
printf("Mass erase completed successfully.\n");
} else { } else {
err = stlink_erase_flash_mass(sl); err = stlink_erase_flash_section(sl, o.addr, o.size, false);
if (err == -1) {
printf("stlink_erase_flash_section() == -1\n");
goto on_error;
}
printf("Section erase completed successfully.\n");
} }
if (err == -1) {
printf("stlink_erase_flash_mass() == -1\n");
goto on_error;
}
printf("Mass erase completed successfully.\n");
// reset after erase // reset after erase
if (stlink_reset(sl, RESET_AUTO)) { if (stlink_reset(sl, RESET_AUTO)) {
@ -262,7 +295,7 @@ int32_t main(int32_t ac, char** av) {
fprintf(stderr, "open(%s) == -1\n", o.filename); fprintf(stderr, "open(%s) == -1\n", o.filename);
goto on_error; goto on_error;
} }
err = (uint32_t)write(fd, &option_byte, 4); err = (uint32_t) write(fd, &option_byte, 4);
if (err == -1) { if (err == -1) {
printf("could not write buffer to file (%d)\n", err); printf("could not write buffer to file (%d)\n", err);
goto on_error; goto on_error;

Wyświetl plik

@ -17,7 +17,7 @@
#include <helper.h> #include <helper.h>
static bool starts_with(const char * str, const char * prefix) { static bool starts_with(const char * str, const char * prefix) {
uint32_t n = strlen(prefix); uint32_t n = (uint32_t) strlen(prefix);
if (strlen(str) < n) { return (false); } if (strlen(str) < n) { return (false); }
@ -70,7 +70,7 @@ static int32_t get_integer_from_char_array (const char *const str, uint32_t *rea
fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n");
return (-1); return (-1);
} else { } else {
*read_value = value; *read_value = (uint32_t) value;
return (0); return (0);
} }
} }
@ -98,10 +98,14 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (strcmp(av[0], "--version") == 0) { if (strcmp(av[0], "--version") == 0) {
printf("v%s\n", STLINK_VERSION); printf("v%s\n", STLINK_VERSION);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (strcmp(av[0], "--help") == 0 || strcmp(av[0], "-h") == 0) {
return 1;
} else if (strcmp(av[0], "--debug") == 0) { } else if (strcmp(av[0], "--debug") == 0) {
o->log_level = DEBUG_LOG_LEVEL; o->log_level = DEBUG_LOG_LEVEL;
} else if (strcmp(av[0], "--opt") == 0) { } else if (strcmp(av[0], "--opt") == 0) {
o->opt = ENABLE_OPT; o->opt = ENABLE_OPT;
} else if (strcmp(av[0], "--mass-erase") == 0) {
o->mass_erase = ENABLE_OPT;
} else if (strcmp(av[0], "--reset") == 0) { } else if (strcmp(av[0], "--reset") == 0) {
o->reset = 1; o->reset = 1;
} else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) {
@ -199,7 +203,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (result != 0) { if (result != 0) {
return (bad_arg ("--flash")); return (bad_arg ("--flash"));
} else { } else {
o->flash_size = (size_t)flash_size; o->flash_size = (uint32_t) flash_size;
} }
} else if (strcmp(av[0], "--connect-under-reset") == 0) { } else if (strcmp(av[0], "--connect-under-reset") == 0) {
o->connect = CONNECT_UNDER_RESET; o->connect = CONNECT_UNDER_RESET;
@ -259,7 +263,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (result != 0) { if (result != 0) {
return bad_arg ("size"); return bad_arg ("size");
} else { } else {
o->size = (size_t) size; o->size = (uint32_t) size;
} }
} }
@ -283,7 +287,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (result != 0) { if (result != 0) {
return bad_arg ("size"); return bad_arg ("size");
} else { } else {
o->size = (size_t) size; o->size = (uint32_t) size;
} }
break; break;
@ -300,7 +304,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (result != 0) { if (result != 0) {
return bad_arg("option bytes read: invalid size"); return bad_arg("option bytes read: invalid size");
} else { } else {
o->size = (size_t) size; o->size = (uint32_t) size;
} }
} }
break; break;
@ -370,7 +374,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
if (result != 0) { if (result != 0) {
return (bad_arg ("addr")); return (bad_arg ("addr"));
} else { } else {
o->addr = (stm32_addr_t)addr; o->addr = (stm32_addr_t) addr;
} }
} else if (o->format == FLASH_FORMAT_IHEX) { // expect filename } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename
if (ac != 1) { return (invalid_args("write <path>")); } if (ac != 1) { return (invalid_args("write <path>")); }

Wyświetl plik

@ -7,7 +7,7 @@
#ifndef FLASH_OPTS_H #ifndef FLASH_OPTS_H
#define FLASH_OPTS_H #define FLASH_OPTS_H
#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; 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}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1};
@ -26,6 +26,7 @@ struct flash_opts {
uint32_t val; uint32_t val;
uint32_t flash_size; // --flash=n[k, M] uint32_t flash_size; // --flash=n[k, M]
int32_t opt; // enable empty tail data drop optimization int32_t opt; // enable empty tail data drop optimization
int32_t mass_erase; // Use mass-erase when programming flash instead of sector-erase
int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD
enum connect_type connect; enum connect_type connect;
}; };

Wyświetl plik

@ -158,7 +158,7 @@ static bool parse_frequency(char* text, uint32_t* result) {
return false; return false;
} }
*result = (uint32_t)value; *result = (uint32_t) value;
return true; return true;
} }
@ -412,7 +412,7 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) {
} }
static bool read_trace(stlink_t *stlink, st_trace_t *trace) { static bool read_trace(stlink_t *stlink, st_trace_t *trace) {
uint8_t* buffer = 0; uint8_t buffer[STLINK_V3_TRACE_BUF_LEN];
int32_t length = stlink_trace_read(stlink, buffer, sizeof(buffer)); int32_t length = stlink_trace_read(stlink, buffer, sizeof(buffer));
if (length < 0) { if (length < 0) {

Wyświetl plik

@ -12,7 +12,7 @@
#include <win32_socket.h> #include <win32_socket.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <sys/poll.h> #include <poll.h>
#endif #endif
#include "gdb-remote.h" #include "gdb-remote.h"
@ -20,7 +20,7 @@
static const char hex[] = "0123456789abcdef"; static const char hex[] = "0123456789abcdef";
int32_t gdb_send_packet(int32_t fd, char* data) { int32_t gdb_send_packet(int32_t fd, char* data) {
uint32_t data_length = (uint32_t)strlen(data); uint32_t data_length = (uint32_t) strlen(data);
int32_t length = data_length + 4; int32_t length = data_length + 4;
char* packet = malloc(length); // '$' data (hex) '#' cksum (hex) char* packet = malloc(length); // '$' data (hex) '#' cksum (hex)

Wyświetl plik

@ -92,13 +92,18 @@ static void _cleanup() {
static void cleanup(int32_t signum) { static void cleanup(int32_t signum) {
printf("Receive signal %i. Exiting...\n", signum); printf("Receive signal %i. Exiting...\n", signum);
_cleanup(); _cleanup();
exit(1); // if asked to gracefully terminate
(void)signum; if(signum == SIGTERM){
// return 0
exit(0);
}else{
exit(1);
}
} }
#if defined(_WIN32) #if defined(_WIN32)
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) {
printf("Receive signal %i. Exiting...\r\n", (int32_t)fdwCtrlType); printf("Receive signal %i. Exiting...\r\n", (int32_t) fdwCtrlType);
_cleanup(); _cleanup();
return FALSE; return FALSE;
} }
@ -113,7 +118,7 @@ int32_t parse_options(int32_t argc, char** argv, st_state_t *st) {
{"no-reset", optional_argument, NULL, 'n'}, {"no-reset", optional_argument, NULL, 'n'},
{"hot-plug", optional_argument, NULL, 'n'}, {"hot-plug", optional_argument, NULL, 'n'},
{"connect-under-reset", optional_argument, NULL, 'u'}, {"connect-under-reset", optional_argument, NULL, 'u'},
{"freq", optional_argument, NULL, 'F'}, {"freq", required_argument, NULL, 'F'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION},
{"serial", required_argument, NULL, SERIAL_OPTION}, {"serial", required_argument, NULL, SERIAL_OPTION},
@ -147,11 +152,11 @@ int32_t parse_options(int32_t argc, char** argv, st_state_t *st) {
; ;
int32_t option_index = 0; int option_index = 0;
int32_t c; int32_t c;
int32_t q; int32_t q;
while ((c = getopt_long(argc, argv, "hv::p:mnu", long_options, &option_index)) != -1) while ((c = getopt_long(argc, argv, "hv::p:mnuF:V", long_options, &option_index)) != -1)
switch (c) { switch (c) {
case 0: case 0:
break; break;
@ -285,6 +290,7 @@ static const char* const target_description =
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target version=\"1.0\">" "<target version=\"1.0\">"
" <architecture>arm</architecture>" " <architecture>arm</architecture>"
" <osabi>none</osabi>"
" <feature name=\"org.gnu.gdb.arm.m-profile\">" " <feature name=\"org.gnu.gdb.arm.m-profile\">"
" <reg name=\"r0\" bitsize=\"32\"/>" " <reg name=\"r0\" bitsize=\"32\"/>"
" <reg name=\"r1\" bitsize=\"32\"/>" " <reg name=\"r1\" bitsize=\"32\"/>"
@ -354,7 +360,8 @@ char* make_memory_map(stlink_t *sl) {
if (sl->chip_id == STM32_CHIPID_F4 || if (sl->chip_id == STM32_CHIPID_F4 ||
sl->chip_id == STM32_CHIPID_F446 || sl->chip_id == STM32_CHIPID_F446 ||
sl->chip_id == STM32_CHIPID_F411xx) { sl->chip_id == STM32_CHIPID_F411xx) {
strcpy(map, memory_map_template_F4); snprintf(map, sz, memory_map_template_F4,
sl->sram_size);
} else if (sl->chip_id == STM32_CHIPID_F4_DE) { } else if (sl->chip_id == STM32_CHIPID_F4_DE) {
strcpy(map, memory_map_template_F4_DE); strcpy(map, memory_map_template_F4_DE);
} else if (sl->core_id == STM32_CORE_ID_M7F_SWD) { } else if (sl->core_id == STM32_CORE_ID_M7F_SWD) {
@ -387,7 +394,7 @@ char* make_memory_map(stlink_t *sl) {
snprintf(map, sz, memory_map_template_H72x3x, snprintf(map, sz, memory_map_template_H72x3x,
sl->flash_size, sl->flash_size,
sl->flash_pgsz); sl->flash_pgsz);
} else { } else {
snprintf(map, sz, memory_map_template, snprintf(map, sz, memory_map_template,
sl->flash_size, sl->flash_size,
sl->sram_size, sl->sram_size,
@ -682,7 +689,7 @@ static int32_t flash_go(stlink_t *sl, st_state_t *st) {
for (struct flash_block* fb = flash_root; fb; fb = fb->next) { for (struct flash_block* fb = flash_root; fb; fb = fb->next) {
ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length);
for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t) FLASH_PAGE) {
// update FLASH_PAGE // update FLASH_PAGE
stlink_calculate_pagesize(sl, page); stlink_calculate_pagesize(sl, page);
@ -698,14 +705,14 @@ static int32_t flash_go(stlink_t *sl, st_state_t *st) {
for (struct flash_block* fb = flash_root; fb; fb = fb->next) { for (struct flash_block* fb = flash_root; fb; fb = fb->next) {
ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length);
for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t) FLASH_PAGE) {
uint32_t length = fb->length - (page - fb->addr); uint32_t length = fb->length - (page - fb->addr);
// update FLASH_PAGE // update FLASH_PAGE
stlink_calculate_pagesize(sl, page); stlink_calculate_pagesize(sl, page);
ILOG("flash_do: page %08x\n", page); ILOG("flash_do: page %08x\n", page);
uint32_t len = (length > FLASH_PAGE) ? (uint32_t)FLASH_PAGE : length; uint32_t len = (length > FLASH_PAGE) ? (uint32_t) FLASH_PAGE : length;
ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len);
if (ret) { goto error; } if (ret) { goto error; }
} }
@ -981,8 +988,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
params = separator + 1; params = separator + 1;
} }
uint32_t queryNameLength = (uint32_t)(separator - &packet[1]); uint32_t queryNameLength = (uint32_t) (separator - &packet[1]);
char* queryName = calloc(queryNameLength + 1, 1); char* queryName = calloc(1, queryNameLength + 1);
strncpy(queryName, &packet[1], queryNameLength); strncpy(queryName, &packet[1], queryNameLength);
DLOG("query: %s;%s\n", queryName, params); DLOG("query: %s;%s\n", queryName, params);
@ -1000,8 +1007,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
__s_addr = strsep(&tok, ","); __s_addr = strsep(&tok, ",");
s_length = tok; s_length = tok;
uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16), uint32_t addr = (uint32_t) strtoul(__s_addr, NULL, 16),
length = (uint32_t)strtoul(s_length, NULL, 16); length = (uint32_t) strtoul(s_length, NULL, 16);
DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
type, op, annex, addr, length); type, op, annex, addr, length);
@ -1018,14 +1025,14 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
} }
if (data) { if (data) {
uint32_t data_length = (uint32_t)strlen(data); uint32_t data_length = (uint32_t) strlen(data);
if (addr + length > data_length) { length = data_length - addr; } if (addr + length > data_length) { length = data_length - addr; }
if (length == 0) { if (length == 0) {
reply = strdup("l"); reply = strdup("l");
} else { } else {
reply = calloc(length + 2, 1); reply = calloc(1, length + 2);
reply[0] = 'm'; reply[0] = 'm';
strncpy(&reply[1], data, length); strncpy(&reply[1], data, length);
} }
@ -1041,7 +1048,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
params = separator + 1; params = separator + 1;
} }
uint32_t hex_len = strlen(params); uint32_t hex_len = (uint32_t) strlen(params);
uint32_t alloc_size = (hex_len / 2) + 1; uint32_t alloc_size = (hex_len / 2) + 1;
uint32_t cmd_len; uint32_t cmd_len;
char *cmd = malloc(alloc_size); char *cmd = malloc(alloc_size);
@ -1161,8 +1168,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
__s_addr = strsep(&tok, ","); __s_addr = strsep(&tok, ",");
s_length = tok; s_length = tok;
uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16), uint32_t addr = (uint32_t) strtoul(__s_addr, NULL, 16),
length = (uint32_t)strtoul(s_length, NULL, 16); length = (uint32_t) strtoul(s_length, NULL, 16);
DLOG("FlashErase: addr:%08x,len:%04x\n", DLOG("FlashErase: addr:%08x,len:%04x\n",
addr, length); addr, length);
@ -1179,12 +1186,12 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
__s_addr = strsep(&tok, ":"); __s_addr = strsep(&tok, ":");
data = tok; data = tok;
uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16); uint32_t addr = (uint32_t) strtoul(__s_addr, NULL, 16);
uint32_t data_length = status - (uint32_t)(data - packet); uint32_t data_length = status - (uint32_t) (data - packet);
// Length of decoded data cannot be more than encoded, as escapes are removed. // Length of decoded data cannot be more than encoded, as escapes are removed.
// Additional byte is reserved for alignment fix. // Additional byte is reserved for alignment fix.
uint8_t *decoded = calloc(data_length + 1, 1); uint8_t *decoded = calloc(1, data_length + 1);
uint32_t dec_index = 0; uint32_t dec_index = 0;
for (uint32_t i = 0; i < data_length; i++) { for (uint32_t i = 0; i < data_length; i++) {
@ -1340,16 +1347,16 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
if (ret) { DLOG("g packet: read_all_regs failed\n"); } if (ret) { DLOG("g packet: read_all_regs failed\n"); }
reply = calloc(8 * 16 + 1, 1); reply = calloc(1, 8 * 16 + 1);
for (int32_t i = 0; i < 16; i++) { for (int32_t i = 0; i < 16; i++) {
sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); sprintf(&reply[i * 8], "%08x", (uint32_t) htonl(regp.r[i]));
} }
break; break;
case 'p': { case 'p': {
uint32_t id = (uint32_t)strtoul(&packet[1], NULL, 16); uint32_t id = (uint32_t) strtoul(&packet[1], NULL, 16);
uint32_t myreg = 0xDEADDEAD; uint32_t myreg = 0xDEADDEAD;
if (id < 16) { if (id < 16) {
@ -1391,7 +1398,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
if (reply == NULL) { if (reply == NULL) {
// if reply is set to "E00", skip // if reply is set to "E00", skip
reply = calloc(8 + 1, 1); reply = calloc(1, 8 + 1);
sprintf(reply, "%08x", myreg); sprintf(reply, "%08x", myreg);
} }
@ -1402,8 +1409,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
char* s_reg = &packet[1]; char* s_reg = &packet[1];
char* s_value = strstr(&packet[1], "=") + 1; char* s_value = strstr(&packet[1], "=") + 1;
uint32_t reg = (uint32_t)strtoul(s_reg, NULL, 16); uint32_t reg = (uint32_t) strtoul(s_reg, NULL, 16);
uint32_t value = (uint32_t)strtoul(s_value, NULL, 16); uint32_t value = (uint32_t) strtoul(s_value, NULL, 16);
if (reg < 16) { if (reg < 16) {
@ -1443,7 +1450,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
for (int32_t i = 0; i < 16; i++) { for (int32_t i = 0; i < 16; i++) {
char str[9] = {0}; char str[9] = {0};
strncpy(str, &packet[1 + i * 8], 8); strncpy(str, &packet[1 + i * 8], 8);
uint32_t reg = (uint32_t)strtoul(str, NULL, 16); uint32_t reg = (uint32_t) strtoul(str, NULL, 16);
ret = stlink_write_reg(sl, ntohl(reg), i); ret = stlink_write_reg(sl, ntohl(reg), i);
if (ret) { DLOG("G packet: stlink_write_reg failed"); } if (ret) { DLOG("G packet: stlink_write_reg failed"); }
@ -1456,8 +1463,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
char* s_start = &packet[1]; char* s_start = &packet[1];
char* s_count = strstr(&packet[1], ",") + 1; char* s_count = strstr(&packet[1], ",") + 1;
stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16);
uint32_t count = (uint32_t)strtoul(s_count, NULL, 16); uint32_t count = (uint32_t) strtoul(s_count, NULL, 16);
uint32_t adj_start = start % 4; uint32_t adj_start = start % 4;
uint32_t count_rnd = (count + adj_start + 4 - 1) / 4 * 4; uint32_t count_rnd = (count + adj_start + 4 - 1) / 4 * 4;
@ -1472,7 +1479,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
// read failed somehow, don't return stale buffer // read failed somehow, don't return stale buffer
reply = calloc(count * 2 + 1, 1); reply = calloc(1, count * 2 + 1);
for (uint32_t i = 0; i < count; i++) { for (uint32_t i = 0; i < count; i++) {
reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
@ -1487,8 +1494,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
char* s_count = strstr(&packet[1], ",") + 1; char* s_count = strstr(&packet[1], ",") + 1;
char* hexdata = strstr(packet, ":") + 1; char* hexdata = strstr(packet, ":") + 1;
stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16);
uint32_t count = (uint32_t)strtoul(s_count, NULL, 16); uint32_t count = (uint32_t) strtoul(s_count, NULL, 16);
int32_t err = 0; int32_t err = 0;
if (start % 4) { if (start % 4) {
@ -1498,7 +1505,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
for (uint32_t i = 0; i < align_count; i++) { for (uint32_t i = 0; i < align_count; i++) {
char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 };
uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); uint8_t byte = (uint8_t) strtoul(hextmp, NULL, 16);
sl->q_buf[i] = byte; sl->q_buf[i] = byte;
} }
@ -1514,7 +1521,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
for (uint32_t i = 0; i < aligned_count; i++) { for (uint32_t i = 0; i < aligned_count; i++) {
char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 };
uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); uint8_t byte = (uint8_t) strtoul(hextmp, NULL, 16);
sl->q_buf[i] = byte; sl->q_buf[i] = byte;
} }
@ -1528,7 +1535,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
if (count) { if (count) {
for (uint32_t i = 0; i < count; i++) { for (uint32_t i = 0; i < count; i++) {
char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 };
uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); uint8_t byte = (uint8_t) strtoul(hextmp, NULL, 16);
sl->q_buf[i] = byte; sl->q_buf[i] = byte;
} }
@ -1542,8 +1549,8 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
case 'Z': { case 'Z': {
char *endptr; char *endptr;
stm32_addr_t addr = (stm32_addr_t)strtoul(&packet[3], &endptr, 16); stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16);
stm32_addr_t len = (stm32_addr_t)strtoul(&endptr[1], NULL, 16); stm32_addr_t len = (stm32_addr_t) strtoul(&endptr[1], NULL, 16);
switch (packet[1]) { switch (packet[1]) {
case '1': case '1':
@ -1585,7 +1592,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) {
} }
case 'z': { case 'z': {
char *endptr; char *endptr;
stm32_addr_t addr = (stm32_addr_t)strtoul(&packet[3], &endptr, 16); stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16);
// stm32_addr_t len = strtoul(&endptr[1], NULL, 16); // stm32_addr_t len = strtoul(&endptr[1], NULL, 16);
switch (packet[1]) { switch (packet[1]) {

Wyświetl plik

@ -8,7 +8,7 @@ static const char* const memory_map_template_F4 =
"<memory-map>" "<memory-map>"
" <memory type=\"rom\" start=\"0x00000000\" length=\"0x100000\"/>" // code = sram, bootrom or flash; flash is bigger " <memory type=\"rom\" start=\"0x00000000\" length=\"0x100000\"/>" // code = sram, bootrom or flash; flash is bigger
" <memory type=\"ram\" start=\"0x10000000\" length=\"0x10000\"/>" // ccm ram " <memory type=\"ram\" start=\"0x10000000\" length=\"0x10000\"/>" // ccm ram
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x20000\"/>" // sram " <memory type=\"ram\" start=\"0x20000000\" length=\"0x%x\"/>" // sram
" <memory type=\"flash\" start=\"0x08000000\" length=\"0x10000\">" // Sectors 0...3 " <memory type=\"flash\" start=\"0x08000000\" length=\"0x10000\">" // Sectors 0...3
" <property name=\"blocksize\">0x4000</property>" // 16 kB " <property name=\"blocksize\">0x4000</property>" // 16 kB
" </memory>" " </memory>"

Wyświetl plik

@ -191,7 +191,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode); DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode);
*ret = (uint32_t)open(name, open_mode_flags[mode], 0644); *ret = (uint32_t) open(name, open_mode_flags[mode], 0644);
saved_errno = errno; saved_errno = errno;
DLOG("Semihosting: return %d\n", *ret); DLOG("Semihosting: return %d\n", *ret);
@ -210,11 +210,11 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
return (-1); return (-1);
} }
fd = (int32_t)args[0]; fd = (int32_t) args[0];
DLOG("Semihosting: close(%d)\n", fd); DLOG("Semihosting: close(%d)\n", fd);
*ret = (uint32_t)close(fd); *ret = (uint32_t) close(fd);
saved_errno = errno; saved_errno = errno;
DLOG("Semihosting: return %d\n", *ret); DLOG("Semihosting: return %d\n", *ret);
@ -234,7 +234,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
return (-1); return (-1);
} }
fd = (int32_t)args[0]; fd = (int32_t) args[0];
buffer_address = args[1]; buffer_address = args[1];
buffer_len = args[2]; buffer_len = args[2];
@ -262,7 +262,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len); DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len);
*ret = (uint32_t)write(fd, buffer, buffer_len); *ret = (uint32_t) write(fd, buffer, buffer_len);
saved_errno = errno; saved_errno = errno;
if (*ret == (uint32_t)-1) { if (*ret == (uint32_t)-1) {
@ -290,7 +290,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
return (-1); return (-1);
} }
fd = (int32_t)args[0]; fd = (int32_t) args[0];
buffer_address = args[1]; buffer_address = args[1];
buffer_len = args[2]; buffer_len = args[2];
@ -323,7 +323,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
*ret = buffer_len; *ret = buffer_len;
return (-1); return (-1);
} else { } else {
*ret = buffer_len - (uint32_t)read_result; *ret = buffer_len - (uint32_t) read_result;
} }
} }
@ -333,7 +333,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
} }
case SEMIHOST_SYS_ERRNO: case SEMIHOST_SYS_ERRNO:
{ {
*ret = (uint32_t)saved_errno; *ret = (uint32_t) saved_errno;
DLOG("Semihosting: Errno return %d\n", *ret); DLOG("Semihosting: Errno return %d\n", *ret);
break; break;
} }
@ -381,7 +381,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
} }
DLOG("Semihosting: unlink('%s')\n", name); DLOG("Semihosting: unlink('%s')\n", name);
*ret = (uint32_t)unlink(name); *ret = (uint32_t) unlink(name);
saved_errno = errno; saved_errno = errno;
DLOG("Semihosting: return %d\n", *ret); DLOG("Semihosting: return %d\n", *ret);
free(name); free(name);
@ -399,11 +399,11 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
return (-1); return (-1);
} }
fd = (int32_t)args[0]; fd = (int32_t) args[0];
offset = (off_t)args[1]; offset = (off_t) args[1];
DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int32_t)offset); DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int32_t) offset);
*ret = (uint32_t)lseek(fd, offset, SEEK_SET); *ret = (uint32_t) lseek(fd, offset, SEEK_SET);
saved_errno = errno; saved_errno = errno;
if (*ret != (uint32_t)-1) { *ret = 0; /* Success */ } if (*ret != (uint32_t)-1) { *ret = 0; /* Success */ }

Wyświetl plik

@ -50,6 +50,17 @@ static void stlink_gui_init(STlinkGUI *self) {
self->file_mem.base = 0; self->file_mem.base = 0;
} }
static void help(void)
{
puts("usage: stlink-gui [options] file\n");
puts("options:");
puts(" --version/-v Print version information.");
puts(" --help/-h Show this help.");
puts("");
puts("examples:");
puts(" stlink-gui path/to/file");
}
static gboolean set_info_error_message_idle(STlinkGUI *gui) { static gboolean set_info_error_message_idle(STlinkGUI *gui) {
if (gui->error_message != NULL) { if (gui->error_message != NULL) {
gchar *markup; gchar *markup;
@ -87,6 +98,8 @@ static void stlink_gui_set_sensitivity(STlinkGUI *gui, gboolean sensitivity) {
gtk_widget_set_sensitive(GTK_WIDGET(gui->flash_button), sensitivity); gtk_widget_set_sensitive(GTK_WIDGET(gui->flash_button), sensitivity);
} }
gtk_widget_set_sensitive(GTK_WIDGET(gui->reset_button), sensitivity && (gui->sl != NULL));
gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), sensitivity && (gui->sl != NULL)); gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), sensitivity && (gui->sl != NULL));
} }
@ -271,10 +284,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) {
int32_t res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin); int32_t res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin);
if (res == 0) { if (res == 0) {
if (gui->file_mem.memory) { if (gui->file_mem.memory) { g_free(gui->file_mem.memory); }
g_free(gui->file_mem.memory);
}
gui->file_mem.size = size; gui->file_mem.size = size;
gui->file_mem.memory = g_malloc(size); gui->file_mem.memory = g_malloc(size);
gui->file_mem.base = begin; gui->file_mem.base = begin;
@ -306,12 +316,12 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) {
if (gui->file_mem.memory) { g_free(gui->file_mem.memory); } if (gui->file_mem.memory) { g_free(gui->file_mem.memory); }
goffset file_size = g_file_info_get_size(file_info); goffset file_size = g_file_info_get_size(file_info);
if ((0 > file_size) && ((goffset)G_MAXSIZE <= file_size)) { if ((0 > file_size) && ((goffset)G_MAXSIZE <= file_size)) {
stlink_gui_set_info_error_message(gui, "File too large."); stlink_gui_set_info_error_message(gui, "File too large.");
goto out_input; goto out_input;
} }
gui->file_mem.size = file_size; gui->file_mem.size = file_size;
gui->file_mem.memory = g_malloc(gui->file_mem.size); gui->file_mem.memory = g_malloc(gui->file_mem.size);
@ -334,8 +344,8 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) {
gui->progress.fraction = (gdouble)(off + n_read) / gui->file_mem.size; gui->progress.fraction = (gdouble)(off + n_read) / gui->file_mem.size;
} }
out_input: g_object_unref(input_stream); out_input: g_object_unref(input_stream);
out: g_object_unref(file); out: g_object_unref(file);
} }
g_idle_add((GSourceFunc)stlink_gui_update_filemem_view, gui); g_idle_add((GSourceFunc)stlink_gui_update_filemem_view, gui);
@ -445,7 +455,7 @@ static gchar *dev_format_chip_id(guint32 chip_id) {
} }
static gchar *dev_format_mem_size(gsize flash_size) { static gchar *dev_format_mem_size(gsize flash_size) {
return (g_strdup_printf("%u kB", (uint32_t)(flash_size / 1024))); return (g_strdup_printf("%u kB", (uint32_t) (flash_size / 1024)));
} }
@ -525,6 +535,7 @@ static void stlink_gui_set_disconnected(STlinkGUI *gui) {
gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(gui->disconnect_button), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(gui->disconnect_button), FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(gui->connect_button), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(gui->connect_button), TRUE);
gtk_widget_set_sensitive(GTK_WIDGET(gui->reset_button), FALSE);
} }
static void disconnect_button_cb(GtkWidget *widget, gpointer data) { static void disconnect_button_cb(GtkWidget *widget, gpointer data) {
@ -555,6 +566,16 @@ static void stlink_gui_open_file(STlinkGUI *gui) {
"_Open", GTK_RESPONSE_ACCEPT, "_Open", GTK_RESPONSE_ACCEPT,
NULL); NULL);
/* Start file chooser from last used directory */
if (gui->filename != NULL){
gchar *last_dir = g_path_get_dirname(gui->filename);
if (last_dir){
gtk_file_chooser_set_current_folder(
GTK_FILE_CHOOSER(dialog), last_dir);
g_free(last_dir);
}
}
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { 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));
@ -574,6 +595,17 @@ static void stlink_gui_open_file(STlinkGUI *gui) {
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);
} }
static gboolean open_file_from_args(STlinkGUI *gui) {
if (gui->filename != NULL) {
stlink_gui_set_sensitivity(gui, FALSE);
gtk_notebook_set_current_page(gui->notebook, PAGE_FILEMEM);
gtk_widget_show(GTK_WIDGET(gui->progress.bar));
gtk_progress_bar_set_text(gui->progress.bar, "Reading file");
g_thread_new("file", (GThreadFunc)stlink_gui_populate_filemem_view, gui);
}
return (FALSE);
}
static void open_button_cb(GtkWidget *widget, gpointer data) { static void open_button_cb(GtkWidget *widget, gpointer data) {
STlinkGUI *gui; STlinkGUI *gui;
(void)widget; (void)widget;
@ -596,8 +628,9 @@ static gpointer stlink_gui_write_flash(gpointer data) {
g_return_val_if_fail((gui->sl != NULL), NULL); g_return_val_if_fail((gui->sl != NULL), NULL);
g_return_val_if_fail((gui->filename != NULL), NULL); g_return_val_if_fail((gui->filename != NULL), NULL);
if (stlink_mwrite_flash( if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory,
gui->sl, gui->file_mem.memory, (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { (uint32_t) gui->file_mem.size, gui->sl->flash_base,
SECTION_ERASE) < 0) {
stlink_gui_set_info_error_message(gui, "Failed to write to flash"); stlink_gui_set_info_error_message(gui, "Failed to write to flash");
} }
@ -645,6 +678,20 @@ static void flash_button_cb(GtkWidget *widget, gpointer data) {
} }
} }
static void reset_button_cb(GtkWidget *widget, gpointer data) {
STlinkGUI *gui;
(void)widget;
gui = STLINK_GUI(data);
g_return_if_fail(gui->sl != NULL);
stlink_exit_debug_mode(gui->sl);
stlink_reset(gui->sl, RESET_AUTO);
stlink_enter_swd_mode(gui->sl);
}
int32_t export_to_file(const char*filename, const struct mem_t flash_mem) { int32_t export_to_file(const char*filename, const struct mem_t flash_mem) {
printf("%s\n", filename); printf("%s\n", filename);
FILE * f = fopen(filename, "w"); FILE * f = fopen(filename, "w");
@ -819,6 +866,9 @@ static void stlink_gui_build_ui(STlinkGUI *gui) {
gui->flash_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "flash_button")); 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); g_signal_connect(G_OBJECT(gui->flash_button), "clicked", G_CALLBACK(flash_button_cb), gui);
gui->reset_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "reset_button"));
g_signal_connect(G_OBJECT(gui->reset_button), "clicked", G_CALLBACK(reset_button_cb), gui);
gui->export_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "export_button")); 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); g_signal_connect(G_OBJECT(gui->export_button), "clicked", G_CALLBACK(export_button_cb), gui);
@ -901,6 +951,26 @@ int32_t main(int32_t argc, char **argv) {
stlink_gui_build_ui(gui); stlink_gui_build_ui(gui);
stlink_gui_init_dnd(gui); stlink_gui_init_dnd(gui);
/* Parse remaining cli arguments */
argc--;
argv++;
while (argc > 0){
if (strcmp(argv[0], "--version") == 0 || strcmp(argv[0], "-v") == 0) {
printf("v%s\n", STLINK_VERSION);
exit(EXIT_SUCCESS);
} else if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-h") == 0) {
help();
return 1;
}
if (argc == 1 && g_file_test(*argv, G_FILE_TEST_IS_REGULAR)){
/* Open hex file at app startup */
gui->filename = g_strdup(*argv);
g_idle_add((GSourceFunc)open_file_from_args, gui);
}
argc--;
argv++;
}
gtk_main(); gtk_main();
return (0); return (0);
} }

Wyświetl plik

@ -65,6 +65,7 @@ struct _STlinkGUI {
GtkToolButton *flash_button; GtkToolButton *flash_button;
GtkToolButton *export_button; GtkToolButton *export_button;
GtkToolButton *open_button; GtkToolButton *open_button;
GtkToolButton *reset_button;
/* flash dialog */ /* flash dialog */
GtkDialog *flash_dialog; GtkDialog *flash_dialog;

Wyświetl plik

@ -2,8 +2,9 @@
Name=stlink Name=stlink
GenericName=Stlink Tools GenericName=Stlink Tools
Comment=Open source STM32 MCU programming toolset Comment=Open source STM32 MCU programming toolset
Exec=stlink-gui Exec=stlink-gui %f
Icon=stlink-gui Icon=stlink-gui
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Development;Electronics; Categories=Development;Electronics;
MimeType=text/plain;

Wyświetl plik

@ -33,7 +33,8 @@
<object class="GtkButton" id="flash_dialog_ok_button"> <object class="GtkButton" id="flash_dialog_ok_button">
<property name="label">gtk-ok</property> <property name="label">gtk-ok</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
@ -174,6 +175,20 @@
<property name="homogeneous">True</property> <property name="homogeneous">True</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkToolButton" id="reset_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Reset</property>
<property name="label" translatable="yes">Reset</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-refresh</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child> <child>
<object class="GtkToolButton" id="export_button"> <object class="GtkToolButton" id="export_button">
<property name="visible">True</property> <property name="visible">True</property>

Wyświetl plik

@ -65,7 +65,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) {
sl->chip_id == STM32_CHIPID_L496x_L4A6x || sl->chip_id == STM32_CHIPID_L496x_L4A6x ||
sl->chip_id == STM32_CHIPID_L4Rx) { sl->chip_id == STM32_CHIPID_L4Rx) {
// these chips use dual bank flash // these chips use dual bank flash
if (flashopt & (uint32_t)(1lu << FLASH_L4_OPTR_DUALBANK)) { if (flashopt & (uint32_t) (1lu << FLASH_L4_OPTR_DUALBANK)) {
uint32_t banksize = sl->flash_size / 2; uint32_t banksize = sl->flash_size / 2;
if (flashaddr >= banksize) { if (flashaddr >= banksize) {

Wyświetl plik

@ -65,7 +65,7 @@ void process_chipfile(char *fname) {
return; return;
} }
ts = calloc(sizeof(struct stlink_chipid_params), 1); ts = calloc(1, sizeof(struct stlink_chipid_params));
while (fgets(buf, sizeof(buf), fp) != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) {
@ -224,7 +224,7 @@ void init_chipids(char *dir_to_scan) {
if (d) { if (d) {
while ((dir = readdir(d)) != NULL) { while ((dir = readdir(d)) != NULL) {
nl = strlen(dir->d_name); nl = (uint32_t) strlen(dir->d_name);
if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { if (strcmp(dir->d_name + nl - 5, ".chip") == 0) {
char buf[1024]; char buf[1024];

Wyświetl plik

@ -299,8 +299,7 @@ int32_t stlink_load_device_params(stlink_t *sl) {
sl->sram_size = 0x1000; sl->sram_size = 0x1000;
} }
if (sl->chip_id == STM32_CHIPID_G4_CAT3 || if (sl->chip_id == STM32_CHIPID_G4_CAT3) {
sl->chip_id == STM32_CHIPID_G4_CAT4) {
uint32_t flash_optr; uint32_t flash_optr;
stlink_read_debug32(sl, FLASH_Gx_OPTR, &flash_optr); stlink_read_debug32(sl, FLASH_Gx_OPTR, &flash_optr);
@ -620,7 +619,7 @@ void stlink_print_data(stlink_t *sl) {
*/ */
} }
// DLOG(" %02x", (uint32_t) sl->q_buf[i]); // DLOG(" %02x", (uint32_t) sl->q_buf[i]);
fprintf(stderr, " %02x", (uint32_t)sl->q_buf[i]); fprintf(stderr, " %02x", (uint32_t) sl->q_buf[i]);
} }
// DLOG("\n\n"); // DLOG("\n\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -669,12 +668,12 @@ int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_a
size += 2; size += 2;
} // round size if needed } // round size if needed
stlink_write_mem32(sl, addr + off, (uint16_t)size); stlink_write_mem32(sl, addr + off, (uint16_t) size);
} }
if (length > len) { if (length > len) {
memcpy(sl->q_buf, data + len, length - len); memcpy(sl->q_buf, data + len, length - len);
stlink_write_mem8(sl, addr + len, (uint16_t)(length - len)); stlink_write_mem8(sl, addr + len, (uint16_t) (length - len));
} }
error = 0; // success error = 0; // success
@ -737,12 +736,12 @@ int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) {
size += 2; size += 2;
} // round size if needed } // round size if needed
stlink_write_mem32(sl, addr + off, (uint16_t)size); stlink_write_mem32(sl, addr + off, (uint16_t) size);
} }
if (mf.len > len) { if (mf.len > len) {
memcpy(sl->q_buf, mf.base + len, mf.len - len); memcpy(sl->q_buf, mf.base + len, mf.len - len);
stlink_write_mem8(sl, addr + len, (uint16_t)(mf.len - len)); stlink_write_mem8(sl, addr + len, (uint16_t) (mf.len - len));
} }
// check the file has been written // check the file has been written
@ -880,7 +879,7 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me
} }
*size = (end - *begin) + 1; *size = (end - *begin) + 1;
data = calloc(*size, 1); // use calloc to get NULL if out of memory data = calloc(1, *size); // use calloc to get NULL if out of memory
if (!data) { if (!data) {
ELOG("Cannot allocate %u bytes\n", (*size)); ELOG("Cannot allocate %u bytes\n", (*size));
@ -913,7 +912,7 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me
break; break;
} }
uint32_t l = strlen(line); uint32_t l = (uint32_t) strlen(line);
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) {
--l; --l;
@ -941,14 +940,14 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me
uint8_t reclen = stlink_parse_hex(line + 1); 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"); ELOG("Wrong file format - record length mismatch\n");
res = -1; res = -1;
break; break;
} }
uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | uint16_t offset = ((uint16_t) stlink_parse_hex(line + 3) << 8) |
((uint16_t)stlink_parse_hex(line + 5)); ((uint16_t) stlink_parse_hex(line + 5));
uint8_t rectype = stlink_parse_hex(line + 7); uint8_t rectype = stlink_parse_hex(line + 7);
switch (rectype) { switch (rectype) {
@ -986,8 +985,8 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me
break; break;
case 4: /* Extended Linear Address */ case 4: /* Extended Linear Address */
if (reclen == 2) { if (reclen == 2) {
lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | lba = ((uint32_t) stlink_parse_hex(line + 9) << 24) |
((uint32_t)stlink_parse_hex(line + 11) << 16); ((uint32_t) stlink_parse_hex(line + 11) << 16);
} else { } else {
ELOG("Wrong file format - wrong LBA length\n"); ELOG("Wrong file format - wrong LBA length\n");
res = -1; res = -1;
@ -1181,8 +1180,8 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) {
slv->stlink_v = sl->q_buf[0]; slv->stlink_v = sl->q_buf[0];
slv->swim_v = sl->q_buf[1]; slv->swim_v = sl->q_buf[1];
slv->jtag_v = sl->q_buf[2]; slv->jtag_v = sl->q_buf[2];
slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); slv->st_vid = (uint32_t) ((sl->q_buf[9] << 8) | sl->q_buf[8]);
slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); slv->stlink_pid = (uint32_t) ((sl->q_buf[11] << 8) | sl->q_buf[10]);
slv->jtag_api = STLINK_JTAG_API_V3; slv->jtag_api = STLINK_JTAG_API_V3;
/* preferred API to get last R/W status */ /* preferred API to get last R/W status */
sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2;
@ -1230,7 +1229,7 @@ static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, uint32_t size, save_
aligned_size = (cmp_size + 4) & ~(4 - 1); aligned_size = (cmp_size + 4) & ~(4 - 1);
} }
stlink_read_mem32(sl, addr + off, (uint16_t)aligned_size); stlink_read_mem32(sl, addr + off, (uint16_t) aligned_size);
if (!fn(fn_arg, sl->q_buf, aligned_size)) { if (!fn(fn_arg, sl->q_buf, aligned_size)) {
goto on_error; goto on_error;
@ -1277,11 +1276,11 @@ static uint8_t stlink_parse_hex(const char *hex) {
static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) {
uint32_t addr = the_arg->addr; uint32_t addr = the_arg->addr;
uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + uint8_t sum = 2 + 4 + (uint8_t) ((addr & 0xFF000000) >> 24) +
(uint8_t)((addr & 0x00FF0000) >> 16); (uint8_t) ((addr & 0x00FF0000) >> 16);
if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n",
(addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { (addr & 0xFFFF0000) >> 16, (uint8_t) (0x100 - sum))) {
return (false); return (false);
} }
@ -1304,8 +1303,8 @@ static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the
} }
} }
uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + uint8_t sum = count + (uint8_t) ((addr & 0x0000FF00) >> 8) +
(uint8_t)(addr & 0x000000FF); (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); return (false);
@ -1320,7 +1319,7 @@ static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the
} }
} }
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); return (false);
} }

Wyświetl plik

@ -685,8 +685,6 @@ static int32_t unlock_flash_option(stlink_t *sl) {
break; break;
case STM32_FLASH_TYPE_H7: case STM32_FLASH_TYPE_H7:
optkey_reg = FLASH_H7_OPT_KEYR; optkey_reg = FLASH_H7_OPT_KEYR;
if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK)
optkey2_reg = FLASH_H7_OPT_KEYR2;
break; break;
case STM32_FLASH_TYPE_L0_L1: case STM32_FLASH_TYPE_L0_L1:
optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF;
@ -885,7 +883,7 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) {
x &= ~(1 << FLASH_L4_CR_MER1); x &= ~(1 << FLASH_L4_CR_MER1);
x &= ~(1 << FLASH_L4_CR_MER2); x &= ~(1 << FLASH_L4_CR_MER2);
x |= (n << FLASH_L4_CR_PNB); x |= (n << FLASH_L4_CR_PNB);
x |= (uint32_t)(1lu << FLASH_L4_CR_PER); x |= (uint32_t) (1lu << FLASH_L4_CR_PER);
#if DEBUG_FLASH #if DEBUG_FLASH
fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n);
#endif #endif
@ -1124,6 +1122,18 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) {
stlink_read_debug32(sl, FLASH_Gx_CR, &val); stlink_read_debug32(sl, FLASH_Gx_CR, &val);
// sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2. // sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2.
val &= ~(0x7FF << 3); val &= ~(0x7FF << 3);
// sec 3.3.8 - Error PGSERR
// * In the page erase sequence: PG, FSTPG and MER1 are not cleared when PER is set
val &= ~(1 << FLASH_Gx_CR_MER1 | 1 << FLASH_Gx_CR_MER2);
val &= ~(1 << FLASH_Gx_CR_PG);
// Products of the Gx series with more than 128K of flash use 2 banks.
// In this case we need to specify which bank to erase (sec 3.7.5 - BKER)
if (sl->flash_size > (128 * 1024) &&
((flashaddr - STM32_FLASH_BASE) >= sl->flash_size / 2)) {
val |= (1 << FLASH_Gx_CR_BKER); // erase bank 2
} else {
val &= ~(1 << FLASH_Gx_CR_BKER); // erase bank 1
}
val |= ((flash_page & 0x7FF) << 3) | (1 << FLASH_CR_PER); val |= ((flash_page & 0x7FF) << 3) | (1 << FLASH_CR_PER);
stlink_write_debug32(sl, FLASH_Gx_CR, val); stlink_write_debug32(sl, FLASH_Gx_CR, val);
// STM32L5x2xx has two banks with 2k pages or single with 4k pages // STM32L5x2xx has two banks with 2k pages or single with 4k pages
@ -1223,7 +1233,7 @@ int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_
return (-1); return (-1);
} }
fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\r", addr, page_size); fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\n", addr, page_size);
fflush(stdout); fflush(stdout);
// check the next page is within the range to erase // check the next page is within the range to erase
@ -1250,9 +1260,9 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) {
if (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_id != STM32_CHIPID_H7Ax) { if (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_id != STM32_CHIPID_H7Ax) {
// set parallelism // set parallelism
write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_1); write_flash_cr_psiz(sl, 3 /* 64 bit */, BANK_1);
if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) {
write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); write_flash_cr_psiz(sl, 3 /* 64 bit */, BANK_2);
} }
} }
@ -1281,7 +1291,9 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) {
return (err); return (err);
} }
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length,
stm32_addr_t addr,
const enum erase_type_t erase_type) {
/* Write the block in flash at addr */ /* Write the block in flash at addr */
int32_t err; int32_t err;
uint32_t num_empty, idx; uint32_t num_empty, idx;
@ -1315,7 +1327,7 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_
*/ */
err = stlink_write_flash(sl, addr, data, err = stlink_write_flash(sl, addr, data,
(num_empty == length) ? length : length - num_empty, (num_empty == length) ? length : length - num_empty,
num_empty == length); num_empty == length, erase_type);
stlink_fwrite_finalize(sl, addr); stlink_fwrite_finalize(sl, addr);
return (err); return (err);
} }
@ -1327,7 +1339,8 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_
* @param addr where to start writing * @param addr where to start writing
* @return 0 on success, -ve on failure. * @return 0 on success, -ve on failure.
*/ */
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr,
const enum erase_type_t erase_type) {
/* Write the file in flash at addr */ /* Write the file in flash at addr */
int32_t err; int32_t err;
uint32_t num_empty, idx; uint32_t num_empty, idx;
@ -1344,7 +1357,7 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
stlink_checksum(&mf); stlink_checksum(&mf);
if (sl->opt) { if (sl->opt) {
idx = (uint32_t)mf.len; idx = (uint32_t) mf.len;
for (num_empty = 0; num_empty != mf.len; ++num_empty) { for (num_empty = 0; num_empty != mf.len; ++num_empty) {
if (mf.base[--idx] != erased_pattern) { if (mf.base[--idx] != erased_pattern) {
@ -1370,11 +1383,11 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
/* In case the address is within the OTP area we use a different flash method */ /* In case the address is within the OTP area we use a different flash method */
if(addr >= sl->otp_base && addr < sl->otp_base + sl->otp_size) { if(addr >= sl->otp_base && addr < sl->otp_base + sl->otp_size) {
err = stlink_write_otp(sl, addr, mf.base, err = stlink_write_otp(sl, addr, mf.base,
(num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty); (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty);
} else { } else {
err = stlink_write_flash(sl, addr, mf.base, 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) ? (uint32_t) mf.len : (uint32_t)mf.len - num_empty,
num_empty == mf.len); num_empty == mf.len, erase_type);
} }
stlink_fwrite_finalize(sl, addr); stlink_fwrite_finalize(sl, addr);
unmap_file(&mf); unmap_file(&mf);
@ -1424,7 +1437,7 @@ int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *d
aligned_size = (cmp_size + 4) & ~(4 - 1); aligned_size = (cmp_size + 4) & ~(4 - 1);
} }
stlink_read_mem32(sl, address + off, (uint16_t)aligned_size); stlink_read_mem32(sl, address + off, (uint16_t) aligned_size);
if (memcmp(sl->q_buf, data + off, cmp_size)) { if (memcmp(sl->q_buf, data + off, cmp_size)) {
ELOG("Verification of flash failed at offset: %u\n", off); ELOG("Verification of flash failed at offset: %u\n", off);
@ -1483,7 +1496,9 @@ int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) {
return 0; return 0;
} }
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly) { int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
uint32_t len, uint8_t eraseonly,
const enum erase_type_t erase_type) {
int32_t ret; int32_t ret;
flash_loader_t fl; flash_loader_t fl;
ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr);
@ -1509,7 +1524,8 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3
stlink_core_id(sl); stlink_core_id(sl);
// Erase this section of the flash // Erase this section of the flash
if (stlink_erase_flash_section(sl, addr, len, true) < 0) { if ((erase_type == SECTION_ERASE) &&
stlink_erase_flash_section(sl, addr, len, true) < 0) {
ELOG("Failed to erase the flash prior to writing\n"); ELOG("Failed to erase the flash prior to writing\n");
return (-1); return (-1);
} }

Wyświetl plik

@ -10,6 +10,12 @@
#define BANK_1 0 #define BANK_1 0
#define BANK_2 1 #define BANK_2 1
enum erase_type_t {
NO_ERASE = 0,
SECTION_ERASE = 1,
MASS_ERASE = 2,
};
uint32_t get_stm32l0_flash_base(stlink_t *); uint32_t get_stm32l0_flash_base(stlink_t *);
uint32_t read_flash_cr(stlink_t *, uint32_t); uint32_t read_flash_cr(stlink_t *, uint32_t);
void lock_flash(stlink_t *); void lock_flash(stlink_t *);
@ -39,15 +45,20 @@ void clear_flash_cr_pg(stlink_t *, uint32_t);
int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr); int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr);
int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_t size, bool align_size); int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_t size, bool align_size);
int32_t stlink_erase_flash_mass(stlink_t *sl); int32_t stlink_erase_flash_mass(stlink_t *sl);
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr); int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length,
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr); stm32_addr_t addr, const enum erase_type_t erase);
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr,
const enum erase_type_t erase);
int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr); int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr);
int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length);
int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size); int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size);
int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, uint32_t size); int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, uint32_t size);
int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr);
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly); int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); uint32_t len, uint8_t erase_only,
const enum erase_type_t erase);
int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
uint32_t len);
void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t);
#endif // COMMON_FLASH_H #endif // COMMON_FLASH_H

Wyświetl plik

@ -320,7 +320,7 @@ int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint
} }
memcpy(sl->q_buf, loader_code, loader_size); memcpy(sl->q_buf, loader_code, loader_size);
int32_t ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t)loader_size); int32_t ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t) loader_size);
if (ret) { return (ret); } if (ret) { return (ret); }
@ -400,7 +400,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t
* several bytes garbage have been written due to the unaligned * several bytes garbage have been written due to the unaligned
* firmware size. * firmware size.
*/ */
if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { if ((int32_t) rr.r[2] > 0 || (int32_t) rr.r[2] < -7) {
ELOG("Flash loader write error\n"); ELOG("Flash loader write error\n");
goto error; goto error;
} }
@ -460,7 +460,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
for (off = 0; off < pagesize && !ret; off += 64) { for (off = 0; off < pagesize && !ret; off += 64) {
uint32_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; uint32_t chunk = (pagesize - off > 64) ? 64 : pagesize - off;
memcpy(sl->q_buf, base + count * pagesize + off, chunk); memcpy(sl->q_buf, base + count * pagesize + off, chunk);
ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t) chunk);
} }
} }
@ -471,7 +471,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
if (sl->verbose >= 1) { if (sl->verbose >= 1) {
// show progress; writing procedure is slow and previous errors are misleading // show progress; writing procedure is slow and previous errors are misleading
fprintf(stdout, "\r%3u/%3u halfpages written", count + 1, num_half_pages); fprintf(stdout, "%3u/%3u halfpages written\n", count + 1, num_half_pages);
fflush(stdout); fflush(stdout);
} }
@ -614,7 +614,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) {
int32_t voltage; int32_t voltage;
if (sl->version.stlink_v == 1) { if (sl->version.stlink_v == 1) {
WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); WLOG("STLINK V1 cannot read voltage, use default voltage 3.2 V\n");
voltage = 3200; voltage = 3200;
} else { } else {
voltage = stlink_target_voltage(sl); voltage = stlink_target_voltage(sl);
@ -713,9 +713,9 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) {
} }
if (sl->chip_id != STM32_CHIPID_H7Ax) { if (sl->chip_id != STM32_CHIPID_H7Ax) {
// set parallelism // set parallelism
write_flash_cr_psiz(sl, 3 /* 64bit */, BANK_1); write_flash_cr_psiz(sl, 3 /* 64 bit */, BANK_1);
if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) {
write_flash_cr_psiz(sl, 3 /* 64bit */, BANK_2); write_flash_cr_psiz(sl, 3 /* 64 bit */, BANK_2);
} }
} }
} else { } else {
@ -750,15 +750,15 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
sl->flash_type == STM32_FLASH_TYPE_C0) { sl->flash_type == STM32_FLASH_TYPE_C0) {
if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 && (len % 16)) { if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 && (len % 16)) {
WLOG("Data size is aligned to 16 byte"); WLOG("Aligning data size to 16 bytes\n");
len += 16 - len%16; len += 16 - len % 16;
} }
DLOG("Starting %3u page write\n", len / sl->flash_pgsz); DLOG("Starting %3u page write\n", len / sl->flash_pgsz);
for (off = 0; off < len; off += sizeof(uint32_t)) { for (off = 0; off < len; off += sizeof(uint32_t)) {
uint32_t data; uint32_t data;
if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) {
fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fprintf(stdout, "%3u/%-3u pages written\n", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz));
fflush(stdout); fflush(stdout);
} }
@ -780,7 +780,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
uint32_t flash_regs_base = get_stm32l0_flash_base(sl); uint32_t flash_regs_base = get_stm32l0_flash_base(sl);
uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? L0_WRITE_BLOCK_SIZE : L1_WRITE_BLOCK_SIZE; uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? L0_WRITE_BLOCK_SIZE : L1_WRITE_BLOCK_SIZE;
DLOG("Starting %3u page write\r\n", len / sl->flash_pgsz); DLOG("Starting %3u page write\n", len / sl->flash_pgsz);
off = 0; off = 0;
@ -788,7 +788,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
if (stm32l1_write_half_pages(sl, fl, addr, base, len, pagesize)) { if (stm32l1_write_half_pages(sl, fl, addr, base, len, pagesize)) {
return (-1); return (-1);
} else { } else {
off = (size_t)(len / pagesize) * pagesize; off = (uint32_t) (len / pagesize) * pagesize;
} }
} }
@ -797,7 +797,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
uint32_t data; uint32_t data;
if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) {
fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fprintf(stdout, "%3u/%-3u pages written\n", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz));
fflush(stdout); fflush(stdout);
} }
@ -834,7 +834,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
if (sl->verbose >= 1) { if (sl->verbose >= 1) {
// show progress; writing procedure is slow and previous errors are // show progress; writing procedure is slow and previous errors are
// misleading // misleading
fprintf(stdout, "\r%3u/%-3u pages written", ++write_block_count, fprintf(stdout, "%3u/%-3u pages written\n", ++write_block_count,
(len + sl->flash_pgsz - 1) / sl->flash_pgsz); (len + sl->flash_pgsz - 1) / sl->flash_pgsz);
fflush(stdout); fflush(stdout);
} }
@ -854,7 +854,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t
if (sl->verbose >= 1) { if (sl->verbose >= 1) {
// show progress // show progress
fprintf(stdout, "\r%u/%u bytes written", off, len); fprintf(stdout, "%u/%u bytes written\n", off, len);
fflush(stdout); fflush(stdout);
} }
} }
@ -902,7 +902,7 @@ int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) {
// enable interrupt // enable interrupt
if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) {
stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN |
(dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS)));
} }
// restore DMA state // restore DMA state

Wyświetl plik

@ -19,18 +19,22 @@
uint32_t time_ms() { uint32_t time_ms() {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
return (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000);
} }
int32_t arg_parse_freq(const char *str) { int32_t arg_parse_freq(const char *str) {
char *tail; int32_t value = -1;
int32_t value = (int32_t)strtol(str, &tail, 10); if (str != NULL) {
char* tail = NULL;
if (tail[0] == 'M' && tail[1] == '\0') { value = strtol(str, &tail, 10);
value = value*1000; if (tail != NULL) {
} else if ((tail[0] != 'k' || tail[1] != '\0') && tail[0] != '\0') { if (tail[0] == 'M' && tail[1] == '\0') {
return -1; value = value*1000;
}
else if (tail[0] != '\0' && !(tail[0] == 'k' && tail[1] == '\0')) {
value = -1; // error
}
}
} }
return value; // frequency in kHz
return value;
} }

Wyświetl plik

@ -46,10 +46,10 @@ static void* TransformFunction(Md5Context* ctx, void const* data, uintmax_t size
uint32_t saved_d; uint32_t saved_d;
#define GET(n) (ctx->block[(n)]) #define GET(n) (ctx->block[(n)])
#define SET(n) (ctx->block[(n)] = ((uint32_t)ptr[(n) * 4 + 0] << 0) | \ #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 + 1] << 8) | \
((uint32_t)ptr[(n) * 4 + 2] << 16) | \ ((uint32_t) ptr[(n) * 4 + 2] << 16) | \
((uint32_t)ptr[(n) * 4 + 3] << 24)) ((uint32_t) ptr[(n) * 4 + 3] << 24))
ptr = (uint8_t*)data; ptr = (uint8_t*)data;
@ -188,7 +188,7 @@ void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */
Context->hi++; Context->hi++;
} }
Context->hi += (uint32_t)(BufferSize >> 29); Context->hi += (uint32_t) (BufferSize >> 29);
used = saved_lo & 0x3f; used = saved_lo & 0x3f;
@ -207,7 +207,7 @@ void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */
} }
if ( BufferSize >= 64 ) { if ( BufferSize >= 64 ) {
Buffer = TransformFunction( Context, Buffer, BufferSize & ~(uint32_t)0x3f ); Buffer = TransformFunction( Context, Buffer, BufferSize & ~(uint32_t) 0x3f );
BufferSize &= 0x3f; BufferSize &= 0x3f;
} }
@ -239,33 +239,33 @@ void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */
memset( &Context->buffer[used], 0, free - 8 ); memset( &Context->buffer[used], 0, free - 8 );
Context->lo <<= 3; Context->lo <<= 3;
Context->buffer[56] = (uint8_t)(Context->lo); Context->buffer[56] = (uint8_t) (Context->lo);
Context->buffer[57] = (uint8_t)(Context->lo >> 8); Context->buffer[57] = (uint8_t) (Context->lo >> 8);
Context->buffer[58] = (uint8_t)(Context->lo >> 16); Context->buffer[58] = (uint8_t) (Context->lo >> 16);
Context->buffer[59] = (uint8_t)(Context->lo >> 24); Context->buffer[59] = (uint8_t) (Context->lo >> 24);
Context->buffer[60] = (uint8_t)(Context->hi); Context->buffer[60] = (uint8_t) (Context->hi);
Context->buffer[61] = (uint8_t)(Context->hi >> 8); Context->buffer[61] = (uint8_t) (Context->hi >> 8);
Context->buffer[62] = (uint8_t)(Context->hi >> 16); Context->buffer[62] = (uint8_t) (Context->hi >> 16);
Context->buffer[63] = (uint8_t)(Context->hi >> 24); Context->buffer[63] = (uint8_t) (Context->hi >> 24);
TransformFunction( Context, Context->buffer, 64 ); TransformFunction( Context, Context->buffer, 64 );
Digest->bytes[0] = (uint8_t)(Context->a); Digest->bytes[0] = (uint8_t) (Context->a);
Digest->bytes[1] = (uint8_t)(Context->a >> 8); Digest->bytes[1] = (uint8_t) (Context->a >> 8);
Digest->bytes[2] = (uint8_t)(Context->a >> 16); Digest->bytes[2] = (uint8_t) (Context->a >> 16);
Digest->bytes[3] = (uint8_t)(Context->a >> 24); Digest->bytes[3] = (uint8_t) (Context->a >> 24);
Digest->bytes[4] = (uint8_t)(Context->b); Digest->bytes[4] = (uint8_t) (Context->b);
Digest->bytes[5] = (uint8_t)(Context->b >> 8); Digest->bytes[5] = (uint8_t) (Context->b >> 8);
Digest->bytes[6] = (uint8_t)(Context->b >> 16); Digest->bytes[6] = (uint8_t) (Context->b >> 16);
Digest->bytes[7] = (uint8_t)(Context->b >> 24); Digest->bytes[7] = (uint8_t) (Context->b >> 24);
Digest->bytes[8] = (uint8_t)(Context->c); Digest->bytes[8] = (uint8_t) (Context->c);
Digest->bytes[9] = (uint8_t)(Context->c >> 8); Digest->bytes[9] = (uint8_t) (Context->c >> 8);
Digest->bytes[10] = (uint8_t)(Context->c >> 16); Digest->bytes[10] = (uint8_t) (Context->c >> 16);
Digest->bytes[11] = (uint8_t)(Context->c >> 24); Digest->bytes[11] = (uint8_t) (Context->c >> 24);
Digest->bytes[12] = (uint8_t)(Context->d); Digest->bytes[12] = (uint8_t) (Context->d);
Digest->bytes[13] = (uint8_t)(Context->d >> 8); Digest->bytes[13] = (uint8_t) (Context->d >> 8);
Digest->bytes[14] = (uint8_t)(Context->d >> 16); Digest->bytes[14] = (uint8_t) (Context->d >> 16);
Digest->bytes[15] = (uint8_t)(Context->d >> 24); Digest->bytes[15] = (uint8_t) (Context->d >> 24);
} }
/* Md5Calculate /* Md5Calculate

Wyświetl plik

@ -52,7 +52,7 @@ int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) {
aligned_size = (cmp_size + 4) & ~(4 - 1); aligned_size = (cmp_size + 4) & ~(4 - 1);
} }
stlink_read_mem32(sl, addr + off, (uint16_t)aligned_size); stlink_read_mem32(sl, addr + off, (uint16_t) aligned_size);
if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { if (memcmp(sl->q_buf, mf->base + off, cmp_size)) {
return (-1); return (-1);
@ -80,7 +80,7 @@ int32_t map_file(mapped_file_t *mf, const char *path) {
if (sizeof(st.st_size) != sizeof(size_t)) { if (sizeof(st.st_size) != sizeof(size_t)) {
// on 32 bit systems, check if there is an overflow // on 32 bit systems, check if there is an overflow
if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { if (st.st_size > (off_t) MAX_FILE_SIZE /*1 GB*/ ) {
// limit file size to 1 GB // limit file size to 1 GB
fprintf(stderr, "mmap() uint32_t overflow for file %s\n", path); fprintf(stderr, "mmap() uint32_t overflow for file %s\n", path);
goto on_error; goto on_error;
@ -88,14 +88,14 @@ int32_t map_file(mapped_file_t *mf, const char *path) {
} }
mf->base = mf->base =
(uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); (uint8_t *)mmap(NULL, (size_t) (st.st_size), PROT_READ, MAP_SHARED, fd, 0);
if (mf->base == MAP_FAILED) { if (mf->base == MAP_FAILED) {
fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path);
goto on_error; goto on_error;
} }
mf->len = (size_t)st.st_size; mf->len = (uint32_t) st.st_size;
error = 0; // success error = 0; // success
on_error: on_error:

Wyświetl plik

@ -18,11 +18,11 @@ void md5_calculate(mapped_file_t *mf) {
Md5Context md5Context; Md5Context md5Context;
MD5_HASH md5Hash; MD5_HASH md5Hash;
Md5Initialise(&md5Context); Md5Initialise(&md5Context);
Md5Update(&md5Context, mf->base, (uint32_t)mf->len); Md5Update(&md5Context, mf->base, (uint32_t) mf->len);
Md5Finalise(&md5Context, &md5Hash); Md5Finalise(&md5Context, &md5Hash);
printf("md5 checksum: "); printf("md5 checksum: ");
for (int32_t i = 0; i < (int32_t)sizeof(md5Hash); i++) { for (int32_t i = 0; i < (int32_t) sizeof(md5Hash); i++) {
printf("%x", md5Hash.bytes[i]); printf("%x", md5Hash.bytes[i]);
} }

Wyświetl plik

@ -108,7 +108,7 @@ static int32_t stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uin
int32_t ret = 0; int32_t ret = 0;
if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) {
WLOG("Only full write of option bytes area is supported\n"); WLOG("Only full write of option bytes area is supported\n");
return -1; return -1;
} }
@ -211,7 +211,7 @@ static int32_t stlink_write_option_control_register_f0(stlink_t *sl, uint32_t op
user_options = (option_cr >> option_offset >> 2) & 0xFFFF; user_options = (option_cr >> option_offset >> 2) & 0xFFFF;
user_data = (option_cr >> user_data_offset) & 0xFFFF; user_data = (option_cr >> user_data_offset) & 0xFFFF;
#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) #define VAL_WITH_COMPLEMENT(v) (uint16_t) (((v)&0xFF) | (((~(v))<<8)&0xFF00))
opt_val[0] = (option_cr & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; opt_val[0] = (option_cr & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp;
opt_val[1] = VAL_WITH_COMPLEMENT(user_options); opt_val[1] = VAL_WITH_COMPLEMENT(user_options);
@ -330,7 +330,7 @@ int32_t stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) {
return stlink_read_debug32( return stlink_read_debug32(
sl, sl,
sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), sl->option_base + (uint32_t) (sl->option_size / 4 - 1) * sizeof(uint32_t),
option_byte); option_byte);
} }
@ -919,7 +919,7 @@ int32_t stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t
md5_calculate(&mf); md5_calculate(&mf);
stlink_checksum(&mf); stlink_checksum(&mf);
err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len);
stlink_fwrite_finalize(sl, addr); stlink_fwrite_finalize(sl, addr);
unmap_file(&mf); unmap_file(&mf);

Wyświetl plik

@ -18,17 +18,17 @@
// These functions encode and decode little endian uint16 and uint32 values. // These functions encode and decode little endian uint16 and uint32 values.
uint16_t read_uint16(const unsigned char *c, const int32_t pt) { uint16_t read_uint16(const unsigned char *c, const int32_t pt) {
return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); return ((uint16_t) c[pt]) | ((uint16_t) c[pt + 1] << 8);
} }
void write_uint16(unsigned char *buf, uint16_t ui) { void write_uint16(unsigned char *buf, uint16_t ui) {
buf[0] = (uint8_t)ui; buf[0] = (uint8_t) ui;
buf[1] = (uint8_t)(ui >> 8); buf[1] = (uint8_t) (ui >> 8);
} }
uint32_t read_uint32(const unsigned char *c, const int32_t pt) { uint32_t read_uint32(const unsigned char *c, const int32_t pt) {
return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | return ((uint32_t) c[pt]) | ((uint32_t) c[pt + 1] << 8) |
((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); ((uint32_t) c[pt + 2] << 16) | ((uint32_t) c[pt + 3] << 24);
} }
void write_uint32(unsigned char *buf, uint32_t ui) { void write_uint32(unsigned char *buf, uint32_t ui) {

Wyświetl plik

@ -28,10 +28,10 @@
* SB Device Class Definition for Mass Storage Devices: * SB Device Class Definition for Mass Storage Devices:
* www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf * www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
* *
* dt - Data Transfer (IN/OUT) * dt - Data Transfer (IN/OUT)
* CBW - Command Block Wrapper * CBW - Command Block Wrapper
* CSW - Command Status Wrapper * CSW - Command Status Wrapper
* RFU - Reserved for Future Use * RFU - Reserved for Future Use
* *
* Originally, this driver used scsi pass through commands, which required the * Originally, this driver used scsi pass through commands, which required the
* usb-storage module to be loaded, providing the /dev/sgX links. The USB mass * usb-storage module to be loaded, providing the /dev/sgX links. The USB mass
@ -172,7 +172,7 @@ static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) {
dbugp += sprintf(dbugp, "Sending CDB ["); dbugp += sprintf(dbugp, "Sending CDB [");
for (uint8_t i = 0; i < cdb_len; i++) { for (uint8_t i = 0; i < cdb_len; i++) {
dbugp += sprintf(dbugp, " 0x%02x", (uint32_t)cdb[i]); dbugp += sprintf(dbugp, " 0x%02x", (uint32_t) cdb[i]);
} }
sprintf(dbugp, "]\n"); sprintf(dbugp, "]\n");
@ -288,7 +288,7 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t
} }
if (transferred != sizeof(sense)) { if (transferred != sizeof(sense)) {
WLOG("received unexpected amount of sense: %d != %u\n", transferred, (uint32_t)sizeof(sense)); WLOG("received unexpected amount of sense: %d != %u\n", transferred, (uint32_t) sizeof(sense));
} }
uint32_t received_tag; uint32_t received_tag;

Wyświetl plik

@ -31,7 +31,7 @@
#include "register.h" #include "register.h"
static inline uint32_t le_to_h_u32(const uint8_t* buf) { static inline uint32_t le_to_h_u32(const uint8_t* buf) {
return ((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); return ((uint32_t) ((uint32_t) buf[0] | (uint32_t) buf[1] << 8 | (uint32_t) buf[2] << 16 | (uint32_t) buf[3] << 24));
} }
static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz) { static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz) {
@ -98,17 +98,17 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char
while (1) { while (1) {
res = 0; res = 0;
t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int32_t)txsize, &res, 3000); t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int32_t) txsize, &res, 3000);
if (t) { if (t) {
ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t));
return (-1); return (-1);
} else if ((size_t)res != txsize) { } else if ((size_t) res != txsize) {
ELOG("%s send request wrote %u bytes, instead of %u\n", cmd, (uint32_t)res, (uint32_t)txsize); ELOG("%s send request wrote %u bytes, instead of %u\n", cmd, (uint32_t) res, (uint32_t) txsize);
} }
if (rxsize != 0) { if (rxsize != 0) {
t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int32_t)rxsize, &res, 3000); t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int32_t) rxsize, &res, 3000);
if (t) { if (t) {
ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t));
@ -143,7 +143,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char
return (-1); return (-1);
} }
if (check_error == CMD_CHECK_REP_LEN && res != (int32_t)rxsize) { if (check_error == CMD_CHECK_REP_LEN && res != (int32_t) rxsize) {
ELOG("%s wrong reply length\n", cmd); ELOG("%s wrong reply length\n", cmd);
res = -1; res = -1;
} }
@ -169,7 +169,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char
static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf,
uint32_t txsize, const char *cmd) { uint32_t txsize, const char *cmd) {
return ((int32_t)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); return ((int32_t) send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd));
} }
@ -682,10 +682,10 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) {
cmd[i++] = STLINK_DEBUG_APIV3_SET_COM_FREQ; cmd[i++] = STLINK_DEBUG_APIV3_SET_COM_FREQ;
cmd[i++] = 0; // SWD mode cmd[i++] = 0; // SWD mode
cmd[i++] = 0; cmd[i++] = 0;
cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); cmd[i++] = (uint8_t) ((map[speed_index] >> 0) & 0xFF);
cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); cmd[i++] = (uint8_t) ((map[speed_index] >> 8) & 0xFF);
cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); cmd[i++] = (uint8_t) ((map[speed_index] >> 16) & 0xFF);
cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); cmd[i++] = (uint8_t) ((map[speed_index] >> 24) & 0xFF);
size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ");
@ -728,7 +728,7 @@ int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
return (-1); return (-1);
} }
sl->q_len = (int32_t)size; sl->q_len = (int32_t) size;
stlink_print_data(sl); stlink_print_data(sl);
return (0); return (0);
@ -759,7 +759,7 @@ int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) {
/* V1: regs data from offset 0 */ /* V1: regs data from offset 0 */
/* V2: status at offset 0, regs data from offset 4 */ /* V2: status at offset 0, regs data from offset 4 */
int32_t reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; int32_t reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4;
sl->q_len = (int32_t)size; sl->q_len = (int32_t) size;
stlink_print_data(sl); stlink_print_data(sl);
for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4); for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4);
@ -799,14 +799,14 @@ int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *reg
cmd[i++] = STLINK_DEBUG_APIV2_READREG; cmd[i++] = STLINK_DEBUG_APIV2_READREG;
} }
cmd[i++] = (uint8_t)r_idx; cmd[i++] = (uint8_t) r_idx;
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG"); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG");
if (size < 0) { if (size < 0) {
return (-1); return (-1);
} }
sl->q_len = (int32_t)size; sl->q_len = (int32_t) size;
stlink_print_data(sl); stlink_print_data(sl);
r = read_uint32(sl->q_buf, reg_offset); r = read_uint32(sl->q_buf, reg_offset);
DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);
@ -856,10 +856,10 @@ int32_t _stlink_usb_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stl
switch (r_idx) { switch (r_idx) {
case 0x14: case 0x14:
regp->primask = (uint8_t)(r & 0xFF); regp->primask = (uint8_t) (r & 0xFF);
regp->basepri = (uint8_t)((r >> 8) & 0xFF); regp->basepri = (uint8_t) ((r >> 8) & 0xFF);
regp->faultmask = (uint8_t)((r >> 16) & 0xFF); regp->faultmask = (uint8_t) ((r >> 16) & 0xFF);
regp->control = (uint8_t)((r >> 24) & 0xFF); regp->control = (uint8_t) ((r >> 24) & 0xFF);
break; break;
case 0x21: case 0x21:
regp->fpscr = r; regp->fpscr = r;
@ -902,32 +902,32 @@ int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_
if (ret == -1) { return (ret); } if (ret == -1) { return (ret); }
val = (uint8_t)(val >> 24); val = (uint8_t) (val >> 24);
switch (r_idx) { switch (r_idx) {
case 0x1C: /* control */ case 0x1C: /* control */
val = (((uint32_t)val) << 24) | val = (((uint32_t) val) << 24) |
(((uint32_t)regp->faultmask) << 16) | (((uint32_t) regp->faultmask) << 16) |
(((uint32_t)regp->basepri) << 8) | (((uint32_t) regp->basepri) << 8) |
((uint32_t)regp->primask); ((uint32_t) regp->primask);
break; break;
case 0x1D: /* faultmask */ case 0x1D: /* faultmask */
val = (((uint32_t)regp->control) << 24) | val = (((uint32_t) regp->control) << 24) |
(((uint32_t)val) << 16) | (((uint32_t) val) << 16) |
(((uint32_t)regp->basepri) << 8) | (((uint32_t) regp->basepri) << 8) |
((uint32_t)regp->primask); ((uint32_t) regp->primask);
break; break;
case 0x1E: /* basepri */ case 0x1E: /* basepri */
val = (((uint32_t)regp->control) << 24) | val = (((uint32_t) regp->control) << 24) |
(((uint32_t)regp->faultmask) << 16) | (((uint32_t) regp->faultmask) << 16) |
(((uint32_t)val) << 8) | (((uint32_t) val) << 8) |
((uint32_t)regp->primask); ((uint32_t) regp->primask);
break; break;
case 0x1F: /* primask */ case 0x1F: /* primask */
val = (((uint32_t)regp->control) << 24) | val = (((uint32_t) regp->control) << 24) |
(((uint32_t)regp->faultmask) << 16) | (((uint32_t) regp->faultmask) << 16) |
(((uint32_t)regp->basepri) << 8) | (((uint32_t) regp->basepri) << 8) |
((uint32_t)val); ((uint32_t) val);
break; break;
} }
@ -1026,7 +1026,7 @@ int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) {
if (send_size < 0) { if (send_size < 0) {
return (-1); return (-1);
} else if (send_size != 2) { } else if (send_size != 2) {
ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int32_t)send_size); ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int32_t) send_size);
return (-1); return (-1);
} }
@ -1041,7 +1041,7 @@ int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) {
int32_t res = 0; int32_t res = 0;
int32_t t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); int32_t t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000);
if (t || res != (int32_t)trace_count) { if (t || res != (int32_t) trace_count) {
ELOG("read_trace read error %d\n", t); ELOG("read_trace read error %d\n", t);
return (-1); return (-1);
} }
@ -1084,40 +1084,40 @@ static stlink_backend_t _stlink_usb_backend = {
}; };
/* return the length of serial or (0) in case of errors */ /* return the length of serial or (0) in case of errors */
size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) { uint32_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) {
unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2]; unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2];
/* truncate the string in the serial buffer */ /* truncate the string in the serial buffer */
serial[0] = '\0'; serial[0] = '\0';
/* get the LANGID from String Descriptor Zero */ /* get the LANGID from String Descriptor Zero */
int32_t ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); int32_t ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial));
if (ret < 4) return 0; if (ret < 4) return 0;
uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); uint32_t langid = desc_serial[2] | (desc_serial[3] << 8);
/* get the serial */ /* get the serial */
ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial, ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial,
sizeof(desc_serial)); sizeof(desc_serial));
if (ret < 0) return 0; // could not read serial if (ret < 0) return 0; // could not read serial
unsigned char len = desc_serial[0]; unsigned char len = desc_serial[0];
if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */ if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */
/* good ST-Link adapter */ /* good ST-Link adapter */
ret = libusb_get_string_descriptor_ascii( ret = libusb_get_string_descriptor_ascii(
handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE); handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE);
if (ret < 0) return 0; if (ret < 0) return 0;
} else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */
/* fix-up the buggy serial */ /* fix-up the buggy serial */
for (uint32_t i = 0; i < STLINK_SERIAL_LENGTH; i += 2) for (uint32_t i = 0; i < STLINK_SERIAL_LENGTH; i += 2)
sprintf(serial + i, "%02X", desc_serial[i + 2]); sprintf(serial + i, "%02X", desc_serial[i + 2]);
serial[STLINK_SERIAL_LENGTH] = '\0'; serial[STLINK_SERIAL_LENGTH] = '\0';
} else { } else {
return 0; return 0;
} }
return strlen(serial); return (uint32_t)strlen(serial);
} }
/** /**
@ -1256,7 +1256,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect,
desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) { desc.idProduct == STLINK_USB_PID_STLINK_V3_NO_MSD_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3P) {
slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT;
slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN; slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN;
} else { } else {
@ -1396,7 +1397,7 @@ static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[],
return (slcur); return (slcur);
} }
size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq) { uint32_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq) {
libusb_device **devs; libusb_device **devs;
stlink_t **sldevs; stlink_t **sldevs;

Wyświetl plik

@ -23,6 +23,7 @@
#define STLINK_USB_PID_STLINK_V3S_PID 0x374f #define STLINK_USB_PID_STLINK_V3S_PID 0x374f
#define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 #define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753
#define STLINK_USB_PID_STLINK_V3_NO_MSD_PID 0x3754 #define STLINK_USB_PID_STLINK_V3_NO_MSD_PID 0x3754
#define STLINK_USB_PID_STLINK_V3P 0x3757
#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK) #define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK)
@ -36,7 +37,8 @@
(pid) == STLINK_USB_PID_STLINK_V3E_PID || \ (pid) == STLINK_USB_PID_STLINK_V3E_PID || \
(pid) == STLINK_USB_PID_STLINK_V3S_PID || \ (pid) == STLINK_USB_PID_STLINK_V3S_PID || \
(pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID || \ (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID || \
(pid) == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) (pid) == STLINK_USB_PID_STLINK_V3_NO_MSD_PID || \
(pid) == STLINK_USB_PID_STLINK_V3P)
#define STLINK_SUPPORTED_USB_PID(pid) (STLINK_V1_USB_PID(pid) || \ #define STLINK_SUPPORTED_USB_PID(pid) (STLINK_V1_USB_PID(pid) || \
STLINK_V2_USB_PID(pid) || \ STLINK_V2_USB_PID(pid) || \
@ -100,10 +102,10 @@ int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size);
// static stlink_backend_t _stlink_usb_backend = { }; // static stlink_backend_t _stlink_usb_backend = { };
size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial); uint32_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial);
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq); stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq);
// static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq); // static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq);
size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq); uint32_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq);
void stlink_probe_usb_free(stlink_t **stdevs[], uint32_t size); void stlink_probe_usb_free(stlink_t **stdevs[], uint32_t size);
#endif // USB_H #endif // USB_H

Wyświetl plik

@ -23,7 +23,7 @@ void *mmap (void *addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, i
count = read(fd, buf, len); count = read(fd, buf, len);
if (count != (ssize_t)len) { if (count != (ssize_t) len) {
free (buf); free (buf);
return (MAP_FAILED); return (MAP_FAILED);
} }

Wyświetl plik

@ -17,8 +17,8 @@ int32_t gettimeofday(struct timeval *tv, struct timezone *tz) {
ulint.LowPart = ftime.dwLowDateTime; ulint.LowPart = ftime.dwLowDateTime;
ulint.HighPart = ftime.dwHighDateTime; ulint.HighPart = ftime.dwHighDateTime;
tv->tv_sec = (int32_t)(ulint.QuadPart / 10000000L); tv->tv_sec = (int32_t) (ulint.QuadPart / 10000000L);
tv->tv_usec = (int32_t)(ulint.QuadPart % 10000000L); tv->tv_usec = (int32_t) (ulint.QuadPart % 10000000L);
} }
if (NULL != tz) { if (NULL != tz) {

Wyświetl plik

@ -49,7 +49,7 @@ static bool execute_test(const struct Test * test) {
strcpy(cmd_line, test->cmd_line); strcpy(cmd_line, test->cmd_line);
for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) {
if ((size_t)ac >= sizeof(av) / sizeof(av[0])) return (false); if ((size_t) ac >= sizeof(av) / sizeof(av[0])) return (false);
av[ac] = tok; av[ac] = tok;
++ac; ++ac;
@ -91,7 +91,7 @@ static struct Test tests[] = {
.freq = 0, .freq = 0,
.format = FLASH_FORMAT_BINARY } .format = FLASH_FORMAT_BINARY }
}, },
{ "--debug --reset write test.bin 0x80000000", 0, { "--debug --mass-erase --reset write test.bin 0x80000000", 0,
{ .cmd = FLASH_CMD_WRITE, { .cmd = FLASH_CMD_WRITE,
.serial = { 0 }, .serial = { 0 },
.filename = "test.bin", .filename = "test.bin",
@ -99,6 +99,7 @@ static struct Test tests[] = {
.size = 0, .size = 0,
.reset = 1, .reset = 1,
.log_level = DEBUG_LOG_LEVEL, .log_level = DEBUG_LOG_LEVEL,
.mass_erase = 1,
.freq = 0, .freq = 0,
.format = FLASH_FORMAT_BINARY } .format = FLASH_FORMAT_BINARY }
}, },
@ -187,6 +188,19 @@ static struct Test tests[] = {
.size = 0, .size = 0,
.reset = 0, .reset = 0,
.log_level = STND_LOG_LEVEL, .log_level = STND_LOG_LEVEL,
.mass_erase = 1,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--mass-erase erase", 0,
{ .cmd = FLASH_CMD_ERASE,
.serial = { 0 },
.filename = NULL,
.addr = 0,
.size = 0,
.reset = 0,
.log_level = STND_LOG_LEVEL,
.mass_erase = 1,
.freq = 0, .freq = 0,
.format = FLASH_FORMAT_BINARY } .format = FLASH_FORMAT_BINARY }
}, },