def _report_bw(cls, action, length, time): if time < 1.0: print "%s %s in %d ms @ %s/s" % (action, pretty_size(length), 1000*time, pretty_size(length/time)) else: print "%s %s in %d seconds @ %s/s" % (action, pretty_size(length), time, pretty_size(length/time))
def test_flashdevice_4_long_rw(self): """Long R/W test """ # Max size to perform the test on size = 1<<20 # Whether to test with random value, or contiguous values to ease debug randomize = True # Fill in the whole flash with a monotonic increasing value, that is # the current flash 32-bit address, then verify the sequence has been # properly read back from hashlib import sha1 # limit the test to 1MiB to keep the test duration short, but performs # test at the end of the flash to verify that high addresses may be # reached length = min(len(self.flash), size) start = len(self.flash)-length print "Erase %s from flash @ 0x%06x(may take a while...)" % \ (pretty_size(length), start) delta = time.time() self.flash.unlock() self.flash.erase(start, length, True) delta = time.time()-delta self._report_bw('Erased', length, delta) if str(self.flash).startswith('SST'): # SST25 flash devices are tremendously slow at writing (one or two # bytes per SPI request MAX...). So keep the test sequence short # enough length = 16<<10 print "Build test sequence" if not randomize: buf = Array('I') back = Array('I') for address in range(0, length, 4): buf.append(address) # Expect to run on x86 or ARM (little endian), so swap the values # to ease debugging # A cleaner test would verify the host endianess, or use struct # module buf.byteswap() # Cannot use buf directly, as it's an I-array, # and SPI expects a B-array else: from random import seed seed(0) buf = Array('B') back = Array('B') buf.extend((randint(0, 255) for x in range(0, length))) bufstr = buf.tostring() print "Writing %s to flash (may take a while...)" % \ pretty_size(len(bufstr)) delta = time.time() self.flash.write(start, bufstr) delta = time.time()-delta length = len(bufstr) self._report_bw('Wrote', length, delta) wmd = sha1() wmd.update(buf.tostring()) refdigest = wmd.hexdigest() print "Reading %s from flash" % pretty_size(length) delta = time.time() data = self.flash.read(start, length) delta = time.time()-delta self._report_bw('Read', length, delta) #print "Dump flash" #print hexdump(data.tostring()) print "Verify flash" rmd = sha1() rmd.update(data.tostring()) newdigest = rmd.hexdigest() print "Reference:", refdigest print "Retrieved:", newdigest if refdigest != newdigest: errcount = 0 back.fromstring(data) for pos in xrange(len(buf)): if buf[pos] != data[pos]: print 'Invalid byte @ offset 0x%06x: 0x%02x / 0x%02x' % \ (pos, buf[pos], back[pos]) errcount += 1 # Stop report after 16 errors if errcount >= 32: break raise AssertionError('Data comparison mismatch')
def __str__(self): return 'Atmel %s%d %s' % \ (self._device, len(self)>>17, pretty_size(self._size, lim_m=1<<20))
def __str__(self): return 'Spansion %s %s' % \ (self._device, pretty_size(self._size, lim_m=1<<20))
def __str__(self): return 'Micron %s%03d %s' % \ (self._device, len(self)>>17, pretty_size(self._size, lim_m=1<<20))
def test_flashdevice_4_long_rw(self): """Long R/W test """ # Fill in the whole flash with a monotonic increasing value, that is # the current flash 32-bit address, then verify the sequence has been # properly read back from hashlib import sha1 buf = Array('B') # limit the test to 1MiB to keep the test duration short, but performs # test at the end of the flash to verify that high addresses may be # reached length = min(len(self.flash), 1<<20) start = len(self.flash)-length print "Erase %s from flash (may take a while...)" % \ pretty_size(length) delta = time.time() self.flash.unlock() self.flash.erase(start, length, True) delta = time.time()-delta self._report_bw('Erased', length, delta) if str(self.flash).startswith('SST'): # SST25 flash devices are tremendously slow at writing (one or two # bytes per SPI request MAX...). So keep the test sequence short # enough length = 16<<10 print "Build test sequence" buf.extend((randint(0, 255) for x in range(0, length))) # for address in range(0, length, 4): # buf.append(address) # # Expect to run on x86 or ARM (little endian), so swap the values # # to ease debugging # # A cleaner test would verify the host endianess, or use struct module # print "Swap sequence" # buf.byteswap() # Cannot use buf, as it's an I-array, and SPI expects a B-array bufstr = buf.tostring() print "Writing %s to flash (may take a while...)" % \ pretty_size(len(bufstr)) delta = time.time() self.flash.write(start, bufstr) delta = time.time()-delta length = len(bufstr) self._report_bw('Wrote', length, delta) wmd = sha1() wmd.update(buf.tostring()) refdigest = wmd.hexdigest() print "Reading %s from flash" % pretty_size(length) delta = time.time() data = self.flash.read(start, length) delta = time.time()-delta self._report_bw('Read', length, delta) #print "Dump flash" #print hexdump(data.tostring()) print "Verify flash" rmd = sha1() rmd.update(data.tostring()) newdigest = rmd.hexdigest() print "Reference:", refdigest print "Retrieved:", newdigest if refdigest != newdigest: raise AssertionError('Data comparison mismatch')