Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package picotool for openSUSE:Factory 
checked in at 2023-02-20 17:46:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/picotool (Old)
 and      /work/SRC/openSUSE:Factory/.picotool.new.22824 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "picotool"

Mon Feb 20 17:46:09 2023 rev:9 rq:1066719 version:1.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/picotool/picotool.changes        2021-12-10 
21:53:32.590923298 +0100
+++ /work/SRC/openSUSE:Factory/.picotool.new.22824/picotool.changes     
2023-02-20 17:46:39.623705034 +0100
@@ -1,0 +2,11 @@
+Wed Feb 15 13:02:35 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 1.1.1:
+  * Add --update option to `load` command to skip unchanged flash
+    sectors (speed improvement).
+  * A number of minor bug fixes and documentation improvements.
+  * Support non contiguous flash ELF/UF2 which were written
+    incorrectly before (and yet still passed verify due to
+    another bug).
+
+-------------------------------------------------------------------

Old:
----
  picotool-1.1.0.tar.gz

New:
----
  picotool-1.1.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ picotool.spec ++++++
--- /var/tmp/diff_new_pack.4YYd3L/_old  2023-02-20 17:46:42.567721665 +0100
+++ /var/tmp/diff_new_pack.4YYd3L/_new  2023-02-20 17:46:42.571721688 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package picotool
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %define sdk_version 1.3.0
 Name:           picotool
 URL:            https://github.com/raspberrypi/picotool
-Version:        1.1.0
+Version:        1.1.1
 Release:        0
 Summary:        Tool to inspect RP2040 binaries
 License:        BSD-3-Clause

++++++ pico-sdk-1.3.0.tar.gz ++++++

++++++ picotool-1.1.0.tar.gz -> picotool-1.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/CMakeLists.txt 
new/picotool-1.1.1/CMakeLists.txt
--- old/picotool-1.1.0/CMakeLists.txt   2021-11-01 20:37:01.000000000 +0100
+++ new/picotool-1.1.1/CMakeLists.txt   2023-02-10 15:49:19.000000000 +0100
@@ -40,7 +40,7 @@
     add_subdirectory(${PICO_SDK_PATH}/src/host/pico_platform pico_platform)
 
     add_executable(picotool main.cpp)
-    set(PICOTOOL_VERSION 1.1.0)
+    set(PICOTOOL_VERSION 1.1.1)
     set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
     set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, 
${CMAKE_BUILD_TYPE}")
     target_compile_definitions(picotool PRIVATE
@@ -60,5 +60,5 @@
             picoboot_connection_cxx
             ${LIBUSB_LIBRARIES})
     # allow `make install`
-    install(TARGETS picotool)
+    install(TARGETS picotool RUNTIME DESTINATION bin)
 endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/README.md new/picotool-1.1.1/README.md
--- old/picotool-1.1.0/README.md        2021-11-01 20:37:01.000000000 +0100
+++ new/picotool-1.1.1/README.md        2023-02-10 15:49:19.000000000 +0100
@@ -4,15 +4,39 @@
 
 You also need to install `libusb-1.0`.
 
-Linux/Mac: use your favorite package tool. For example, on Ubuntu:
+### Linux / macOS
+
+Use your favorite package tool to install dependencies. For example, on Ubuntu:
+
+```console
+sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
+```
+
+On Linux you can add udev rules in order to run picotool without sudo:
 
 ```console
-sudo apt install build-essential pkg-config libusb-1.0-0-dev
+sudo cp udev/99-picotool.rules /etc/udev/rules.d/
 ```
 
-Windows: download from here https://libusb.info/
+### Windows
+
+##### For Windows without MinGW
 
-If you are on Windows, set LIBUSB_ROOT environment variable to the install 
directory
+Download libUSB from here https://libusb.info/
+
+set LIBUSB_ROOT environment variable to the install directory.
+```console
+mkdir build
+cd build
+cmake -G "NMake Makefiles" ..
+nmake
+```
+
+##### For Windows with MinGW in WSL
+
+Download libUSB from here https://libusb.info/
+
+set LIBUSB_ROOT environment variable to the install directory.
 
 ```console
 mkdir build
@@ -21,14 +45,19 @@
 make
 ```
 
