public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] IO_Flash & DataFlash
@ 2004-08-31 10:09 Savin Zlobec
  2004-08-31 11:08 ` Andrew Lunn
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Savin Zlobec @ 2004-08-31 10:09 UTC (permalink / raw)
  To: ecos-discuss

Hi,

I'am writing a DataFlash driver and I would like to use it also through 
the io_flash API,
but it seems that the io_flash only supports 2^n block sizes (judging by 
the calculation
and usage of block_mask). DataFlash memory array is divided into 3 
levels - sectors,
blocks and pages of wich none has 2^n size. 

Supporting this in io_flash is probably just a matter of some ifdefs in 
read/program/erase
functions - is this correct ? But does anything else (RedBoot, jffs2, 
...) also depend on
2^n block sizes ?

thanx
        savin
 
 

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] IO_Flash & DataFlash
  2004-08-31 10:09 [ECOS] IO_Flash & DataFlash Savin Zlobec
@ 2004-08-31 11:08 ` Andrew Lunn
  2004-08-31 12:44 ` Mike Jastrebtsoff
  2004-09-09 13:17 ` Andrew Lunn
  2 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2004-08-31 11:08 UTC (permalink / raw)
  To: Savin Zlobec; +Cc: ecos-discuss

On Tue, Aug 31, 2004 at 12:06:20PM +0200, Savin Zlobec wrote:
> Hi,
> 
> I'am writing a DataFlash driver and I would like to use it also through 
> the io_flash API,
> but it seems that the io_flash only supports 2^n block sizes (judging by 
> the calculation
> and usage of block_mask). DataFlash memory array is divided into 3 
> levels - sectors,
> blocks and pages of wich none has 2^n size. 
> 
> Supporting this in io_flash is probably just a matter of some ifdefs in 
> read/program/erase
> functions - is this correct ? But does anything else (RedBoot, jffs2, 
> ...) also depend on
> 2^n block sizes ?

It should not be too hard to make the io_flash code work with odd size
blocks for flash. jffs2 i have no idea about, you would be better
asking dwmw2. Redboot i think uses a few masks, so would need some
changes.

I will take a look at the new flash code tonight.

        Andrew

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] IO_Flash & DataFlash
  2004-08-31 10:09 [ECOS] IO_Flash & DataFlash Savin Zlobec
  2004-08-31 11:08 ` Andrew Lunn
@ 2004-08-31 12:44 ` Mike Jastrebtsoff
  2004-09-09 13:17 ` Andrew Lunn
  2 siblings, 0 replies; 4+ messages in thread
From: Mike Jastrebtsoff @ 2004-08-31 12:44 UTC (permalink / raw)
  To: ecos-discuss

Hello, Savin.

I developed DataFlash driver some time ago,(but it wasn't finished)
and I had the same issue.

Simple solution is a ignoring of "unnecessary" bytes in DataFlash
page. DF Page size is 528 bytes and if we will align that to 512 bytes
we will losing 16 bytes per page only.

It can be used internally by DF driver for block regeneration(after
10.000 writes by Atmels's datasheet).

As for as I remember Atmels' proprietary filesystem - DFFS using this feature.

Regards,
        Mike
SZ> Hi,

SZ> I'am writing a DataFlash driver and I would like to use it also through
SZ> the io_flash API,
SZ> but it seems that the io_flash only supports 2^n block sizes (judging by
SZ> the calculation
SZ> and usage of block_mask). DataFlash memory array is divided into 3
SZ> levels - sectors,
SZ> blocks and pages of wich none has 2^n size. 

SZ> Supporting this in io_flash is probably just a matter of some ifdefs in
SZ> read/program/erase
SZ> functions - is this correct ? But does anything else (RedBoot, jffs2,
SZ> ...) also depend on
SZ> 2^n block sizes ?

SZ> thanx
SZ>         savin
 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] IO_Flash & DataFlash
  2004-08-31 10:09 [ECOS] IO_Flash & DataFlash Savin Zlobec
  2004-08-31 11:08 ` Andrew Lunn
  2004-08-31 12:44 ` Mike Jastrebtsoff
@ 2004-09-09 13:17 ` Andrew Lunn
  2 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2004-09-09 13:17 UTC (permalink / raw)
  To: Savin Zlobec; +Cc: ecos-discuss, eCos Patches

