Skip to content

Commit 5dbfd98

Browse files
committed
espflash: Reduce the memory fragmentation during write.
espflash used to implicitely allocate four times per write the ~4k buffer for the data. That caused devices with smaller memory to fail due to memory fragmentation. This change reduces it to once per block.
1 parent a080872 commit 5dbfd98

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

micropython/espflash/espflash.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from micropython import const
3232
from time import sleep
3333
import binascii
34+
import gc
3435

3536
_CMD_SYNC = const(0x08)
3637
_CMD_CHANGE_BAUDRATE = const(0x0F)
@@ -113,8 +114,11 @@ def _poll_reg(self, addr, flag, retry=10, delay=0.050):
113114
raise Exception(f"Register poll timeout. Addr: 0x{addr:02X} Flag: 0x{flag:02X}.")
114115

115116
def _write_slip(self, pkt):
117+
gc.collect()
116118
pkt = pkt.replace(b"\xDB", b"\xdb\xdd").replace(b"\xc0", b"\xdb\xdc")
117-
self.uart.write(b"\xC0" + pkt + b"\xC0")
119+
self.uart.write(b"\xC0")
120+
self.uart.write(pkt)
121+
self.uart.write(b"\xC0")
118122
self._log(pkt)
119123

120124
def _read_slip(self):
@@ -256,32 +260,31 @@ def flash_write_file(self, path, blksize=0x1000):
256260
total_blocks = (size + blksize - 1) // blksize
257261
erase_blocks = 1
258262
print(f"Flash write size: {size} total_blocks: {total_blocks} block size: {blksize}")
263+
gc.collect()
264+
buf = bytearray(blksize + 16)
265+
erase_cmd = bytearray(16)
266+
mv = memoryview(buf)
259267
with open(path, "rb") as f:
260268
seq = 0
261269
subseq = 0
262270
for i in range(total_blocks):
263-
buf = f.read(blksize)
271+
nread = f.readinto(mv[16: 16 + blksize])
264272
# Update digest
265273
if self.md5sum is not None:
266-
self.md5sum.update(buf)
274+
self.md5sum.update(mv[16:16 + blksize])
267275
# The last data block should be padded to the block size with 0xFF bytes.
268-
if len(buf) < blksize:
269-
buf += b"\xFF" * (blksize - len(buf))
270-
checksum = self._checksum(buf)
276+
if nread < blksize:
277+
mv[nread + 16, blksize + 16] = b"\xFF" * (blksize - nread)
278+
checksum = self._checksum(mv[16: 16 + blksize])
271279
if seq % erase_blocks == 0:
272280
# print(f"Erasing {seq} -> {seq+erase_blocks}...")
273-
self._command(
274-
_CMD_SPI_FLASH_BEGIN,
275-
struct.pack(
276-
"<IIII", erase_blocks * blksize, erase_blocks, blksize, seq * blksize
277-
),
278-
)
281+
struct.pack_into(
282+
"<IIII", erase_cmd, 0, erase_blocks * blksize, erase_blocks, blksize, seq * blksize
283+
),
284+
self._command(_CMD_SPI_FLASH_BEGIN, erase_cmd)
279285
print(f"Writing sequence number {seq}/{total_blocks}...")
280-
self._command(
281-
_CMD_SPI_FLASH_DATA,
282-
struct.pack("<IIII", len(buf), seq % erase_blocks, 0, 0) + buf,
283-
checksum,
284-
)
286+
struct.pack_into("<IIII", mv[0: 16], 0, nread, seq % erase_blocks, 0, 0)
287+
self._command(_CMD_SPI_FLASH_DATA, buf, checksum)
285288
seq += 1
286289

287290
print("Flash write finished")

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy