Massive data to store in flash memory

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
Post Reply
norman
Active Member
Posts: 55
Joined: Wed Jan 11, 2012 2:27 pm

Massive data to store in flash memory

Post by norman »

Hello,
I'm working with a XS1-L16A and a M25P16 flash memory. I have more than 1000 bytes to save and more in the future so i want to use the free space of the flash memory. I don't need to often change those data, several times but not often.
M25P16 is a 16Mb / 2Mo flash memory and the XS1 software needs an average space of 65000 bytes, so i've got loooot of remaining space.
the problem is about saving those data in the flash : the flash system needs to erase a sector of space (65535 bytes minimum), all bits to 1, before writing byte by byte the data, because only the 0 can be write byte by byte.
So, for example, if i want to change 10 bytes of 1000, the only way i found is to "download" all the data in the XS1, change the 10 bytes, and then upload those updated 1000 bytes. This means to make a "char table[1000]" data in the XS1. This could be a problem when there is more and more data to save, because the XS1-L16 can only handle 65535 bytes for data and code on one tile.

I was thinking to use another sector of the flash as a direct buffer but not sure it can work.
Am i completely mistaking and is there a method to do that correctly ?
thanks !


User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Hello Norman. Some details and clarifications to your post.

The serial flash memory IC is defined in Mbits ('mega bits') but your writes will be in bytes. Respectively the # of bytes = Mbits / 8.

Have a review of this article on the subject:

http://www.totalphase.com/support/artic ... ash-Center

Also, when writing to the storage serial flash, you can ERASE (this is a command) on a sector by sector basis. The size of each sector is defined in the vendor's datasheet. So it should be possible for you to read a sector and store the contents to a local array in RAM -> erase the sector on the target serial flash memory -> write the local array (perhaps modified or not) to the target flash device.

If the speed of the write is not important then serial flash is the lowest cost option. Otherwise you may consider to review the FRAM devices (ie. Cypress or similar) which offers much longer storage life with a faster write time than traditional flash device.
norman
Active Member
Posts: 55
Joined: Wed Jan 11, 2012 2:27 pm

Post by norman »

mon2 wrote:read a sector and store the contents to a local array in RAM -> erase the sector on the target serial flash memory -> write the local array (perhaps modified or not) to the target flash device.
Yes indeed, this is what i'm doing now but - because the sector is 65535 bytes in this case - if i have lot of data to change/save, the RAM of the xs1 will be quickly full. The local array can't be sized of 65535, it's the size of the full xs1 tile, code and data. So i was wondering if i misunderstood something or if there is another way to do.
thanks !
User avatar
ahenshaw
Experienced Member
Posts: 96
Joined: Mon Mar 22, 2010 8:55 pm

Post by ahenshaw »

Can you switch to another device that has a "small sector erase" option, such as the On Semiconductor LE25S161? Like the device that you are using, it has a 64K-byte sector size, but it appears to also support a 4K-byte sector erase size.

LE25S161 Datasheet
User avatar
ers35
Active Member
Posts: 62
Joined: Mon Jun 10, 2013 2:14 pm
Contact:

Post by ers35 »

You can reserve two sectors and alternate copying all the data between them on each page write. When copying, check if the page to which you are writing should contain copied data or new data. This means you only need a 256 byte buffer to write any amount of data. A more efficient implementation would write more than a page at a time. Page reads can be done by reading from the most recently written to sector.

See the following (untested, may contain bugs) example for guidance:

Code: Select all

// xcc -target=XS1-L16A-128-QF124-C8 M25P16-flash.xc -report -lflash -o M25P16-flash.xe

#include <flash.h>
#include <string.h>
#include <xs1.h>

static unsigned sector_flag = 0;

// toggle between writing in sector 0 and sector 1, always erasing the other sector
int M25P16_writeDataPage(unsigned n, const unsigned char src[])
{
  // 256
  unsigned num_pages = fl_getDataSectorSize(0) / 256;
  // 0
  unsigned src_page_offset = sector_flag * 256;
  // 256
  unsigned dst_page_offset = (sector_flag ^ 1) * 256;
  unsigned char buf[256];
  // copy from one sector to the other, except for the new data in page 'n'
  int status = 0;
  for (unsigned i = 0; i < num_pages; i += 1)
  {
    // 0, 1, 2, ... 255
    unsigned src_page = src_page_offset + i;
    // 256, 257, 258, ... 511
    unsigned dst_page = dst_page_offset + 1;
    if (i == n)
    {
      // write new data
      status = fl_writeDataPage(dst_page, src);
    }
    else
    {
      // copy old data
      fl_readDataPage(src_page, buf);
      status = fl_writeDataPage(dst_page, buf);
    }
    if (status != 0)
    {
      return status;
    }
  }
  // erase the old sector so it can be written to next time.
  fl_eraseDataSector(sector_flag);
  sector_flag ^= 1;
  return status;
}

int M25P16_readDataPage(unsigned n, unsigned char dst[])
{
  // always read from the most recently written to sector
  unsigned src_page = sector_flag * 256;
  return fl_readDataPage(src_page, dst);
}

fl_SPIPorts flash = {
  XS1_PORT_1A,
  XS1_PORT_1B,
  XS1_PORT_1C,
  XS1_PORT_1D,
  XS1_CLKBLK_1
};

int main()
{
  const fl_DeviceSpec spec[1] = {FL_DEVICE_NUMONYX_M25P16};
  fl_connectToDevice(flash, spec, 1);
  fl_eraseAllDataSectors();
  unsigned char buf[256] = {0};
  // init buf with a pattern to see if the writes are successful
  for (unsigned i = 0; i < sizeof(buf); i += 1)
  {
    buf[i] = i;
  }
  // write 65536 bytes without having a buffer that large
  for (unsigned i = 0; i < 256; i += 1)
  {
    M25P16_writeDataPage(i, buf);
  }
  return 0;
}
norman
Active Member
Posts: 55
Joined: Wed Jan 11, 2012 2:27 pm

Post by norman »

thank you all for your advice, i have to look that way :)
Post Reply