Leider kann ich die Module pC/FAT sowie pC/FFS nicht frei zugänglich machen. Jedoch kann ich hier eine vereinfachte Form der MMC- und SD-Card Ports auf die SPI-Schnittstelle für diverser Controller bereit stellen.
Mittels dieser Ports kann man ein anderes FileSystem auf diese Schnittstelle, und damit auf MMC- und SD-Cards zugreifen lassen. Oder, wie als Test durch mich erfolgt, ein in Software realisierter MMC/SD-to-USB Adapter programmiert werden. Dieser meldet sich dann als MassStorage (removable media) USB-Device am PC und man hat Zugriff auf die MMC- und SD-Cards wie bei einem prof. Adapter (nur etwas langsamer, da SPI-mode und Softwarerealisierung).
Einschränkungen der vereinfachten MMC/SD-Ports:
- kein Interrupt- oder DMA-Mode
- keine ausführlichen Media-Infos
- kein Read / Write im CallBack Mode
- kein direkter RTOS-Support
(with MMCplus/HD-MMC/M-Bridge/SDHC/SDXC support)
Bei einer Portierung auf weitere Controller müssen neben der SPI-Speed Adaption nur einige Parameter der Hardware bekannt und entsprechend eingerichtet werden. Dazu gehören die verwendeten PIO-Pin's für WP (WriteProtect), CD (CardDetect) sowie die Einstellungen für MOSI, MISO, SCLK und /SS. Desweiteren muß der passende SPI-mode 3 eingestellt werden.
zu verwendender SPI-Mode des Controllers (Masters)
Nachfolgendes Diagramm zeigt den SPI-Mode, der für die Kommunikation mit MMC- und SD-Karten im SPI-Mode benötigt wird:
Zum Thema Geschwindigkeit
In der nachfolgenden Tabelle sind alle wichtigen Parameter der mir vorliegenden MMC/MMCplus/M-Bridge/SD/SDHC- Karten als Gegenüberstellung aufgeführt. Diese veranschaulicht recht gut, daß die SPI-Geschwindigkeit nur indirekt/relativ mit den Performanceangaben der Hersteller für MMC/SD-Modes im Zusammenhang bei SPI-Mode steht.
Dabei sind die Angaben Nac und Nbs von besonderem Interesse.
- Nac = max. Zyklen zwischen Read_CMD und Daten
- Nbs = max. Zyklen zwischen Write_CMD+Daten und End-of-Busy
Diese Angaben schwanken zwischen den verschiedenen Karten/Herstellern teils sehr stark. Sie geben eine Auskunft darüber, wie schnell der interne Speicher wirklich gelesen / geschrieben werden kann. ABER ! - auch diese Werte stellen den jeweiligen absoluten maximal-Wert dar. Das heißt aber auch wiederum, ein Speicher mit hohem Nbs kann trotzdem möglicherweise schneller mit einem Write-CMD fertig sein, als ein Speicher mit niedrigerem Nbs. Jedoch ergeben diese Angaben eine Tendenz über die vom jeweiligen Hersteller maximal möglichen/erwarteten/zulässigen Zyklen.
![]() | ||||||||
Card | MMC | MMC | MMC | MMC | MMC | MMCmicro | RS-MMC | MMCmobile |
MID-OID | 01-0000 | 01-0000 | 06-0000 | 02-0000 | 48-FFFF | 6F-0000 | 02-0000 | 2C-0000 |
maxclk | 20MHz | 20MHz | 20MHz | 20MHz | 20MHz | 20MHz | 20MHz | 20(26)MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 10.012 | 10.012 | 10.012 | 10.012 | 800.000 | 50.000 | 100.000 | 50.000 |
Nbs | 40.048 | 40.048 | 40.048 | 40.048 | 102.400.000 | 1.600.000 | 400.000 | 1.600.000 |
maxsectors | 31.424 | 62.720 | 125.440 | 250.880 | 2.007.040 | 1.003.520 | 62720 | 125.440 |
sectorsize | 512 | 512 | 512 | 512 | 512 | 512 | 512 | 512 |
![]() | ||||||||
Card | MMCmobile | MMCmobile | MMCmobile | MMCmobile | MMCplus | MMC | MMCplus | MMCplus |
MID-OID | 15-0000 | 00-0000 | 6F-0000 | 70-0000 | 1E-FFFF | 4B-4342 | 1E-FFFF | 19-5944 |
maxclk | 20MHz | 20MHz | 20(52)MHz | 20(52)MHz | 20(52)MHz | 20MHz | 20(52)MHz | 20(52)MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 15.012 | 30.000 | 10.000 | 200.012 | 50.000 | 35.000 | 200.000 | 200.012 |
Nbs | 1.921.536 | 480.000 | 1.280.000 | 25.601.536 | 1.600.000 | 1.120.000 | 6.400.000 | 25.601.536 |
maxsectors | 1.003.520 | 1.935.360 | 1.945.600 | 1.983.488 | 990.208 | 2.022.912 | 1.981.952 | 1.988.096 |
sectorsize | 512 | 512 | 1024 | 1024 | 512 | 512 | 1024 | 2048 |
![]() | ||||||||
Card | M-Bridge | SD | microSD | SD | SD | SD | miniSD | microSD |
MID-OID | 04-4450 | 01-4150 | 13-474B | 03-4453 | 02-4D54 | 03-4453 | 03-4453 | 1B-4D53 |
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 10.000 | 5.012 | 50.000 | 15.000 | 2.000 | 15.000 | 15.000 | 802.200 |
Nbs | 320.000 | 160.384 | 1.600.000 | 240.000 | 64.000 | 240.000 | 240.000 | 12.835.200 |
maxsectors | 1.990.656 | 29.120 | 249.344 | 246.016 | 1.000.448 | 1.984.000 | 1.984.000 | 1.995.776 |
sectorsize | 512 | 512 | 512 | 512 | 512 | 512 | 512 | 512 |
![]() | ||||||||
Card | SD | SD | SD | SD | microSD | microSD | SD | SD |
MID-OID | 1B-4D53 | 1B-4D53 | 1C-5653 | 29-4441 | 03-4453 | 1E-4241 | 02-4D54 | 01-4150 |
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 802.200 | 802.200 | 50.000 | 10.000 | 15.000 | 200.000 | 400.000 | 5.012 |
Nbs | 12.835.200 | 12.835.200 | 1.600.000 | 320.000 | 240.000 | 6.400.000 | 1.600.000 | 80.192 |
maxsectors | 1.995.776 | 1.995.776 | 1.999.872 | 1.964.032 | 1.985.024 | 1.948.672 | 1.927.168 | 1.967.616 |
sectorsize | 512 | 512 | 512 | 1024 | 1024 | 1024 | 1024 | 1024 |
![]() | ||||||||
Card | SD | SD | SD | SD | SD / SDHC | SDHC | SDHC | |
MID-OID | 02-4D54 | 1B-4D53 | 03-4453 | 19-5944 | 1C-5653 | 1B-4D53 | 03-4453 | |
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | |
Nac | 20.000 | 200.000 | 15.000 | 20.012 | 30.000 | 100.000 | 100.000 | 100.000 |
Nbs | 640.000 | 6.400.000 | 240.000 | 2.561.536 | 120.000 | 250.000 | 250.000 | 250.000 |
maxsectors | 1.921.024 | 1.981.440 | 1.931.264 | 1.956.352 | 1.967.616 | 7.870.464 | 7.811.072 | 7.959.552 |
sectorsize | 1024 | 1024 | 1024 | 2048 | 2048 | 512 | 512 | 512 |
![]() | ||||||||
Card | SDHC | SDHC | SDHC | SDHC | SDHC | SDHC | microSDHC | microSDHC |
MID-OID | 1B-4D53 | 03-6883 | 02-4D54 | 01-4150 | 03-4453 | 02-4D54 | 03-4453 | 27-4850 |
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 |
Nbs | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 |
maxsectors | 7.811.072 | 7.913.472 | 7.729.152 | 7.741.440 | 7.744.512 | 7.741.440 | 7.959.552 | 7.843.840 |
sectorsize | 512 | 512 | 512 | 512 | 512 | 512 | 512 | 512 |
![]() | ||||||||
Card | microSDHC | microSDHC | SDHC | SDHC | SDHC | SDHC | SDHC | SDHC |
MID-OID | 03-4453 | 1E-4241 | 1D-4441 | 27-4850 | 01-4150 | 1E-4241 | 19-5944 | 03-4453 |
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz | 25MHz |
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz | 8MHz |
Nac | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 | 100.000 |
Nbs | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 | 250.000 |
maxsectors | 15.954.944 | 15.661.056 | 15.332.352 | 15.720.448 | 31.645.696 | 31.387.648 | 31.776.768 | 31.116.288 |
sectorsize | 512 | 512 | 512 | 512 | 512 | 512 | 512 | 512 |
![]() | ||||||||
Card | microSDHC | SDHC | microSDHC | SDXC |
| |||
MID-OID | 03-4453 | 02-4D54 | 03-4453 | 1E-4241 | ||||
maxclk | 25MHz | 25MHz | 25MHz | 25MHz | ||||
usedclk* | 8MHz | 8MHz | 8MHz | 8MHz | ||||
Nac | 100.000 | 100.000 | 100.000 | 100.000 | ||||
Nbs | 250.000 | 250.000 | 250.000 | 500.000 | ||||
maxsectors | 31.116.288 | 63.700.992 | 62.333.952 | 124.925.952 | ||||
sectorsize | 512 | 512 | 512 | 512 | ||||
* Um vergleichbare Werte für Nac und Nbs zu erhalten, wurden die Parameter mittels des STR-H711 Boards
gelesen, da dort die maximal nutzbare CLK für SPI (bei MMC und SD Karten) 8MHz beträgt.
Nicht unterstützte Karten:
![]() | Die Transcend 4GB MMCplus lässt sich nicht in den SPI Idle-state versetzten (GO_IDLE_STATE) |
Ein Blick in eine Karte? Warum nicht ...
Was gibt's da so besonderes?
Der Schreibschutzschalter hat keine meldende Verbindung zum Innenleben. Das heißt, ignoriert der Adapter / der Host den Schalter, kann (wenn kein WriteProtect per Software gesetzt wurde) trotzdem geschrieben werden.
Warum unterschiedliche Angaben von maxsectors bei gleichem Brutto-Speicher ?
In eigendlich allen MMC- und SD-Karten wird Wear-Leveling betrieben, um den physikalischen Speicher gleichmäßig (max. Erase-/Schreibzyklen der Pages) zu belasten. Dabei werden die Nutzer- (logischen) Pages, z.B. mittels einer Art Tabelle, physikalischen Pages zugeordnet. Diese Verwaltung / Tabelle braucht natürlich auch eine Teil des Flash-Speichers (und darf selbst auch nicht ständig die selben phys. Pages verwenden).
Zum Wear-Leveling gibt es reichlich Patente weltweit und seit der Übernahme von M-Systems durch SanDisk ist liegen diese sehr zentral (->Lizenzen). Aber einige wenige gute Ideen / Alternativlösungen sind patentfrei...
Und hier noch einige hilfreiche Links zum Thema MMC/SD , SDHC sowie Wear-Leveling: