[TUT][C] Simple FAT and SD tutorial

37 posts / 0 new
Last post
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After coming across quite many SD tutorials that are based on Petit FS or FatFS and guide the user through modifying these libraries, I thought it would be interesting to make one that would really start from the fundamentals of reading FAT file systems, so you'd actually understand all of the code, not just the pins you connected to your MCU.

The first part of this effort is now available, I'm planning a similar 3-5 part layout as my previous V-USB tutorial I posted here a while ago:

http://codeandlife.com/2012/04/02/simple-fat-and-sd-tutorial-part-1/

The second part covers reading longer files using the file allocation table, and converts everything into a compact and portable library:

http://codeandlife.com/2012/04/07/simple-fat-and-sd-tutorial-part-2/

The third part introduces the hardware built around ATmega88 and communicating with the SD card using SPI.

http://codeandlife.com/2012/04/25/simple-fat-and-sd-tutorial-part-3/

The last part combines the information in parts 2 and 3 to create a simple FAT16 library for reading any 1-2 GB card.

http://codeandlife.com/2012/04/27/simple-fat-and-sd-tutorial-part-4/

I might also do additional parts covering FAT32, SDHC or file writing, depending on reader interest. All and any feedback is appreciated, if you have some specific things you'd like me to cover in the future, please let me know!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Excellent communications skills and very well organised. Look forward to parts 2 and 3.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks! I do like writing tutorials a lot, it's a great way to organize my own thoughts on a given subject.

The part 2 has been published, ending up with a FAT16 library that should be easily ported to AVR (doing that in part 3). I ended up with a memory footprint of 51 bytes instead of the 44 in Petit FatFS. On the other hand, I prefer my version for code readability. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jokkebk wrote:
The part 2 has been published, [...]
FYI, the updated project ZIP file that you reference in part 2 seems to be missing from your website.

Thank you for writing these tutorials. I haven't had a chance yet to thoroughly read them and put them to proper use with some hardware, but playing around with SD cards and the FAT filesystem is on my AVR MCU "to do" list. Your tutorials appear to be a great guide for when I do finally get around to trying that. Nice work!

Regards,
Bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meteor wrote:
jokkebk wrote:
The part 2 has been published, [...]
FYI, the updated project ZIP file that you reference in part 2 seems to be missing from your website.

Whoops, fixed that. And thanks for the kind words!

I'll look in to the hardware part this weekend (I already succeeded in communicating with SD card using bus pirate and setting up ATtiny as a SPI slave so I'm halfway there), so the part 3 might even get finished this Sunday, or at least in the beginning of next week.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Part 3 is now available. I also suggested readers to post questions to this forum instead of just to my blog, that way there's more audience for both the questions and answers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

just about all what I need..

thanks dude
very appreciate that...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Awesome tutorial!

Quote:
I might also do additional parts covering FAT32, SDHC or file writing, depending on reader interest
highly interested!
Currently I am wrapping it into a C++ singleton, but I still have to write the writing routines...

EDIT: I totally forgot to say that I was able to write too a long time ago with the help of this and the Bus Pirate tutorial.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a great tutorial ! I agree, most of the resources available for interfacing SD cards are just instructions to get the FatFS libraries working.
Thanks a lot for this!

(I also love the way the tut is presented)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is now a fourth part at

http://codeandlife.com/2012/04/27/simple-fat-and-sd-tutorial-part-4/

however it is still sector based.

Does anyone know of something a litle higher level?

Specifically, I want to

CheckFileExists
OpenFile
fgets() // read text lines, each lind ending with \n
CloseFil

I also want to be able to write text files a line at a time ....

all of the standard fopen(), fgetc() fgets(), fprintf(), fclose() stuff

If you can help, please reply to my thread at http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=125733

menawhile, I will continue to google

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jamawg wrote:
There is now a fourth part at

http://codeandlife.com/2012/04/27/simple-fat-and-sd-tutorial-part-4/

however it is still sector based.

Does anyone know of something a litle higher level?

Specifically, I want to

CheckFileExists
OpenFile
fgets() // read text lines, each lind ending with \n
CloseFil

Short answer also here, in hopes that it will help other readers of the tutorial...

The reading part of your question should be trivial to implement. The fat16_open_file() returns error value if file is not found, so CheckFileExists is almost 1:1 covered (you can make a wrapper function if you don't mind calling the exact same function again after you've made sure that file exists). Of course it doesn't understand complete paths (say CheckFileExists("some_dir/subdir/somefile.txt"), but writing a recursive function to handle those is quite easy.

Separate fopen() and fclose() are not needed because your AVR has no concept of file handles unless you implement them yourself. Only reason to do that would be so that you can have multiple files open - in that case you're right and some refactoring of the code would be needed (make a file handle structure to store sector and offset of open file, and create reading function that uses the data in handle instead of global library variables).

fgets() is basically reading the file byte at a time, and stopping when you get to the end or encounter '\n':

char line[20];
int len = 0;

while(len<20 && fat16_state.file_left) {
  if(fat16_read_file(1)) {
    line[len++] = *fat16_buffer;
    if(*fat16_buffer == '\n')
      break;
  } else break; // EOF or some other error
}

if(len >= 20) // too long line
  deal_with_error();
else
  line[len] = NULL; // terminate string

Quite easy, right? Note that most AVRs don't have enough memory to read long lines of text at one go. Due to memory limitations, higher level file functions are usually not feasible.

I might write an additional tutorial on writing files this month. :)

Joonas

Pages