Forum: Mikrocontroller und Digitale Elektronik Elm Chan FatFs SD Karte auf Keil MCB2300 LCP2378


von Bernhard S. (benp4p)


Angehängte Dateien:

Lesenswert?

Hallo ich bin ein Anfänger auf dem Gebiet Microkontroller und Embedded 
Systems. Aber ich habe Interesse mich in diese Thematik einzuarbeiten. 
Ich versuche Elm Chan FatFs Filesystem für eine SD Karte Transcend DHC 
16GB Speicherkarte auf dem Keil MCB2300 LCP2378 zum Laufen zu bringen, 
leider erhalte ich Fehlermeldungen in der Form undefined Symbol 
MMC_disk_read, MMC_disk_write, MMC_disk_status ... ich benutze von Keil 
uVison 4.74 nachdem ich das zip-Archiv von Chans Seite: 
http://elm-chan.org/fsw/ff/00index_e.html
runtergeladen habe, wurden die header .h Dateien und die .c Dateien in 
das Keil Project eingebunden. Nach dem Einbinden kompilierte ich die .h 
und .c Dateien und erhielt dann diese Meldungen. Aus den Application 
notes:
http://elm-chan.org/fsw/ff/en/appnote.html
konnte ich entnehmen, dass ich eine mmc.c, spi.c und die device.h 
bereitstellen muss (siehe Grafik). Leider weiß ich überhaupt nicht, wie 
diese Dateien aussehen müssen bzw. was ich in diese beiden .c und in der 
.h Datei reinschreiben muss. Seither komme ich nicht weiter, daher bitte 
ich um eure Hilfe.

: Bearbeitet durch User
von TomA (Gast)


Lesenswert?

Hallo Bernhard,

ich bin gerade dabei, das Petit FatFs von Elm Chan mit einen 89S8253 
(MCS51) zu verwenden. Im Grunde mußte ich dazu nur die Funktionen der 
Datei "DISKIO.C" an die Hardware des 89S8253 anpassen und in der Datei 
PFF.h wählen, welche Funktionen ich wünsche (Read, write, etc). Der Rest 
funktioniert unverändert, wie heruntergeladen.

Gruß. Tom

von grundschüler (Gast)


Lesenswert?

Die elm-chan-sd-Beispiele unterscheiden sich im Prinzip nur durch den 
lowlevel-Teil, das heißt die Anbindung zwischen den spi-pins und der 
Karte. Am einfachsten fängt man mit dem Projekt foolproof an wenn die 
Karte per bitbanging läuft, stellt man den software-spi auf hardware um.

Für foolproof musst du nur die io-on/off-defines an deinen uc anpassen.

von Bernhard S. (benp4p)


Angehängte Dateien:

Lesenswert?

@TomA, @grundschüler

danke erstmal für eure Rückmeldungen, dass heißt also, dass ich die 
angegebenen Dateien aus der Grafik roter Kreis ( mmc.c, spi.c und die 
device.h)
nicht bereitstellen muss. @Tom also muss ich nur die "DISKIO.C" an meine 
Hardware anpassen ? @grundschüler ja ich werde mir das Projekt foolproof 
ansehen. Gibt es eurer Erfahrung Probleme mit dem Elm Chan FatFs 
Filesystem und bestimmten SD oder SDHC Karten mit Kapazitäten von 16 GB 
?

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>danke erstmal für eure Rückmeldungen, dass heißt also, dass ich die
>angegebenen Dateien aus der Grafik roter Kreis ( mmc.c, spi.c und die
>device.h)
>nicht bereitstellen muss.

NEIN! Du MUSST sie bereitstellen. Im einfachsten Fall ein vorhandenes 
Projekt für AVR kopieren und die Dateien anpassen, dann sieht man 
nämlich, was dort rein muss.

> @Tom also muss ich nur die "DISKIO.C" an meine
>Hardware anpassen ?

Nein, dort stehen nur allgemeine Definitionen drin. Man muss nur in 
mmc.c die die folgenden Dinge anpassen