-for Windows non MinGW/WSL:
+##### For Windows with MinGW in MSYS2:
+
+No need to download libusb separately or set `LIBUSB_ROOT`.
 
 ```console
+pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
 mkdir build
 cd build
-cmake -G "NMake Makefiles" ..
-nmake
+MSYS2_ARG_CONV_EXCL=- cmake .. -G"MSYS Makefiles" 
-DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
+make
+make install DESTDIR=/  # optional
 ```
+
 ## Overview
 
 `picotool` is a tool for inspecting RP2040 binaries, and interacting with 
RP2040 devices when they are in BOOTSEL mode. (As of version 1.1 of `picotool` 
it is also possible to interact with RP2040 devices that are not in BOOTSEL 
mode, but are using USB stdio support from the Raspberry Pi Pico SDK by using 
the `-f` argument of `picotool`).
@@ -43,7 +72,7 @@
 SYNOPSYS:
     picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>] 
[-f] [-F]
     picotool info [-b] [-p] [-d] [-l] [-a] <filename> [-t <type>]
-    picotool load [-n] [-N] [-v] [-x] <filename> [-t <type>] [-o <offset>] 
[--bus <bus>] [--address <addr>] [-f] [-F]
+    picotool load [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o 
<offset>] [--bus <bus>] [--address <addr>] [-f] [-F]
     picotool save [-p] [--bus <bus>] [--address <addr>] [-f] [-F] <filename> 
[-t <type>]
     picotool save -a [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t 
<type>]
     picotool save -r <from> <to> [--bus <bus>] [--address <addr>] [-f] [-F] 
