Forum: Mikrocontroller und Digitale Elektronik Sd Card Addressierung


von Cassiopeia (Gast)


Lesenswert?

Hallo,

ich komme mit der Addressierung meiner SD Card nicht ganz klar.
Momentan verwende ich den Source Code von Ulrich Radig und beschreibe
ohne FAT Sektoren der SD Card. Den Code kann ich eigentlich
nachvollziehen. Im Argumentteil von CMD24 wird die Startaddresse des
512 Byte grossen Sektors angeben. Die Funktion zum schreiben eines
Sektors bekommt allerdings die Addresse/Nummer des Sektors als
Übergabewert.

Beispiel:
addr = 0x200; // Sektor 200
mmc_write_sector(addr,data_block);

Die geschriebenen Daten sollten doch dann auf Addresse
0x200*0x200=0x40000 liegen (0x200 = 512 Sektorgrößee)?
Leider ist die nicht der Fall! Aber warum? Die Daten liegen im Fall des
Beispiels auf Addresse 0x27200.

Hinweise zur späteren Erweiterung einer Funktion zum schreiben eines
files mit FAT16 Ünterstützung sind auch willkommen. Hat jemand einen
Link zu einer ausführlichen Beschreibung von FAT16 mit Bezug auf SD
card?

Danke

Hier noch der Source zu
U08 mmc_write_sector (U32 addr,U08 *Buffer)
//###################################################################### 
######
{
  U08 tmp;
  //Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
  U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};

  /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
    addr wird von Blocks zu Bytes umgerechnet danach werden
    diese in das Commando eingefügt*/

  addr = addr << 9; //addr = addr * 512

  cmd[1] = ((addr & 0xFF000000) >>24 );
  cmd[2] = ((addr & 0x00FF0000) >>16 );
  cmd[3] = ((addr & 0x0000FF00) >>8 );

  //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
  tmp = mmc_write_command (cmd);
  if (tmp != 0)
    {
    return(tmp);
    }

  //Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
  for (U08 a=0;a<100;a++)
    {
    mmc_read_byte();
    }

  //Sendet Start Byte an MMC/SD-Karte
  mmc_write_byte(0xFE);

  //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
  for (U16 a=0;a<512;a++)
    {
    mmc_write_byte(*Buffer++);
    }

  //CRC-Byte schreiben
  mmc_write_byte(0xFF); //Schreibt Dummy CRC
  mmc_write_byte(0xFF); //CRC Code wird nicht benutzt

  //Wartet auf MMC/SD-Karte Bussy
  while (mmc_read_byte() != 0xff){};

  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  MMC_Disable();

return(0);
}

von Olaf (Gast)


Lesenswert?

> Leider ist die nicht der Fall! Aber warum? Die
> Daten liegen im Fall des Beispiels auf Addresse 0x27200

Woher weisst du das? Hast du das an einem anderen Computer ueberprueft?
Bist du dir darueber im klaren das manche Betriebsysteme ab
Partitionsbegin zaehlen, du aber ab physikalischem Beginn der Karten?

> Hat jemand einen Link zu einer ausführlichen Beschreibung
> von FAT16 mit Bezug auf SD card?

Das hat keinen besonderen Bezug zur SD-Karte. Sobald du in der Lage
bist beliebige Sektoren zu lesen und zu schreiben kannst du darauf
aufbauen ohne einen Gedanken daran zu verschwenden was darunter liegt.

In der Ct wurde das alles mal sehr gut beschrieben. War glaub ich so
ende der 80er bis mitte 90er Jahre. :-)
Was ich so im Internet gelesen habe war meist eher halbgares Zeug mit
einer Menge Fehlern.

Olaf

von Cassiopeia (Gast)


Lesenswert?

Hm werd mal über den Zählbeginn nachdenken. Ansonsten hab ich die
Addressen von WinHex einem Hexeditor der auch ganze Laufwerke öffnen
kann. Eigentlich zählt der wenn ich des richtig sehe vom physikalichen
Beginn der Karte ab.

von Olaf (Gast)


Lesenswert?

Das sollte doch einfach feststellbar sein. Schau dir einfach den ersten
Sektor an. Ist das der MBR?

Olaf

von Cassiopeia (Gast)


Lesenswert?

Ja stimmt der erste Sektor ist der MBR, also ist der Zählbeginn auch der
physikalisch Beginn der Karte. Führt mich jetzt wieder zur
ursprünglichen Frage!

C.

von Cassiopeia (Gast)


Lesenswert?

Keine weiteren Tips? Verwendet sonst niemand den wie ich dachte
verbreiteten Code von Ulrich Radig?

C.

von Andy (Gast)


Lesenswert?

>Beispiel:
>addr = 0x200; // Sektor 200
>mmc_write_sector(addr,data_block);

>Die geschriebenen Daten sollten doch dann auf Addresse
>0x200*0x200=0x40000 liegen (0x200 = 512 Sektorgrößee)?
>Leider ist die nicht der Fall! Aber warum? Die Daten liegen im Fall
des
>Beispiels auf Addresse 0x27200.

Ich glaube, du hast es nicht ganz verstanden, wie die Karte deine Daten
ablegt und was sie dazu braucht. Im obigen Beispiel würde das
folgendermassen aussehen:
Du willst mit dieser Funktion ab der Adresse addr dein Datenblock
data_block abgelegt haben, d.h. 0x200+0x200=0x400, also der nächste
Datenblock beginnt bei 0x400 usw., d.h. du schreibst deine Daten immer
auf eine Adresse, die das Vielfache von 0x200 ist.

von Cassiopeia (Gast)


Lesenswert?

Der Übergabeparameter der Funktion mmc_write_sector ist aber doch nicht
die eigentliche Addresse sondern die Sektornummer. Deswegen die
Rechnung 0x200*0x200 = 0x40000. Ich will quasi den Datenblock in den
Sektor 0x200 schreiben und das erste Bit dieses Sektors hat dann die
Addresse 0x40000.

Oder versteh ich da was falsch?

C.

von Andy (Gast)


Lesenswert?

das ist genau richtig

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.