1
/* Port controls  (Platform dependent) */
2
#define CS_LOW()  PORTB &= ~1      /* CS=low */
3
#define  CS_HIGH()  PORTB |= 1      /* CS=high */
4
#define MMC_CD    (!(PINB & 0x10))  /* Card detected.   yes:true, no:false, default:true */
5
#define MMC_WP    (PINB & 0x20)    /* Write protected. yes:true, no:false, default:false */
6
#define  FCLK_SLOW()  SPCR = 0x52    /* Set slow clock (F_CPU / 64) */
7
#define  FCLK_FAST()  SPCR = 0x50    /* Set fast clock (F_CPU / 2) */
8
9
/*-----------------------------------------------------------------------*/
10
/* Power Control  (Platform dependent)                                   */
11
/*-----------------------------------------------------------------------*/
12
/* When the target system does not support socket power control, there   */
13
/* is nothing to do in these functions and chk_power always returns 1.   */
14
15
static
16
void power_on (void)
17
{
18
  {  /* Remove this block if no socket power control */
19
    PORTE &= ~_BV(7);  /* Socket power on (PE7=low) */
20
    DDRE |= _BV(7);
21
    for (Timer1 = 2; Timer1; );  /* Wait for 20ms */
22
  }
23
24
  PORTB |= 0b00000101;  /* Configure SCK/MOSI/CS as output */
25
  DDRB  |= 0b00000111;
26
27
  SPCR = 0x52;      /* Enable SPI function in mode 0 */
28
  SPSR = 0x01;      /* SPI 2x mode */
29
}
30
31
static
32
void power_off (void)
33
{
34
  SPCR = 0;        /* Disable SPI function */
35
36
  DDRB  &= ~0b00110111;  /* Set SCK/MOSI/CS as hi-z, INS#/WP as pull-up */
37
  PORTB &= ~0b00000111;
38
  PORTB |=  0b00110000;
39
40
  {  /* Remove this block if no socket power control */
41
    PORTE |= _BV(7);    /* Socket power off (PE7=high) */
42
    for (Timer1 = 20; Timer1; );  /* Wait for 20ms */
43
  }
44
}
45
46
47
48
/*-----------------------------------------------------------------------*/
49
/* Transmit/Receive data from/to MMC via SPI  (Platform dependent)       */
50
/*-----------------------------------------------------------------------*/
51
52
/* Exchange a byte */
53
static
54
BYTE xchg_spi (    /* Returns received data */
55
  BYTE dat    /* Data to be sent */
56
)
57
{
58
  SPDR = dat;
59
  loop_until_bit_is_set(SPSR, SPIF);
60
  return SPDR;
61
}
62
63
/* Send a data block fast */
64
static
65
void xmit_spi_multi (
66
  const BYTE *p,  /* Data block to be sent */
67
  UINT cnt    /* Size of data block (must be multiple of 2) */
68
)
69
{
70
  do {
71
    SPDR = *p++; loop_until_bit_is_set(SPSR,SPIF);
72
    SPDR = *p++; loop_until_bit_is_set(SPSR,SPIF);
73
  } while (cnt -= 2);
74
}
75
76
/* Receive a data block fast */
77
static
78
void rcvr_spi_multi (
79
  BYTE *p,  /* Data buffer */
80
  UINT cnt  /* Size of data block (must be multiple of 2) */
81
)
82
{
83
  do {
84
    SPDR = 0xFF; loop_until_bit_is_set(SPSR,SPIF); *p++ = SPDR;
85
    SPDR = 0xFF; loop_until_bit_is_set(SPSR,SPIF); *p++ = SPDR;
86
  } while (cnt -= 2);
87
}


Der Rest bleibt wie er ist.

>@grundschüler ja ich werde mir das Projekt foolproof
>ansehen. Gibt es eurer Erfahrung Probleme mit dem Elm Chan FatFs
>Filesystem und bestimmten SD oder SDHC Karten mit Kapazitäten von 16 GB
>?

