Reply by September 10, 20092009-09-10
>> Function pointers cause a bit of an issue in overlay linker/locators. The >> linker attempts to overlay code and memory because there is no MMU or heap.
> Function pointers addresses are calculated at compile time and stored > in flash.
Calculation and storage are not the issue. _Calling_ functions via those pointers is. The problem is that some architectures (most notably the 8051) just don't have enough stack space (nor pointer registers) to afford putting anything besides the return address in there. It forbids itself to put automatic variables or function arguments on these systems' stacks. So C compilers for such architectures allocate even automatic variables statically. To reduce the impact of that on RAM consumption, they analyze the call tree in order to find out which functions' automatic data are never needed simultaneously, so they can statically be allocated to the same location. That optimization is called data overlaying. Function pointers make that analysis hard --- potentially impossible, even.
> I use them on HCS08 microcontrollers and never had a problem.
Consider yourself having been spared a worthwile, educating experience.
> If you statically link the architecture dependent code, you force a > potential user to modify your code.
We're talking embedded systems here (and potentially small ones at that) --- users don't get to decide whether they want to modify the code or not. More often than not, they won't even know that there is code running in that thing they just bought.
Reply by Enrico September 10, 20092009-09-10
Hi,

> Function pointers cause a bit of an issue in overlay linker/locators. The > linker attempts to overlay code and memory because there is no MMU or hea=
p.
> With function pointer it can=92t trace the call tree so it can=92t do any > overlay. I learnt this the hard way, had to go back in redo allot of fanc=
y
> code with normal functions.
forgive pal, but this is the very first time I hear that. Function pointers addresses are calculated at compile time and stored in flash. I use them on HCS08 microcontrollers and never had a problem. If you statically link the architecture dependent code, you force a potential user to modify your code.
> The device I discovered a problem on also uses UIP as TCPIP stack and PPP > for a GPRS connection and the modem is quite busy. I saw the modem/serial > code go haywire and over running a buffer in a bad comms scenario. I thin=
k
> this is what damaged the FAT.
Ok. You might want to have PC-lint check your code for buffers overrun.
> The version I put on Google is just a FS, I will put it on a JTAG debugge=
r
> and put break points in all the error and recovery code arias, then run t=
he
> test routine in an endless loop for a few days to see what it takes to we=
ar
> out the flash and how the code reacts when the flash starts getting > unreliable.
Ok Enrico Migliore
Reply by heindekock September 9, 20092009-09-09
>Hi, > >> In the error I experienced, it looked liked some other process messed
up
>> my FAT buffer. > >there might be an error in the code... > >Compile your code with Visual C after activating the LEVEL 4 option >which is the most severe (the Visual C Express edition is now free >from Microsoft). >Make sure the compiler issues absolutely no warnings. > >Use function pointers to call all the functions that are architecture >dependent. >Don't be scared by function pointers: even 8 bit microcontrollers with >1k flash can handle them correctly. >In this way, your C code will compile cleanly on ANY architecture. > >See the following example: the client of your code, will have to make >2 function calls, before using the filesystem: > >#include <fs.h> > >void main (void) >{ > fs_config_t *conf; > > fs_init (); > > conf->disk_sector_read = dataflash_read; > conf->disk_sector_write = dataflash_write; > > fs_config (&conf); > >} > > >> I was quite impressed with the recovery routine that picked >> up all the loose pages and reconstructed the FAT. > >Nice feature. > >Good luck pal :-) > >ciao, >Enrico Migliore >
Function pointers cause a bit of an issue in overlay linker/locators. The linker attempts to overlay code and memory because there is no MMU or heap. With function pointer it can&rsquo;t trace the call tree so it can&rsquo;t do any overlay. I learnt this the hard way, had to go back in redo allot of fancy code with normal functions. The device I discovered a problem on also uses UIP as TCPIP stack and PPP for a GPRS connection and the modem is quite busy. I saw the modem/serial code go haywire and over running a buffer in a bad comms scenario. I think this is what damaged the FAT. The version I put on Google is just a FS, I will put it on a JTAG debugger and put break points in all the error and recovery code arias, then run the test routine in an endless loop for a few days to see what it takes to wear out the flash and how the code reacts when the flash starts getting unreliable. Could be fun! Cheers Hein de Kock --------------------------------------- This message was sent using the comp.arch.embedded web interface on http://www.EmbeddedRelated.com
Reply by Enrico September 9, 20092009-09-09
Hi,

