Flash Destroyer how-to
EEPROMs, such as flash memory, store data in electronic devices like cell phones, smart cards, SD cards, and solid-state drives. This type of memory can only endure a limited number of writes, it will eventually wear out and it won't store new data. The Flash Destroyer explores that limit by writing and verifying a common EEPROM chip, rated for 1 million writes, until it burns out.
How long will it take to complete a million write-verify cycles? The Flash Destroyer's current top speed is about 736 cycles per minute, or 22 hours to complete 1 million writes. Back that off to one write per second (11days) or per 10 seconds (110days) and the time increases dramatically. The Flash Destroyer has several alternative firmwares with different write speeds that can be loaded over USB.
Obviously the chip isn't intended for this type of abuse. A million cycle 'limitation' isn't bad at the user scale. The EEPROM inside a common SLE4442 smart card, often used in copy shops, has similar limitations. The life span is adequate because even one write per minute, every minute, gives it a 2 year lifespan - that's a lot of copies. Applications that need to write data more frequently use a different type of memory like SRAM.
How many writes an EEPROM will actually endure is anyone's guess. Like an overclocked CPU, some will go way over the rated minimum, some will go a little over the minimum, but all should endure at least the rated number of writes. The Flash Destroyer on the live feed is running at about 408 writes per minute. It started at 08:11 GMT May 25, and should reach a million on Wednesday night (May 26), and two million on Friday afternoon (May 28). Can you guess the final count?
Preorder the Flash Destroyer 'I like to solder' kit for $30, including worldwide shipping.
When you're ready to destroy some flash, follow us after the break.
A PIC 18F2550 fills an EEPROM with values, and then verifies the content. Each successful write-verify cycle adds one to the counter display. When the EEPROM starts to have read verification errors, the writing stops and the number of successful write-cycles is displayed.
This project was inspired by endless Slashdot discussions about solid-state storage. There aren't any tubes or moving parts in the EEPROM that deteriorate, yet in a not-unreasonable amount of time the chip will cease to work. We find it fascinating and want to witness it first hand.
Technically this is an EEPROM Destroyer. Flash memory is a type of EEPROM that is slightly different than the memory in the 24AA01. Flash Destroyer just sounds cooler.
A Microchip PIC 18F2550 microcontroller (IC2) communicates with the EEPROM chip and drives the multiplexed display. The 18F2550 comes in through-hole and surface mount packages, we used the through-hole DIP version for this kit.
The DIP package turns out to be a lot harder to get than the surface mount version, that drives up the price of the kit a bit because Seeed has to import chips from the US to China.
The PIC runs on 5volts. The supply pin gets a 0.1uF decoupling capacitor (C1). A 20MHz crystal (Q1) and two 27pF capacitors (C5, C6) provide a clock source.
The 18F2550 with USB is overkill for this design, but the USB peripheral makes it easy to upgrade the firmware without a PIC programmer. Currently USB is only used for firmware upgrades.
The USB peripheral has an internal 3.3volt regulator that needs 0.22uF of capacitance on the VUSB pin. We used two 0.1uF caps (C2, C3) on the prototype but the kits should ship with one 0.22uF capacitor. A standard USB B connector (J2) is used because it's the most widely-available through-hole USB socket.
The PIC MCLR/VPP pin requires special handling. The MCLR function measures the power supply and resets the PIC when the voltage is too low to operate reliably. MCLR must be connected to the supply voltage through a current-limiting resistor (R1).
13volts are applied to the MCLR/VPP pin to put the PIC into programming mode. This voltage could leak back through resistor R1 into the power supply and damage sensitive components on the PCB. A small diode (D1) keeps the programming voltage out of the power supply.
The 5 pin ICSP header provides access to the PIC programming pins. Since all 21 available PIC I/O pins are used for the display and EEPROM, the programming pins are shared with the common cathode controls of two display segments (read more about the display below). We usually avoid sharing the programming pins with anything, but the cathode transistors don't use a lot of current and didn't interfere with programming or debugging during development.
EEPROM is a type of data storage chip with a limited number of write cycles. The Flash Destroyer tests the number times an EEPROM can be written before it stops correctly saving new values.
We used a Microchip 24AA01-I/P 128byte I2C EEPROM (IC2), rated for 1million write cycles. Other voltages (24LC/24AA), brands, and sizes of I2C EEPROMs can be tested with a minor firmware upgrade. The EEPROM is socketed so it's easy to swap in a new chip.
The EEPROM runs from the 5volt power supply, the power pin requires a 0.1uF decoupling capacitor (C4).
Data goes in and out of the EEPROM on a two wire communication bus called I2C. Devices on an I2C bus have open collector outputs - they can pull the signal low to make a 0, but they don't output a high level to make a 1. Instead of the pins outputting a voltage, pull-up resistors hold the bus high. Two 2K2 resistors (R18, R19) hold the I2C bus high, the devices on the I2C bus just pull the signals low as needed.
Some EEPROMs have a write protect pin and a configurable I2C address. We grounded all four standard control pins so EEPROMs with these functions will be properly configured.
Seven numeric LED blocks (DISP1-7) display the number of successful EEPROM writes and any error status messages. The seven blocks can count 9,999,999 successful writes. If needed, the most significant digits of larger values could be shown using the decimal points on each block.
Directly driving the display would take more than 50 PIC pins, or a bunch of output expanders. Instead, we use multiplexing to control all seven blocks with only 15 PIC pins. Multiplexing is a technique that lights each block briefly in quick succession, giving the appearance that the blocks are always on. Read more about multiplexed displays here and here.
Each block contains 8 LEDs, one for each segment and the decimal point. The anode (+) side of each LED is brought to a pin. Each block also has a ground pin that's connected internally to all the LED cathodes (-). A positive voltage applied to an anode pin lights an LED segment in the block.
The anodes of each block are connected to the same pin of the other blocks. Each string of segments is connected one PIC pin through a current-limiting resistor(R10-R17). Segments in our block are rated for 25mA continuous current, but are rated for a 150mA pulse current when lit briefly in a multiplexed configuration. We used a 120ohm resistor for ~20mA current because that's the maximum a PIC pin can output. If the anodes were switched with something that can handle higher currents, smaller resistors could be used (>22ohms) to make the display much brighter.
Multiplexing requires a way to light each block briefly while the others stay off. We do that by enabling the common cathode of each block while the correct anode pins are powered. The current from a fully-lit block could be 160mA or more, while a PIC pin can only sink about 20mA. We use a NPN transistor (Q2-Q8) to switch the heavier load, a 10K base resistor (R3-R9) limits the amount of current the transistor draws from the PIC pin. [LED resistor and transistor corrections May 31, 2010, thanks rsdio]
A 6mm tactile switch (S1) connects to a PIC pin for user input. A 10K pull-up resistor (R2) holds the PIC pin high when there's no input, a button press pulls the PIC pin low.
The circuit is powered by 5volts. A standard 7805 voltage regulator (IC3) converts an external 7-10volt supply to 5volts. The supply voltage is provided through a 2.1mm DC connector, center positive (J1).
The regulator has a 0.33uF input capacitor (C8) and a 0.1uF output capacitor (c7). It would probably be good to use an additional 10uF capacitor on both pins too, but the current arrangement is consistent with the 7805 datasheet.
The PCB is double sided and all through-hole. It takes almost all of the allowable board space in the freeware version of Eagle. We had prototype boards made through the Seeed Studio Fusion service. You can get one of our extras on the next few Free PCB Sundays.
Click for a large PCB image. Note that the resistors are the small 1/8th watt variety, used to save board space.
|C1-C4, C7||5||0.1uF capacitor||C025|
|C5, C6||2||15pF capacitor||C025|
|DIS1-7||7||7seg com. cathode w/dp||HD-H103|
|IC3||1||7805T 5volt regulator||TO220H|
|ICSP||1||05x1 0.1” pin header||MA05-1|
|J1||1||2.1mm DC power jack||PTH|
|J2||1||USB B connector||USB-B-PTH|
|Q2-Q8||7||800mA+ NPN transistor (BC337)||TO92|
|S1||1||6mm tact switch||DTS-6|
|SC1||1||28pin DIP socket||DIP-28|
|SC2||1||8pin DIP socket||DIP-8|
C5,6; Q2-Q8; R10-17 updated May 31, 2010.
This is our first through-hole, 'I like to solder' kit. It's a kit for people who like to solder, and it delivers with more than 100 action-packed pins.
We start soldering with the shortest components and work our way up:
- First we solder the resistors, diodes, and capacitors.
- Next the button, voltage regulator (don't forget to bend it first), and transistors.
- Finally we place the chunky tall stuff: the LED blocks, IC sockets, crystal, and jacks.
It's a good idea to power up the board and measure the supply voltage before putting the PIC or EEPROM chips in the sockets. Probably the easiest way to test the supply voltage is to measure between pin 2 (+5volts) and 3 (ground) of the ICSP header. The supply should read 5volts.
The firmware has two primary tasks that are performed in a loop:
- Write and verify the EEPROM with the PIC hardware I2C module.
- Cycle through the LED blocks and display the correct number on each.
There are also occasional tasks, such as:
- Save the current count to the PIC's internal EEPROM.
- Detect errors and halt the write-verify process.
The USB connection is currently only used for firmware upgrades. It is possible to add your own USB functions to the firmware, but there is currently NO USB functionality.
I2C EEPROM write and verify
A simple write-verify routine tests the EEPROM for write failures:
- Fill the chip with the value 0x55 (01010101 in binary).
- Read the chip and verify that all values match 0x55.
- If the values match, repeat with the XOR of the previous write value (0xaa, or 10101010 in binary).
Eventually the EEPROM will wear out, and the read value won't match the write value. When an error is detected, the Flash Destroyer saves the current write count to the PIC's internal EEPROM and stops the write-verify process.
The write and verify routine also detects a number of I2C bus errors, such as an EEPROM that stops responding. On an I2C error the Flash Destroyer will also save the current count and halt testing.
We use the PIC hardware I2C module to communicate with the EEPROM. The hardware module is somewhat faster than doing it via software. For maximum flexibility, the source code also includes software I2C routines from the Bus Pirate that can be enabled with a #define switch.
In the next two sections we'll walk though the EEPROM write-verify process. Logic analyzer output from a Saleae Logic illustrates each step. The Logic is a great piece of kit with beautiful output. This article was prepared well in advance, or we would have used the Open Logic Sniffer and SUMP to capture the waveforms instead.
Write the EEPROM
The PIC talks to the EEPROM over a two-wire I2C bus. One wire carries data (SDA), the other carries clock ticks (SCL) that tell devices when to read or write the data wire. Here's a good overview of I2C.
The storage space inside the EEPROM is broken into pages. Pages are usually between 8 and 256bytes longs, depending on the size of the chip. Only one page can be written at a time, then we have to give the EEPROM a chance to save the data before we can read or write again.
Our task is to fill the entire EEPROM with the same value and then verify the contents. Writing the entire chip takes a bunch of small write operations, each separated by a delay while the chip completes the write. Our EEPROM has 128bytes of storage, organized into 8byte pages, so takes 16 write-wait cycles to fill the whole chip.
Here's an overview of the EEPROM write process:
- Send a start bit, 7bit address, write bit, and check for ACK
- Send the write pointer start address (increments by page size each time), check for ACK
- Send one page of data to write, check each ACK. End with a stop bit
- Send the I2C address until the EEPROM finishes saving and responds with an ACK. Repeat steps 1-4 until the entire chip is filled.
Each step is explained and illustrated below.
Step 1 - Send a start bit, 7bit address, write bit, and check for ACK
All I2C transactions begin with a start bit. The PIC pulls the data line (SDA) from high to low while the clock (SCL) is high. Normally SDA doesn't change while the clock is high, and this 'illegal' state resets all the chips listening to the I2C bus.
After the start bit, the PIC sends the EEPROM's 7bit I2C address, and the read or write bit. For common Microchip EEPROMs the 7bit address is 0x50 (1010000). The eight bit tells the EEPROM if we want to read (1) or write (0). We want to write the chip, so the complete address to send is 10100000 (0xa0). We superimposed the bit value over each clock tick in the logic analyzer output above.
After the 8 data bits are sent, the PIC releases control of the SDA line and sends one more clock tick (yellow highlighted area). This ninth bit is a receive confirmation built into the I2C protocol. The EEPROM ACKnowledges (ACKs) the address was received by pulling the SDA low. If the chip was missing or the address incorrect, there would be no ACK and the bus would stay high because of the pull-up resistors. The yellow area highlights where the EEPROM controls SDA and holds it low, this is the ACK.
Step 2 - Send the write start address (increments by page size each time)
The second byte we send determines where the data is saved in the EEPROM's storage space. Our little 128byte EEPROM uses a single byte value to set an internal address pointer to one of the 128bytes of internal storage. Larger EEPROMs use two bytes to address more than 256bytes of space. The EEPROM ACKs the byte by holding SDA low (yellow highlighted area).
The EEPROM can only write one page at a time, so we use multiple write operations to fill the whole chip. Each time the write pointer is incremented by the page size until the entire chip is filled.
Our chip has 8byte pages, so the address increments by 8 each time we write to the EEPROM. First we write 8 bytes starting at data location 0, then 8 bytes starting at location 8, then at 16, and so on, until the entire chip is filled.
Step 3 - Send one page of data to write, end with a stop bit
The PIC firmware alternates between filling the chip with 0x55 (01010101) and 0xaa (10101010). This alternating pattern of 1 and 0 should help detect 'stuck' bits or bytes that never change.
In this output 0x55 is being sent to the EEPROM. Each byte we send is ACKed by the EEPROM pulling SDA low for the ninth clock bit (yellow area).
After sending a full page (8 bytes), the I2C transaction is ended with an I2C stop bit. A stop bit is an 'illegal' operation like the start bit, it is the only time the data signal changes from low to high while the clock is already high.
Step 4 - Send the I2C address until the EEPROM responds with an ACK
The EEPROM is not immediately ready for another write or read operation, it takes some time to save the page of data. The EEPROM won't respond to it's address while a write is in progress, so we can tell when a write is finished by sending the EEPROM's address until it ACKs.
The top logic capture shows the EEPROM ignoring its address while a write is in progress. It leaves the SDA line high during the ACK bit (top yellow highlight). The bottom capture shows the first time the chip responds after the save is complete, the EEPROM holds SDA low during the ACK bit (bottom yellow highlight).
Steps 1-4 are repeated, writing one page each time, until the entire chip is filled.
Read the EEPROM
Reading is a lot easier than writing. EEPROM reads are not limited to a single page, we can read the entire chip in one operation instead of lots of segments. The read operation goes like this:
- Reset the address pointer to the beginning with a partial write operation
- Send a start bit, 7bit address, read bit, and check for ACK
- Read data, PIC ACKs each byte this time
- NACK the last byte to end the read, send a stop bit
Each step is explained and illustrated below.
Step 1 - Reset the address pointer to the beginning with a write operation
Unlike write operations, there's no opportunity to set the address pointer with the read command. The read starts wherever the pointer is currently set. Before we start reading from the EEPROM we need to tell it where we want to read from. This is done with a partial write operation. This command only sets the internal write address pointer, it doesn't contain any data so it doesn't change anything on the chip.
First we address the EEPROM and make sure it's responding. A start bit resets the I2C bus, the 7bit EEPROM address (0x50) and write bit (1) are sent, and the EEPROM ACKs (yellow highlight). This is the same as step 1 of the EEPROM write routine.
We want to start reading from the beginning of the EEPROM, so we send 0 to set the write pointer to the first byte. The EEPROM responds with an ACK (yellow highlight).
This is similar to step 2 of the EEPROM write routine, except the transaction is ended immediately with a stop bit. No data follows, and nothing is actually written. All we did was set the internal address pointer to the first location in the EEPROM.
Step 2 - Send a start bit, 7bit address, read bit, and check for ACK
The address pointer is set to the beginning of the chip, now we can use the chip's read address to fetch the data.
A start bit resets the I2C bus before the read. Next, we send the 7bit EEPROM address (1010000) and the read bit (1). Previously we sent a write bit (0) with the address, but this time we use the read bit (1) to tell the EEPROM we want to read from it. The complete read address is 10100001 (0xa1).
The EEPROM ACKs the read address (shown in yellow), and will now output data onto the SDA pin each time the PIC raises and lowers the clock pin.
Step 3 - Read the chip, ACK each byte
Every 8 clock ticks from the PIC read one byte of data from the EEPROM. The yellow highlighted area in the output is where the EEPROM manipulates SDA, the PIC always controls SCL.
On every ninth bit the EEPROM releases SDA, and it's the PIC's turn to ACKnowledge the data by pulling SDA low (non-highlighted 9th bit).
Each byte read from the EEPROM is compared to the value we wrote in the previous step (0x55 or 0xaa). A mismatch triggers the error handler which saves the current count and flashes an error message on the display.
Step 4 - NACK the last byte to end the read, send a stop bit
When we're done reading, we must Not ACKnowdlege (NACK) the last byte by leaving SDA high during the ACK bit. NACK is very important because without it the EEPROM will continue to output data and ignore any further start or stop bits. After NACKing a read we can end the transaction with an I2C stop bit.
If the contents of the EEPROM match the value written earlier, the counter shown on the display increments. The counter is stored as a 32bit unsigned long variable, with a maximum value of 4,294,967,295 before rolling over to 0 again.
After a successful write-verify cycle, the loop continues at the beginning.
The display driver runs the multiplexed display. It lights each 7segment block briefly in quick succession, giving the appearance that the blocks are always on.
A timer in the PIC generates an interrupt a few hundred times per second. When the timer interrupt triggers, the PIC runs a piece of code that disables the current 7-segment block and sets the output pins for the next segment.
Save current value
The PIC saves the current write-verify count to its internal EEPROM when button S1 is pressed. This EEPROM is inside the PIC, and separate from the EEPROM in IC2. This is handy if you need to power down the Flash Destroyer but want to save the current write count.
The count is saved with a simple checksum. When the board is powered, the PIC reads the value in the EEPROM and the checksum. If the checksum is good the count continues with the saved value. If the checksum is bad, for example on a blank chip, the count starts from 0.
The bootloader appears as an USB HID device on a computer, and doesn't require any drivers. We use this bootloader a lot, so look for a comprehensive guide shortly.
The firmware can be updated with any of the Diolan utilities for Windows, Linux, Mac, BSD, etc. The Flash Destroyer is not configured to be USB powered, and it requires an external power supply during firmware updates.
The Flash Destroyer requires a 7-10volt DC external power supply with a common 2.1mm DC connector (center pin is positive).
'Flash' and 'destroy' are displayed briefly after power is connected. Then the Flash Destroyer starts to write and verify the EEPROM. Each time the chip is successfully verified the counter on the display increments.
Save current count
The counter value can be saved to the PIC's internal memory by pushing the button (S1). The display will show 'save'. This is handy if you need to unplug the Flash Destroyer but don't want to lose the current count.
To erase the saved value:
- Press the button while the display shows 'destroy' after power is connected
- The display will show 'erase' to confirm
- Hold the button down the entire time 'erase' is on the display, or release the button now to cancel
- The display will show 'erased' and the count will reset
The Flash Destroyer writes and then verifies the EEPROM until it detects an error. The current firmware detects two error types:
- Verify error (dead)
- I2C error (I2C Err)
A verify error means that the Flash Destroyer wrote one value to the EEPROM, but read something different. This is the primary failure the Flash Destroyer is designed to detect. After enough writes the EEPROM will no longer hold new values, and will be 'stuck' at a previous value.
When a verify error is detected the current count is saved internally and the verification process stops. The display alternates between the success count, and the verify error message (dead). Additional verification steps could be added to a future firmware.
I2C errors are related to random electrical problems or other potential defects. I2C errors probably aren't related to flash failure, but we thought it was good to catch them anyways. An I2C error also aborts the verification process and automatically saves the current count. The display alternates 'I2C Err' and the current count.
How long will it take for an EEPROM to burn out? The EEPROM is rated for a minimum of 1 million write cycles, but it could be many times that before there's an error.
At top speed we counted 736 write-verify cycles per minute, or 22hours to reach the minimum rated number of writes. Since some users might not want their Flash Destroyer to burn out so quickly, we created multiple firmwares with different write frequencies:
- Fast - continuous writing at maximum speed, reaches 1 million writes in one day.
- Medium - writes every 1 second, reaches 1 million in 12 days.
- Slow - writes every 1 minute, reaches 1 million in 2 years.
Load your preferred firmware using the USB bootloader. Flash Destroyer kits ship with the fast firmware installed.
Taking it further
The first version of the Flash Destroyer firmware has pretty basic functionality. We're already thinking of new features to add:
- Menu of options (speed, EEPROM type, etc)
- Auto save on certain 'milestone' values
- Verify read errors, I2C errors
- Show larger values with decimals if needed.
- USB connectivity for main firmware
- Additional power supply capacitors on updated hardware
Do you have any requests? You can join the discussion in the forum.
The Flash Destroyer is available as an 'I like to solder' kit for $17 (including worldwide shipping) until sold out.