Keine Ahung, hab ich damit nie benutzt, nur 1,4, und 8GB. Lief soweit 
problemlos.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Die >=16 GB Karten haben i.d.R. einen andren Partition Code, wenn die 
FAT Implementation den kennt gibt es kein Problem.

: Bearbeitet durch User
von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Bernhard S. schrieb:
> Hallo ich bin ein Anfänger auf dem Gebiet Microkontroller und Embedded
> Systems. Aber ich habe Interesse..

> Ich versuche Elm Chan FatFs Filesystem .. auf dem Keil MCB2300 LCP2378 zum 
Laufen zu bringen,..

Tja, da fehlen dir eben die Programmteile, die du selbst beitragen 
müßtest.

Ich häng dir mal ne Implemetation für den LPC2478 dran. Such dir raus, 
was du brauchst. Zum Erkennen des Zustandes der Fassung brauchst du dann 
noch ne Systemtimer-Routine (eben ne Systemuhr auf Timerbasis, so alle 
10 ms oder so). Ebenso müßtest du dir deine eigenen Kommandoprogramme 
selber schreiben, also Anzeigen, Kopieren, Dir auflisten, nen Pfad 
verwalten usw.

Der 2378 müßte doch eigentlich kompatibel zum 2578 sein - bis auf das 
fehlende TFT-Interface.

W.S.

von Bernhard S. (benp4p)


Lesenswert?

Hallo W.S.

danke für Ihre Rückmeldung und für die Hilfsbereitschaft. Ich werde die 
Implementation ausprobieren und darüber berichten wie es gelaufen ist.


Viele Grüße

Bernhard

: Bearbeitet durch User
von Bernhard S. (benp4p)


Lesenswert?

Hallo W.S.

Leider erhalte ich folgende Fehlermeldung in Microvision4

cannot open source input file "startup.h"
cannot open source input file  "conv.h"



Diese beiden Headerdateien "startup.h" , "conv.h"
sind auch nicht im Zip-Archiv SD_Card_LPC2478.zip enthalten.
Muss ich diese Dateien selber erstellen ? Und wenn ja, was muss da 
drinnen stehen ?

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>cannot open source input file "startup.h"
>cannot open source input file  "conv.h"

Das sieht nach den startup Dateien für diese speziellen Prozessoren aus. 
Die brauchen aber nicht alle. Die meisten Compiler packen den Startup 
Code "unsichtbar" mit rein, ohne Headerfiles.

Einfach mal auskommentieren.

von grundschüler (Gast)


Lesenswert?

Bernhard S. schrieb:
> Diese beiden Headerdateien "startup.h" , "conv.

Erstmal ein lauffähiges Projekt ohne sd-Karte erstellen. Wenn das 
funktioniert, die elm-chan-Dateien in dieses Projekt einbinden. Der code 
von W.S. scheint für sdio zu sein. Da brauchst du ein anderes Pinout als 
für den sd-code,

von Bernhard S. (benp4p)


Lesenswert?

grundschüler schrieb:
> Bernhard S. schrieb:
>> Diese beiden Headerdateien "startup.h" , "conv.
>
> Erstmal ein lauffähiges Projekt ohne sd-Karte erstellen. Wenn das
> funktioniert, die elm-chan-Dateien in dieses Projekt einbinden. Der code
> von W.S. scheint für sdio zu sein. Da brauchst du ein anderes Pinout als
> für den sd-code,

Hallo grundschüler, ich habe ein lauffähiges Projekt, wenn ich die 
elm-chan Dateien einbinde, benötige ich die folgenden Files ( mmc.c, 
spi.c und die
device.h), ich bin mir nicht sicher was hier rein muss.

von Bernhard S. (benp4p)


Lesenswert?

Falk Brunner schrieb:
> @ Bernhard S. (benp4p)
>
>>cannot open source input file "startup.h"
>>cannot open source input file  "conv.h"
>
> Das sieht nach den startup Dateien für diese speziellen Prozessoren aus.
> Die brauchen aber nicht alle. Die meisten Compiler packen den Startup
> Code "unsichtbar" mit rein, ohne Headerfiles.
>
> Einfach mal auskommentieren.

