Quantcast
Channel: Efficient way of writing to flash memory without losing data - Electrical Engineering Stack Exchange
Viewing all articles
Browse latest Browse all 3

Efficient way of writing to flash memory without losing data

$
0
0

For my project, I am writing some code that gets some results and I want to store these results on external flash memory. The external flash memory in question is a MX25R8035F. I found that writing without erasing only works the first time I wrote something to an address.

But because of this I'm running into some memory issues. The smallest erase is a sector erase (4096 bytes.) If I want to write to a specific address I would first need to read the sector that contains that address, change the bytes that I want to be changed and then write the whole sector (writing is only per page.)

Is there a more efficient way of using this external flash memory? Specifically using less memory to change one or two bytes.

The function I use now this can be found below:

uint8_t EXT_FLASH_write(size_t address, uint8_t *buf, size_t length) {/* * The entire sector will be erased when writing to an offset inside that sector * Therefore this function will first retrieve all data inside the sector and update the retrieved * data with the values inside buff which and will then write the entire content back to the sector */    uint8_t wbuf[4];    SPI_Transaction transaction;    uint32_t sectorBaseAddr;    uint8_t temp[EXT_FLASH_ERASE_SECTOR_SIZE];    uint8_t tries;    size_t ilen; /* interim length per instruction */    uint32_t bufIndex = 0;    uint8_t pageIterations;    while (length > 0) {        // first retrieve entire sector so it can be erased on the chip        sectorBaseAddr = EXT_FLASH_SECTOR_BASE_ADDR(address);        EXT_FLASH_read(sectorBaseAddr, temp, EXT_FLASH_ERASE_SECTOR_SIZE);        // Erase the sector on the chip        EXT_FLASH_erase(address, EXT_FLASH_ERASE_SECTOR_SIZE);        ilen = EXT_FLASH_PROGRAM_PAGE_SIZE                - (address % EXT_FLASH_PROGRAM_PAGE_SIZE);        if (length < ilen)            ilen = length;        memcpy(temp + (address - sectorBaseAddr), buf + bufIndex, length);        bufIndex += ilen;        address += ilen;        length -= ilen;        tries = 0;        if (EXT_FLASH_writeEnable() != 0) {            if (tries == EXT_FLASH_MAX_TRIES) {                return 1;            }            tries++;        }        tries = 0;        while (EXT_FLASH_waitReady() != 2) {            if (tries == EXT_FLASH_MAX_TRIES) {                return 1;            }            EXT_FLASH_writeEnable();            tries++;        }        // programming the external flash can only be done in pages        // so divide current sector into pages and write each page separately         for (pageIterations = 0;                 pageIterations * EXT_FLASH_PROGRAM_PAGE_SIZE< EXT_FLASH_ERASE_SECTOR_SIZE; pageIterations++) {            EXT_FLASH_select();            wbuf[0] = EXT_FLASH_CODE_PROGRAM;            wbuf[1] = ((sectorBaseAddr+ (pageIterations * EXT_FLASH_PROGRAM_PAGE_SIZE)) >> 16)& 0xff;            wbuf[2] = ((sectorBaseAddr+ (pageIterations * EXT_FLASH_PROGRAM_PAGE_SIZE)) >> 8)& 0xff;            wbuf[3] = (sectorBaseAddr+ (pageIterations * EXT_FLASH_PROGRAM_PAGE_SIZE)) & 0xff;            // Configure the transaction            transaction.count = sizeof(wbuf);            transaction.txBuf = wbuf;            transaction.rxBuf = NULL;            if (!SPI_transfer(masterSpi, &transaction)) {                /* failure */                EXT_FLASH_deselect();                return 1;            }            // Configure the transaction            transaction.count = EXT_FLASH_PROGRAM_PAGE_SIZE;            transaction.txBuf = temp+ (pageIterations * EXT_FLASH_PROGRAM_PAGE_SIZE);            transaction.rxBuf = NULL;            if (!SPI_transfer(masterSpi, &transaction)) {                /* failure */                EXT_FLASH_deselect();                return 1;            }            EXT_FLASH_deselect();        }    }    return 0;}

Viewing all articles
Browse latest Browse all 3

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>