diff --git a/esptool.py b/esptool.py index a47c3b74a..c75664059 100755 --- a/esptool.py +++ b/esptool.py @@ -2148,6 +2148,19 @@ def __call__(self, parser, namespace, values, option_string=None): except IndexError: raise argparse.ArgumentError(self,'Must be pairs of an address and the binary filename to write there') pairs.append((address, argfile)) + + # Sort the addresses and check for overlapping + end = 0 + for address, argfile in sorted(pairs): + argfile.seek(0,2) # seek to end + size = argfile.tell() + argfile.seek(0) + sector_start = address & ~(ESPLoader.FLASH_SECTOR_SIZE - 1) + sector_end = ((address + size + ESPLoader.FLASH_SECTOR_SIZE - 1) & ~(ESPLoader.FLASH_SECTOR_SIZE - 1)) - 1 + if sector_start < end: + message = 'Detected overlap at address: 0x%x for file: %s' % (address, argfile.name) + raise argparse.ArgumentError(self, message) + end = sector_end setattr(namespace, self.dest, pairs) diff --git a/test/test_esptool.py b/test/test_esptool.py index c93aa3311..bc46f8e64 100755 --- a/test/test_esptool.py +++ b/test/test_esptool.py @@ -184,6 +184,19 @@ def test_length_not_aligned_4bytes(self): def test_length_not_aligned_4bytes_no_compression(self): self.run_esptool("write_flash -u 0x0 images/%s" % NODEMCU_FILE) + def test_write_overlap(self): + output = self.run_esptool_error("write_flash 0x0 images/bootloader.bin 0x1000 images/one_kb.bin") + self.assertIn("Detected overlap at address: 0x1000 ", output) + + def test_write_sector_overlap(self): + # These two 1KB files don't overlap, but they do both touch sector at 0x1000 so should fail + output = self.run_esptool_error("write_flash 0xd00 images/one_kb.bin 0x1d00 images/one_kb.bin") + self.assertIn("Detected overlap at address: 0x1d00", output) + + def test_write_no_overlap(self): + output = self.run_esptool("write_flash 0x0 images/bootloader.bin 0x2000 images/one_kb.bin") + self.assertNotIn("Detected overlap at address", output) + class TestFlashSizes(EsptoolTestCase): def test_high_offset(self):