11 years, 1 month ago.

Mass Storage with internal flash memory

Hi,

I am working on a project where I need to have a config file (in which I can change the parameters). I want to access this file from mass storage i.e. in a way I can open the config file while the mbed is connected to windows to change the parameters and save it. The mbed code should be able to read the parameters from the config file.

The issue is that I don't want to use any external flash memory/SD card/the 2MB memory connected on the mbed. So, I would have to use the internal flash memory (512 K for LPC1768 and 32 K for 11U24) to save this config file. I know we can reserve some space (a sector) in the internal flash memory to save the data. But how to mount that section as a mass storage? Is it possible to do it?

1 Answer

11 years, 1 month ago.

The 11u24 has EEPROM which might be more suitable.

Regardless of that, you can use http://mbed.org/users/Sissors/code/USBFileSystem/ to both read a file locally and mount it via the LPCs USB pins (so not the USB connector on your board).

For writing the flash memory there is the IAP library: http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/. Those two combined should be able to give you what I think you want.

Do take into account file systems are inefficient for a few bytes. If you want it available as mass-storage device you have no choice, but you could also consider just sending the data via a serial connection and then writing it to the flash memory.

Accepted Answer

Thanks for the help.

Yes, any of EEPROM/flash should be fine as long as I am able to mount them as mass storage. In the first URL you shared, the example code mounts RAM as mass storage (the code is for 1768 and worked for that but it is not implemented for 11u24). Can you please guide/point me to any code which illustrates on how to mount EEPROM/Flash as mass storage in the similar way it is done for RAM?

Sorry, if the question looks naive. I am new this.

posted by Tushar Chugh 17 Oct 2013

I am fairly sure sure no one has done it before using an mbed.