> In the error I experienced, it looked liked some other process messed up > my FAT buffer.
there might be an error in the code... Compile your code with Visual C after activating the LEVEL 4 option which is the most severe (the Visual C Express edition is now free from Microsoft). Make sure the compiler issues absolutely no warnings. Use function pointers to call all the functions that are architecture dependent. Don't be scared by function pointers: even 8 bit microcontrollers with 1k flash can handle them correctly. In this way, your C code will compile cleanly on ANY architecture. See the following example: the client of your code, will have to make 2 function calls, before using the filesystem: #include <fs.h> void main (void) { fs_config_t *conf; fs_init (); conf->disk_sector_read = dataflash_read; conf->disk_sector_write = dataflash_write; fs_config (&conf); }
> I was quite impressed with the recovery routine that picked > up all the loose pages and reconstructed the FAT.
Nice feature. Good luck pal :-) ciao, Enrico Migliore
Reply by karthikbalaguru September 9, 20092009-09-09
On Sep 9, 3:02 am, Vladimir Vassilevsky <nos...@nowhere.com> wrote:
> karthikbalaguru wrote: > > Yes, wear levelling & power failure scenarios are not well handled > > with FAT16 and it is well handled in the JFS. Further, there is no > > much necessity to create files in runtime in embedded. > > Huh? > > If there is no need to create files at runtime, then there is no need > for the file system. You can include the data as the constant arrays. > > BTW, there is a whole big area of the embedded systems for data > acquisition, monitoring and logging. All they do is creating and writing > files. >
In most of the scenarios constant arrays are preferred in embedded. But Yes, if you go in for lot of logging then it is required. Karthik Balaguru
Reply by Vladimir Vassilevsky September 8, 20092009-09-08

karthikbalaguru wrote:


> Yes, wear levelling & power failure scenarios are not well handled > with FAT16 and it is well handled in the JFS. Further, there is no > much necessity to create files in runtime in embedded.
Huh? If there is no need to create files at runtime, then there is no need for the file system. You can include the data as the constant arrays. BTW, there is a whole big area of the embedded systems for data acquisition, monitoring and logging. All they do is creating and writing files. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
Reply by karthikbalaguru September 8, 20092009-09-08
On Sep 8, 11:50=A0pm, Enrico <zig...@libero.it> wrote:
> Hi, > > > I wrote a flash file system for an 8051 project using a 2MB dataflash o=
ver
> > the last 3 years. > > Ok > > > I tried to stay as close to stdio from dos (fopen, etc) > > as possible. > > fopen() and his brothers belong to the C standard I/O library > (<stdio.h>) and not to the filesystem. > > Filesystems export only: open (), close (), read (), write (), lseek > (), et cetera > > Filesystems compile and run perfectly without the standard library > code. > > > > > > >I had to shape and change it a few times as hind sight makes > > us cleverer. I needed some special functionality like shrinking the fil=
e
> > from the front like a FIFO that caused me to veer of a bit (programmer=
=92s
> > creative license). =A0It also has the ability to handle binary files. I > > stored and retrieved bitmaps successfully. > > The version I call final has been in the field for a while now and seem > > stable. Here and there a piece of the fat disappears with disastrous > > effect. I wrote recovery code but of course I never tested it, after st=
ress
> > test I was happy. All in all over 3K pieces of hardware run it now so t=
he 2
> > or3 problems I had don=92t worry me much. > > I would like to put this code somewhere where we can all use it and may=
be
> > contribute to it. I=92ll need some help with a repository and copyright > > stuff. I would like it to be as free as possible and see if any fs expe=
rts
> > out there would like to comment or improve on it. > > If you have experience with this kind of stuff and can help please do, =
if
> > you don=92t, I would like to request that we keep the thread as clean a=
s
> > possible, DONT CLUTTER IT WITH NONSENS! Let=92s see how efficiently we =
can
> > get this out there and usable for everyone. > > Years ago, I extracted the FAT16 filesystem from Pat Villani's FreeDOS > project and made it architecture independent. > The only function architecture dependent were: > > media_init() > media_read () =A0/* read a sector */ > media_write () =A0/* write a sector */ > > I also extracted the MINIX standard I/O library and compiled it over > the FAT16 filesystem. > > The code was debugged on Visual C 6.0. > As a media, I used a usb disk plugged in the PC. > > The code is in production on hundreds of embedded devices (M16C+ > dataflash). All works nice. Never had problems. > > It was a very important C exercise... That I won't ever repeat again > in my life. > > FAT filesystems are risky on embedded systems for the following > reasons: > > 1) Unless you purchase a commercial product, the second copy of the > FAT is never used to back up if the first fails > 2) FAT16 don't do WEAR LEVELLING, that means that after 10.000/50.000 > of write sessions your Dataflash may fail > 3) Speaking of embedded systems: in many many cases, there's > absolutely no need to create new files at run time. > 4) Power fail failure during write sessions may corrupt FAT and files > > Back then I was very excited running the FreeDOS filesystem and the > MINIX stdio library on a 16 bit M16C microcontroller... > Production volumes now are too big and I don't wanna risk...I save my > data at fixed flash addresses, use 32 CRC, and keep 2 copies of the > data. > > Suggestions for you :-) > > Dataflash Write > ------------------ > 1) A write must be followed by a read, to check if you wrote the > sector correctly > 2) Poll the status register of the dataflash, and wait for the write > to be completed. Don't assume the > 3) Use the extra 8 bytes of each sector to store the CRC (16 bit is > fine) > 4) You may want to use ECC code correction. I remember correctly, 8 > bytes may correct up to 8 bit on a buffer of 256. > 5) Use wear levelling if the application is supposed to write > frequently onto the Dataflash. > 6) Don't go 20 MHz... Slow down to 4 or 8 MHz > > Dataflash Read > ------------------ > 1) Each time you read a sector onto the Dataflash, do it two times on > 2 different buffers and then compare their content. > > The best filesystem for embedded sytems is a journaling fileystem. > Each time you make a write, you add a record to the log. > In case of Power Failure, you lose only the very last write and the > filesystem is safe. > > Hope this'll help > Enrico Migliore
Yes, wear levelling & power failure scenarios are not well handled with FAT16 and it is well handled in the JFS. Further, there is no much necessity to create files in runtime in embedded. Agreed w.r.t. embedded systems . Karthik Balaguru
Reply by heindekock September 8, 20092009-09-08
> >FAT filesystems are risky on embedded systems for the following >reasons: > >1) Unless you purchase a commercial product, the second copy of the >FAT is never used to back up if the first fails >2) FAT16 don't do WEAR LEVELLING, that means that after 10.000/50.000 >of write sessions your Dataflash may fail >3) Speaking of embedded systems: in many many cases, there's >absolutely no need to create new files at run time. >4) Power fail failure during write sessions may corrupt FAT and files > >Back then I was very excited running the FreeDOS filesystem and the >MINIX stdio library on a 16 bit M16C microcontroller... >Production volumes now are too big and I don't wanna risk...I save my >data at fixed flash addresses, use 32 CRC, and keep 2 copies of the >data. > > >Suggestions for you :-) > > >Dataflash Write >------------------ >1) A write must be followed by a read, to check if you wrote the >sector correctly >2) Poll the status register of the dataflash, and wait for the write >to be completed. Don't assume the >3) Use the extra 8 bytes of each sector to store the CRC (16 bit is >fine) >4) You may want to use ECC code correction. I remember correctly, 8 >bytes may correct up to 8 bit on a buffer of 256. >5) Use wear levelling if the application is supposed to write >frequently onto the Dataflash. >6) Don't go 20 MHz... Slow down to 4 or 8 MHz > >Dataflash Read >------------------ >1) Each time you read a sector onto the Dataflash, do it two times on >2 different buffers and then compare their content. > >The best filesystem for embedded sytems is a journaling fileystem. >Each time you make a write, you add a record to the log. >In case of Power Failure, you lose only the very last write and the >filesystem is safe. > >Hope this'll help >Enrico Migliore >
Thank you for the input The code is now available at http://code.google.com/p/small-ffs/downloads/list This little system changed a lot from its inception. Speed was of course an issue, especially since it originally rolled out on a standard 8051 12 clock cycle CPU with a 36 Meg crystal. This only runs at 3 MIPS so the data flash speed was not reached as I did not have a spi integrated in the 8051, all IOs clocked from code making effective speed very slow. The above code was ported onto the DK3300 dev kit from ST so its slightly better but still not fast and I didn&rsquo;t bother to use spi port again. What you mentioned is mostly done with the exception of a CRC check it just became to taxing on the system. I used the extra bytes but just to get a few more bytes in a page, it bit my bad when one production run came with the D type flash in binary address mode. This is an irreversible setting so I had to quickly build in a check for that setting, luckily the ram buffers are allocated dynamically after the page size is determined to handle a variety of data flash sizes (I mostly use 16Mbit/2Mbyte with 512/528 bytes per page). The application that first ran the system had about 40 files, hardly ever bigger than 20K and exclusively text, I mixed the use of fixed location memory with normal fat like structure. A few setup type files never changed, and the rest constantly changed. In the traditional fat like scheme every time I wanted to remove data from the front of the file, I would open the file read out the spent data, write the remaining data to a new file, remove original and rename the new to the old. Slow, risky and a huge source of wear. It irritated me so much that I designed this system with the ability to just shift the file start page/position in the fat so the file can shrink from the front without rewriting all the content. I also tagged the pages with file number, prev page, next page and an index. This allows an integrity check on the chain of pages which I do at startup or at user request to look for any lost/unlinked pages. In the demo above I write 100 files of 10K bytes (1Meg total used), then rewrite them, then append another 5K (1.5Meg total used) then clip, as I call it, 1k from the front (1.4K total used) then rename them all and lastly delete them all. I&rsquo;m comfortable with the current level of performance for my needs. However, the very rapidly changing data like usage meters I store raw in the flash for both speed and wear purposes. In the error I experienced, it looked liked some other process messed up my FAT buffer. I was quite impressed with the recovery routine that picked up all the loose pages and reconstructed the FAT. The fat backup becomes the fat in this case and any loose pages are removed. But to test that properly I will have to step into that section of code and disrupt the fat update process to simulate a failure. I just haven&rsquo;t felt compelled to do that yet. Hopefully I get some energetic contributors that feel like digging into that part of the code or maybe simulate the flash with another small micro or even a PC, then we can drop chars and pages as we please to see how robust the code is. thanks again for the input. --------------------------------------- This message was sent using the comp.arch.embedded web interface on http://www.EmbeddedRelated.com
Reply by Enrico September 8, 20092009-09-08
Hi,

