6

I'm implementing FAT16 on SD card with Atmega328.

I often need to change just one or two bytes in the sector (512B region).

I know how Flash works and that it needs to overwrite entire sector at once, but I was wondering if there maybe was some special command that would make the card itself handle it?

The point is, the atmega has only 2k RAM, and allocating 512 just for a read-modify-write SD card buffer is very unfavorable. Is there no other way?

(PS. AFAIK the atmega can't natively have external ram)

MightyPork
  • 18,270
  • 10
  • 79
  • 133
  • 1
    Yes, this is a PITA, but I have not found a way round it:( – Martin James Jun 10 '15 at 09:34
  • One hack comes to a mind: Write old sector data to unused sector on SD card, and then write it back again but this time replace necessary bytes with new data. It's not fast or pretty, but should work if you can find reasonable way to find unused sector. – user694733 Jun 10 '15 at 14:15
  • @user694733 That could be nice if I could write while reading, but afaik the SD/SPI protocol can't do that. Or I misunderstood? – MightyPork Jun 10 '15 at 14:19
  • @user694733: How would that safe the 512 byte buffer? – too honest for this site Jun 10 '15 at 14:21
  • @MightyPork You don't have to do it at the same time in one go. Have a small buffer (64 bytes for example), read first block, write first block, read second block... That is, if SD protocol allows partial writes. I cannot remember if it did. – user694733 Jun 10 '15 at 14:21
  • but when you write to a sector, it first erases the entire sector and then writes the new data. That's how FLASH works. – MightyPork Jun 10 '15 at 14:22
  • Porky: If you do FAT, you already have a buffer for the data. So why not use this same buffer? I suspect your "one or two bytes" are mostly for FAT manipulation? The small AVRs are actually not so much designed to implement such things. Using a bigger MCU is not an option? – too honest for this site Jun 10 '15 at 14:24
  • @user694733: Forget about this. There is some optional stuff related to this, but it need not work and I would definitively not rely on this - what if the card-controller firmware decides to omit it? Also, this is not necesarily supported for SPI mode (which is used here very likely). – too honest for this site Jun 10 '15 at 14:25
  • @Olaf I've implemented the FAT with normal gcc, only now I'm adding the hardware I/O functionality. There's no buffer in the actual FAT (except a struct for the boot sector and the file handle). (Bigger µC is of course a good idea, but I have some eBay Arduinos that'd be shame not to use :) – MightyPork Jun 10 '15 at 14:27
  • Anyways I got it working, there's not much RAM left but it reads files all right, so I guess that'll have to do. – MightyPork Jun 10 '15 at 14:28
  • Arduinos are overestimated. As you have to add the SD-Card anyway, why not make your own PCB which already inclused that. Arduions have not that much additional stuff on the board. Rule of thumb: first thnik what you want to do, then desing (or by) the appropriate hardware:-) You would not use a Smart for F1 racing. – too honest for this site Jun 10 '15 at 14:30
  • @Olaf I did a quick glance at specs and it indeed seems that it's possible that not all cards support partial writes. CSD register seems to have bit for that, but later 2.0 version this bit is always supposed to be zero? Anyway, it was hacky solution to begin with. – user694733 Jun 10 '15 at 14:32
  • @user694733: If that is not SD, but µSD, not even SPI-support is guaranteed. Although I would actually rely on _that_ (not seen a µSDC without). – too honest for this site Jun 10 '15 at 14:34
  • Simple block-writes without FS might be an option. Would require some software on an PC, but that could be written in a HLL easily. – too honest for this site Jun 10 '15 at 14:35
  • @Olaf those are Arduino Nano's for $2, it's really just the Atmega with an USB-UART chip. – MightyPork Jun 10 '15 at 14:44
  • 1
    You could use two of them: one for whateveryoudo, the other for FAT. Interconnect through UART/i2c or 2nd SPI (whatever is available). Or use a proper MCU:-P – too honest for this site Jun 10 '15 at 14:46
  • Yeah that could work :D Really hacky but yea., could be good use for one of those without the USB chip – MightyPork Jun 10 '15 at 14:47
  • I would not call that hacky. It is actually just like PC and NAS: one cares about data manipulation, the other about atorage, filesystem, etc. However, I made that an answer; if you like it ... . – too honest for this site Jun 10 '15 at 15:16

2 Answers2

1

ELM Petit FAT File System Module claims:

It can be incorporated into the tiny microcontrollers with limited memory even if the RAM size is less than sector size.

In fact:

  • Very small RAM consumption (44 bytes work area + certain stack).

It is open source; so you might take a look at how it does that (or just use it as-is).

The write function does have some significant restrictions, such as while it can modify a file, it cannot create or change the size of one - which is probably the compromise necessary to avoid sector buffers.

There is a full featured version of ELM FatFS, but that requires significantly more code and RAM space. The page also has links to the FAT32 specification, and some technical notes on how SD cards work which might be useful.

EDIT:

In fact this is not particularly helpful. Petit FAT's claim refers only to the filesystem layer itself, it does not include any hardware specific device driver, and for SD/MMC there is no getting away from the 512 byte read-modify-write cycle.

Although the AVR may not support memory-mapped external memory, one could use an external serial memory device such as a Cypress FRAM or nvSRAM to store the sector data; although being non-volatile, it may remove the need for SD altogether unless large removable media is specifically required.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • I'm reading through the source, but it's completely obfuscated :( – MightyPork Jun 10 '15 at 09:10
  • from what I see, it appears PetitFAT is only the FAT layer, it does not actually deal with the SD (flash) I/O. The file that is supposed to handle it is just a skeleton for you to fill in. – MightyPork Jun 10 '15 at 09:16
  • 1
    All the FAT file systems I've seen are like that. The lowest layer, the one that inits the device and reads/writes 512-byte sectors, is device/environment-specific and must be supplied by the developer. It's obviously unreasonable to attempt to support a huge array of devices with polling/interrupt/DMA drivers for each. – Martin James Jun 10 '15 at 09:32
  • @MightyPork : Yes, necessarily so; the author does not know what hardware you will run it on. Looking at it however; you are right that it is not SD card specific and that writing to an SD card may indeed require additional buffering over and above the filesystem itself. I have only ever used it in read-only mode, and did not implement the `disk_writep()` interface. Ultimately I think the answer to your question is "no" - See similar question on http://www.avrfreaks.net/forum/sdcard-single-byte-read-write-operation – Clifford Jun 10 '15 at 11:08
  • For what its worth, I can vouch for the small ROM footprint of PetitFAT. I've used it for a bootloader that fit in a little under 8kB flash on an stm32. – Brian McFarland Jun 10 '15 at 13:19
  • I have the FAT16 already fully implemented, I was really just wondering about the SD card buffer. – MightyPork Jun 10 '15 at 13:38
1

YOu cannot changge just few bytes in a sector without reading/writing the the whole 512 bytes. So you actually do need the RAM for buffer.

However, there are ways to pre-alloc the filespace or update the FAT every some writes only. That will even conserve write cycles, but might result in data loss if power down before the FAT has been updated (however, it might not corrupt the filesystem if implemented properly).

As you state that these are cheap ArduinoNano (clones - supposedly), you could just use two of them interconnected with UART/SPI/i2C - whatever is available, even 8 bit bit-bang would work.

One does whateveryouwanttodo and the other is just for SD-card/FAT processing.

Reminds me of the Comodore 64 and its floppy-disc drive 1541 which also included a small CPU (well "MCU", but not single chip).

too honest for this site
  • 12,050
  • 4
  • 30
  • 52