The first URL just links to library which can handle the filesystem and USB part. There is indeed a RAM disk example (I think the 11u24 doesn't have enough RAM to implement it). So for flash you will have to write it yourself. The USBFileSystem library needs you to implement a few functions (see its wiki). Using the iap library you can do that.

posted by Erik - 17 Oct 2013

Ok. Thanks a ton. Will try to integrate both these libraries get the things working for Flash.

posted by Tushar Chugh 18 Oct 2013

In IAP libraries, the function that is implemented is to write data to flash from RAM (the same is explained in the data sheet). Any idea on how to write the data stored in a variable(rather than copying from RAM) to write to flash memory?

posted by Tushar Chugh 19 Oct 2013

Also in the USBFileSystem written by you, can you tell me the memory address for RAM where in.txt and out.txt are being saved. By this I can read data from RAM and can save it to flash and that might be able to solve half of my problem. In addition to this, is http://mbed.org/users/AdamGreen/code/FlashFileSystem/ of any relevance?

posted by Tushar Chugh 19 Oct 2013

A variable == data in RAM. The FileSystem requires you to write/read char arrays. The IAP uses the same. Only difference is that IAP uses chars, and FileSystem uses uint8_t. I don't know if the compiler automatically casts one to the other, otherwise you need to manually cast them (using (char*) and (uint8_t*) to cast them to char pointers/uint8_t pointers).

posted by Erik - 19 Oct 2013

Looks like in that links he manually, read-only appends a filesystem he made on his PC on the mbed flash memory. But he cannot write to it, and it also isn't really a good point to start from and make it able to write to it.

Regarding the address of in and out.txt, I have no idea. Thats the beauty of it: You don't need to know that, the filesystem library handles it for you.

What you need to do is implement the following functions (see the USBFileSystem wiki, it is the same also as the normal FileSystem, minus some dashes):

virtual int disk_initialize() { return 0; }   
virtual int _disk_status() { return 0; }
virtual int disk_read(uint8_t * buffer, uint64_t sector) { return 0;}
virtual int _disk_write(const uint8_t * buffer, uint64_t sector) = 0;
virtual int disk_sync() { return 0; }
virtual uint64_t disk_sectors() = 0;

Some of them you may even ignore, but read, write and sectors you have to implement.

The main problem is that you can only erase flash memory in blocks of 32kB, while a sector of the filesystem is 512B.

posted by Erik - 19 Oct 2013

I tried integrating the two by modifying your USBFileSystem example but it is not working for me. I am able to see the mount but not able to access it. I think I am not doing it in the correct way that it should be done. Can you please help in identifying the issues? I have uploaded the code on github at https://github.com/techie2sh/CodeArena . Let me know if you want me to upload it at some other location.

posted by Tushar Chugh 20 Oct 2013

You made the flash sector equal to the sector of the file system, so if it wants to write data in sector 1, it overwrites your own program.

Frankly I think it is better to use another method. This is possible, but it will be very hard to implement.

posted by Erik - 20 Oct 2013

Thanks a ton again! Any guidance on how differently should I implement it? Sorry, I am working on this on the first time and I am feeling lost here. With online compiler, I am just following hit and trial.

posted by Tushar Chugh 20 Oct 2013

What are the exact requirements? Does it have to be on the flash of the LPC, and does it have to be via a MSD thing?

posted by Erik - 20 Oct 2013

I want to save a config (text) file in inbuilt flash memory of LPC. For example in config file I can specify A corresponds to 1 and B corresponds to 2. Essentially, instead of changing the code user can just plug in mbed as a mass storage device and can open the text file to change the configuration. Like in this case user can open the file to change A -> 2 and B-> 1. Since the memory requirements are on the lower side, hence don't want to use any external memory (even 2MB which comes with mbed). I am fine with any mechanism to achieve this. Thanks :)

posted by Tushar Chugh 20 Oct 2013

Well then there aren't too many options :P.

What I would do: First get it to work with RAMDisk. That is the straightforward way and at least gives some experience with this stuff. Step 2: just in an empty program make sure you can read and write 512 bytes using IAP.

And finally step 3: Get the RAMDisk library, and figure out how the data works that is loaded in the filesystem. When in doubt, just try some stuff (been there, done that). Now keep the RAMDisk, however just check if the sector number with your file in it is requested, then redirect it to your IAP code. So you only have to write a single sector to your flash, and everything else you use from RAMDisk.

When that works, delete the code that initially copies everything from the flash to the RAM (thats done in the initializer using memcopy, what you see in the ram disk file is stored on flash).

posted by Erik - 20 Oct 2013

Nice suggestion. Let me try it out. Thanks! Just to re-iterate what you said to see if I am getting it correctly here is what you mean:

I should keep the same framework as done in RAMDisk library i.e. RAM will still act as a mass storage. And when the user writes to the file (it will hit the _disk_write function), then I can take the data (buffer variable defined as a param in _disk_write function) and write only a single sector and save it in flash memory.

Am I getting it correct?

posted by Tushar Chugh 20 Oct 2013

Yep, and obviously also read that sector again from the flash memory

posted by Erik - 20 Oct 2013

Finally, it worked for me!! Thanks for the help and I really appreciate your patience.

I was working with your RAMDisk code and found that I am not able to save more than 30 characters in the file (way less if you use new line character). Is there any limitation which you know about? Can you please verify about this?

posted by Tushar Chugh 21 Oct 2013

Well for sure it is limitted on one sector per file: 512 bytes. But that should work up to roughly 512 characters. Although I never tested it for long stuff.

posted by Erik - 21 Oct 2013

Yeah, ideally it should work for 512 characters but at my end it is not working for more than 30 characters. Would it be possible for you to replicate the issue at your end?

posted by Tushar Chugh 21 Oct 2013

When you use a new line character it will stop printing (at least I assume you are using that one).

It can definately do more than 512 characters, at least for me it works, as long as I do it the first time. After that it is limitted on the number of characters I used the first time for some reason. It seems as if the file system is buffering too much somehow, but quite frankly not a clue what or why.

That will also be a problem btw when you write one sector to flash: The length is defined in another sector. I do get back again to that it really might be a better idea to get other demands, since this isn't exactly basic, and also soon going over my head.

Why not just use the localfilesystem? That is meant to be used for stuff like this. To put it frankly: I am not feeling like currently trying to find out why this thing is having some weird behavior, and since no-one pays me it is still a hobby ;)

Edit: Just got an idea what it might be, if the mbed file system library is buffering a bit more than I want it to do it could happen. But my day is over, and I don't know when I will get to looking at it. However if that is the case, and it looks like it, then eveyrthing gets written fine to disk, including longer things. And if you would still want to do it this way (localfilesystem is a way better idea), you would need to enter a hardcoded fixed length anyway for your file.

Edit2: And with short look I have no clue how I could prevent it from doing that buffering. Problem is I think it does not read the file information sector again after the USB has written to it, since it doesn't realise the USB has written to it. And I don't know if you can force it to do that.

posted by Erik - 21 Oct 2013

Thanks for having a look at it :)

512 characters limit is fine for me. But somehow I am not able to save more than 30 characters in the file. By saving what I mean is: a. Windows is able to save the contents in the file. So you would be able to see the content when it is mounted. b. But if you see the content what mbed has saved. It would be only 30 characters at max. This also happens when I read the data from flash and write to the file (changed the initialize method of your code). Note: I am not using any new line or special character. Example sequence is 0000000000111111111122222222223333333333. In this case entire 3's would be lost and only first 30 characters will come.

posted by Tushar Chugh 22 Oct 2013

and I don't want to use external memory. So, though LocalFileSytem is better but out of picture for my use case. :(

posted by Tushar Chugh 22 Oct 2013

So which program are you using to test what it stores?

And what is your use case that LFS isn't an option?

posted by Erik - 22 Oct 2013

For people reading this later: I got a solution for the buffer issue and should be implemented in the coming days, so USBFileSystem shouldn't be affected by that anymore.

posted by Erik - 22 Oct 2013