Ich habe dieses Header auskommentiert, nun sucht der Compiler nach 
weiteren Header Files, die gar nicht im Archiv vorhanden sind.

von Bernhard S. (benp4p)


Lesenswert?

W.S. schrieb:
> Zum Erkennen des Zustandes der Fassung brauchst du dann
> noch ne Systemtimer-Routine

Eine Timer Routine in der überprüft wird ob eine SD Karte eingesteckt 
wurde oder nicht ?

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>> Zum Erkennen des Zustandes der Fassung brauchst du dann
>> noch ne Systemtimer-Routine

>Eine Timer Routine in der überprüft wird ob eine SD Karte eingesteckt
>wurde oder nicht ?

Ja, das wird zyklisch geprüft. Viel wichtiger sind aber dort die 
Timeoutzähler, welche von anderen Routinen genutzt werden.

von Bernhard S. (benp4p)


Lesenswert?

Falk Brunner schrieb:
> Viel wichtiger sind aber dort die
> Timeoutzähler, welche von anderen Routinen genutzt werden.

Ich habe bisher keine Erfahrung mit TimeoutZähler, sind diese schon 
vorhanden oder muss ich diese implementieren.

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>Ich habe bisher keine Erfahrung mit TimeoutZähler, sind diese schon
>vorhanden oder muss ich diese implementieren.

Sie sind schon vorhanden in mmc.c
1
/*-----------------------------------------------------------------------*/
2
/* Device Timer Interrupt Procedure                                      */
3
/*-----------------------------------------------------------------------*/
4
/* This function must be called in period of 10ms                        */
5
6
void disk_timerproc (void)

von Bernhard S. (benp4p)


Lesenswert?

Falk Brunner schrieb:
> @ Bernhard S. (benp4p)
>
>>Ich habe bisher keine Erfahrung mit TimeoutZähler, sind diese schon
>>vorhanden oder muss ich diese implementieren.
>
> Sie sind schon vorhanden in mmc.c
>
>
1
> /*-----------------------------------------------------------------------*/
2
> /* Device Timer Interrupt Procedure 
3
> */
4
> /*-----------------------------------------------------------------------*/
5
> /* This function must be called in period of 10ms 
6
> */
7
> 
8
> void disk_timerproc (void)
9
>

Hallo Falk Brunner,

wie sollte ich nun am besten vorgehen. Soll ich nun Elm Chan FatFs 
benutzen ? Dort sind aber auch drei Dateien notwendig, die zu erstellen 
sind, ich hab ehrlich gesagt keine Ahnung was da rein muss. Ich lese 
gerade das Manual zum 2378 , bzw. wie man einen Timer implementiert, mit 
Timern kenne ich mich ehrlich gesagt auch nicht aus.

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>wie sollte ich nun am besten vorgehen.

Sagte ich das nicht bereits mehrfach?

> Soll ich nun Elm Chan FatFs benutzen ?

JA!

> Dort sind aber auch drei Dateien notwendig, die zu erstellen
>sind, ich hab ehrlich gesagt keine Ahnung was da rein muss.

Musst du auch gar nicht! Nimm eines der fertigen Projekte, dort 
existieren diese Dateien samt Inhalt. Man muss nur SEHR wenig anpassen!

Genauer muss man, wenn es mit SPI laufen soll, nur in der mmc.c ein paar 
defines und die drei Funktionen anpassen. Das wars!

Beitrag "Re: Elm Chan FatFs SD Karte auf Keil MCB2300 LCP2378"

Nimm das Beispiel vom AVR und ändere es ab.

>Ich lese
>gerade das Manual zum 2378 , bzw. wie man einen Timer implementiert, mit
>Timern kenne ich mich ehrlich gesagt auch nicht aus.

Dann musst du es lernen. Timer aufsetzen, ISR hinschreiben, dort die 
Funktion aufrufen.

von Bernhard S. (benp4p)


Lesenswert?

Falk Brunner schrieb:
> Dann musst du es lernen. Timer aufsetzen, ISR hinschreiben, dort die
> Funktion aufrufen.