[-- Attachment #1: Type: text/plain, Size: 991 bytes --]

On Tue, Aug 31, 2004 at 12:06:20PM +0200, Savin Zlobec wrote:
> Hi,
> 
> I'am writing a DataFlash driver and I would like to use it also through 
> the io_flash API,
> but it seems that the io_flash only supports 2^n block sizes (judging by 
> the calculation
> and usage of block_mask). DataFlash memory array is divided into 3 
> levels - sectors,
> blocks and pages of wich none has 2^n size. 
> 
> Supporting this in io_flash is probably just a matter of some ifdefs in 
> read/program/erase
> functions - is this correct ? But does anything else (RedBoot, jffs2, 
> ...) also depend on
> 2^n block sizes ?

Hi Savin

I just committed these patches which means the the flash_v2 code
should not support arbitary size blocks. Please let me know if this
works for the DataFlash, i've only been able to test with a synthetic
flash driver.

Looking at the jffs2 mailling list it looks like jffs2 should be
ok. You will need to test to be sure. I've not looked at RedBoot yet.

        Andrew

[-- Attachment #2: flash.diff --]
[-- Type: text/plain, Size: 4299 bytes --]

Index: io/flash/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/ChangeLog,v
retrieving revision 1.38.2.6
diff -u -r1.38.2.6 ChangeLog
--- io/flash/current/ChangeLog	21 Aug 2004 13:47:55 -0000	1.38.2.6
+++ io/flash/current/ChangeLog	9 Sep 2004 13:03:56 -0000
@@ -1,3 +1,8 @@
+2004-09-09  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/flash.c: Support flash blocks of arbitary size. The
+	DataFlash devices for example have block of 528 bytes.
+
 2004-08-21  Andrew Lunn  <andrew.lunn@ascom.ch>
 
         * removed the functions cyg_flash_get_limits and
Index: io/flash/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/flash.c,v
retrieving revision 1.26.2.3
diff -u -r1.26.2.3 flash.c
--- io/flash/current/src/flash.c	21 Aug 2004 13:47:56 -0000	1.26.2.3
+++ io/flash/current/src/flash.c	9 Sep 2004 13:03:57 -0000
@@ -343,6 +343,22 @@
   return flash_block_size(dev, flash_base);
 }
 
+// Return the first address of a block. The flash might not be aligned
+// in terms of its block size. So we have to be careful and use
+// offsets.
+static inline cyg_flashaddr_t 
+flash_block_begin(cyg_flashaddr_t addr, struct cyg_flash_dev *dev)
+{
+  size_t block_size;
+  cyg_flashaddr_t offset;
+  
+  block_size = flash_block_size(dev, addr);
+  
+  offset = addr - dev->start;
+  offset = (offset / block_size) * block_size;
+  return offset + dev->start;
+}
+
 
 __externC int 
 cyg_flash_erase(const cyg_flashaddr_t flash_base, 
@@ -377,8 +393,7 @@
     end_addr = dev->end;
   }
   
-  block_size = flash_block_size(dev, addr);
-  block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1));
+  block = flash_block_begin(addr, dev);
   
 #ifdef CYGSEM_IO_FLASH_CHATTER
   dev->pf("... Erase from %p-%p: ", (void*)block, (void*)end_addr);
@@ -391,6 +406,8 @@
     unsigned char *dp;
     bool erased = true;
 
+    block_size = flash_block_size(dev, addr);
+
     // If there is a read function it probably means the flash
     // cannot be read directly.
     if (!dev->funs->flash_read) {
@@ -412,7 +429,7 @@
       *err_address = block;
       break;
     }
-    block += flash_block_size(dev, block);
+    block += block_size;
 #ifdef CYGSEM_IO_FLASH_CHATTER
     dev->pf(".");
 #endif
@@ -488,7 +505,7 @@
     if (size > block_size) size = block_size;
     
     // Writing from the middle of a block?
-    offset = (size_t)addr & (block_size-1);
+    offset = (size_t)addr % block_size;
     if (offset)
       size = MIN(block_size - offset, size);
     stat = dev->funs->flash_program(dev, addr, ram, size);
@@ -576,7 +593,7 @@
     if (size > block_size) size = block_size;
     
     // Reading from the middle of a block?
-    offset = (size_t)addr & (block_size-1);
+    offset = (size_t)addr % block_size;
     if (offset)
       size = MIN(block_size - offset, size);
     if (dev->funs->flash_read) {
@@ -651,8 +668,7 @@
     end_addr = dev->end;
   }
   
-  block_size = flash_block_size(dev, addr);
-  block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1));
+  block = flash_block_begin(addr, dev);
   
 #ifdef CYGSEM_IO_FLASH_CHATTER
   dev->pf("... Locking from %p-%p: ", (void*)block, (void*)end_addr);
@@ -685,7 +701,7 @@
     return stat;
   }
   
-  if (flash_base + len - 1 > dev->end) {        // Off by one?
+  if (flash_base + len - 1 > dev->end) {        
     // The region to erase if bigger than this driver handles. Recurse
     return cyg_flash_lock(dev->end+1, 
                           len - (dev->end - flash_base) - 1,
@@ -728,8 +744,7 @@
     end_addr = dev->end;
   }
   
-  block_size = flash_block_size(dev, addr);
-  block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1));
+  block =   block = flash_block_begin(addr, dev);
   
 #ifdef CYGSEM_IO_FLASH_CHATTER
   dev->pf("... Unlocking from %p-%p: ", (void*)block, (void*)end_addr);
@@ -762,7 +777,7 @@
     return stat;
   }
   
-  if (flash_base + len - 1 > dev->end) {        // Off by one?
+  if (flash_base + len - 1 > dev->end) {        
     // The region to erase if bigger than this driver handles. Recurse
     return cyg_flash_lock(dev->end+1, 
                           len - (dev->end - flash_base) - 1,

[-- Attachment #3: synth_flash.diff --]
[-- Type: text/plain, Size: 7810 bytes --]

Index: devs/flash/synthv2/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/Attic/ChangeLog,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 ChangeLog
--- devs/flash/synthv2/current/ChangeLog	21 Aug 2004 13:45:53 -0000	1.1.2.2
+++ devs/flash/synthv2/current/ChangeLog	9 Sep 2004 13:06:25 -0000
@@ -1,3 +1,8 @@
+2004-09-09  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/flash_synth.c: Allo the use of arbitary sized block.
+	* test/flash3.c: Allow the use of small blocks
+
 2004-08-21  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* tests/flash[23].c: Removed calls to cyg_flash_get_block_info()
Index: devs/flash/synthv2/current/cdl/flash_synth.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/cdl/Attic/flash_synth.cdl,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 flash_synth.cdl
--- devs/flash/synthv2/current/cdl/flash_synth.cdl	5 Aug 2004 13:25:33 -0000	1.1.2.1
+++ devs/flash/synthv2/current/cdl/flash_synth.cdl	9 Sep 2004 13:06:26 -0000
@@ -80,8 +80,7 @@
 	display        "Size of one block of synth flash"
 	flavor	       data
 	default_value  65536
-        legal_values   4096 to 999999
-        requires       { (CYGNUM_FLASH_SYNTH_V2_BLOCKSIZE % 4096) == 0 }
+        legal_values   512 to 999999
 	description    "
 	        This controls the size of one block of flash. This is 
 		the minimum size that can be erased."
Index: devs/flash/synthv2/current/src/synth.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/src/Attic/synth.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 synth.c
--- devs/flash/synthv2/current/src/synth.c	5 Aug 2004 13:25:34 -0000	1.1.2.1
+++ devs/flash/synthv2/current/src/synth.c	9 Sep 2004 13:06:26 -0000
@@ -60,6 +60,10 @@
 #include <cyg/io/flash.h>
 #include <cyg/flash/synth.h>
 
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
+
 /* Helper function. The Linux system call cannot pass 6 parameters. Instead
    a structure is filled in and passed as one parameter */
 static int 
@@ -208,8 +212,8 @@
 #endif
     struct cyg_flash_synth_priv *priv = dev->priv;
     int offset = (int)block_base;
-    size_t block_size;
-    int i;
+    size_t remaining;
+    int write_size;
 
     offset -= dev->start;
     
@@ -223,17 +227,15 @@
 
     CYG_ASSERT(sizeof(empty) < config->block_size,
                "Eckk! Can't work with such small blocks");
-    CYG_ASSERT((config->block_size % sizeof(empty)) == 0,
-               "Eckk! Can't work with that odd size block");
     CYG_ASSERT(config->boot_blocks && sizeof(empty) < config->boot_block_size,
                "Eckk! Can't work with such small blocks");
-    CYG_ASSERT((config->boot_blocks && config->block_size % sizeof(empty)) == 0,
-               "Eckk! Can't work with that odd size block");
     
-    block_size = flash_block_size(dev, block_base);
+    remaining = flash_block_size(dev, block_base);
 
-    for (i=0; (i * sizeof(empty)) < block_size; i++) {
-        cyg_hal_sys_write(priv->flashfd, empty, sizeof(empty));
+    while (remaining) {
+      write_size = MIN(remaining, sizeof(empty));
+      cyg_hal_sys_write(priv->flashfd, empty, write_size);
+      remaining -= write_size;
     }
     return CYG_FLASH_ERR_OK;
 }
Index: devs/flash/synthv2/current/tests/flash1.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/tests/Attic/flash1.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 flash1.c
--- devs/flash/synthv2/current/tests/flash1.c	5 Aug 2004 13:25:34 -0000	1.1.2.1
+++ devs/flash/synthv2/current/tests/flash1.c	9 Sep 2004 13:06:26 -0000
@@ -94,10 +94,12 @@
   
     CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_init");
 
+#ifdef CYGSEM_IO_FLASH_LEGACY_DEVICE_API
+    //Strictly speaking, this is a device driver call, not a user API call.
     flash_dev_query(data);
     CYG_TEST_PASS_FAIL(!strncmp(data,"Linux Synthetic Flash",sizeof(data)),
                        "flash_query"); 
-
+#endif
     ret = flash_get_limits(NULL,&flash_start,&flash_end);
     CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_limits");
 
Index: devs/flash/synthv2/current/tests/flash3.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/tests/Attic/flash3.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 flash3.c
--- devs/flash/synthv2/current/tests/flash3.c	21 Aug 2004 13:45:53 -0000	1.1.2.2
+++ devs/flash/synthv2/current/tests/flash3.c	9 Sep 2004 13:06:26 -0000
@@ -105,7 +105,8 @@
     int block_size=0, blocks=0;
     cyg_flashaddr_t prog_start;
     unsigned char * ptr;
-
+    size_t copyright_len;
+    
     CYG_TEST_INIT();
 
     // Reference the flash dev so the linker does not throw it away
@@ -151,16 +152,25 @@
   
     CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
 
-    ret = cyg_flash_program(flash_start,&copyright,sizeof(copyright),NULL);
+    // With small blocks we have to use less of the copyright messages
+    // Since we make assumptions about fitting the message into a
+    // block.
+    if (block_size < sizeof(copyright)*2/3) {
+      copyright_len = block_size / 3;
+    } else {
+      copyright_len = sizeof(copyright);
+    }
+    
+    ret = cyg_flash_program(flash_start,&copyright,copyright_len,NULL);
     CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
   
     /* Check the contents made it into the flash */
     CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
-                                copyright,sizeof(copyright)),
+                                copyright,copyright_len),
                        "flash program contents");
 
     /* .. and check nothing else changed */
-    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
+    for (ptr=(unsigned char *)flash_start+copyright_len,ret=0; 
          ptr < (unsigned char *)flash_end; ptr++) {
         if (*ptr != 0xff) {
             ret++;
@@ -169,24 +179,23 @@
   
     CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
 
-    /* Program over a block boundary */
-    prog_start = flash_start + block_size - sizeof(copyright)/2;
-    ret = cyg_flash_program(prog_start,&copyright,sizeof(copyright),NULL);
+    prog_start = flash_start + block_size - copyright_len/2;
+    ret = cyg_flash_program(prog_start,&copyright,copyright_len,NULL);
     CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
   
     /* Check the first version is still OK */
     CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
                                 copyright,
-                                sizeof(copyright)),
+                                copyright_len),
                        "Original contents");
   
     CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                 copyright,
-                                sizeof(copyright)),
+                                copyright_len),
                        "New program contents");
 
     /* Check the bit in between is still erased */
-    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
+    for (ptr=(unsigned char *)flash_start+copyright_len,ret=0; 
          ptr < (unsigned char *)prog_start; ptr++) {
         if (*ptr != 0xff) {
             ret++;
@@ -212,7 +221,7 @@
     /* Lastly check the first half of the copyright message is still there */
     CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                 copyright,
-                                sizeof(copyright)/2),
+                                copyright_len/2),
                        "Block 1 OK");
 
 #if 0


[-- Attachment #4: Type: text/plain, Size: 148 bytes --]

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-09-09 13:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-31 10:09 [ECOS] IO_Flash & DataFlash Savin Zlobec
2004-08-31 11:08 ` Andrew Lunn
2004-08-31 12:44 ` Mike Jastrebtsoff
2004-09-09 13:17 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).