<filename> [-t <type>]
@@ -399,7 +428,7 @@
 ```cmake
 pico_set_program_name(foo "not foo") # as "foo" would be the default
 pico_set_program_description(foo "this is a foo")
-pico_set_program_version_string(foo "0.00001a")
+pico_set_program_version(foo "0.00001a")
 pico_set_program_url(foo "www.plinth.com/foo")
 ```
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/cli.h new/picotool-1.1.1/cli.h
--- old/picotool-1.1.0/cli.h    2021-11-01 20:37:01.000000000 +0100
+++ new/picotool-1.1.1/cli.h    2023-02-10 15:49:19.000000000 +0100
@@ -88,7 +88,7 @@
 
         void add(const string& major_group, const string& minor_group, const 
string& option, const string& description) {
             auto &v = contents[major_group][minor_group];
-            // we don't want to repeated the same option
+            // we don't want to repeat the same option
             if (std::find_if(v.begin(), v.end(), [&](const auto &x) { return 
x.first == option; }) == v.end()) {
                 v.emplace_back(option, description);
             }
@@ -301,6 +301,7 @@
 
         vector<string> synopsys() const override {
             string s = string("<") + this->_name + ">";
+            if (this->_max > 1) s += "..";
             return {s};
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/cmake/FindLIBUSB.cmake 
new/picotool-1.1.1/cmake/FindLIBUSB.cmake
--- old/picotool-1.1.0/cmake/FindLIBUSB.cmake   2021-11-01 20:37:01.000000000 
+0100
+++ new/picotool-1.1.1/cmake/FindLIBUSB.cmake   2023-02-10 15:49:19.000000000 
+0100
@@ -12,12 +12,12 @@
     # in cache already
     set(LIBUSB_FOUND TRUE)
 else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
-    IF (NOT WIN32)
+    IF (NOT MSVC)
         # use pkg-config to get the directories and then use these values
         # in the FIND_PATH() and FIND_LIBRARY() calls
         find_package(PkgConfig)
         pkg_check_modules(PC_LIBUSB libusb-1.0)
-    ENDIF(NOT WIN32)
+    ENDIF ()
     FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
             HINTS $ENV{LIBUSB_ROOT}/include/libusb-1.0
             PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/main.cpp new/picotool-1.1.1/main.cpp
--- old/picotool-1.1.0/main.cpp 2021-11-01 20:37:01.000000000 +0100
+++ new/picotool-1.1.1/main.cpp 2023-02-10 15:49:19.000000000 +0100
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifdef _MSC_VER
+#ifdef _WIN32
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
@@ -37,7 +37,7 @@
 #endif
 
 // tsk namespace is polluted on windows
-#ifdef _MSC_VER
+#ifdef _WIN32
 #undef min
 #undef max
 
@@ -201,7 +201,7 @@
         }
         f--;
         assert(p >= f->first);
-        if (p > f->second.first) {
+        if (p >= f->second.first) {
             throw not_mapped_exception();
         }
         return std::make_pair(mapping(p - f->first, f->second.first - 
f->first), f->second.second);
@@ -278,6 +278,7 @@
         bool execute = false;
         bool no_overwrite = false;
         bool no_overwrite_force = false;
+        bool update = false;
     } load;
 
     struct {
@@ -343,7 +344,7 @@
     string get_doc() const override {
          return "Display information from the target device(s) or 
file.\nWithout any arguments, this will display basic information for all 
connected RP2040 devices in BOOTSEL mode";
     }
-} info_cmd;
+};
 
 struct verify_command : public cmd {
     verify_command() : cmd("verify") {}
@@ -366,7 +367,7 @@
     string get_doc() const override {
         return "Check that the device contents match those in the file.";
     }
-} verify_cmd;
+};
 
 struct save_command : public cmd {
     save_command() : cmd("save") {}
@@ -392,7 +393,7 @@
     string get_doc() const override {
         return "Save the program / memory stored in flash on the device to a 
file.";
     }
-} save_cmd;
+};
 
 struct load_command : public cmd {
     load_command() : cmd("load") {}
@@ -403,6 +404,7 @@
             (
                 option('n', "--no-overwrite").set(settings.load.no_overwrite) 
% "When writing flash data, do not overwrite an existing program in flash. If 
picotool cannot determine the size/presence of the program in flash, the 
command fails" +
                 option('N', 
"--no-overwrite-unsafe").set(settings.load.no_overwrite_force) % "When writing 
flash data, do not overwrite an existing program in flash. If picotool cannot 
determine the size/presence of the program in flash, the load continues anyway" 
+
+                option('u', "--update").set(settings.load.update) % "Skip 
writing flash sectors that already contain identical data" +
                 option('v', "--verify").set(settings.load.verify) % "Verify 
the data was written correctly" +
                 option('x', "--execute").set(settings.load.execute) % "Attempt 
to execute the downloaded file as a program after the load"
             ).min(0).doc_non_optional(true) % "Post load actions" +
@@ -418,7 +420,7 @@
     string get_doc() const override {
         return "Load the program / memory range stored in a file onto the 
device.";
     }
-} load_cmd;
+};
 
 struct help_command : public cmd {
     help_command() : cmd("help") {}
@@ -437,7 +439,7 @@
     string get_doc() const override {
         return "Show general help or help for a specific command";
     }
-} help_cmd;
+};
 
 struct version_command : public cmd {
     version_command() : cmd("version") {}
@@ -462,7 +464,7 @@
     string get_doc() const override {
         return "Display picotool version";
     }
-} version_cmd;
+};
 
 struct reboot_command : public cmd {
     bool quiet;
@@ -699,7 +701,11 @@
 }
 
 struct memory_access {
-    virtual void read(uint32_t, uint8_t *buffer, uint size) = 0;
+    virtual void read(uint32_t p, uint8_t *buffer, uint size) {
+        read(p, buffer, size, false);
+    }
+
+    virtual void read(uint32_t, uint8_t *buffer, uint size, bool zero_fill) = 
0;
 
     virtual bool is_device() { return false; }
 
@@ -726,10 +732,10 @@
     }
 
     // read a vector of types that have a raw_type_mapping