> I wrote a flash file system for an 8051 project using a 2MB dataflash ove=
r
> the last 3 years.
Ok
> I tried to stay as close to stdio from dos (fopen, etc) > as possible.
fopen() and his brothers belong to the C standard I/O library (<stdio.h>) and not to the filesystem. Filesystems export only: open (), close (), read (), write (), lseek (), et cetera Filesystems compile and run perfectly without the standard library code.
>I had to shape and change it a few times as hind sight makes > us cleverer. I needed some special functionality like shrinking the file > from the front like a FIFO that caused me to veer of a bit (programmer=92=
s
> creative license). =A0It also has the ability to handle binary files. I > stored and retrieved bitmaps successfully. > The version I call final has been in the field for a while now and seem > stable. Here and there a piece of the fat disappears with disastrous > effect. I wrote recovery code but of course I never tested it, after stre=
ss
> test I was happy. All in all over 3K pieces of hardware run it now so the=
2
> or3 problems I had don=92t worry me much. > I would like to put this code somewhere where we can all use it and maybe > contribute to it. I=92ll need some help with a repository and copyright > stuff. I would like it to be as free as possible and see if any fs expert=
s
> out there would like to comment or improve on it. > If you have experience with this kind of stuff and can help please do, if > you don=92t, I would like to request that we keep the thread as clean as > possible, DONT CLUTTER IT WITH NONSENS! Let=92s see how efficiently we ca=
n
> get this out there and usable for everyone.
Years ago, I extracted the FAT16 filesystem from Pat Villani's FreeDOS project and made it architecture independent. The only function architecture dependent were: media_init() media_read () /* read a sector */ media_write () /* write a sector */ I also extracted the MINIX standard I/O library and compiled it over the FAT16 filesystem. The code was debugged on Visual C 6.0. As a media, I used a usb disk plugged in the PC. The code is in production on hundreds of embedded devices (M16C+ dataflash). All works nice. Never had problems. It was a very important C exercise... That I won't ever repeat again in my life. FAT filesystems are risky on embedded systems for the following reasons: 1) Unless you purchase a commercial product, the second copy of the FAT is never used to back up if the first fails 2) FAT16 don't do WEAR LEVELLING, that means that after 10.000/50.000 of write sessions your Dataflash may fail 3) Speaking of embedded systems: in many many cases, there's absolutely no need to create new files at run time. 4) Power fail failure during write sessions may corrupt FAT and files Back then I was very excited running the FreeDOS filesystem and the MINIX stdio library on a 16 bit M16C microcontroller... Production volumes now are too big and I don't wanna risk...I save my data at fixed flash addresses, use 32 CRC, and keep 2 copies of the data. Suggestions for you :-) Dataflash Write ------------------ 1) A write must be followed by a read, to check if you wrote the sector correctly 2) Poll the status register of the dataflash, and wait for the write to be completed. Don't assume the 3) Use the extra 8 bytes of each sector to store the CRC (16 bit is fine) 4) You may want to use ECC code correction. I remember correctly, 8 bytes may correct up to 8 bit on a buffer of 256. 5) Use wear levelling if the application is supposed to write frequently onto the Dataflash. 6) Don't go 20 MHz... Slow down to 4 or 8 MHz Dataflash Read ------------------ 1) Each time you read a sector onto the Dataflash, do it two times on 2 different buffers and then compare their content. The best filesystem for embedded sytems is a journaling fileystem. Each time you make a write, you add a record to the log. In case of Power Failure, you lose only the very last write and the filesystem is safe. Hope this'll help Enrico Migliore
Reply by heindekock September 8, 20092009-09-08
>On Sep 8, 10:21=A0am, bigbrownbeastie ><bigbrownbeastiebigbrownf...@googlemail.com> wrote: >> >The version I call final has been in the field for a while now and
seem
>> >stable. Here and there a piece of the fat disappears with disastrous >> >effect. I wrote recovery code but of course I never tested it, after
str=
>ess >> >test I was happy. All in all over 3K pieces of hardware run it now so
th=
>e 2 >> >or3 problems I had don=92t worry me much. >> >> hahaha, DO NOT WANT ! > >0.1% chance of failure, is that suitable for IEC61508 SIL -3 ? >
Try to keep in mind that it could be hardware failure! --------------------------------------- This message was sent using the comp.arch.embedded web interface on http://www.EmbeddedRelated.com