I'm doing a project on PIC, which needs a large amount of memory to store data. I want to use an SD card as the memory storage element. I don't want any type of file system.

I googled the interfacing of SD cards with microcontrollers. I found that all of them are using some kind of file system. Is it possible to interface an SD card without any file system, like a serial EEPROM?

I did this years ago on a project using MMC mode and it's certainly possible although a lot easier if you have 512 bytes of RAM free to hold a sector. Did you have that much available?
–
PeterJJun 7 '14 at 7:36

Yeah you can, but take into account that SD cards are flash devices, so any data you write will trigger a block write. Repeated small write will wear out a block incredibly fast. Also, you will probably have very long pauses between writes as a block read-modify-write can take up to 100ms in a crappy SD card, and still something like a couple ms in a good card. And this amount of time is variable; depends on garbage collection and such.
–
user36129Jun 7 '14 at 7:41

1

It's too long ago for me to remember reliably but I think you might get stuck with having to program an entire page at once, unlike some other FLASH devices where you can erase a page and then keep adding bytes.
–
PeterJJun 7 '14 at 7:45

1

@user36129: That seems very odd. If one starts with an empty creating and deleting 8 files would entail 16 writes to the first block of directory space. Doing the process again would entail another 16. Perhaps someone came up with the brilliant idea of doing wear leveling only for the first dozen or so sectors of the drive?
–
supercatOct 10 '14 at 17:05

3 Answers
3

You didn't mention which PIC you are using, but assuming it is one of the smaller ones such as the PIC16 then with it's limited RAM (99% of PIC16's have no more than 1K of RAM) it would be impossible to implement even a FAT16 file system since multiple 512 byte buffers are needed. (Microchip has a useful library to implement a FAT16/FAT32 file system but it is only applicable to the PIC18, PIC24, dsPIC33 and PIC32.)

You did mention that due to limited RAM, you would like to just write or read a byte at a time. Although, as others have stated, an SD card is typically broken up into 512 byte blocks, you don't need to use all of the bytes. Worse case, you could store just one byte per block and waste the other 511. This seems preposterous, but due to the enormous size of the SD cards available today it would actually work. If you have an 8GB card, than means there are 16M blocks, which means you can store 16 MB of data in this way.

However, it is going to be very slow, something like 10 ms or more per block of 512 bytes, because you are going to have to issue a command to erase each block before it is written. (In the unlikely case you stored just one byte per block, as mentioned before, then this means it would take 10 ms to write that one byte.)

You didn't mention the amount of data that is contained in one of your log entries, but it would be much much better if you could buffer up one entry (say 25 bytes or whatever that is) and write that to a block. So each block becomes a log entry. Because the time to write the bytes is once again dominated by the time it takes to erase the block, writing out an entry log entry will be as fast as writing a single byte.

Since you are essentially using this as extended memory, you don't have remove the card and read it in a PC (which would require using special software to dump out the raw blocks). Instead, since you already have the read block routine in your code anyway, and assuming you have a UART, I would dump the log data out in a serial fashion to a PC; you could use a FTDI UART-to-USB bridge and the data would appear on your PC as a COM port.

@tcrosely are you sure about 10ms or more per byte? Have you really seen it or is it just a hunch? on SDSC as well as SDXC cards, the BLOCK LENGTH is 512 bytes. Also, how would a file system change anything? if you give that one byte to filesystem then also the same process happens.
–
rjha94Oct 8 '14 at 19:52

@rjha94 Thanks, that was a typo -- should have been 10 ms per block. Corrected.
–
tcrosleyOct 8 '14 at 22:24

counter point, by special software, all that someone would need to read it is dd piped into grep or cut. a few simple lines of script and basic linux/bsd tools. Hell, I'm sure even windows has a tool to read raw devices that can be accessed through a bat file
–
PasserbyOct 8 '14 at 23:15

@Passerby I was under the impression the OP was trying to use the SD card as simply an extension of memory. He wouldn't be unmounting it and using it on another computer. He mentioned PIC, so he definitely isn't using Linux.
–
tcrosleyOct 9 '14 at 0:01

Yes, any file system will be calling lower level functions that could be named something like writeBlock and readBlock, which are the ones that you'd be calling directly. Since you are using a microcontroller, you'll most like interface to the card in SPI mode, which is perfectly fine for logging applications - not so much for faster applications like video recording.

Your block size will be typically 512 bytes, so that's the minimum chunk of data that you'll be writing/reading in one go. Single byte transactions are not supported (there is no command you can send to make such a thing happen).

Having said that, you might want to think about how you're going to get the data out of the card, since there is no file system. This means that when you plug it into your computer (if that's how you're getting the data out) running a mainstream OS, there won't be any files that you can just drag and drop onto your desktop. You'll have to write a special application that accesses the SD card's raw data.

For that simple reason I would suggest to use a file system, such as FAT32, which is very common in logging applications and you'll find several ready-to-use libraries on the net.

An alternative approach would be to require that the card contain a great big file which uses all of the space that the embedded system should be using. That would greatly reduce the amount of "file-system" logic needed on the embedded device.
–
supercatOct 8 '14 at 23:25

@supercat Yes, I've actually done that, if only to avoid having an inconsistent filesystem if the card is ejected while recording.
–
apalopohapaOct 9 '14 at 22:22

If a card is ejected unexpectedly, there may be nothing you can do, since cards will often, as part of their wear-leveling algorithms, move blocks around of data which have not been written for awhile. In theory, they should do this in such a fashion that even if power is lost during the process no corruption would result. Unfortunately, it's tough to provide such assurances given the restrictions on right sequencing posed by many NAND flash chips.
–
supercatOct 9 '14 at 22:52

I have just read the SD card physical layer specification and experimented with reading and writing blocks using AVR, I find the previous answers discouraging so I will put my own views

(1) it may be easier to read/write blocks for logger applications that just append data. sure there are many FAT libraries available on net but it just takes effort to wire a FAT library. (atleast if you want to understand what you are doing). For appending logs you only need to track the last block number.

(2) The block writes won't be slower than FatFS writes. Any FatFS library would finally use the same commands. make a unsigned char[512] buffer and write it to a block.

(3) with 4GB cards, you will have approx. 7* 10^6 blocks and that should give you 81 days of logging with every second logging w/o any buffering. The number should improve with buffering.

I would highly recommend writing data in a format which is FAT compatible even if that simply means writing a single directory entry for a file which starts at the first cluster, and a FAT which links each cluster to the one after it, if one exists. That will prevent data corruption if the SD card is inserted into a computer, and will also allow the computer to read the data on the SD card without having to use sector-level access.
–
supercatOct 8 '14 at 20:13