-    template <typename T> vector<T> read_vector(uint32_t addr, uint count) {
+    template <typename T> vector<T> read_vector(uint32_t addr, uint count, 
bool zero_fill = false) {
         assert(count);
         vector<typename raw_type_mapping<T>::access_type> buffer(count);
-        read(addr, (uint8_t *)buffer.data(), count * sizeof(typename 
raw_type_mapping<T>::access_type));
+        read(addr, (uint8_t *)buffer.data(), count * sizeof(typename 
raw_type_mapping<T>::access_type), zero_fill);
         vector<T> v;
         v.reserve(count);
         for(const auto &e : buffer) {
@@ -738,9 +744,9 @@
         return v;
     }
 
-    template <typename T> void read_into_vector(uint32_t addr, uint count, 
vector<T> &v) {
+    template <typename T> void read_into_vector(uint32_t addr, uint count, 
vector<T> &v, bool zero_fill = false) {
         vector<typename raw_type_mapping<T>::access_type> buffer(count);
-        if (count) read(addr, (uint8_t *)buffer.data(), count * 
sizeof(typename raw_type_mapping<T>::access_type));
+        if (count) read(addr, (uint8_t *)buffer.data(), count * 
sizeof(typename raw_type_mapping<T>::access_type), zero_fill);
         v.clear();
         v.reserve(count);
         for(const auto &e : buffer) {
@@ -784,7 +790,7 @@
         return FLASH_START;
     }
 
-    void read(uint32_t address, uint8_t *buffer, uint size) override {
+    void read(uint32_t address, uint8_t *buffer, uint size, __unused bool 
zero_fill) override {
         if (flash == get_memory_type(address)) {
             connection.exit_xip();
         }
@@ -852,13 +858,25 @@
         return binary_start;
     }
 
-    void read(uint32_t address, uint8_t *buffer, uint32_t size) override {
+    void read(uint32_t address, uint8_t *buffer, uint32_t size, bool 
zero_fill) override {
         while (size) {
-            auto result = rmap.get(address);
-            uint this_size = std::min(size, result.first.max_offset - 
result.first.offset);
-            assert( this_size);
-            fseek(file, result.second + result.first.offset, SEEK_SET);
-            fread(buffer, this_size, 1, file);
+            uint this_size;
+            try {
+                auto result = rmap.get(address);
+                this_size = std::min(size, result.first.max_offset - 
result.first.offset);
+                assert(this_size);
+                fseek(file, result.second + result.first.offset, SEEK_SET);
+                fread(buffer, this_size, 1, file);
+            } catch (not_mapped_exception &e) {
+                if (zero_fill) {
+                    // address is not in a range, so fill up to next range 
with zeros
+                    this_size = rmap.next(address) - address;
+                    this_size = std::min(this_size, size);
+                    memset(buffer, 0, this_size);
+                } else {
+                    throw e;
+                }
+            }
             buffer += this_size;
             address += this_size;
             size -= this_size;
@@ -881,12 +899,12 @@
 struct remapped_memory_access : public memory_access {
     remapped_memory_access(memory_access &wrap, range_map<uint32_t> rmap) : 
wrap(wrap), rmap(rmap) {}
 
-    void read(uint32_t address, uint8_t *buffer, uint size) override {
+    void read(uint32_t address, uint8_t *buffer, uint size, bool zero_fill) 
override {
         while (size) {
             auto result = get_remapped(address);
             uint this_size = std::min(size, result.first.max_offset - 
result.first.offset);
             assert( this_size);
-            wrap.read(result.second + result.first.offset, buffer, this_size);
+            wrap.read(result.second + result.first.offset, buffer, this_size, 
zero_fill);
             buffer += this_size;
             address += this_size;
             size -= this_size;
@@ -991,16 +1009,15 @@
 }
 
 string read_string(memory_access &access, uint32_t addr) {
-    const uint max_length = 256; // todo better incremental length handling
-    auto v = access.read_vector<char>(addr, 256);
+    const uint max_length = 512;
+    auto v = access.read_vector<char>(addr, max_length, true); // zero fill
     uint length;
     for (length = 0; length < max_length; length++) {
         if (!v[length]) {
             break;
         }
     }
-    return string(v.data(), length);
-}
+    return string(v.data(), length);}
 
 struct bi_visitor_base {
     void visit(memory_access& access, const binary_info_header& hdr) {
@@ -1571,17 +1588,18 @@
         strcpy(b, "No ");
     }
     char *buf = b + strlen(b);
+    int buf_len = b + sizeof(b) - buf;
     if (settings.address != -1) {
         if (settings.bus != -1) {
-            sprintf(buf, "accessible RP2040 device in BOOTSEL mode was found 
at bus %d, address %d.", settings.bus, settings.address);
+            snprintf(buf, buf_len, "accessible RP2040 device in BOOTSEL mode 
was found at bus %d, address %d.", settings.bus, settings.address);
         } else {
-            sprintf(buf, "accessible RP2040 devices in BOOTSEL mode were found 
with address %d.", settings.address);
+            snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode 
were found with address %d.", settings.address);
         }
     } else {
         if (settings.bus != -1) {
-            sprintf(buf, "accessible RP2040 devices in BOOTSEL mode were found 
found on bus %d.", settings.bus);
+            snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode 
were found found on bus %d.", settings.bus);
         } else {
-            sprintf(buf, "accessible RP2040 devices in BOOTSEL mode were 
found.");
+            snprintf(buf, buf_len,"accessible RP2040 devices in BOOTSEL mode 
were found.");
         }
     }
     return b;
@@ -1773,7 +1791,7 @@
     return false;
 }
 
-vector<range> get_colaesced_ranges(file_memory_access &file_access) {
+vector<range> get_coalesced_ranges(file_memory_access &file_access) {
     auto rmap = file_access.get_rmap();
     auto ranges = rmap.ranges();
     std::sort(ranges.begin(), ranges.end(), [](const range& a, const range &b) 
{
@@ -1782,7 +1800,14 @@
     // coalesce all the contiguous ranges
     for(auto i = ranges.begin(); i < ranges.end(); ) {
         if (i != ranges.end() - 1) {
-            if (i->to == (i+1)->from) {
+            uint32_t erase_size;
+            // we want to coalesce flash sectors together (this ends up 
creating ranges that may have holes)
+            if( get_memory_type(i->from) == flash ) {
+                erase_size = FLASH_SECTOR_ERASE_SIZE;
+            } else {
+                erase_size = 1;
+            }
+            if (i->to / erase_size == (i+1)->from / erase_size) {
                 i->to = (i+1)->to;
                 i = ranges.erase(i+1) - 1;
                 continue;
@@ -1819,7 +1844,7 @@
             visitor.visit(access, hdr);
         }
     }
-    auto ranges = get_colaesced_ranges(file_access);
+    auto ranges = get_coalesced_ranges(file_access);
     for (auto mem_range : ranges) {
         enum memory_type t1 = get_memory_type(mem_range.from);
         enum memory_type t2 = get_memory_type(mem_range.to);
@@ -1847,21 +1872,31 @@
             bool ok = true;
             vector<uint8_t> file_buf;
             vector<uint8_t> device_buf;
-            for (uint32_t base = mem_range.from; base < mem_range.to && ok; ) {
+            for (uint32_t base = mem_range.from; base < mem_range.to && ok;) {
                 uint32_t this_batch = std::min(mem_range.to - base, 
batch_size);
                 if (type == flash) {
                     // we have to erase an entire page, so then fill with zeros
-                    range aligned_range(base & ~(FLASH_SECTOR_ERASE_SIZE - 1), 
(base & ~(FLASH_SECTOR_ERASE_SIZE - 1)) + FLASH_SECTOR_ERASE_SIZE);
+                    range aligned_range(base & ~(FLASH_SECTOR_ERASE_SIZE - 1),
+                                        (base & ~(FLASH_SECTOR_ERASE_SIZE - 
1)) + FLASH_SECTOR_ERASE_SIZE);
                     range read_range(base, base + this_batch);
                     read_range.intersect(aligned_range);
-                    file_access.read_into_vector(read_range.from, 
read_range.to - read_range.from, file_buf);
+                    file_access.read_into_vector(read_range.from, 
read_range.to - read_range.from, file_buf, true); // zero fill to cope with 
holes
                     // zero padding up to FLASH_SECTOR_ERASE_SIZE
                     file_buf.insert(file_buf.begin(), read_range.from - 
aligned_range.from, 0);
                     file_buf.insert(file_buf.end(), aligned_range.to - 
read_range.to, 0);
                     assert(file_buf.size() == FLASH_SECTOR_ERASE_SIZE);
-                    con.exit_xip();
-                    con.flash_erase(aligned_range.from, 
FLASH_SECTOR_ERASE_SIZE);
-                    raw_access.write_vector(aligned_range.from, file_buf);
+
+                    bool skip = false;
+                    if (settings.load.update) {
+                        vector<uint8_t> read_device_buf;
+                        raw_access.read_into_vector(aligned_range.from, 
batch_size, read_device_buf);
+                        skip = file_buf == read_device_buf;
+                    }
+                    if (!skip) {
+                        con.exit_xip();
+                        con.flash_erase(aligned_range.from, 
FLASH_SECTOR_ERASE_SIZE);
+                        raw_access.write_vector(aligned_range.from, file_buf);
+                    }
                     base = read_range.to; // about to add batch_size
                 } else {
                     file_access.read_into_vector(base, this_batch, file_buf);
@@ -1871,6 +1906,9 @@
                 bar.progress(base - mem_range.from, mem_range.to - 
mem_range.from);
             }
         }
+    }
+    for (auto mem_range : ranges) {
+        enum memory_type type = get_memory_type(mem_range.from);
         if (settings.load.verify) {
             bool ok = true;
             {
@@ -1881,7 +1919,10 @@
                 uint32_t pos = mem_range.from;
                 for (uint32_t base = mem_range.from; base < mem_range.to && 
ok; base += batch_size) {
                     uint32_t this_batch = std::min(mem_range.to - base, 
batch_size);
-                    file_access.read_into_vector(base, this_batch, file_buf);
+                    // note we pass zero_fill = true in case the file has 
holes, but this does
+                    // mean that the verification will fail if those holes are 
not filed with zeros
+                    // on the device
+                    file_access.read_into_vector(base, this_batch, file_buf, 
true);
                     raw_access.read_into_vector(base, this_batch, device_buf);
                     assert(file_buf.size() == device_buf.size());
                     for (uint i = 0; i < this_batch; i++) {
@@ -1924,7 +1965,7 @@
     auto file_access = get_file_memory_access();
     auto con = get_single_bootsel_device_connection(devices);
     picoboot_memory_access raw_access(con);
-    auto ranges = get_colaesced_ranges(file_access);
+    auto ranges = get_coalesced_ranges(file_access);
     if (settings.range_set) {
         range filter(settings.from, settings.to);
         for(auto& range : ranges) {
@@ -1950,7 +1991,10 @@
                     uint32_t batch_size = 1024;
                     for(uint32_t base = mem_range.from; base < mem_range.to && 
ok; base += batch_size) {
                         uint32_t this_batch = std::min(mem_range.to - base, 
batch_size);
-                        file_access.read_into_vector(base, this_batch, 
file_buf);
+                        // note we pass zero_fill = true in case the file has 
holes, but this does
+                        // mean that the verification will fail if those holes 
are not filed with zeros
+                        // on the device
+                        file_access.read_into_vector(base, this_batch, 
file_buf, true);
                         raw_access.read_into_vector(base, this_batch, 
device_buf);
                         assert(file_buf.size() == device_buf.size());
                         for(uint i=0;i<this_batch;i++) {
@@ -2032,7 +2076,7 @@
     libusb_device_handle *dev_handle;
     ret = libusb_open(device, &dev_handle);
     if (ret) {
-#if _MSC_VER
+#if _WIN32
         fail(ERROR_USB, "Unable to access device to reboot it; Make sure there 
is a driver installed via Zadig\n", ret);
 #else
         fail(ERROR_USB, "Unable to access device to reboot it; Use sudo or 
setup a udev rule\n", ret);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/picotool-1.1.0/picoboot_connection/picoboot_connection_cxx.h 
new/picotool-1.1.1/picoboot_connection/picoboot_connection_cxx.h
--- old/picotool-1.1.0/picoboot_connection/picoboot_connection_cxx.h    
2021-11-01 20:37:01.000000000 +0100
+++ new/picotool-1.1.1/picoboot_connection/picoboot_connection_cxx.h    
2023-02-10 15:49:19.000000000 +0100
@@ -28,11 +28,16 @@
 
     struct connection {
         explicit connection(libusb_device_handle *device, bool exclusive = 
true) : device(device), exclusive(exclusive) {
+            // do a device reset in case it was left in a bad state
+            reset();
             if (exclusive) exclusive_access(EXCLUSIVE);
         }
         ~connection() {
             if (exclusive) {
-                picoboot_exclusive_access(device, NOT_EXCLUSIVE);
+                if (picoboot_exclusive_access(device, NOT_EXCLUSIVE)) {
+                    // failed to restore exclusive access, so just reset
+                    reset();
+                }
             }
         }
         void reset();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picotool-1.1.0/udev/99-picotool.rules 
new/picotool-1.1.1/udev/99-picotool.rules
--- old/picotool-1.1.0/udev/99-picotool.rules   1970-01-01 01:00:00.000000000 
+0100
+++ new/picotool-1.1.1/udev/99-picotool.rules   2023-02-10 15:49:19.000000000 
+0100
@@ -0,0 +1,10 @@
+SUBSYSTEM=="usb", \
+    ATTRS{idVendor}=="2e8a", \
+    ATTRS{idProduct}=="0003", \
+    MODE="660", \
+    GROUP="plugdev"
+SUBSYSTEM=="usb", \
+    ATTRS{idVendor}=="2e8a", \
+    ATTRS{idProduct}=="000a", \
+    MODE="660", \
+    GROUP="plugdev"

Reply via email to