Im timer wird überprüft ob eine SD Karte eingesteckt wurde, dann wird 
eine ISR aufgerufen, die aus der SD Karte z.B. die Dateien auflistet 
oder ?

von Falk B. (falk)


Lesenswert?

@ Bernhard S. (benp4p)

>Im timer wird überprüft ob eine SD Karte eingesteckt wurde,

NEIN! Einfach nur die Funktion aufrufen, die kümmert sich um alles!

>dann wird
>eine ISR aufgerufen, die aus der SD Karte z.B. die Dateien auflistet
>oder ?

NEIN! Das ist nur eine KLEINE Funktion, die keinerlei direkte Aktionen 
ausführt! Schau sie dir an, sie ist trivial! Es gibt 2 Timeout Zähler, 
welche von anderen Funktion aus ff.c benutzt werden. Dazu noch die 
Überwachung der INSERT und WRTE PROTECT Schalter vom SD-Kartenhalter, 
fertig.

1
/*-----------------------------------------------------------------------*/
2
/* Device Timer Interrupt Procedure                                      */
3
/*-----------------------------------------------------------------------*/
4
/* This function must be called in period of 10ms                        */
5
6
void disk_timerproc (void)
7
{
8
  BYTE n, s;
9
10
11
  n = Timer1;        /* 100Hz decrement timer */
12
  if (n) Timer1 = --n;
13
  n = Timer2;
14
  if (n) Timer2 = --n;
15
16
  s = Stat;
17
18
  if (SOCKWP)        /* Write protected */
19
    s |= STA_PROTECT;
20
  else          /* Write enabled */
21
    s &= ~STA_PROTECT;
22
23
  if (SOCKINS)      /* Card inserted */
24
    s &= ~STA_NODISK;
25
  else          /* Socket empty */
26
    s |= (STA_NODISK | STA_NOINIT);
27
28
  Stat = s;        /* Update MMC status */
29
}

von grundschüler (Gast)


Lesenswert?

In dieser Reihenfolge funktioniert die Einbidung:
1
#if USE_MMC
2
  //+++++++++++++++++++++ mmc +++++++++++++++++++++++++++++++++++
3
  #include "C:\zuc\chan_sd\ffconf.h"
4
  #include "C:\zuc\chan_sd\integer.h"
5
  #include "C:\zuc\chan_sd\diskio.h"
6
  #include "C:\zuc\chan_sd\ff.h"
7
  #include "C:\zuc\chan_sd\ff.c"
8
  #include "mmc_avr.c"
9
  FIL Fil;  /* File object needed for each open file */
10
  //--------------------------------------------------------
11
#endif
12
....
13
14
und so der aufruf (aus foolproof)
15
16
17
18
#if USE_MMC //++++++++++++++ foolproof ++++++++++++++
19
  UINT bw,res;
20
  res=  f_mount(&FatFs, "", 0);    /* Give a work area to the default drive */
21
  #if 1
22
    res=f_open(&Fil, "newfile.txt", FA_WRITE | FA_CREATE_ALWAYS);   /* Create a file */
23
    if (res== FR_OK) {
24
        res=  f_write(&Fil, "It works!\r\n", 11, &bw);  
25
      f_close(&Fil);                /* Close the file */
26
      if (bw == 11) {    /* Lights green LED if data written well */
27
        lgw(4,1,"foolproof ok    ");
28
      } else{
29
        lgw(4,1,"foolproof failed");
30
      }
31
    }
32
  #endif
33
#endif //-------------- foolproof --------------

Bei den *.c-dateien musst du aufpassen, die werden normalerweise separat 
kompiliert. Wenn du das willst, das entsprechende include löschen und im 
Mkefile eintragen...

Die Include-Dateien eine nach der anderen einbinden und austesten. Wenn 
in den Dateien undefined includes stehen, diese löschen.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Bernhard S. schrieb:
> Diese beiden Headerdateien "startup.h" , "conv.h"
> sind auch nicht im Zip-Archiv SD_Card_LPC2478.zip enthalten.
> Muss ich diese Dateien selber erstellen ? Und wenn ja, was muss da
> drinnen stehen ?

Herrje, ich habe dir NICHT geschrieben, daß meine Quellen ready for 
copy&paste sind, sondern dafür, daß du dir rauspicken kannst, was du 
haben willst.

In startup.h stehen bei mir all die Dinge, die im Startupcode enthalten 
sind und die ich publik machen will. In conv.c (nebst conv.h) finden 
sich Konvertierungen aller Art, Long nach String, Float nach String und 
solche Konsorten. Die ganze conv.* kannst du dir aus der Lernbetty hier 
im Forum herauspicken.

Ich werde langsam GRIMMIG, denn eigentlich erwarte ich, daß du dich 
bemühst, so eine angehängte Datei in ihrem Sinn zu verstehen.

Noch ein Wort zum Systemtimer: So ein Projekt für nen LPC2478 und 
Konsorten sollte über eine Systemuhr verfügen. Bei Cortexen hat man 
jetzt einen Timer dafür direkt in der CPU, aber bei ARM7TDMI muß man 
sich einen Timer dafür ausgucken - und der kann dann auch von Zeit zu 
Zeit nach der SD-Karte gucken. Schließlich will ja keiner jedesmal die 
Karte von Hand mounten - oder?

W.S.

von W.S. (Gast)


Lesenswert?

Bernhard S. schrieb:
> Im timer wird überprüft ob eine SD Karte eingesteckt wurde, dann wird
> eine ISR aufgerufen, die aus der SD Karte z.B. die Dateien auflistet
> oder ?

Nochmal diese Thema in Ruhe:
Ein Timer im µC ist im Prinzip ein Zähler, der entweder von einem 
Portbein oder von dem internen Takt zum hoch- (ode manchmal runter-) 
zählen veranlaßt wird. Nun kann man ihn so programmieren, daß er 
jedesmal, wenn er eine bestimmte Anzahl von Takten gezählt hat, sich 
selbst zurücksetzt und von neuem mit Zählen anfängt und daß er bei 
diesem Ereignis einen Interrupt auslöst. Diese unterbricht die laufende 
Arbeit der CPU und läßt sie eine sogenannte Interrupt-Routine 
abarbeiten. Wenn man nun den Zähler so programmiert, daß er z.B. alle 10 
ms einmal fertig wird, dann hat man damit eine Systemuhr, die im 10 ms 
Takt iregndwelche Variablen hochzählen kann (z.B. einen für die 
Millisekunden, einen für die Sekunden , Minuten, Stunden, Tage.....). 
Nebenher kann so eine Interruptroutine auch wiederkehrende simple 
Arbeiten verrichten, z.B. nach der SC-Karte schauen. Wenn keine drin war 
und nun eine drin ist, dann das Mounten starten und wenn keine drin ist 
aber zuvor eine drin war, dann die SD-Karte austragen, damit der Rest 
der Firmware weiß, daß momentan keine Karte steckt.

Klaro?

Bedenke auch, daß die Routinen von Chan so etwa in der Mitte stehen: zu 
allerunterst sind die Routinen, zum Mounten und Erkennen des Kartentyps 
und zum Lesen und Schreiben von Sektoren, darüber sitzt eine Art 
Verteiler-Bonze, der die Zugriffe des Filesystems auf unterschiedliche 
Medien verteilt (sofern man hat), darüber eben das Filesysten und 
darüber dann die eigentliche Benutz-Schicht, also Programmteile, die 
Dateien lesen und schreiben. Eines davon kann sowas wie ein 
COMMAND.COM sein, also ein kommandozeilen-User-Interface, was z.B. ein 
Directory auflisten oder Dateien kopieren kann.

W.S.

von Bernhard S. (benp4p)


Lesenswert?

W.S. schrieb:
> angehängte Datei in ihrem Sinn zu verstehen

Das werde ich machen, danke für deine Hilfe, ich will und muss mich ja 
in dieses Thema einarbeiten.

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.