Forum: Projekte & Code MMC SD library FAT16 FAT32 read write


von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

hier mal meine fat16/fat32 lib für atmel atmegas.
noch ich sag mal im alpha 2 status ;)

was geht ist:

- auslesen eines MBR ( muss im code eingestellt werden...)

- datei anlegen        open('w',rstr);
- datei schreiben      ffwrite(c);
- datei anhängen       open('a',rstr);
- datei lesen          c=ffread();
- datei löschen        ffrm(fileName);
- direktory wechseln   ffcd(dirName);  (immer nur eins nach dem anderen)
- direktory anzeigen   ffls();
- datei seek           ffseek(234);    (ab stelle 0, nur beim lesen)

- commando promt    hier kann komplette funktionalität getestet werden !
- umwandeln von "t.txt" -> "T        TXT"    fat_str("t.txt);


mit einem atmega168 @ 20 mhz schafft man lesend ~ 220.000 bytes/sec,
mit einem atmega32  @ 8  mhz schafft man lesend ~  20.000 bytes/sec,
bei fat 32 mit größeren clustern wird es immer schneller ;)

würde mich über anregungen, oder verbesserungsvorschläge freuen !

ps: hab Ulrich Radigs mmc.h/mmc.c etwas erweiter, an dieser stelle danke
    für die veröffentlichung dieser dateien.

grüße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

einige bug-fixes sind gemacht, eine lib zum einlesen von
tastatureingaben, über eine at-tastatur ist jetzt dabei.

nur falls es jemanden interessiert ;)

von Alexander D. (zebprophet)


Lesenswert?

g das thema interessiert doch immer.

wie sieht es mit dem speicherbedarf aus? funktioniert der code auch - 
read only - auf einem atmega16 (1kb ram)?

von gast (Gast)


Lesenswert?

mich würde nicht nur der quelltext, sondern auch deine quellen 
interessieren, gerade spezifikation, umsetzung mit atmega etc.

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ Alexander D.

würde sogar mit write funktionieren, man müsste nur in der main auf ein 
paar sachen verzichten, wie den commando prompt und so. nur die 
fat-0.x.c und file-0.x.c sind auch super so zu gebrauchen.

@ gast

quellen sind einmal die Fatgen103.pdf spezifikationen von MS gewesen und

https://www.pjrc.com/tech/8051/ide/fat32.html

entickelt hab ich das ganze mit linux.
habe mir raw images von mmc/sd karten gemacht und das mit 
low-level-datei-lese funktionen mit linux gcc geschrieben, da kann man 
dann schön debugen.


zu dem code,
das einzige problem, warum read und write nich z.b. auf einem atmega8 
läuft ist, weil nicht genügend flash da ist, ram würde locker reichen.

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

neue optimierungen und bugs beseitigt beim schreiben !

fat16 schreiben von 60.000 bytes in 1,421 sec -> 41KB
fat16 lesen     von 60.000 bytes in 0,823 sec -> 71KB

fat32 schreiben von 60.000 bytes in 1,249 sec -> 46KB
fat32 lesen     von 60.000 bytes in 0,747 sec -> 78KB


die werte, mit atmega32 @ 8 mhz (interner takt).

status: ist jetzt voll funktionsfähig !


grüße daniel

von Siegmar (Gast)


Lesenswert?

Hallo

Habs zwar noch nicht testen können, sieht aber Klasse aus !!
Tolle Arbeit !!!
Noch einen schönen Abend
Gruß
Siegmar

von holger (Gast)


Lesenswert?

>#include "fat-0.3.c"
>#include "file-0.3.c"

Das macht man nicht ;) Gibt nur Probleme.
Bastel dir mal eine fat.h und file.h.

von Daniel R. (zerrome)


Lesenswert?

hallo,

@  Siegmar

danke, hört man gerne :)
wenn du zum testen kommst, laß doch mal hören wo es hinkt,
wenn es hinkt ;)

@ holger

ja werd ich machen. nur noch keine lust gehabt...
ist mir auch noch ein kleines rätsel warum das unbedingt nötig ist.
würde es reichen nur die funktionen in einer *.h datei "bekannt" zu 
machen, die von anderen *.c dateien aus aufgerufen werden ? das würde 
für mich am meisten sinn machen. wäre dann quasi sowas wie private oder 
public. also private nur in der *.c selber als prototyp, public in der 
*.h...

von kalhou (Gast)


Lesenswert?

Da ich mich momentan auch gerade mit dem Thema befasse, werde ich die 
Library mal ausprobieren. Ich hab aber gehört, dass FAT32 auf SD-Karten 
nicht funktioniert ? Oder ist nur ein Gerücht ?

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ kalhou

es kommt auf die größe der karte an. manche sind zu klein um sie mit 
fat32 zu formatieren. andere wieder sind zu groß um sie mit fat 16 zu 
formatieren...
welchen controller willst du denn benutzen und wie willst du die karte 
anschließen?

grüße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

kleinere änderungen, grad der optimierung erhöht.

ohne lcd, tastatur und benchmark teil,
jetzt 709 bytes statischer ram (bei lesen und schreiben mit commando 
prompt) und 10127 bytes an flash speicher verbrauch.
mit allem 740 ram und 11796 flash.

compiler optimierung 2 besser als s...


grüße daniel

von kalhou (Gast)


Lesenswert?

Die Karte hängt an einem atmega128 momentan ist sie über hardware spi 
angeschlossen... d.h. 1Gb sollte mit FAT32 funktionieren ?

von kalhou (Gast)


Lesenswert?

So... hab jetzt die Library mal ausprobiert.

Zuerst hatte ich Probleme, da ich das Ganze in AVR-Studio probierte und 
daher kein Makefile verwendete, dass mir Studio diverse Fehler 
zurückgab, die sich mit der Einbindung eines Makefiles praktisch in Luft 
auflösten.
Trotzdem wäre es von Vorteil wenn es auch ohne die Einbindung eines 
externen Makefiles funktionieren würde ;)

Weiter habe ich dann probiert ein paar Zeichen aus einer Datei zu lesen.
1
#include <stdlib.h>
2
#include <string.h>  
3
#include <avr/io.h>
4
#include <avr/pgmspace.h>  
5
#include <avr/interrupt.h>      
6
7
#define F_CPU 14745600UL
8
#include <util/delay.h>
9
10
#include "uart-0.1.h"      
11
#include "mmc-0.2.h"      
12
#include "fat-0.3.h"      
13
#include "file-0.3.h"  
14
15
#define BUFF_SIZE 15  
16
unsigned char kb_buffer[BUFF_SIZE];  
17
18
int main(void){
19
  DDRA = 0xFF;
20
  PORTA = 0x00;
21
22
  uinit(); 
23
      
24
  uputs("Boot ok\n\r");
25
26
  if (mmc_init() == 0){       //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten  
27
  uputs("SD Init ok\n\r");
28
  } 
29
  else{
30
  uputs("SD Init failed\n\r");
31
  }
32
33
  if(0==fat_initfat()){
34
     uputs("FAT Init ok\n\r");    
35
   }
36
  else{
37
    uputs("FAT Init failed\n\r");
38
  }
39
40
  //Datei lesen
41
  ffopen('r',"delme.txt");
42
43
  uputc(fread());
44
  uputc(fread());
45
  uputc(fread());
46
  uputc(fread());
47
  uputc(fread());
48
  uputc(fread());
49
  uputc(fread());
50
  uputc(fread());
51
  uputs("\n\r");
52
  ffclose();
53
54
  for(;;){
55
    PORTA = 0xFF;
56
  }
57
}

Das Init Zeugs hat funktioniert und wurde mir auch schön auf der UART 
angezeigt. Scheint das lesen der Datei nicht zu funktionieren.

Was ich noch vermisse ist eine Funktion zum beschreiben der Dateien, 
sowie eine Funktion zum lesen ganzer Strings ;)

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ kalhou

also beschreiben einer datei würde wie folgt laufen:
1
//1
2
ffopen('w',"DELME   TXT");                      
3
                               
4
//2
5
unsigned char str[22]="das soll auf die karte";           
6
unsigned char i=0;
7
8
//3
9
do{
10
11
   ffwrite(str[i]);
12
   i++;
13
}while(str[i]!='\0');
14
15
//4
16
ffclose();

-1 die funktion ffopen erwartet als datei bezeichnung einen string im 
8.3 format, alles großgeschrieben ! man kann zum wandeln von z.b. 
delme.txt" die funktion fat_str nutzen, die macht aus "delme.txt" "DELME 
TXT".

-2 str enthält 22 bytes die auf die karte sollen, i ist nur ein index 
zähler für den str

-3 in der schleife wird auf die karte geschrieben, der ganze string

-4 schließt die datei (erst hier wird die datei tatsächlich angelegt, 
vorher werden nur die daten der datei auf die karte geschrieben)

noch zu 1:
es gibt auch noch ffopen('a',"DELME   TXT"); das würde die datei zum 
anhängen öffnen, wird dann ab letztem zeichen weiter geschrieben.

nur öffnen zum lesen wäre ffopen('r',"DELME   TXT"); und dein obiger 
code

von kalhou (Gast)


Lesenswert?

Zum Verständniss: verwendet habe ich die aktuellste Version 
"mmc-0.3.1.zip" dort findet sich leider keine Funktion "fat_str"
1
#include <stdlib.h>
2
#include <string.h>  
3
#include <avr/io.h>
4
#include <avr/pgmspace.h>  
5
#include <avr/interrupt.h>      
6
7
#define F_CPU 14745600UL
8
#include <util/delay.h>
9
10
#include "uart-0.1.h"      
11
#include "mmc-0.2.h"      
12
#include "fat-0.3.h"      
13
#include "file-0.3.h"  
14
15
#define BUFF_SIZE 15  
16
unsigned char kb_buffer[BUFF_SIZE];  
17
18
int main(void){
19
  DDRA = 0xFF;
20
  PORTA = 0x00;
21
22
  uinit(); 
23
      
24
  uputs("Boot ok\n\r");
25
26
  if (mmc_init() == 0){       //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten  
27
  uputs("SD Init ok\n\r");
28
  } 
29
  else{
30
  uputs("SD Init failed\n\r");
31
  }
32
33
  if(0==fat_initfat()){
34
     uputs("FAT Init ok\n\r");    
35
   }
36
  else{
37
    uputs("FAT Init failed\n\r");
38
  }
39
40
  //Datei schreiben
41
  
42
  //1
43
  ffopen('w',"DELME   TXT");                      
44
                               
45
  //2
46
  unsigned char str[22]="das soll auf die karte";           
47
  unsigned char i=0;
48
49
  //3
50
  do{
51
52
   ffwrite(str[i]);
53
   i++;
54
  }while(str[i]!='\0');
55
56
  //4
57
  ffclose();
58
59
60
  for(;;){
61
    PORTA = 0xFF;
62
  }
63
}

Das Beispiel hier funktioniert nur soweit ich keine Datei auf der Karte 
habe die "delme.txt" heisst!
Wenn ich eine Datei "delme.txt" auf der Karte habe und dann mit dem 
Modus 'a'  den String dranhängen will, klappt das nicht und der 
Kontroller bleibt hängen (zu sehen an den LEDS (PORTA) die nie angehen.

Das lesen schlug in beiden fällen Fehl.

1. Heisst das also, dass man soweit nur Files in Grossbuchstaben ablegen 
kann ?
2. Warum wurde die fat_str Funktion nicht direkt in fopen integriert ?
3. Wird es in naher Zukunft noch Funktionen geben zum direkten 
Lesen/Schreiben von Strings ?
4. Wird es ebenfalls in naher Zukunft die Möglichkeit geben mehrere 
Dateien zu öffnen ? Wäre ja eigentlich keine Sache, da man nur bei fopen 
eine File Struktur zurückgeben und bei jeder Funktion wie fread auf den 
Zeiger auf diese Struktur zugreifen müsste :)

von Daniel R. (zerrome)


Lesenswert?

hallo,

sieh dir mal mit einem hex editor die daten auf der karte an.

da wirst du sehen, dass dort 8.3 einträge und lange datei namen drauf 
sind.
bei allen 8.3 datei namen werden großbuchstaben sein. wenn der datei 
name bzw. die endung nicht 8 bzw 3 zeichen haben, wird mit leerzeichen 
aufgefüllt, bis 8.3 erfüllt ist!
wenn du mit dem pc eine datei auf der karte anlegst, dann wird es bei 
dem beispiel "delme.txt" einen 8.3 eintrag geben der "DELME   TXT" 
lautet. nur mit diesen 8.3 namen arbeitet die library.
fat_str ist aus dem grund nicht in ffopen integriert, weil es auch ohne 
läuft und ich das ganze so schrumpfen möchte, das es irgendwann auf 
einen mega8 passt.

-1. egal was für eine datei du anlegst, es wird immer ein großbuchstaben 
8.3 name mit angelegt. von jedem betriebssystem, dass ich kenne.

-3. da ist die funktion zum schreiben von strings...
1
ffwriteString(unsigned char str[],unsigned char name[], unsigned char option){
2
3
  ffopen(option,name);                      
4
  unsigned long int i=0;    
5
6
7
  do{
8
9
   ffwrite(str[i]);
10
   i++;
11
  }while(str[i]!='\0');
12
13
 
14
  ffclose();
15
}
nur so aus dem kopf, sollte aber gehn :)


-4. mehrere dateien wird es erstmal nicht geben, aus ram gründen.
aber du hast doch schon einen weg aufgezeigt wie es gehen könnte. wenn 
du es änderst, poste doch einfach mal eine ergebnisse :)

zu dem problem mit dem anhängen, werd ich später mal ausprobieren...

von Daniel R. (zerrome)


Lesenswert?

hallo,

bei mir gibt es mit folgendem code keine probleme:
1
  // löscht datei, wenn vorhanden...
2
  ffrm("DELME   TXT");    
3
  
4
  // schreibt in die datei (kann nur schreiben wenn nicht vorhanden ist)
5
  ffwriteString("das soll in die datei","DELME   TXT",'w'); 
6
7
  // anhängen von daten
8
  ffwriteString(", mehr noch","DELME   TXT",'a');

benutzt wird die ffwirteString von siehe oben...

wegen dem einlesen von strings kannst du dir ja nach dem beispiel was 
basteln...

grüße daniel

von kalhou (Gast)


Lesenswert?

lesen und schreiben habe ich jetzt soweit geschafft.. werde morgen mal 
weiter schauen...

eine letzte frage bleibt: bei langen dateinamen < 8 zeichen wird das ja 
mit ~1 gemacht.. also z.b. aus "langer-dateiname" wird "langer~1.txt" 
wie funktioniert das allerdings wenn ich zwei "ähnliche" dateinamen habe 
? also z.b. "langedatei1" und "langedatei2" würden ja dann beide mit 
"langed~1" abgekürzt... geht das überhaupt ?

von Daniel R. (zerrome)


Lesenswert?

daraus wird dann: langed~1, langed~2 usw... ist dann etwas 
unübersichtlich ;)

vorallem wenn es so etwas ist wie langedatei-wichtig-von-chef.txt und 
langedatei-wichtig-von-frau.txt weil daraus auch langed~1 und langed~2 
wird

von kalhou (Gast)


Lesenswert?

also wenn ich jetzt "langedatei-wichtig-von-chef.txt" und
"langedatei-wichtig-von-frau.txt" auf der sd habe wie weiss ich dann 
welche datei ich mit "langed~1" resp. "langed~2" anspreche ?

gruss

von Joachim (Gast)


Lesenswert?

> wie weiss ich dann
> welche datei ich mit "langed~1" resp. "langed~2" anspreche ?

Öffnen und nachgucken?

von Kevin K. (kalhou)


Lesenswert?

Dürfte wohl für den Controller weniger einfach werden, anhand des 
Inhaltes einer Datei darauf zu schliessen, wie der originale Dateiname 
lautet. Es sei denn der originale Dateiname steht versteckt irgendwo in 
der Datei, was ich mir aber nicht vorstellen kann!
Das Problem ist ja, dass wenn ich die Datei 
"langedatei-wichtig-von-frau.txt" öffnen will, nicht beide Dateien 
"langed~1" und "langed~2" aufmachen sollte, um herauszufinden welche der 
beiden jetzt die Datei ist die ich brauche.

von holger (Gast)


Lesenswert?

Auf lange Dateinamen sollte man beim uC grundsätzlich
verzichten. Die Auswertung benötigt eine Menge RAM.
Man kommt mit den 8.3 Dateinamen eigentlich immer klar.
Unter DOS war das früher auch nicht anders ;)

von Kevin K. (kalhou)


Lesenswert?

Das Problem ist nur, wenn ich auf meinem MP3-Player eine Datei in Form 
von "Interpret - Titel" ablege, bekomme ich schon mächtig Probleme, da 
z.b. ein Album 10 Lieder drauf hat "Interp~1...10" wird schon ein wenig 
schwierig zum auslesen.

von holger (Gast)


Lesenswert?

>wenn ich auf meinem MP3-Player eine Datei

Ich wusste das du das sagen würdest!
Gut, da macht das Sinn. Welcher 8.3 Name zum
langen Dateinamen gehört ist relativ einfach
rauszufinden: Der 8.3 Eintrag steht direkt hinter
den Einträgen des langen Dateinamens.

von tbd (Gast)


Lesenswert?

oder id3-tags auslesen ;)

von kalhou (Gast)


Lesenswert?

das problem bei den id3 tags ist nur, dass sie unterschiedlicher nicht 
sein könnten. die einen stehen am anfang, die anderen am ende.. di einen 
beginnen mit TAG, die anderen mit id3 etc. das tag auszuwerten ist ja 
noch einfach, da immer 30 bytes reserviert sind.... werds wohl trotzdem 
irgendwie versuchen alle möglichkeiten auszulesen :o

von Daniel R. (zerrome)


Lesenswert?

hallo,

das problem von langen dateinamen ist das die auch mal 255 zeichen lang 
sein können.
ich finde, wenn man z.b. einen mp3 player baut, sollte der auch die id3 
tags anzeigen wenn er die lieder spielt. es git doch pc programme, die 
die mp3 sammlungen sortieren und ordentlich tagen...

grüße daniel

von kalhou (Gast)


Lesenswert?

So, hab jetzt ein bisschen mit der Library herumexpermientiert.
Was ich probiere zu machen ist z.b. mit ffls(); alle Dateien eines 
Verzeichnisses auszulesen und statt mit uart an den PC zu senden, die 
Dateinamen in einer weiteren Datei zwischenzuspeichern. Ist sowas 
theoretisch möglich oder müsste ich dafür mehrere Files offen haben ?
Hab schon ein wenig probiert die Funktionen auf mehrere Files 
umzuschreiben, aber zu der File Struktur die ich jedesmal als Zeiger 
übergeben muss kommt auch noch die Fat Struktur dazu, die ja atm. auch 
statisch ist und welche ich wohl auch irgendwie über einen Zeiger 
mitgeben müsste, aber um das umzuschreiben bin ich mir zu wenig mit dem 
FAT Dateisystem vertraut...

Jemand eine Idee ?

Gruss

von Daniel R. (zerrome)


Lesenswert?

hallo,

die funktion "lsRowsOfClust(unsigned long int start_sec)" in file-0.3.c 
bekommt einen start sektor eines clusters übergeben und arbeitet dann 
selbständig den cluster ab (also die sektoren). und in dieser funktion 
benutzt du einfach anstatt der uart ausgaben, einen teil in dem du die 
namen oder was auch immer dich interessiert von der datei woanders 
speicherst.
in dem teil wo die uart ausgaben sind ist die aktuelle datei auf dem 
struct:file zu finden, mit allen möglichen angaben. in dem struct:fat 
ist der aktuell geladenen sektor zu finden.
macht zusammen: name, attribut, reihe in sektor, den sektor selber, 
größe, länge, 1.cluster. also alles was man zur weiteren verarbeitung 
braucht.

hilft das?

güße daniel

von kalhou (Gast)


Lesenswert?

Das Problem ist nur, dass wenn ich dort wo die UART Ausgaben gemacht 
werden, probiere ein anderes File zu öffnen, dies nicht zu funktionieren 
scheint da er wohl immernoch etwas in der Fat struct am rumschreiben ist 
und ffopen ja schliesslich auch auf diese zugreift ?

Was mir gerade vorhin aufgefallen ist, dass die ffls Funktion mir die 
Dateien mehrmals ausgibt wenns mehr als nur ein paar auf der Karte hat.
z.b. habe ich 3 Ordner gemacht und er hat mir diese 3 Ordner einige Male 
aufgelistet und dazwischen immer Punkte ausgegeben z.b. wie folgt

ORDNER1
ORDNER2
ORDNER3
.
.
..
..
.
ORDNER1
ORDNER2
ORDNER3
.
.
..
..
.

etc.

von Torsten S. (tse)


Lesenswert?

1) In eine Codesammlung gehört fertiger, funktionsfähiger Code. Sagt ja 
der Name schon.

2) Gute Programmierkenntnisse der verwendeten Sprache sind dafür 
zwingend erforderlich.(#include "fat-0.3.c")

3) Es gibt bereits (erprobte) Libs hier in dieser Codesammlung die 
SD/MMC + FAT unterstützen. Wozu das Rad neu erfinden?

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ Torsten S.

sieh mal in meinen ersten post, 4. zeile...

#include "fat-0.3.c" funktioniert doch oder? übersichtlicher ist das 
auslagern von prototypen in *.h dateien auf jeden fall nicht !
c standart ist, dass jede datei auch einzelnd compilierbar sein soll. 
ist doch so auch gegeben.

warum das rad neu erfinden? weil ich mein eigenes rad will! zudem hat ja 
wohl selber machen noch den größten lerneffekt. so wie theorie und 
praxis halt !

@  kalhou

schick mir ein image von der karte und dem von dir verwendeten code, 
dann kann ich dir genau sagen woran es liegt. sonst must bischen selber 
probieren. bei mir läuft es, das einzige problem sind mit linux 
formatierte karten, weil die komischerweise das root dir, wenn es nur 1 
cluster groß ist mit 0x0ffffff8 als ende markiert haben...
und dachte es ist eindeutig, man kann IMMER nur eine datei zum 
lesen/schreiben/anhängen öffnen! man kann aber durchaus mehrere 
nacheinander öffnen usw...

von Torsten S. (tse)


Lesenswert?

Daniel Platte wrote:

> warum das rad neu erfinden? weil ich mein eigenes rad will! zudem hat ja
> wohl selber machen noch den größten lerneffekt. so wie theorie und
> praxis halt !

OK. Warum nicht. Aber bitte erst wenns fertig ist in die Codesammlung.

> #include "fat-0.3.c" funktioniert doch oder? übersichtlicher ist das
> auslagern von prototypen in *.h dateien auf jeden fall nicht !

Ein großer Fehler, diplomatisch ausgedrückt. Sei froh, das noch keiner 
von den C-Experten seinen Senf dazugegeben hat.

Bitte meine Posting nicht als rumnörgeln betrachten, sondern als 
konstruktive Kritik um Dich auf den "richtigen" Weg zu bringen.

Torsten

von Daniel R. (zerrome)


Lesenswert?

hm,

meiner meinung nach ist der code schon durchaus brauchbar. vielleicht im 
falschen forum, mag sein. dann möge es bitte jemand verschieben.

bei der letzten version mmc-0.3.zip läuft bei mir mit verschieden 
formatierungen und cluster größen alles gut.

warum sind *.h dateien denn so wichtig? bzw der richtige weg (hatte es 
ja auch schon geändert..)?

bin offen für verbesserungen und anregungen, ist ja der sinn weshalb der 
code hier öffentlich rumsteht :)

güße daniel

von kalhou (Gast)


Lesenswert?

Könnte ich Morgen mal machen..
hab den code allerdings ein wenig abgeändert. Man sollte allerdings 
rausfinden was es ist. Zu dem Prototypen: Hab es auch so gelernt, dass 
man die Prototypen in das Headerfile auslagert und im zugehörigen c File 
dann einfach das Headerfile dazunimmt. Was wirklich richtig ist weiss 
ich auch nicht. Vielmehr stört micht, das wenn ich in einem c File z.b. 
strings.h benutze und im main-File dann eine Funktion aus diesem c File 
aufrufen will ich dann nochmals strings.h includen muss.

von Kevin K. (kalhou)


Angehängte Dateien:

Lesenswert?

Hier ist mein Beispielcode!

Habe gewisse Anpassungen an den Libraries vorgenommen z.b. die Struktur 
für Fat und File im Headerfile definiert etc. aber der Code sollte 
allgemein verständlich sein.

Auf der SD Karte hatte ich lediglich 3 Ordner (ORDNER1,2,3). Die Karte 
ist eine 1GB SanDisk und ist mit FAT32 formatiert.

Der Code wurde im AVRStudio compiliert, daher stammt auch das Makefile, 
welches noch im Ordner enthalten ist.



Gruss

[EDIT]
hab gerade gesehen, dass die Karte mit FAT16 mit Vista formatiert war. 
Hab sie dann FAT32 formatiert und ging gleich. Allerdings bleibt mein 
Problem das ich während der Funktion ffls(); statt der UART Ausgabe eine 
Datei und dann den Namen der aktuellen Datei dort reinschreiben will ;)

von Daniel R. (zerrome)


Lesenswert?

hallo,

werd mir deinen code und den fehler bei fat16-ffls mal ansehen, 
allerdings leider erst sonntag. bin übers wochenende weg..

grüße daniel

von Daniel R. (zerrome)


Lesenswert?

hallo,
hab mir den code angesehen, läuft bei mir problemlos. schade das du kein 
image von der karte gemacht hast, mit der es nicht ging. so ist der 
fehler für mich nicht reproduzierbar.
zu deinem problem, was du möchtes ist eine datei suchen um dann etwas 
damit zu machen oder?

wenn ja:
die funktion ffopen gibt 0 zurück wenn die datei die du lesen/anhängen 
willst in dem aktuellen verzeichniss vorhanden ist. wenn 0 zurück kommt, 
ist die datei auch schon fürs lesen oder anhängen "vorbereitet", also 
mit ffread() / ffwrite() zugänglich. kommt 1 bei ffopen('w',dateiName") 
zurück ist die datei vorhanden und muss gelöscht werden vor dem 
schreiben.

wenn nein:
hab ich keine ahnung was du machen willst ;)
dann erkläre es mal...

grundsätzlich sollten die datei-operation funktionen in file-0.x.c nur 
extern genutzt werden, da so sicher gestellt ist, das alle flags und 
structs richtig geladen/gesetzt sind. das war nämlich das problem bei 
dem was du wolltest...
z.b. wenn man file.name benutzen will aber dann ffopen aufruft, läd 
ffopen was neues auf file.name, weil ffopen eben auch ein dir auf eine 
datei durchsucht, und alles mögiche auf file.name landet bevor man das 
hat was man will...

grüße daniel

von Kevin K. (kalhou)


Lesenswert?

genau gesagt möchte ich alle files eines ordner auslesen und statt dann 
die filenamen über usart auszugeben, würde ich gerne den filenamen in 
eine liste eintragen, die dann etwa so aussieht

"
DATEI1  MP3; Interpret1; Titel1
DATEI2  MP3; Interpret2; Titel2
DATEI3  MP3; Interpret3; Titel3
DATEI4  MP3; Interpret4; Titel4
"

das ganze wäre z.b. in einer txt datei eingetragen: Also soll er 
eigentlich jedes File in dieser Form in eine Liste eintragen (ID3 Tag 
Erkennung habe ich schon gemacht)

wenn ich mehrere Files offen haben könnte wäre das ja kein Problem, da 
aber die Funktion lsRowsOfClust() selbst auf die File/Fat Struktur 
zugreifft gibt es ein Problem solange ich nur eine Datei offen haben 
kann.
Was mir in diesem Zusammenhang aufgefallen ist: Du hast ja anfänglich 
gesagt du würdest kein Support für mehrere Files die offen sind 
anbieten, da damit möglichst wenig Ressourcen gebraucht werden, 
allerdings sieht es so aus als wäre in fat-0.x.c eine statische Variable
1
extern unsigned char   sector[512];
 vorhanden die immer 512bytes Platz wegnimmt, ob man nun eine Datei 
offen hat, oder nicht..

von Daniel R. (zerrome)


Lesenswert?

hallo,

wieso willst du so eine datei anlegen? ist doch doppelt, weil es diese 
struktur doch eigentlich schon in dem ordner gibt...
man könnte das ganze so erweitern, dass id3 tags ausgelesen werden und 
mit angezeit werden, anstatt z.b. die länge der datei.

ps: hab grade getestet, läuft auch problemlos auf atmegas die nur 1kB 
ram haben.

von Daniel R. (Gast)


Lesenswert?

Hallo,
kann man mit der Lib auch formatieren?

von Daniel R. (zerrome)


Lesenswert?

hallo,

nein kann man nicht und wird man auch erstmal nicht.

von G.K. (Gast)


Lesenswert?

Daniel Platte (zerrome)

Danke für Deine Beiträge in Groß-/Kleinschreibung.

von gast (Gast)


Lesenswert?

> Danke für Deine Beiträge in Groß-/Kleinschreibung.

Da klemmen noch mehr Tasten. Beispiel:
1
*(unsigned char*)vi++=*bytesOfSec++;

von Siegmar (Gast)


Lesenswert?

"sUpEr Kommentare"

von JoJo (Gast)


Lesenswert?

Warum fehlen in so vielen Libs die Formatier-Routinen?
Sind die so aufwendig?
Kann doch jedes Handy/Kamera außerdem erspart man sich
damit die "Kompatibilitätsprobleme" mit Windows etc.

von Daniel R. (zerrome)


Lesenswert?

hm,

hab mir ehrlich gesagt noch nie gedanken darum gemacht eine formatier 
routine zu schreiben, wäre sicher nicht besonders schwer. gut, bei 
gelegenheit mach ich das mal :)

groß/kleinschreibung ist einfach nur nervig. ich schreibe außerdem sehr 
viel jeden tag, da bin ich froh wenn ich mal meine kleinen finger etwas 
schonen kann (die betätigen shift bei 10 finger tippen).


1
*(unsigned char*)vi++=*bytesOfSec++;

mit einem gecasteten void pointer byteweise auf 4 byte große variablen 
zu schreiben ist bis jetzt noch die eleganteste lösung meiner meinung 
nach...

güße daniel

von Joachim (Gast)


Lesenswert?

> Warum fehlen in so vielen Libs die Formatier-Routinen?
> Sind die so aufwendig?

Man muss für jede Kartenkapazität die passenden Werte (Clustergröße 
etc.) festlegen. Windows benutzt hierzu noch aus den alten DOS-Zeiten 
entstandene Werte. Nimmt man willkürlich andere Kombinationen, kann es 
Kompatibilitätsprobleme mit Windows geben. Deshalb ist es besser, gleich 
auf einem PC zu formatieren.
Außerdem sind alle SD-Karten werkseitig mit FAT16/32 vorformatiert.

> Kann doch jedes Handy/Kamera

Handy und Kameras können viel. Zum Beispiel auch nette Bildchen und 
Menüs auf Displays anzeigen.
Ist aber kein Problem. Gib einem Mikrocontrollerfreak 0,01 Cent für 
jedes je verkaufte Handy oder jede Kamera, und er wird Dir jede 
erdenkliche Funktion in der Lib implementieren ;-)
Ich selbst habe z.B. noch nie eine Karte in einer Kamera formatiert.
Wozu soll das gut sein? (Fotografiere sehr viel mit Canon EOS 20D)

> außerdem erspart man sich damit die "Kompatibilitätsprobleme" mit Windows etc.

Wenn man selbst formatiert und nicht alles genau richtig macht, fangen 
die Kompatibilitätsprobleme mit Windows etc. erst an!


Joachim

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

hier nochmal eine etwas verbesserte version.
bug in run_cmd behoben.
benchmark teil kann mit #define benchmark 0 oder 1 ein oder aus 
geschaltet werden.

grüße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

bug beim leere datei lesen beseitigt.

so das wäre es dann erstmal.

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

die neuste version ist erweitert um:

ffmkdir - legt verzeichniss in aktuellem verzeichniss an.
ffrm    - kann jetzt auch ordner löschen. löscht rekursiv !

in der fat-0.3.h ist ein define :

#define smallFatSys  1

wird es auf

#define smallFatSys  0

gesetzt, dann passt der code in einen atmega8 , mit schreib und lese 
unterstüzung und kommando prompt !

falls jemand fehler findet, bitte melden !

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

bugfix in ffrm...

von Timo (Gast)


Lesenswert?

Hallo Daniel,

erst einmal Danke für die Arbeit die du dir machst.

Allerdings habe ich noch ein Problem:
(Vorneweg: Ich benutze die Version 0.3.1 und den CodeVisionAVR-Compiler.
 Ich habe also den Code an einigen Stellen angepasst. Dies betraf in den
 meisten Fällen jedoch nur Variablendeklaration u.ä..)

Also:
Ich erstelle eine Datei mit
1
temp = ffopen('w',dateiim8.3format);
, was auch wunderbar funktioniert.
Nun möchte ich an diese Datei jeweils verschiedene Daten (Strings) 
anhängen
(z.B. Datum  Uhrzeit  ...) und die TXT-Datei später im PC auslesen.
1
temp = ffopen('a',dateiim8.3format);
2
ffwrite('irgendeinzeichen');
3
...
4
ffclose;

Das funktioniert auch noch, allerdings nur bis die Datei eine Größe von 
512Byte überschreitet. Lese ich nun die Datei im PC aus, sehe ich nur 
die Zeichen, die auf den neuen Sektor geschrieben wurden.
Dies ist bei allen Vielfachen von 512 der Fall. (Also bei jedem neuen 
Sektor?)
Nun würde mich mal interessieren, ob das ein allgemeiner Fehler ist oder 
ob ich beim Anpassen an CodeVision einen Fehler gemacht habe.
Wenn das der Fall ist, wäre ich für Tips dankbar, wo ich zu suchen habe. 
;)

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

ja danke. dicker bug in ffwrite und was blödes in ffopen.


ist geändert !

och als arbeit würde ich das nicht umbedingt bezeichnen ;) macht doch 
spass

von Timo (Gast)


Lesenswert?

Ok, schon mal Danke fürs Ändern.
Mit meinem CodeVision bekomme ich nun leider in so fern Probleme, das 
beim Linken die Fehlermeldung: "Error(s) occured" during assembly." 
erscheint. Könntest du mir sagen, an welchen Funktionen Du für die 
Version 0.4.2 etwas geändert hast, damit ich nicht alles noch mal 
portieren muss?!

also in ffopen, ffwrite & fat_setCluster hab ich schon was gefunden..

schon mal vielen Dank...

von Lolipop E. (lolipoper)


Lesenswert?

Mir ist nun mein ForumPW wieder eingefallen, deswegen nicht mehr Timo, 
sondern nun LoLiPoPer.
Ich habe nun einfach noch mal die komplette Version 0.4.2 nach CV 
portiert.

Jetzt klappt es schon besser. Aber es läuft noch nicht ganz rund.
Jetzt steht in der Datei, die ich wie oben beschrieben anlege, der erste 
Teil (die ersten 512 Bytes) drin, dann ist eine Pause von 512 Byte(nur 
Leerzeichen)und ab hier gibt es noch kleine Fehler jeweils wenn die 
Vielfachen von 512Bytes erreicht werden.
Kleine Fehler in so fern, dass immer ein paar Zeichen verloren gehen.
Das ganze sieht in der TXT in etwa so aus:


<----512Byte----><----512Byte----><----512Byte----><----512Byte----><--- 
--...
"text text text ""               ""text text tex"    "text text t"
                         |                         |                |
                   große Lücke                kleine Lücke     kl. Lücke

Wenn du da noch mal schauen könntest, wäre das klasse..
Macht ja Spaß ;)

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

eben erst zurück gekommen...

da ist wohl noch eine variable falsch gesetzt gewesen.
danke für deine mithlife und geduld. bin selbst die ganze zeit schon am 
bugs suchen, aber je mehr mitmachen umso besser wird es werden.

ist ein wenig umständlich hier nur den auszug zu posten, deshalb als 
anhang die geänderte file-0.3.c

geändert nur eine zeile in ffopen in dem teil:
1
   if(option=='a' && file_flag==0){
und zwar fehlte die angabe(nach zeile 94):
1
   cntSecOfClust=s+1;
die für ffwrite nötig ist, um zu wissen in welchem sektor des clusters 
man sich grade befindet. die berechnung ist da auch noch etwas 
umständlich, wie auch in ffseek...

von Lolipop E. (lolipoper)


Angehängte Dateien:

Lesenswert?

Servus..

bei der Menge an Code ist es ja ganz klar, dass man mal ne Kleinigkeit 
übersieht. Alles klein Problem..

Die von mir beschriebene "große Lücke" ist nun weg. Die kleinen gibt es 
allerdings immer noch.
Ich hänge als Anhang mal die Textdatei an, damit du dir selbst n Bild 
machen kannst.
In der Datei werden immer Datensätze in dieser Form:
#;NUMMER;DATUM;UHRZEIT;MESSWERT (für Import in Excel)
aneinandergereit. An einigen Stellen fehlen eben einige Daten.
(Wenn du die Datei mit Excel öffnest ist das auch ganz gut zu erkennen.)

Was mir noch aufgefallen ist:
Wenn ich mit ffopen('w',"DATEINAMTXT"); eine Datei anlegen will, diese 
jedoch schon existiert, bekommen ich von ffopen nicht immer den 
Rückgabewert 1 geliefert. d.h. die Datei wird neu angelegt und befindet 
sich dann zwei mal auf der SD-Karte. Die Inhalte sind jeweils die 
gleichen und es geht auch nix verloren. Schön is das aber nicht. ;)
Ab und zu ist der Rückgabewert aber korrekterweise auch 0.

So, das sollte erst mal genug sein.. ;)

von Daniel R. (zerrome)


Lesenswert?

hallo,

woher kommen die daten die auf die karten sollen denn? sind die auf 
jeden fall korrekt? werde morgen nochmal exzessiv testen mit großen 
datenmengen und hin und her kopieren von dateien usw...

hattest du die karte neu formatiert, als du den neuen code verwendet 
hattest?
wenn nicht könnten so sachen mit ffopen('w',"DATEINAMTXT"); passieren. 
werde ich mir morgen aber auch nochmal genau anschauen.

güße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

kann die bugs nicht bestätigen. habe mehrere dateien mit w erstellt, mit 
a sachen angehangen in verschiedenen größe (vielfachache von 512 usw). 
läuft immer alles ok. kommen deine daten über den uart?

poste doch mal die funktionsaufrufe wie du sie machst. vielleicht werd 
ich daraus schlauer.

als anhang nochmal das aktuellste programm

von Lolipop E. (lolipoper)


Lesenswert?

hmm.. wenns bei dir so läuft, kann es ja eigentlich nur an mir liegen.

Ich poste mal die Funktionsaufrufe, evtl. ist ja dort ein Schnitzer 
drin.
Ansonsten kann es ja immer noch sein, dass beim Portieren nach CV was 
falsch gelaufen ist.

Vorweg: Die SD-Karte ist eine ScanDisk 512MB.
        Formatiert habe ich diese mit WindowsXP Prof. als FAT und auch 
mal
        als FAT32. (Ich formatiere die Karte auch bei ca. jedem 2. 
Versuch
        neu.)
Hier jetzt die Aufrufe:
1
// External Interrupt 6 service routine                                    
2
// Interrupt wird ausgelöst, wenn entweder die SD-Karte rausgezogen oder 
3
// eingesteckt wird. Entsprechend wird SD_ONLINE = 0 gesetzt oder die 
4
// Initialisierung durchgeführt und SD_ONLINE = 1 gesetzt.
5
interrupt [EXT_INT6] void ext_int6_isr(void)
6
{  
7
  char temp;
8
  delay_ms(500);    //Warten, bis Karte richtig ein- / ausgesteckt
9
  if(((SD_Detect)==0)&&(SD_WriteProtect==0)){
10
        puts1(SDKartegefunden);
11
        
12
        puts1(SDInit);
13
        temp = mmc_init();              
14
        if(temp==0){
15
                puts1(OK);     
16
                puts1(FATInit);
17
                temp = fat_initfat();                  
18
                if(temp==0){
19
                        puts1(OK);
20
        
21
                        puts1(messdatatxterstellen);
22
                        temp = DV_MESSDATATXTerstellen();
23
                        if(temp==0)puts1(OK);
24
                        else puts1(Dateibereitsvorhanden); 
25
                        
26
                        SD_ONLINE = 1;
27
                        }    
28
                 else puts1(Fehler);
29
        }
30
        else puts1(Fehler);
31
  }      
32
  else {
33
    puts1(SDKartenichtgefunden);
34
    SD_ONLINE = 0;
35
    }
36
}
dazu die Funktion DV_MESSDATATXTerstellen();
1
char DV_MESSDATATXTerstellen(){
2
        char temp=0;                            
3
        temp = ffopen('w',messdatatxt);
4
        if(temp==1) return(1);                  //Datei existiert bereits             
5
        do{   
6
                ffwrite(messdatatext[temp]);
7
                temp++;
8
        }
9
        while(messdatatext[temp]!='\0');        
10
        ffclose();
11
        return(0);   
12
        }
Diese Funktion wird in der mainloop jede Sekunde aufgerufen:
1
char DV_MessungSpeichern(int Nummer){
2
        char temp;
3
        char TEMP[4]="   ";  
4
        unsigned long int Abstand; 
5
        unsigned char Abstand_ASCII[32];
6
        #asm("cli");
7
        
8
        itoa(Nummer,TEMP);
9
        
10
        temp = ffopen('a',messdatatxt);
11
        if(temp==1) return(1);                  //Datei nicht vorhanden
12
       
13
        ffwrite('#');                           //Zeilenführungszeichen 
14
        ffwrite(';');      
15
        
16
        ffwrite(TEMP[0]); 
17
        ffwrite(TEMP[1]); 
18
        ffwrite(TEMP[2]);
19
        ffwrite(';');     
20
        
21
        ffwrite(Tag_ASCII[0]);
22
        ffwrite(Tag_ASCII[1]);
23
        ffwrite('.');       
24
        ffwrite(Monat_ASCII[0]);
25
        ffwrite(Monat_ASCII[1]);
26
        ffwrite('.');         
27
        ffwrite(Jahr_ASCII[0]);
28
        ffwrite(Jahr_ASCII[1]);
29
        ffwrite(Jahr_ASCII[2]);
30
        ffwrite(Jahr_ASCII[3]);
31
        ffwrite(';');        
32
        
33
        ffwrite(Stunde_ASCII[0]);
34
        ffwrite(Stunde_ASCII[1]);
35
        ffwrite(':');  
36
        ffwrite(Minute_ASCII[0]);
37
        ffwrite(Minute_ASCII[1]);
38
        ffwrite(';');  
39
        ffwrite(';');      
40
        
41
        ffwrite('\n');
42
        ffwrite('\r');
43
        ffclose();  
44
        
45
        #asm("sei"); 
46
        MessungNr++;
47
        return(0);   
48
        }
Die Variablen Sekunde_ASCII, usw. sind globale Variablen, die aus einem 
RTC-Chip stammen. Die Variablen gebe ich im mainloop jeweils zur 
Kontrolle per UART aus.(Da stimmen die Daten immer.)
messdatatxt ist ein globaler String:char* messdatatxt="MESSDATATXT";

Ich hab jetzt noch mal rumprobiert. Folgende Fehler treten auf:
- Ein Datenblock 512Byte fehlt ganz(kommt sehr selten vor).
- Einige Datensätze fehlen teilweise.
- MESSDATA.TXT wird mehrfach erstellt

Hoffentlich hab ich hier was falsch gemacht. Sonst wirds ungemütlich..

von Daniel R. (zerrome)


Lesenswert?

hallo,

also die karte sollte nur dann abgezogen werden, wenn ganz sicher keine 
schreib/anhäng operation gemacht wird. also besser einen pin mit 
schalter versehen und erst nachdem der schalter gedrückt wurden und 
sicher ist, dass die karte nichts mehr macht raus ziehen. oder irgnedwie 
anders sicher stellen, dass keine operation läuft während man den strom 
wegnimmt.

grundsätzlich sieht dein code ok aus. benutzt du die letzte version der 
lib?

habe mit:
 fat32 und 4 sektoren pro cluster
 fat16 und 1 sektor   pro cluster
 fat16 und 4 sektoren pro cluster,
getestet. hab über das programm dateien auf die karte geschrieben, 
angehangen, ausgelesen usw. alles ohne probleme.
kannst du evtl. noch fat und file *.c dateien posten, dann schau ich mir 
mal die änderungen dort an.

hast du ein delay in der main, um DV_MessungSpeichern aufzurufen, oder 
mit timer?

güße daniel

von Lolipop E. (lolipoper)


Angehängte Dateien:

Lesenswert?

moin moin...

jipp, den Taster hab ich drin. Bevor ich die Karte abziehe setze ich 
über einen Taster SD_ONLINE = 0; und DV_MessungSpeichern(); kann nur bei 
SD_ONLINE ==1; aufgerufen werden.
1
 if(SD_ONLINE){ 
2
        temp = DV_MessungSpeichern(MessungNr);
3
        }

Ich hab jetzt mal etwas umprogrammiert. Und zwar beim EXTINT6 mit 
einigem Erfolg:
1
// SD-Card initialisation // FAT-File System initialisation
2
if(((SD_Detect)==0)&&(SD_WriteProtect==0)){
3
        puts1(SDKartegefunden);       
4
        puts1(SDInit);
5
        temp = mmc_init();              
6
        if(temp==0){
7
                puts1(OK);
8
        
9
                puts1(FATInit);
10
                temp = fat_initfat();                  
11
                if(temp==0){
12
                        puts1(OK);
13
                        puts1(messdatatxterstellen);
14
                        temp = ffopen('r',messdatatxt);
15
                        ffclose();
16
                        if(temp==1){
17
                          DV_MESSDATATXTerstellen();
18
                          puts1(OK);
19
                          SD_ONLINE = 1;  
20
                          }           
21
                        else puts1(Dateibereitsvorhanden); 
22
                        }    
23
                 else puts1(Fehler);
24
                 }
25
        else puts1(Fehler);
26
        }
27
else puts1(SDKartenichtgefunden);
sprich: Ich mache die Abfrage, ob eine Datei schon vorhanden ist, indem 
ich versuche sie zu lesen.
Was merkwürdig ist: Auch wenn die Datei vorhanden ist, liefert 
ffopen('r',..); anscheinend immer 1 zurück.
Damit wird DV_MESSDATATXTerstellen(); jedesmal ausgeführt. ABER:
Es bleibt bei EINER Datei!! (verstehe im mom nicht wirklich warum, aber 
das Ergebnis ist das Erwünschte!)
Das Problem reduziert somit auf einen einzigen Fehler:
Wenn ich weniger als 1024Bytes in eine TXT-Datei schreibe klappt alles 
wunderbar. SChreibe ich jedoch mehr als 1024Byte in die Datei fehlen die 
2. 512Bytes (bzw sind diese mit Nullen(Leerzeichen) aufgefüllt). Danach 
ist wieder alles OK.

DIe Lib ist die 0.4.2!

Ahja, und DV_MessungSpeichern(); wird nach einem delay aufgerufen.
(Das auch nur zur Probe. Später soll das dann per Taster laufen.)

Im Anhang sind noch die File.c & die FAT.c. Allerdings in einer 
TXT-Datei, da ich den Code erst mal einfach in die MAIN.c geknallt habe.

Hoffe, du musst nich zu viel Aufwand betreiben..
ALso schon mal Danke..

von Daniel R. (zerrome)


Lesenswert?

hallo,

ich kanns nicht sehen, aber du sorgst doch dafür, dass bei programmstart 
file_flag mit 0 initialisiert wird(ein ffclose macht das auch..)? es 
gibt nämlich nur 3 möglichkeiten warum ffopen('r',datname); 1 zurück 
gibt.

1. wenn file_flag nicht 0 ist.
2. wenn die datei nicht im aktuellen verzeichniss gefunden wurde.
3. wenn das laden des 1. sektors der datei fehl schlägt.

ich habe in der option bei ffopen im write teil etwas geändert, 
erscheint mir sicherer, änder das auch noch grad.
1
if(option=='w' && file_flag==0){  
2
   if(1==fat_loadFileDataFromDir(name)){
3
   ...
4
   ...
5
   ...
6
   return(0);
7
   }
8
}

warum bei daten größer 1024 dieser bug bei dir auftritt ist mir grad 
noch ein rätsel, schau ich mir aber noch genau an.

nach dem delay hatte ich nur gefragt, um sicher sein zu können, dass da 
kein interrupt irgendwo reinpfuscht :)

für mich wäre noch interessant, wieviele sektoren pro cluster hat die 
karte mit fat32 formatiert? wenn du das so grad nicht nachsehen kannst, 
mach einfach mal sowas nach der fat init:
1
char tmp[12];
2
ultoa(fat.secPerClust,tmp,10);
3
uputs("secPerClust: ");
4
uputs(tmp);


ach was mir grad noch einfällt, wie ist die karte an den avr 
angeschlossen?
da können auch mal ein paar bytes verloren gehen wenn die kabel zu lang 
oder so. bin selber jetzt auch auf einen 74hc4050 umgestiegen um die 
karte zuverlässiger anzuschließen (kostet 40 cent).

grüße daniel

von Lolipop E. (lolipoper)


Lesenswert?

Mal wieder Hallo!;)

Das file_flag hatte ich nicht expliziet mit 0 initialisiert. Ich dachte, 
sowas läuft über die Initialisierung von fat_initfat();
Probiert hab ich das jetzt aber mal (auch mit ffclose(); beim 
Programmstart), bringt aber keine Änderung.

Den Teil in ffopen hab ich aktualisiert.

Am Anschluss der Karte kann es eigentlich nicht liegen, da ich das 
"Savvy128"-Board von chip45.com verwende.

Interrupt verwende ich schon, allerdings schalte ich die bei jedem 
Zugriff auf die Karte mit #asm('cli');  aus.
(Ext. Interrupt vom RTC-Chip)

Deinen Code zur Sektorenbestimmung liefert bei FAT32 den Wert "8" und 
bei FAT den Wert "16".

hmm.. mit dem Umweg über ffopen('r',..); zur Dateienerstellung kann ich 
leben, nur das Löschen der Daten wenn ich mehr als 1024 Byte schreibe 
stört schon.

von Daniel R. (zerrome)


Lesenswert?

also,

nach nochmaligem debugen kann ich einen fehler da aussließen.
wichtig ist einfach nur die reihenfolge:

1. ffopen
2. ffwrite/ffread
3. ffclose

dann kann da nix schief gehen. irgendwo fehlt warscheinlich eine 
kleinigkteit in deinem code, irgend eine änderung die ich gemacht habe, 
die du aber nicht gemacht hast. probier mal einfach so in einem test 
programm, die funktionalität der fat-lib (neuste version mmc-0.4.3.zip). 
so kommst du vielleicht auf den fehler.
hab auch nicht deinen ganzen code um mir das mal anzusehen.
z.b. hast du
1
unsigned char ffwrite(unsigned char c){
2
   unsigned long int clusterOld;
3
   clusterOld=currentCluster;
4
   ...
5
   ...
das so geändert. da wird beim schreiben von einem byte immer direkt auch 
eine unnötige long int operation gemacht (4 byte operation), das ist 
ungünstig.

die von dir beschriebene lücke klingt für mich so, als wenn da ffclose 
irgendwo falsch aufgerufen wird.

grüße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

als anhang mal eine ganz einfache nutzung der lib.
erstellt eine datei, schreibt daten rein und hängt daten an.
erstellt einen ordner und erstellt die datei nochmal darin.

grüße daniel

von Kai F. (kai-) Benutzerseite


Lesenswert?

Hallo,
saubere Arbeit!
Vielleicht wäre es bald übersichtlicher einen wiki Artikel zu schreiben, 
wo auch Minimal und Optimalschaltplan drin sind und immer die neuste 
Version drin steht. Eine SD Lib für Codevision wäre super, poste also 
bitte mal den Code sobald er läuft.
Viel Spaß noch

Kai

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ Lolipop Er
wie siehts denn jetzt aus bei dir? läuft es oder nicht?
wenn es dir nichts ausmacht, poste doch auch mal so eine mini version 
mit den änderungen für codevision. falls das noch nicht läuft, können ja 
vielleicht auch andere mal mitschauen.

@  Kai Franke
zum thema wiki, hab ich noch nie gemacht. interesse scheint auch nicht 
allzu groß zu sein. übersichtilicher wäre es allerdings schon ;)

grüße daniel

von Lolipop E. (lolipoper)


Lesenswert?

hey Daniel,

jetzt rennt er!! ;)
Ich habe noch mal die Version 0.4.3 neu portiert. Anscheinend war die 
Kleinigkeit, die Du da geändert hast ausschlaggebend.

Bevor ich das online stelle, möchte ich noch mal ein bisle mit den 
Ordneroperationen rumspielen um zu sehen ob das auch fehlerfrei 
funktioniert.
Und alles n bisle ordentlich machen. (also *.c - & *.h files erstellen.)

Müsste ich bis heut Abend hinbekommen.

bis dann..

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

äh ja, ordner operationen da gibt es noch was... tritt selten auf, aber 
hier der bugfix, sorry.

muss man denn viel ändern zu codevision? ist doch auch ein standart c 
compiler, oder?

von Kai F. (kai-) Benutzerseite


Lesenswert?

Da ich bis zum 15. meinen Artikel für den Artikelwettbewerb fertig haben 
muss, werde ich wohl bis dahin auch wissen wie man einen wiki Artikel 
erstellt und biete an auch für diesen Artikel einen zu erstellen.
Ich sage dann nochmal Bescheid, dann könnt ihr mir ja beide eure 
Errungenschaften schicken und ich vereine sie im wiki.
Editieren und hinzufügen wird ja jeder hinbekommen :P

Gruß
Kai

von Lolipop E. (lolipoper)


Angehängte Dateien:

Lesenswert?

Soo..
denn stelle ich mal den Code online.

So viel ist nicht zu ändern für CV. Hauptsächlich die 
Variablendeklarationen. Ist aber schon immer etwas Aufwand.
Aber nun hab ichs noch mal mit der V0.4.4 gemacht. (Allerdings hab ich 
die Funktionen nicht noch mal sauber formatiert.)
Wenn da noch irgendwo was zukommt, änder ichs auch gern noch mal.(Wäre 
natürlich schöner, wenn ich wüßte in welchem Teil was geändert wurde, 
dann muss ich nicht alles neu machen.)

Der Code wurde auch nicht in irgendeiner Weise extrem optimiert. Wichtig 
war mir in erster Linie, dass alles einwandfrei funktioniert und das 
ist, soweit ich weiß, auch gegeben.

@Daniel:
Wenn Fehler gemeldet werden, wäre es klasse, wenn du da mit nachschauen 
könntest und ich übernehme die Änderungen für CV.

von Daniel R. (zerrome)


Lesenswert?

hallo,

@ Kai Franke

fänd ich super, wenn du daraus einen wiki artikel machen würdest. ich 
schreibe gerne ein paar allgemeine sachen zur fat oder auch speziell zu 
dem code oder so...

@ Lolipop Er

werde die änderungen die ich jetzt ab version 0.4.4 mache in den dateien 
dokumentieren. angepeilt ist so ab version 0.5.x dass die statische 
variable sector[512] dynamisch übergeben wird. so könnte man, wenn das 
programm grade nicht den fat teil nutzt, 512 bytes ram sparen.
werde mir später mal deine umsetzung ansehen.

grüße und danke für die aktive teilnahme

daniel

von Florian (Gast)


Lesenswert?

Hi.
Leider funktioniert das schreiben nicht bei mir.
Er hängt sich immer bei ffopen auf...

Was ist da los?

Gruß Flo

von Daniel R. (zerrome)


Lesenswert?

hallo,
seltsam, also die initialisierung klappt?
was benutzt du für eine karte und wie ist die karte angeschlossen?
wie lautet der genaue aufruf von ffopen, also mit welchen parametern 
usw.

du benutzt die aktuelle version (mmc-0.4.4.zip)?

grüße daniel

von Florian (Gast)


Lesenswert?

Ich benutze version 0.4.4.
Habe den ATMega128.
Die SD karte ist am Hardware SPI interface angeschlossen.
ffopen gibt 1 zurück.

//********************************************************************** 
*******************************************
int main(void){

  lcd_init();
  lcd_string("Computer start",0);

  RoteLED();

  set_cursor(0, 3);
  lcd_string("0%",0);


  //----------sd-karte initialisieren----------
  if(mmc_init() !=0)
  {
    lcd_clear();
    lcd_string("Keine SD-Karte ist eingesteckt.",0);
    while(1);
  }
  //----------sd-karte initialisieren----------



  set_cursor(0, 2);
  for(int i=0;i<16;i++)
  {
    lcd_data(0xff);
    _delay_ms(10);
  }



  set_cursor(0, 3);
  lcd_string("100%",0);

  _delay_ms(1000);
  lcd_clear();



  //----------fat initialisieren----------
  if(fat_initfat()!=0)
  {
    lcd_clear();
    lcd_string("Fat konnte nicht gelesen werden!",0);
    while(1);
  }
  //----------fat initialisieren----------


  lcd_string("FAT-16 gelesen",0);




  if(ffopen('w',"DELME   TXT")==1)
  {
    lcd_clear();
    lcd_string("File konnte nicht angelegt werden!",0);
    while(1);
  }

    //2
  unsigned char str[22]="das soll auf die karte";
  unsigned char i=0;

    //3
  do{

     ffwrite(str[i]);
     i++;
  }while(str[i]!='\0');

  //4
  ffclose();



  set_cursor(0, 2);
  lcd_string("Fertig",0);

  while(1);

  return 0;
}

Ist da was falsch?

Gruß Flo

von Daniel R. (zerrome)


Lesenswert?

hm,
ffopen mit option 'w' gibt auch 1 zurück wenn die datei schon vorhanden 
ist.
versuch mal ein
1
ffrm("DELME   TXT");

vor dem öffnen mit ffopen. das würde die datei löschen für den fall das 
sie da ist.
sieht sonst richtig aus...

von Daniel R. (zerrome)


Lesenswert?

ach was ich grad sehe,
der code von dir ist teilweise aus einem blöden beispiel...
der string str[22] müsste 23 zeichen lang sein, weil
"das soll auf die karte" sind 22 zeichen.

von Florian (Gast)


Lesenswert?

Also habe den Code nun geändert.
Jetzt geht das Programm glatt durch (ohne Fehlermeldungen).
Doch auf dem PC wird keine datei angezeigt. (Auch im Hex-editor sehe ich 
keine neuen einträge!)
Irgendwas stimmt da nicht...

Gruß Flo

von Daniel R. (zerrome)


Lesenswert?

hm

das ist mal komisch. ist die karte vielleicht partitioniert? dann muss 
man das umstellen auf:

#define superfloppy  0

in der fat-0.4.h

standartmäßig ist das so eingestellt, das die karte unpartitioniert ist.

würde erklären warum der pc keine daten sieht, aber die initialisierung 
der karte am mc durchläuft und auch geschrieben werden kann. bei 
fat_initfat() wird nicht auf sinnigkeit der ausgelesenen daten geprüft. 
ergo landen die daten an merkwürdigen stellen der karte, weil die 
bereiche der fat falsch ausgelesen werden...

von Florian (Gast)


Lesenswert?

JUHUHUHU es klappt.
Genau der Fehler war es... ^

Einfach #define superfloppy  auf 0 stellen und ich kann lesen und 
schreiben!!

Vielen Dank.
Gruß Flo

von Daniel R. (zerrome)


Lesenswert?

hallo,

schön das es klappt. muss mir mal überlegen wie ich erkennen kann ob im 
sektor 0 ein mbr steht oder der erste sektor der fat, dann könnte man 
das automatisieren...

grüße daniel

von Daniel R. (zerrome)


Lesenswert?

ein neues update.
die änderungen sind in den *.c dateien dokumentiert.
änderungen nur in der fat-0.4.c und file-0.4.c.

grüße daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

äh hier auch noch die dateien...

von Alex (Gast)


Lesenswert?

Hallo,

mich würde interessieren ob ihr auch solche Probleme mit dem Compiler 
habt in AVR-Studio. Mit jedem Fehlermeldung die ich beseitige, 
erscheinen 10 andere. Das ist ja nichts besonderes :D aber irgendwann 
war ich mit meinem Latein am Ende...

Hat einer von euch eine fehlerfreie AVR-Studio version?

lg alex

von Alex (Gast)


Lesenswert?

Ich nochmal,

das Problem mit den mit AVR-Studio lag wohl am Projekt an sich. Nach 
einem Computer-Neustart und eines neuen Projekts hat das compiling 
fehlerfrei funktioniert.

Bei meinem ATmega88 bedeutet das mit -0s Program: 7498 bytes (91.5% 
Full)
mit smallFileSys 0.

Habe noch zwei Fragen:

1. Wie wirkt sich smallFileSys auf den Funktionsumfang aus?

2. Gibt es ein switch für NUR Schreibzugriff? Bzw. welche Funktionen 
kann ich weglassen um mehr Programmspeicher zu haben.

lg alex

von Daniel R. (zerrome)


Lesenswert?

hallo,

bei "smallFileSys 0" fällt das löschen von dateien und das rekursive 
löschen von ordnern weg, das anlegen von ordnern und das wechseln in 
einen höheren ordner auch ("cd.." quasi). der rest ist dabei.

einen schalter um nur schreib bzw lese zugriffe zu machen hatte ich auch 
schon vor. werd ich auch die tage noch machen. das problem dabei ist, 
dass einige funktionen die zum lesen gebraucht werden auch zum schreiben 
gebraucht werden, ich kann grad nicht so abschätzen wieviel kleiner das 
wird. nur lesen wird man wohl auf weniger als 3 kByte bekommen.

bei mir gab -O2 den kleinsten code


gruß daniel

von Daniel R. (zerrome)


Lesenswert?

also,

ich bekomme eine nur lesen version auf 3618 bytes code gedrückt, ohne 
weitere optimierungen und ohne tolle ff-funktionen wie ffseek usw.
eine nur schreiben variante wird aber nicht viel kleiner werden können 
als 5990 bytes an code. das liegt daran, dass man ja auf jeden fall auch 
das dateisystem lesen muss um schreiben zu können...
will man ein verzeichniss wechseln können, muss der ganze lese kram mit 
rein...
möchte man nur einen daten logger bauen, so wird wohl ein atmega88 oder 
8 mit 8 kBytes flash reichen, will man da mehr, braucht mann mehr flash.

grüße daniel

von Alex (Gast)


Lesenswert?

Hallo,

das hört sich ja sehr gut an :D

Ich bin an der nur schreiben variante interessiert, wäre nett wenn du 
das mal bei gelegenheit zu verfügung stellst.

viele Grüße alex

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hallo,

sorry hat etwas gedauert...
die änderungen sind nicht wild...

avr-size main_.hex
mit den schaltern (nur schreiben ohne große datei funktionen) :
1
#define smallFileSys 0  
2
#define write 0

gibt nach dem kompilieren 6538 bytes an code an. sind doch 500 mehr, 
weil ich übersehen hatte das man beim schreiben auf jeden fall auch noch 
ffseek braucht.

mit den schaltern (komplette unterstützung):
1
#define smallFileSys 1
2
#define write 0

wird der code 8228 bytes groß.

mit den schaltern (minimal system, nur lesend):
1
#define smallFileSys 1
2
#define write 1

wird der code 3618 bytes groß.


güße daniel

von Thomas (Gast)


Lesenswert?

Hallo!

Danke für die Bibliothek!
Insgesamt laufen die Funktionen ganz gut. Mit 2 Sachen habe ich jedoch 
noch einige Probleme:

1. Die Funktion ffopen('w', ...) braucht bestimmt 10 Sekunden um zu 
Entscheiden, dass die Datei nicht vorhanden ist, und eine neue angelegt 
werden muss. Ist das normal? ffopen('a', ...) braucht nämlich nur wenige 
ms.

2. Die Funktion ffopen('a', ...), bzw. das zugehörige ffclose schließt 
die Datei nicht korrekt, sodass sie anschließend am PC (oder MAC) mit 
1,32 GB Größe angezeigt wird. Eine Idee, wodran das liegen könnte? 
(Atmega 2560 mit 2GB SD und 64MB MMC Karte).

MfG Thomas

von Daniel R. (zerrome)


Lesenswert?

hallo,

-1 nein das ist alles andere als normal. es sei denn man möchte eine 
datei in einem ordner anlegen in dem es schon sehr sehr viele 
dateien/ordner gibt.

-2 poste doch mal eine funktionsaufrufe damit ich mir ein bild davon 
machen kann woran es liegt.

wie sind die karten formatiert, also mit fat32 oder fat16? mit welchem 
betriebssystem sind die karten formatiert worden? hast du sie vor der 
benutzung der lib neu formatiert?

klingt ein bischen so als würde fat_loadFileDataFromDir irgendwie ne 
macke haben, weil alle drei optionen/funktionen diese funktion nutzen, 
also ffopen (w/a) und ffclose auch, wenn mit ffopen(a) geöffnet war...
schau ich mir mal genauer an...

von Thomas (Gast)


Lesenswert?

Hey,

der ganze Aufruf sieht in etwa so aus:
1
if( mmc_init() == 0 )
2
{
3
    if(0 == fat_initfat())
4
    {
5
            //Fat initialisation successful
6
            LCD1.LCDBuffer[1] = 0 + 48;
7
            printLCDBufferToGraphic(1);
8
9
            unsigned char j = 0;
10
            unsigned char datei[12]="TEST    PTL";
11
12
            // neu erstellen wenn nicht vorhanden und reinscheiben
13
            if(ffopen('w',datei) == 1)
14
            {
15
                ffopen('a',datei);
16
            }
17
            for(j=0;j<5;j++)
18
            {
19
              ffwrite('b');
20
            }
21
            ffclose();
22
    }
23
}

Ich benutze die KArten mit FAT16, mit FAT32 funktioniert es nicht. 
Formatiert mit Windows, jedoch formatiere ich die Karten nicht nach 
jedem Versuch neu. (Ist ja eigentlich auch nicht der Sinn der Sache)

Einstellung für:
1
#define superfloppy  0
2
#define smallFileSys 1

Ansonsten arbeite ich mit Version 0.4.4, da die Änderung zu 0.4.5 nicht 
groß genug schienen. Habe relativ viel an den Header Dateien geändert, 
um sie schön einzubinden. (Von wegen - wer darf was sehen, und warum / 
warum nicht) - komme von Java, und da ist das alles etwas schöner.

von Daniel R. (zerrome)


Lesenswert?

hm,

die header dateien sind relativ egal denke ich.

es kann sein das wegen der partition irgendwo ein bug ist. versuch mal 
die karte unpartitioniert zu benutzen, dass sollte auf jeden fall 
problemlos funktionieren.

ich komme erst später heute abend zum testen...
ich gehe mal davon aus das nur die header dateien geändert wurden, falls 
nicht, müsste ich mal den ganzen code sehen.

güße daniel

von Daniel R. (zerrome)


Lesenswert?

hallo,

es gab keine bugs in dem partitions bereich, hätte mich sonst vorher mal 
gemeldet.

hier trozdem mal eine neue version, ist schneller geworden, aber auch 
etwas gefährlicher ;)

es ist jetzt umbedingt erforderlich zu prüfen ob richtig geöffnet wurde 
bevor man schreibt !
ein beispiel:

1
// neu erstellen wenn nicht vorhanden und reinscheiben
2
if(0==ffopen('w',datei)){      // prüfen ob öffnen erfolgreich
3
   for(z=0;z<60000;z++){  
4
      ffwrite('a');    
5
      }  
6
   ffclose();
7
   }

nur wenn ffopen null zurück gibt wird ffwrite aufgerufen. ffwrite prüft 
nicht mehr ob öffnen erfolgreich war. zudem ist ffwrite und ffread 
inline geworden.
code ist allgemein kleiner geworden durch vielfache optimierungen !

durchschnittswerte mit einem atmega168 @ 16 mhz:

165 kByte lesend
146 kByte schreibend

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

...

von Daniel R. (zerrome)


Lesenswert?

hier mal noch der erste wiki versuch...

http://www.mikrocontroller.net/articles/FAT32

werde da noch weiter daran arbeiten. jeder der zu fat etwas beitragen 
kann/möchte ist eingeladen dort mitzuarbeiten...

grüße daniel

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Daniel
Ich finde deinen  Quelltext für die SD-Karte eine gute Idee. Habe 
allerdings aber auch meine Probleme damit.
Ich verwende:
AVR-Studio
ATmega32
mmc-0.3.1.zip
Mein Problem:
Trotz intensiver Fehlersuche habe ich es bis jetzt nicht schaffen können 
ein Hexfile mit deinem Quelltext zu erstellen. Habe die 0.3.1 Version 
genommen weil dort auch die Routine für ein LCD dabei ist.  Ich bekommen 
immer Fehlermeldungen. Habe deinen Quelltext nicht verändert. Die 
Fehlermeldungen habe ich in den Anhang gepackt. Wäre nett wenn du oder 
jemand anderes sie mal anschauen könnte. Weiß gerade nicht mehr weiter, 
ist bestimmt nur ein dummer Fehler aber steh da jetzt auf dem Schlauch.
Gruß Alex

von Daniel R. (zerrome)


Lesenswert?

hallo,

ja hm das avr-studio...
hab da letztens auch mal die dateien kompilieren wollen, ging aber 
nicht. irgendwie löst das die c abhänigkeiten nicht alleine?!?. am 
einfachsten ist es wenn du das makefile das bei meiner lib babei ist 
benutzt. beim avr-studio kann man in den projekt eigenschaften ein 
externes makefile angeben. dann gehts. außerdem ist dringend davon 
abzuraten eine ältere version als 0.4.5 zu nutzen (besser 4.5.6), da 
doch noch einige fehler in den vorherigen versionen waren.
um ein lcd zu nutzen, könntest du einfach die lcd routinen mit 
übernehmen...

güße daniel

von Alex (Gast)


Lesenswert?

Danke

Werde ich gleich mal ausprobieren.
Gruß Alex

von holger (Gast)


Lesenswert?

In file-0.4.h

>extern unsigned char ffmkdir(char name[]);    // legt ordner in >aktuellem 
verzeichniss an.
>
>#include "file-0.4.c"

So etwas tut man nicht! *.c Dateien sollte man nicht per
#include einfügen.

von Daniel R. (zerrome)


Lesenswert?

also über das makefile oder wie?

bist du Holger Klabunde?

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Naja zumindest habe ich jetzt nicht mehr so viele Fehlermeldungen aber. 
Aber er erstellt mir kein Hexfile. Woran kann das denn liegen?

Hab mal mein ganzes Prog angefügt vieleicht weißt du ja Rat.
(alles Unveränderte Dateien von dir)

Danke für deine Bemühungen

Gruß Alex

von Daniel R. (zerrome)


Lesenswert?

hallo,

hab grad kein windows da um avr-studio zu starten. aber ich meine mich 
zu erinnern, dass ein projekt und die haupt c datei gleich heißen 
müssen. also solltest du ein projekt namens main_ erstellen und da dann 
alle dateien einfügen...

gruß daniel

von Alex (Gast)


Lesenswert?

Ne hat leider auch nicht funktioniert.

Trotzdem danke
Versuche noch ein bischen rum wenn ich ne Lösung finde poste ich die.

Alex

von zerrome (Gast)


Angehängte Dateien:

Lesenswert?

probier mal das hier. wenn das nicht geht ist dein avr-studio schrott

von zerrome (Gast)


Lesenswert?

hm,
nee seh grad mit meinem avr-studio projekt kann das auch nicht gehn, 
weil der pfad zu den dateien nicht stimmt und der pfad zum kompiler 
warscheinlich auch nicht.
na ja was auf jeden fall geht ist ein neues projekt mit namen main_ zu 
erstellen, dann avr-studio schließen und die dateien main_.c usw in das 
projekt verzeichniss kopieren, dort die vom avr-studio erstellte datei 
main_.c überschreiben. dann das studio wieder starten. eventuell noch 
das externe makefile einstellen.

von Alex (Gast)


Lesenswert?

So hab noch lange rumprobiert aber leider keinen Erfolg gehabt.
Mit der Version 0.4.6 lässt sich kein Hex File erstellen.
Jedoch mit der Version 0.3.1 ist dies kein Problem.
Wieso das so ist weiß ich nicht und kann ich mir auch schlecht erklären.
Hab die AVR Progs extra neu runtergeladen und neu installiert, sogar auf 
anderen PC´s probiert. Leider alles ohne erfolg vielleicht hat ja jemand 
anders noch nen Rat. Würde ja gerne wissen was das Problem genau ist.

Gruß Alex

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

hab jetzt mal die header dateien so umgebaut wie die portierbarkeit wohl 
am größten ist.
leider zu lasten der ausführungsgeschwindigkeit. alleine durch die 
header dateien gehen 20KBytes pro sekunde lesend 
verloren...seltsamerweise wird der code kleiner aber auch langsamer...

@ Alex
probier mal die neue version, damit sollte es besser klappen.
ich denke es liegt nicht am code der 0.4.6 sondern am einbinden im 
avr-studio, daher könnte es mit der 0.4.7 einfacher sein.

grüße daniel

von holger (Gast)


Lesenswert?

Die wenigsten werden WinAVR unter /opt/cross installiert haben ;)

CC = /opt/cross/bin/avr-gcc
OBJCOPY = /opt/cross/bin/avr-objcopy
OBJDUMP = /opt/cross/bin/avr-objdump
SIZE = /opt/cross/bin/avr-size
NM = /opt/cross/bin/avr-nm

von Steffen (Gast)


Lesenswert?

hmmm... 20kB/s weniger ist schon interessant. Wahrscheinlich konnte der 
Compiler bei deiner ersten Version (wo er ja alles in einer einzigen 
Datei bekommt) besser optimieren durch z. B. Inlining (was den größeren 
Code erklärt).

Durch die Aufteilung ist es jetzt allerdings besser in die Verwaltung 
von IDEs wie dem AVRStudio einzubeziehen.

Btw. Super Sache, dass du deinen Code zur Verfügung stellst.

Steffen.

von Alex (Gast)


Lesenswert?

hab das Makefile mal umgeschrieben und volgendes verändert

# Define programs and commands.
SHELL = sh
CC = /WinAVR/bin/avr-gcc
#OBJCOPY = /WinAVR/bin/avr-objcopy
#OBJDUMP = /WinAVR/bin/avr-objdump
#SIZE = /WinAVR/bin/avr-size
#NM = /WinAVR/bin/avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp

so kriege ich auch ein hexfile erstellt aber ob das jetzt auf dem atmega 
läuft werde ich dann später erst sehn. Oder könnte es sein das es ohne 
die auskommentierten Pfade nur so scheint als sollte es Funktionieren? 
Warte noch auf den uc momentan hab ich leider keinen da.
Danke für eure Hilfe.

Gruß Alex

von zerrome (Gast)


Lesenswert?

geht das nicht auch so?

# Define programs and commands.
SHELL = cmd.exe
CC = /WinAVR/bin/avr-gcc.exe
OBJCOPY = /WinAVR/bin/avr-objcopy.exe
OBJDUMP = /WinAVR/bin/avr-objdump.exe
SIZE = /WinAVR/bin/avr-size.exe
NM = /WinAVR/bin/avr-nm.exe
AVRDUDE = avrdude.exe
REMOVE = del -f
COPY = copy


bei "del -f" bin ich mir nicht sicher ob del den parameter f kennt, 
warscheinlich nicht, da müsste man mal nach adequatem ersatz suchen.
"rm -f" -> "Löschen. Ignorieren nicht vorhandener Dateien, keine 
Nachfragen."

copy müsste aber so gehn gehn..

grüße daniel

von Daniel R. (zerrome)


Lesenswert?

lol moment bei windows wird das warscheinlich eher

c:\WinAVR\bin\avr-gcc.exe heißen...

mit optimierung s wird der code jetzt wieder kleiner als mit 2 und der 
geschwindigkeitsverlust geht auf 10KBytes /sec zurück. also von 165 auf 
155KB damit kann ich leben (atmega 168 @ 16mhz).

von Steffen (Gast)


Lesenswert?

Der Pfad zu Winavr wird doch in die Path-Variable eingetragen, sollte es 
nicht reichen die *.exe anzugeben? Er wird sich dann schon einen Pfad 
suchen...

Hab es nicht probiert!

Steffen.

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

neue version

kleine änderungen.
mit windows und linux makefiles usw..

von Michael Z. (incunabulum)


Lesenswert?

Moin Daniel,

wollte mich heute auch mal näher mit deinem SD-Code beschäftigen, 
nachdem meine Platine ansonsten funktioniert. Die Funktionsweise sieht 
verständlich aus.

Was mich momentan am Einsatz hindert ist, dass SPI, Usart wie auch die 
Command-Shell fest mit dem eigentlichen Code verbunden ist. Da ich 
hierfür bereits eigene Bibliotheken habe.... wie kann ich diese auf 
Dauer am besten einbinden und zwar so, dass der Wartungsaufwand bei 
einer Codeaktualisierung deinerseits nicht zu umständlich wird?

Oder hast du schon einmal überlegt, die ganzen relevanten #defines in 
eine Config.h auszulagern. Hierin könnten z. B. Methodennamen für Usart 
und SPI definiert sein oder auch, ob file.h->methode() auf den Usart 
ausgeben soll.... Und diese Datei wäre dann problemlos anpassbar durch 
einen anderen Anwender.

Anders gefragt - wenn ich dir einen entsprechenden Patch schicke würde, 
hättest du Interesse?

cu, Michael

von Michael Z. (incunabulum)


Angehängte Dateien:

Lesenswert?

Ich nochmal.... anbei als zip eine kleine Abwandlung deiner Lib mit 
einem globalem Config-Header-File. Es kompiliert; ausprobiert habe ich 
es aber nicht.

Zur Idee: In mmc_defs.h werden für uart, spi und spi hardware die 
entsprechenden Methodennamen als #define angegeben. Beispiel Uart:
1
#include "uart.h"
2
#define MMC_UART_INIT      uinit
3
#define MMC_UART_PUTC      uputc
4
#define MMC_UART_PUTS      uputs
5
#define MMC_UART_GETC      ugetc
6
#define MMC_UART_GETS      ugets

Möchte ich einen anderen Uart-Code verwenden, so include ich die 
entsprechende Header-Datei und passe die Methodennamen an.
- ugets wird z. Zt. nicht verwendet.
- Die SPI Methoden sollte man nochmal überdenken... da wollte ich dein 
Feedback abwarten bevor ich deinen Code vollständig verstehen will

Somit kann ich flexibel unterschiedliche Basisfunktionen für die 
Peripherieansteuerung verwenden (buffered, unbuffered usart; hardware 
spi, software spi; evtl. debug Lösungen) und bin deutlich flexibler, was 
die gesamte Konfigurierbarkeit anbetrifft. Die restlichen Code-Dateieen 
enthalten jetzt nur noch die SD-Card-Logik allein.

Was hälst du davon?

Michael

von Daniel R. (zerrome)


Lesenswert?

hallo Michael,

gute idee das so zu ändern, dass man unterschiedliche "unterbauten" 
nehmen kann, würde es auch einfacher machen das ganze auf andere 
controller zu portieren.
eine globale "hardware" header datei zu machen, wo die funktionen vom 
spi und die funktionen des uart, also der hardware anbindung der karte 
und der ausgabe, definiert werden ist eine gute lösung. die von dir 
beschriebenen vorteile sind es wert.

leider komme ich vor freitag wohl kaum zur umsetzung, weil ich umziehe 
und lernen mich voll in beschlag nimmt.

bis spätestens sonntag sollte es aber ohne probleme drin sein, wie im 
einzelnen, werde ich mir noch überlegen. weitere ideen sind sehr 
willkommen !

grüße daniel

von Michael Z. (incunabulum)


Angehängte Dateien:

Lesenswert?

Moin Daniel,
Das klingt ja sehr schön :-) Wenn du Zeit hast, dann schau dir meine 
Abwandlung mal an... vielleicht sind ja ein paar brauchbare Ideen drin.

Eine "globale" Hardware-header-Datei würde ich zuerst mal auf die 
mmc-lib beschränken. Warum? Viele dürften für die Ansteuerung der 
peripherie etc. bereits eigene Code-Sammlungen haben. Die mmc-lib müsste 
dann nur noch an diese Libs angedockt werden.

Die SPI Ports und Pins könnte man auch nochmal in eine weitere 
Config-Datei auslagern. So habe ich es jedenfalls bei mir gemacht, siehe 
Attachement SpiDefs.h

Zweite Idee: Ein Debug-Switch. Ist dieser gesetzt, so wird an eine 
ebenfalls frei definierbare Debug-Funktion die aktuelle Aktion (open 
file, read directory etc.) gesendet. Sowas kann man schön so 
programmieren:

#define MMC_DEBUG 0

#if defined(MMC_DEBUG)
  logDebug("bla");
#endif

Anyway, denn erstmal viel Erfolg beim Lernen und Umziehen....

Michael

von Steffen (Gast)


Lesenswert?

Hallo,

interessant wäre, wenn der SPI-Teil umgearbeitet wird, gleich zu 
überlegen, ob nicht eine "universellere" Variante erarbeitet wird. Ziel 
könnte sein, dass mehrere Komponenten am SPI (-Bus) hängen und nicht SS 
sondern ein Portpin für CS verwendet wird. Beim Senden und Empfangen 
muss dann zusätzlich noch mitgeliefert werden, welche SPI-Peripherie 
angesprochen werden soll (SPI-Parameter müssen für jeden Baustein 
gespeichert werden und evtl. vor dem Senden/Empfangen neu angepasst 
werden).

So könnte z.B. ein zusätzlicher CAN-Baustein oder HC595 angeschlossen 
werden ohne eine Software-SPI zu benötigen. Besonders, wenn einzelne 
SPI-Komponenten nur selten benötigt werden (Config.ini auf SD Karte nur 
zum Start notwendig, HC595 für Relaisansteuerung einmal pro Sekunde...).

Steffen.

von Michael Z. (incunabulum)


Lesenswert?

Moin!

Wieso sollte dies ein Problem sein?

In der MMC-Config kannst du imho frei definieren, welchen Pin du als 
SS-Pin verwenden willst. Ob dies nun der "offizielle" SS-Pin des AVRs 
oder ein anderer Pin ist spielt hierbei keine Rolle. Somit kannst du 
auch problemlos mehere SPI-Chips oder -Geräte an den AVR anschließen 
solange du die gleiche Ansteuerungslogik (send_byte etc.) verwendest.

Aufwändiger wird es allerdings, wenn du unterschiedliche 
Busgeschwindigkeiten fahren willst. Da hast du recht.

Michael

von Steffen (Gast)


Lesenswert?

>Aufwändiger wird es allerdings, wenn du unterschiedliche
>Busgeschwindigkeiten fahren willst. Da hast du recht.

Genau dort sehe ich der Herausforderung. An der Stelle ist es 
wahrscheinlich sinnvoll "eine" SPI-Routine zu verwenden. Dann kann man 
sich merken, ob eine Parameteränderung durchgeführt werden muss oder 
nicht.

von holger (Gast)


Lesenswert?

>#define MMC_DEBUG 0
>
>#if defined(MMC_DEBUG)
>  logDebug("bla");
>#endif


Das geht auch noch eleganter.

In der Headerdatei:
1
#define MMC_DEBUG_SECTORS_READ
2
#define MMC_DEBUG_SECTORS_WRITE
3
4
#ifdef MMC_DEBUG_SECTORS_READ
5
 #define DEBUG_MMC_SECTORS_READ  printf
6
#else
7
 #define DEBUG_MMC_SECTORS_READ(...)
8
#endif
9
10
#ifdef MMC_DEBUG_SECTORS_WRITE
11
 #define DEBUG_MMC_SECTORS_WRITE  printf
12
#else
13
 #define DEBUG_MMC_SECTORS_WRITE(...)
14
#endif

Im C-Code:
1
...
2
 DEBUG_MMC_SECTORS_READ("RS %lu 0x%08lX\n",sector,sector);
3
...
4
5
...
6
 DEBUG_MMC_SECTORS_WRITE("WS %lu 0x%08X\n",sector,sector);
7
...

So kann man mehrere Debugausgaben einzeln gezielt ein und
ausschalten. Es wird eben nur das benutzt was man gerade
benötigt. Das was man nicht haben möchte einfach in der
Headerdatei auskommentieren:
1
//#define MMC_DEBUG_SECTORS_READ

Im C Code spart man sich dann auch das

#if defined(MMC_DEBUG)
 Ausgabe("text");
#endif

Die Debugausgabe benötigt nur eine Zeile Code statt drei.

MMC_DEBUG("text");

von Daniel R. (zerrome)


Lesenswert?

hallo,
leider hab ich doch extrem weniger zeit als ich dachte.
bugs würden geändert werden, aber mehr ist momentan nicht drin, sorry.
nächste woche hab ich wohl etwas mehr zeit, hoffe ich...

grüße daniel

von Andi (Gast)


Lesenswert?

Hi Forum,
ich hab das nun auch mal ausprobiert mit dem FAT-Treiber...
Das Init funktioniert noch einwandfrei - danach geht nicht mehr viel:
z.B. ffls() - da hängt er ziemlich lange in einer Schleife, der Grund 
ist, dass die Variable fat.dataDirSec bei mir auf -2 steht...
Wie ist das bei Euch?
Ich hab meine Karte unter Win mit FAT16 und FAT32 formatiert - jedesmal 
mit dem selben Ergebnis...
Habt Ihr eine Idee an was das liegen kann?
Die eine Karte ist eine MMC 512 MB von Transcend, bei der anderen Karte 
(Sandisk 2GB) steht in der FAT-Strukur nur Käse - liegt wohl an der 
Grösse...
Schon mal danke für Eure Tipps...
Andi

von daniel (Gast)


Lesenswert?

hallo,
ist die karte partitioniert?
wenn ja musst du #define superfloppy ändern (in der fat.h).
-2 ist auch ein komischer wert für einen unsigned long int...

grüße daniel

von Michael Z. (incunabulum)


Lesenswert?

Daniel,

hast du inzwischen ein bisschen Zeit gefunden, die Debug- und sonstigen 
Änderungen einzuarbeiten? Dann könnte ich meine selbstgestrickten Dinge 
verwerfen und zurück zu deinem Code wechseln :-)

Michael

von Daniel R. (zerrome)


Lesenswert?

hallo,
bin momentan bis oben hin zu mit arbeit...

ich hab auch die karten meist selber nur mit linux gedebugt,
da hatte ich mir auch eine kleine mmc.c und mmc.h geschrieben, der rest 
code ist platformunabhänig...
das ist die bequemste art den code zu testen.
zudem kann man mit programmen wie WinHex auch images von datenträger 
machen und so kann man sogar ganz ohne mmc karten code debugen und 
testen.
einfach immer eine mmc.c und mmc.h an die hardwaremäßige plattform 
anpassen, schon ist die lib portiert (sofern standart c darauf läuft).
daher tendiere ich momentan dazu die debug geschichte erst in den 
semesterferien mal anzusehen (wie gesagt, debug mit linux ich wesentlich 
komfortabler).
den rest, also die uart und die mmc/spi geschichte so umzubauen, dass 
andere bibliotheken genutzt werden können mach ich über weihnachten, als 
kleines present ;)
spass beiseite, da werd ich wohl endlich ein wenig zeit haben mich 
meinem hobby zu widmen...

grüße daniel

von Andi S. (laserandi)


Lesenswert?

Hi,
ich versuche gerade die Dateien aus mmc-0.4.8.zip unter Linux zu 
kompilieren. Das geht auch Problemlos, nur wenn ich den Schalter write 
auf 1 (read only) setze bekomme ich folgende Fehlermeldungen:
1
~/sd_test/main_.c:50: undefined reference to `ffmkdir'
2
~/sd_test/main_.c:53: undefined reference to `ffmkdir'
3
~/sd_test/main_.c:68: undefined reference to `ffwrite'
4
command.o: In function `run_cmd':
5
~/sd_test/command.c:94: undefined reference to `ffrm'
6
~/sd_test/command.c:101: undefined reference to `ffmkdir'
7
~/sd_test/command.c:149: undefined reference to `ffwrite'
8
make: *** [main_.elf] Fehler 1
Ist das ein Bug oder habe ich etwas übersehen.
Bei "read only" werden diese Funktionen natürlich nicht gebraucht, aber 
ich dachte der write Schalter berücksichtigt diese Option.

Danke
Andi

von Daniel R. (zerrome)


Lesenswert?

hallo,

besser spät als nie ^^

also, in der main_.c wird auf die schreib funktionen zugegriffen, 
genauso wie in der command.c . den schalter auf nur lesend setzen 
funktioniert nicht, wenn man dann doch auf die schreib funktionen 
zugreift.
in der bibliothek selber stimmt das soweit alles. wenn du nur lesen 
möchtest, musst du dir eine main schreiben und nur auf die lesen 
funktionen zugreifen...

grüße daniel

von Martin (Gast)


Lesenswert?

Hallo,

da ich BMPs auf meinem S65-Display ausgeben möchte, die auf der SD_Card 
liegen, wäre es für mich auch interessant direkt auf sector[] 
zuzugreifen.
Die Funktion ffread() ist dafür zu umständlich. Wie könnte man dies 
realisieren?

Güße Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,
also du könntest z.B. aus der fat.c direkt die Funktion:
1
unsigned char fat_loadSector(unsigned long int sec)

aufrufen. Als Parameter bekommt die Funktion den zu ladenden Sektor 
übergeben. Danach ist der Sektor auf sector[].
Setzt allerdings Voraus, dass du den Sektor kennst.
Wenn du damit BMP's lesen möchtest, muss du ja auch die folge Sektoren 
kennen. Deshalb ist die ffread etwas umständlicher. Im Regelfall, gibt 
es aber ja aber nur einen Index der erhöht wird und eine Abfrage... erst 
wenn man 512 Bytes gelesen hat wird es etwas umständlicher, wegen dem 
Problem der folge Sektoren.

Grüße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

wenn ich Dich recht verstehe, habe ich die Datei *.BMP mit ffopen() zu 
öffnen. Der der erste Sector befindet sich nun in sector[]. Da die größe 
der Datei bekannt ist, kann man mit sec++ und fat_loadSector(sec) den 
nächsten Sector in den Buffer sector[] laden. Dies wiederholt man, bis 
die ganze Datei geladen ist und schließt die Datei mit ffclose().

P.S Danke für die schnelle Antwort

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Also Prinzipiell schon,
aber es kann mehrere Sektoren in einem Cluster geben, diese Cluster 
können auch nicht aufeinanderfolgen. Deshalb muss man zwischendurch in 
der Fat nach dem folge Cluster suchen, diesen auf Sektoren umrechnen und 
dann weiter lesen...
Wenn Du das alles beachtest, bist Du genau bei dem was ffread macht.

Das Prinzip wie Fat funktioniert habe ich versucht im Wiki Artikel 
FAT32 zu erklären.

PS: Ist Dir ffread nicht schnell genug? Wieso willst Du da was selber 
machen?

Grüße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

ich hatte am Anfang vermutet, dass ffread zu langsam sei. Inzwischen 
habe ich die Funktion aber benutzt und musste feststellen, das sie für 
den Bildaufbau schnell genug ist. Dieser dauert für die 176x132 Pixel 
(1Pixel=2Byte) ca. 1 Sekunde (gefühlt). Mit dieser Geschwindigkeit kann 
ich leben. Was mir aber noch Sorgen bereitet ist das Schreiben auf 
SD-Card. Dabei wird die FAT so verändert, dass  man die Dateien in 
Windows zwar noch angezeigt bekommt aber das Löschen wird verweigert.

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hi Martin,
das mit der 1 Sekunde ist seltsam wenn du mit 16 Mhz @ Avr arbeitest,
weil mit Deiner Angabe komm ich auf 371712 Bit, ist ja 46464 Byte/Bild, 
da sollte wesentlich mehr drin sein, oder hab ich mich verrechnet?

Zu dem Windows, welches benutzt Du? Vista?
Ich bin da nicht ganz Spezifikations-konform, weil normalerweise müsste 
man die Uhrzeit der Zugriffszeiten (erstellen/lesen...) richtig 
eintragen. Der Einfachheit halber schreib ich Nullen rein...
Hatte beim Testen aber dieses Problem auch nie.
Würde Vista ähnlich sehen, beim Datum 00-00-0000 nicht klar zukommen ^^

Güße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

da ich mit 3,3V Versorgungsspannung arbeite, zwecks der einfacheren 
Anbindung von SD-Card und Display, läuft mein m32 nur mit 12MHz. Nachdem 
ich zwei Byte von SD-Card gelesen habe muß ich sie in ein Integer 
umwandeln und noch zum Display schicken, das kostet zusätzlich Zeit. 
Meine Zeitangabe ist auch nur eine grobe Schätzung, der Bereich ist 
irgendwo zwischen 0,5 und 1s.

Zur SD-Card:
Ich habe es mit XP und Linux getestet. Beide behaupten die Karten seinen 
schreibgeschützt. Das habe ich mit 3 unterschiedlichen Readern getestet, 
auf die richtige Einstellung des mechanischen Schreibschutz habe ich 
auch geachtet. Die Dateien die mit 'a' beschrieben wurden seien 1,5GB 
groß, das behauten beide BS, obwohl die Karten nur 256 bzw. 512MB groß 
sind. Als Software benutze ich Deine mmc-0.4.8. Hardwareprobleme kann 
ich zu 90% ausschliessen, da das Lesen einwandfrei funktioniert, das 
einmalige schreiben auch. Nur das anhängen von Daten an eine bestehende 
Datei produziert den Fehler.

Das Anhängen muß ich aber nochmal genau überprüfen, wenn mir weitere 
SD-Cards zu Verfügung stehen. Mit meiner letzten mache ich nur noch 
Lesetests.

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,
nur um mal abzuklopfen,
Du hast den Code nicht geändert oder so und Du achtest darauf, dass 
ffclose() aufgerufen wurde bevor du den Strom von der Karte nimmst, bzw. 
diese aus der Halterung ziehst (beim schreiben, beim lesen egal).

Mich würde dann auch der Aufruf und so interessieren, um abschätzen zu 
können wo da vielleicht der Fehler liegt.
Hab den Code so in der 0.4.8 Version selber im Gebrauch und mit Datei 
Größen noch nie Probleme gehabt.

Grüße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

ich habe Deine Version komplett übernommen und mit meinen Funktionen 
erweitert. So im nachhinein betrachtet kann ich aber das Abziehen der 
Stromversorgung bevor ein ffclose stattgefunden hat nicht ausschliesen. 
Das geht halt in der Softwareentwicklnugsphase nicht immer.

Ein reaktivieren der SD-Cards unter Windows blieb bis jetzt erfolglos, 
Windows meldet immer einen aktivierten Schreibschutz oder behauptet das 
die Datei text.txt ein Verzeichnis sei. Meine letzte Hoffnung ist nun 
Linux.

Ich könnte auch mal probieren, die Datei mit ffrm() zu löschen.

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,
also auch beim Versuch die Karten zu Formatieren gibt es 
Fehlermeldungen?

Generell ist das sehr seltsam. Eigentlich geht Schreibschutz über 
Software nur mit einem bestimmten Kommando an die Karte, was aber auch 
nicht jede Karte unterstützt...

Einen Versuch die Datei mit ffrm() zu löschen ist es auf jeden Fall 
wert. Schlimmstenfalls bleibt ein bisschen Datenmüll in der Fat über. 
Sollte aber mit einem Scandisk Tool zu beheben sein.

Ich vermute, dass im Dateieintrag der Datei irgendwas steht was keinen 
Sinn macht. Hast Du einen Hex-Editor mit dem Du Dir die Rohdaten auf der 
Karte ansehen kannst? Davon ein Screenshot wäre super :)

Um soetwas zu verhindern, könnte man einen Taster anschließen, der einen 
Interrupt auslöst und ffclose() aufruft.

von Martin (Gast)


Lesenswert?

Hallo,

ich habe es nun mit Linux probiert, alles ohne Erfog. Fdisk und 
mkfs.msdos werden zwar augeführt (ohne Fehlermeldung) aber danach ist 
alles beim Alten. Die Dateien sind also noch vorhanden, selbst ein dd 
if=/dev/zerro of=/dev/sdb brachte keinen Erfolg. Es sieht für mich so 
aus, als ob der Speichercontroler auf der SD-Karte auf read only steht. 
Das Komische ist nur, dass es bei zwei unterschiedlichen SD-Cards 
aufgetreten ist.

Einen Hex-Editor habe ich natürlich, was genau soll ich Dir übermitteln?

Auf die Idee mit der Interruptroutiene bin ich auch schon gekommen, die 
wird mir aber nur was bringen, wenn das Programm in einer Endlosschleife 
fest sitzt. Bei einem Zugriff auf eine falsche Speicherstelle und der 
nachfolgende Sprung ins Nirvana wird mir die ISR die SD-Card nicht 
schützen können, weil sie wahrscheinlich nicht mehr ausgeführt wird.

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hi,
also das mit dem Sprung ins Nirvana versteh ich nicht. Wenn Du sagen wir 
mal konstant Daten wegspeicherst, und ein ffclose wird aufgerufen, wird 
halt nur die Datei ordentlich geschlossen, also die aktuelle Größe usw. 
geschrieben. Macht jedes Betriebssystem ähnlich...
Also Daten Direkt schreiben und den Fat und Datenbereich zum Schluss 
aktualisieren. Deshalb kann man bei Usb-Sticks die einfach so 
herausgezogen wurden (beim schreiben) die Daten meist recovern.

Da Du keinen Code gepostet hast, kann ich nicht genau sagen wo der 
Fehler eigentlich liegen kann... Rechne Dir das mal durch, wie oft man 
eine Zelle beschreiben kann und wie oft du Tatsächlich schreibst.

Interessant wäre für mich der Sektor des Ordners in dem der Dateieintrag 
steht.

Die einzige Möglichkeit eine Karte mit der Lib zu zerstören wird zu oft 
schreiben auf die Karte sein, dass ist definitiv sicher. Wäre aber auch 
mit einem großen Betriebssystem nicht anders !

Wenn Du mit Linux und mkfs keinen Erfolg beim Formatieren der Karten 
hast ist da was ganz anderes im argen.
Aber interessehalber, schick mir mal eine. Dann schau ich da nach. Das 
glaub ich nämlich irgendwie nicht, formatieren mit Linux und dann sind 
da noch Daten so lesbar?!?

Güße Daniel

von Martin (Gast)


Lesenswert?

Hallo,

die Screeshots sind noch in der Mache. Habe soeben feststellen müssen, 
dass WinHex keine Screenshots zulässt. Schicken kann ich Dir auch eine, 
ich habe schlieslich zwei Defekte. Ich bräuchte halt nur die Adresse.

Zum Nirvana:
Wenn der Prozessor eine falsche Speicherstelle liest und versucht den 
Befehl dann auszuführen, wird eine Exception ausgelöst, fals der Befehl 
nicht bekannt ist. Schlimmer ist es aber, wenn an dieser Stelle ein 
ausführbarer Befehl steht, der aber nichts mit dem Programm zu tun hat. 
Das kann den Programmcounter und den Stack verändern. Der Prozessor 
befindet sich dann in einem nicht definierten Zustand. Wenn jetzt ein 
Interrupt ausgelöst wird kann alles mögliche passieren, aber bestimmt 
etwas sinnfreies.

Nach dem Formatieren unter Linux habe ich auch ganz blöd aus der Wäsche 
geschaut, als ich die Dateien wieder gesehen habe. Der 
Fortschrittsbalken beim Formatieren unter Windows bewegt sich auch bis 
zum Ende und dann meldet Windows erst einen Fehler. Sinngemäss "Befehl 
konnte nicht zum Abschluß gebracht werden". Ich denke das war der 
verify.

Ich such mir jetzt einen besseren HexEditor und mache die Screenshots. 
Kannst Du einen empfehlen?

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Also ich nehm auch immer winhex. Musste halt nen gesamt Screenshot 
machen...

Was hat der Prozessor mit der mmc/sd karte zu tun? Die ganze Geschichte 
kommuniziert ja über SPI, also AVR <-> mmc/sd Karte. Da hat keiner 
direkten Zugriff auf Stack oder so des anderen..

Schick mir ne Mail an zerrome aT gmail PunKt com, dann schick ich Dir 
meine Adresse.

Meinst du mit Daten gesehen, dass Du die Daten mit dem Hex-Editor 
gesehen hast? Wäre klar, weil Formatieren nur den Fat Bereich ändert, 
sonst müsste ja immer die Ganze Karte platt gemacht werden.

Grüße Daniel

von Martin (Gast)


Lesenswert?

Hi,

der Screenshot [Alt]+[Druck] bzw. nur [Druck] legt bei mir unter WinHex 
nichts in der Zwischenablage ab, also nichts mit cut and paste!

Der Prozessor arbeit doch wohl die Befehle ab, somit auch die, die für 
das lesen und schreiben auf SD-Card zuständig sind. Der Stack ist der 
letzte Speicherbereich im Ram. Dieser wird benutzt um  Daten, die einer 
Funktion übergeben werden sollen aufzunehmen, aber auch die 
Rücksprungadresse um wieder ins Hauptprogramm oder in die aufrufende 
Funktion zurückzukehren. Der Stackpointer enthält die letzte benutzte 
Adresse auf dem Stack.

Nachdem ich einen Dateibrowser geöffnet habe, hat mir dieser die Dateien 
und Verzeichnisse wieder angezeigt. Das sollte nach einer Formatierung 
eigentlich nicht so sein.top

Die Mail schreibe ich heute Abend.

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,

jetzt versteh ich glaube ich endlich was Du mit dem Nirvana meinst...
Klar, nach der ISR nochmal ins normale Programm zu springen macht in dem 
Fall keinen Sinn. Da wäre dann in der ISR ein exit() oder so angebracht.

Wenn Du einen Screenshot vom gesamten Bildschirm machst wenn Winhex 
offen ist geht nichts in die Zwischenablage? Versuchs mal mit dem tool 
Printkey...

Grüße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

ich bin nun so weit, dass mein "AVR-Portable" BMPs mit 24Bit Farbtiefe 
dank Deiner Lib lesen und auch auf dem Display des S65 anzeigen kann. 
Ein einfaches Spiel (Pong) habe ich auch schon am Laufen. Was ich nun 
gerne noch realisieren möchte, ist das Abspeichern von Spielständen. Nun 
zu meiner Frage:

Gibt es eine Möglichkeit mit ffread den Namen eines Spielers auszulesen 
um den Pointer auf die richtige Stelle hinter dem Namen zu positionieren 
und dann mit ffwrite den Spielstand zu speichern?

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,
ich glaube ich würde das an Deiner Stelle so machen,

ein struct anlegen mit Spielername, Score usw.
Für sagen wir, die Top 10.
Jetzt aus einer Datei die Daten auslesen und ins struct schreiben.
Wenn jetzt ein Spiel vorbei ist, einfach den Score überprüfen und wenn 
nötig einen aus den Top 10 rauswerfen und den aktuellen Spieler ins 
struct schreiben.
Zuletzt noch das aktualisierte struct wieder in die Datei schreiben.

Das Problem ist ja, dass man lese und schreib Vorgänge trennen muss, 
weil nur eine Datei zum schreiben oder lesen geöffnet werden kann. Wäre 
mit dem oben beschriebenen Beispiel kein Problem. Denkbar wären auch 
noch andere Möglichkeiten, solange man lesen und schreiben trennt...

Werde mir da mal was überlegen, weil es ja schon schick wäre, eine Datei 
zu öffnen und dann lesen und schreiben zu können... muss man halt 
bisschen aufpassen was man macht ^^
Das Problem ist ja nicht das überschreiben von alten Daten (da ändert 
sich ja nix am Datei Eintrag in FAT und Ordner), sondern wenn über das 
alte Datei Ende hinweg neu geschrieben wird. Da muss dann ne menge mehr 
gemacht werden...

Grüße Daniel

von Daniel R. (zerrome)


Lesenswert?

Hallo,
deine SD Karten sind angekommen. Die Controller darauf sind OK. Aber es 
sind massenhaft kaputte Sektoren. Zu viele. Ich vermute ja bei so billig 
Herstellern, dass die keine Algorithmen zum mappen von logischen auf 
physikalische Sektoren einbauen...
mkdosfs wirft in der Standart ausgabe (Konsole) keine Fehler, aber dmesg 
liefert die ganzen Fehler...
Die eine Karte kann man sogar an manchen stellen noch beschreiben, die 
andere weigert sich einfach.
Ist eindeutig kaputter Flash, weil die Controller sich noch 
ordnungsgemäß verhalten.

Bin gerade an einer neuen Version der Lib... die 0.5,
da wird es große Änderungen geben. Es wird dann auch möglich sein zu 
lesen und schreiben auf einer geöffneten Datei. Muss aber viel umbauen 
dafür...



Grüße Daniel

von Martin (Gast)


Lesenswert?

Hallo Daniel,

die SD-Cards kannst Du behalten, die brauche ich nicht mehr. Was aber 
komisch ist, sind die haufenweise def. Sektoren, denn die Teile wurden 
kaum benutzt.

Ich bin schon gespannt auf die neue Lib. und stelle mich gerne als 
Betatester zur Verfügung. (So lange ich noch SD-Cards zum Schießen habe 
;-) )

Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo Martin,

wenn du magst kann ich die Karten auch zurück schicken, dann kannste Dir 
die vielleicht auch nochmal ansehen.
Mit Massenhaft kaputten Sektoren meinte ich, dass so bei 10 gemeckert 
wurde. Das ist schon viel, weil eine gute Karte normalerweise noch 
Reserven hat, die benutzt werden wenn wenn defekte entdeckt werden.
Es ist auf jeden Fall Vorsicht geboten bei Flash Speicher..

Die Lib ist jetzt soweit fertig. Bin am testen und Debuggen.
Es entfällt der Parameter beim öffnen einer Datei. Also 'w','r', und 'a' 
sind nun überflüssig.
Es wird entweder die vorhandene Datei geöffnet oder wenn nicht vorhanden 
eine erstellt. Diese kann man dann lesen und beschreiben.
Will man an eine Datei etwas anhängen, wird diese einfach geöffnet und 
mit ffseek(file.length) ans ende gespult. Dann einfach schreiben...
Dazu und zu anderen neuen Aspekten aber noch Code Beispiele.

Denke ich werde Sonntag die Version mmc-0.5 Posten können.

Grüße Daniel

von Daniel R. (zerrome)


Lesenswert?

Es gibt noch Probleme bei fragmentierten Fat-Tabellen. Wenn ich das in 
den Griff bekommen habe ists fertig  :)
Im Idealfall, wo die FAT unfragmentiert voliegt, kann man 256000 
Byte-Blöcke in einem Rutsch lesen. Sollte also auch alles schneller 
werden. Beim schreiben ähnlich...

von Martin (Gast)


Lesenswert?

Hallo Daniel,

wie gesagt, Du kannst die SD-Cards behalten. Ich denke die kannst Du in 
der Testphase ganz gut gebrauchen.

Das hört sich ja schon sehr vielversprechend an. Wie heisst es doch so 
schön:" Gut Ding will Weile haben!". In diesem Sinne wünsche ich Dir 
viel Spass und natürlich auch Erfolg.

Gruss Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,

also wenn ich teste, dann eh nur mit images von Karten, nie mit den 
Karten selber...
Wäre auch viel zu umständlich da immer neu zu Formatieren und Dateien 
drauf zu kopieren um auf einen definierten Zustand zu kommen. So is das 
ne Sache von 2 Sekunden...


Grüße Daniel


edit:

Man stelle sich vor, eine schleife läuft Amok und das über mehrere 
Sekunden/Minuten oder so -> defekte Karte...

von Martin (Gast)


Lesenswert?

Hallo Daniel,

das mit den Images von Karten habe ich nicht verstanden, wo laufen die 
den?

Klär mich auf!



Gruß Martin

von Daniel R. (zerrome)


Lesenswert?

Hallo,

also ich mache ein Image von einer Karte (z.B. mit winhex), also von 
allen Sektoren.
Dieses Image öffne ich in meinem c-Programm als Datei (c-Programm auf 
PC). Diese Datei hat ja die Struktur der Karte und kann somit genau so 
benutzt werden.
Jetzt braucht man nur noch eine angepasste mmc.c und schon kann man 
problemlos Testen, ohne Karten zu gefährden und bequem am PC.
Abschließende Tests mit realer Hardware kommen dann natürlich dazu, aber 
da geht es nicht mehr so darum ob der Code das macht was er soll...

Grüße Daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Sooo,
ist fertig.

Ist gut geworden, schneller und kleiner...
Viel Spaß damit.
Werde morgen oder so mal das Wiki mit bisschen Doku undso füttern.

Wer den Link noch nicht kennt:

http://www.mikrocontroller.net/articles/FAT32



Grüße Daniel

von Matze A. (matzeapa)


Lesenswert?

Hi,

ich bin blutiger Anfänger, zumindest was SD-Karten angeht.
Deswegen auch nen Anfängerfrage :)

Wie beschalte ich denn so eine SD-Karte? Kann mir mal jemand nen 
Schaltplan hochladen? Wär total nett!

Gruß
Matze

von daniel (Gast)


Lesenswert?

Hallo,
hab grad keinen Schaltplan da.
Das Problem ist ja meistens, dass die Karte 3,3 V braucht und so ein MC 
meist mit 5 V läuft. Da muss man also Level shiften. Ich mache das immer 
mit nem HC4050, ist ein Digital IC, dass wenn man es mit 3,3 Volt 
betreibt auch 3,3 Volt an den Ausgängen hat. Ist aber bis 15 V Tolerant 
an den Eingängen.
Ein Eingang hängt mit einem Ausgang zusammen.
Geht glaub ich bis 20 Mhz Frequenz und kostet 20 Cent.
Den Ausgang der Karte kann man direkt an den MC machen, da 3,3 V reichen 
für logisch 1.

mc -> hc4050 -> karte  (für SCLK,DI,CS)

karte -> mc            (für DO)

Grüße Daniel

PS: hab da in der ffmkdir() etwas übersehen, also noch bisschen Vorsicht 
beim Ordner anlegen...fix kommt bald...

von Matze A. (matzeapa)


Lesenswert?

aller besten dank für die hilfee bei der beschaltung!

ich habe zwar keine ordner operationen vor, aber ich werde aufpassen :)

was den einstieg vielleicht für alle anfänger erleichern würde, wäre ein 
beispielprogramm, in dem die meisten / wichtigsten funktionen einmal 
durchlaufen werden (Datei erstellen und öffnen, daten hinein schreiben 
und anhängen, etc (natürlich auch für ordner)). ähnlich wie die 
libraries von fleury und seine testprogramme - muß aber nich soo 
ausführlich und allumspannend sein. ich denke, ein atmega8 hat jeder 
zuhause rumfliegen...

ich muß nämlich gestehen, daß die fülle von dateien und die auf den 
ersten blick recht kryptischen befehlsnamen einen echt abschrecken 
können :)

gruß,
matze

von daniel (Gast)


Lesenswert?

Ja kann ich verstehen,
sieht wahrscheinlich echt seltsam aus wenn man sich die fat.c oder so 
ansieht (und erst der ganze doku Text ^^)... habe da für mich möglichst 
sprechende und lange Namen genommen...

Letztendlich sollen ja für einen normalen Anwender nur die Funktionen 
aus der file.c sein. Wie ffopen, ffclose, ffseek, ffwrite usw...
Ah nicht zu vergessen noch zwei elementare Funktionen mmc_init und 
fat_initfat, sonst nur Funktionen aus file.c...

Mache morgen oder eher Dienstag so ein Mini Beispiel. Bin für Anregungen 
immer zu haben.
Wollte im Rahmen der Dokumentation auch noch eine Beschaltung von MMC/SD 
Karten (Schaltplan und Fotos) machen.
Leider fehlt mir momentan die Zeit um mich richtig aus zu leben in 
meinem Hobby ^^

Grüße Daniel

von Matze A. (matzeapa)


Lesenswert?

Das klingt doch gut. Ich muß nämlich für die Uni Messwerte auf eine 
SD-Karte bannen und deine Library ist goldwert. - aber einen kleinen 
Denkanstoß brauche ich wohl noch :)

Ich habe vielleicht auch gleich noch eine Anmerkung (bitte versteh mich 
nicht falsch, ich finde deine Arbeit klasse und ziehe den Hut!):
So wie ich das verstehe, kann die Funktion ffwrite nur ein einzelnes 
Zeichen auf die Karte schreiben. Für viele Anwendungen ist es aber 
häufig nötig gleich einen ganzen String zu schreiben. Man müßte also 
jeden "Buchstaben" einzeln anweisen.
Wäre es nicht pfiffiger einfach eine Funktion alla:
1
void ffwrites(const char *s )
2
{
3
    while (*s) 
4
      ffwrite(*s++);
5
}

zu schreiben bzw.in die file.c zu packen?!

gruß matze

von Martin (Gast)


Lesenswert?

Hallo Daniel,

ich habe die neue LIB in meine alten Programme eingebaut.
Alle funktionierten auf Anhieb. Zum intensieveren Testen
komme ich in den nächsten Tagen.

Tolle Arbeit, Danke dafür!

Gruß Martin

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

danke das ihr mit testet.

Die angesprochene Funktion ffwrites ist aufgenommen.
Zudem ist in der fat.c noch eine Funktion fat_str hinzu gekommen, die 
sonst immer woanders untergebracht war.
Mit dieser Funktion kann man einen String von "test.txt" in "TEST 
TXT" wandeln, so muss ja schließlich alles auf die karte...

Anbei sind jetzt, wie ich denke einfache Beispiele zur Benutzung der 
Lib, für einen atmega8. Der is leider ein bisschen zu klein für den 
vollen Umfang der Lib (z.B. Ordner Rekursiv löschen und anlegen).

Der Bug in ffmkdir ist behoben. Keine weiteren Bugs bekannt...

Was mich noch stört, ist die Tatsache, dass mehr als 100 KBytes 
schreiben möglich wären, aber durch einen blöden Vergleich von zwei 
unsigned long int (ist nötig wegen der überschreiben Funktionalität) nur 
80-85 KBytes geschrieben werden...
Muss mal sehen ob das nicht einfacher geht...

Grüße Daniel

von Matze A. (matzeapa)


Lesenswert?

Hi,

ich verzweifel langsam. ich komm einfach nicht durch die mmc_init.

ich denke, es liegt an meiner verkabelung. hier eine kleine ascii-skizze 
:)
(ATmega162)

--------\
09 (NC)  \
01 (CS)  | ---------- (PB1)
02 (DI)  | ---------- MOSI   (PB6)
03 (GND) | -------------------------- (-)
04 (VCC) | -------------------------- (+)
05 (CLK) | ---------- SCK    (PB7)
06 (GND) | -------------------------- (-)
07 (DO)  | ---------- MISO   (PB5)
08 (NC)  |
---------

Ich habe den ATmega162 mit 3,3V laufen, daher kein HC4050 dazwischen. 
Ich hoffe, daß ist soweit richtig und ich habe nur ein brett vorm kopf.
Als quellcode habe ich das beispiel von "mmc_0.5.1" genommen.

oder mache ich was falsch, wenn ich mein ISP kabel, das ja die selben 
ports benutzt, dranlasse?

ich komm echt nicht weiter und brauche wirklich hilfe!

gruß und danke, matze

von daniel (Gast)


Lesenswert?

Hi,


bist du sicher, das überhaupt das Programm drauf ist? Ist ISP nicht mit 
5 Volt? Sieht nämlich sonst Ok aus.

Wie lang sind die Kabel vom MC zur Karte?

Und ja, besser ISP Stecker abmachen.



Grüße Daniel

von Matze A. (matzeapa)


Lesenswert?

So, habe den fehler nach langem probieren gefunden. irgendwie hat der 
uart nicht geklappt, wenn der isp nicht angeschlossen war. ich habe 
jetzt als work-around einfach die masse, an der es lag, von PC zum uC 
extra gezogen.
jetzt geht alles.

aber wie zum kuckkuck mach ich nen zeilenumbruch?
ich hab schon alles probiert: \n und \r sogar schon den 0x0D (ascii code 
für zeilenumbruch).

hilfe.

danke,
matze

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Hallo,
schön das es jetzt klappt.

Zeilenumbruch wo? Im Terminal Programm?
Je nachdem welches du benutzt musst du das auf vt100 oder so 
umstellen... dann sollte uputc('\n') oder uputs("\n") auf jeden Fall 
gehen.

Anbei ein Funktionsübersichts Diagramm der ganzen Lib.
Krieg leider die Größe nicht in den Griff. Also hier die Warnung: 2412 x 
7946 Pixel :)

von Matze A. (matzeapa)


Lesenswert?

ne,  im terminalprogramm weiß ich das (ich mach das immer mit 0x0D). 
aber in der*.txt auf der SD karte.
Ich kriegs einfach nicht hin.

gruß
matze

von daniel (Gast)


Lesenswert?

Hallo,

also mein hex Editor sagt bei Windows Zeilenumbruch:

0x0D 0x0A für neue Zeile...

Das ist der Hex Code
1
746573740D0A7A65696C650D0A6E65750D0A
für
1
test
2
zeile
3
neu

Grüße Daniel

von Daniel R. (zerrome)


Lesenswert?

Update,
bei Linux ist ein Zeilenumbruch nur 0x0A...

von Chris (Gast)


Lesenswert?

Ich möchte jedemenge einfache Bytes in eine Textdatei schreiben. Das 
klappt auch alles gut, ich mache mir nur gedanken um die Lebensdauer der 
Karte.

Wäre es besser, wenn ich die Bytes nicht direkt mit ffwrite(byte); auf 
die Karte schreibe, sonderen erstmal in einem großen String speichere 
und diesen dann später komplett auf die Karte übertrage, oder macht das 
keinen unterschied?

Ich benutzte einen MEGA32, RAM wäre noch genug dar, um z.B. 512Bytes 
zupuffern.

von Daniel R. (zerrome)


Lesenswert?

Hallo,

nee das ist kein Problem, da ja schon 512 Bytes gepuffert werden.
Halt ein Sektor, bevor geschrieben wird.

Was allerdings schlecht wäre, ist nach dem schreiben immer direkt ein 
ffclose (obwohl man später eigentlich noch mehr schreiben will), weil 
dabei die Datei Daten ein Update erfahren. Dies bedeutet, dass einmal 
der Sektor wo der Dateieintrag drin steht neu geschrieben wird und evlt. 
muss auch die FAT geupdatet werden (wenn mehr Bytes geschrieben wurden 
als über Cluster schon verkettet sind). Und natürlich der Sektor in dem 
man gerade geschrieben hat auch.

Also einfach öffnen und dann immer mal wieder schreiben ist überhaupt 
kein problem...

Ein Problem könnte sein, wenn man oft innerhalb einer Datei hin und her 
springt. Beispiel:
Ich schreibe in Sektor 1928 ein Byte, jetzt springe ich (mit ffseek) zu 
Sektor 1929 und schreibe wieder ein Byte, weil ich aber Sektor 1928 
verlasse und dieser geändert wurde, muss er vorher geschrieben werden.

Wenn ich jetzt zurück springe, passiert das gleiche wie vorher mit 
Sektor 1928 jetzt mit Sektor 1929.
Das ist der schlimmste Fall, weil für nur 1 geändertes Byte immer ein 
ganzer Sektor geschrieben wird... Würde also 512 Sektor schreib Vorgange 
(also 512*512 Bytes) für 512 Bytes machen. Das wäre schlecht und 
langsam...

Wenn eine Datei angelegt wird, gibt es mindestens 3 Sektor schreib 
Operationen.

1. Anlegen des Datei Eintrags im Ordner.
2. Mindestens einen Sektor mit Daten beschreiben (auch wenn weniger 
Bytes geschrieben werden).
3. Update des Datei Eintrags (Größe usw.).

Macht 3 beschriebene Sektoren. Das wird so gemacht, weil wenn schon mal 
ein Datei Eintrag besteht, kann man mit Recovery-Tools möglicherweise 
bei Datenverlust Daten retten. Dient also rein der Sicherheit. Nötig 
wären nur 2 Sektor schreib Operationen...

Da ein Sektor (512 Bytes) die kleinste Einheit ist die man auf eine 
Karte schreiben kann werden ja eben 512 Bytes gepuffert.

Grüße Daniel

von Chris (Gast)


Lesenswert?

Ok,
vielen Dank dafür!!
Das mit dem ffclose werde ich berücksichtigen.

Gruß
Christian

von Matze A. (matzeapa)


Lesenswert?

Hi,

ich habe noch einen kleinen Zusatz zur file.c (ist vielleicht etwa 
übertrieben, aber vielleicht als Addon nicht schlech):
Wenn man z.B. Messwerte aufnehmen will, macht ein Zeilenumbruch recht 
viel sinn. Ich habe in meine file.c daher hinzugefügt:
1
ffzeilenumbruch ()
2
   {
3
     ffwrite(0x0D);
4
     ffwrite(0x0A);
5
   }

Macht zugegebener Maßen nicht in jeder Anwendung sinn, bei mir 
allerdings schon und ich denke auch bei so mach anderem.

Gruß,
ein Fan dieser Speicherfressenden Library :)
Matze

von Martin (Gast)


Lesenswert?

Hallo Daniel,

ich habe nun die LIB ausfuehrlich getestet und muss sagen, dass alles 
rund laeuft. Meine HireScore-Liste laeuft nun auch und wartet auf die 
Besten.

Gruss Martin

von C.Alex (Gast)


Lesenswert?

Hallo,

ich hab heute die Souce-Files mit WinAVR (ohne mitgelieferte makefile) 
compiliert und es kommt tatsächlich ein Hex-File.
uc=atmega8
optimierung= -Os
smallFileSys 0
write 0
superfloppy  1

Program:    7826 bytes (95.5% Full)
(.text + .data + .bootloader)

Data:        656 bytes (64.1% Full)
(.data + .bss + .noinit)

Als hab ich den parameter smallFileSys 1 gesetzt. Die Größe ist aber bei 
den 7826 byte geblieben.

Ich weiß, dass das Problem bekannt ist. Gibt es dazu schon eine Lösung?



Viele Grüße
C.Alex


PS: Die mitgelieferte makefile hat auch keine abhilfe gebracht.

von daniel (Gast)


Lesenswert?

Hallo,
bin leider noch nicht dazu gekommen, die beiden Optionen von 
smallFileSys und write wieder einzubauen...
Nur superfloppy funktioniert bis jetzt.
Wird wohl auch noch ein wenig dauern, weil ich auch alles auf 
dynamischen Ram verbrauch am umbauen bin...

Grüße Daniel

von C.Alex (Gast)


Lesenswert?

Hallo,

das erklärt natürlich einiges :)

Ich dachte AVRStudio würde wieder rumspinnen. Ich muss auch zugeben, ich 
hab nicht alle 180 Beiträge oben gelesen...


Was aber trotzdem interessant ist: Ich wollte den Code für ATmega88 
compilieren und auf einmal hat er nicht mehr draufgepasst (500byte zu 
groß).
Laut Datenblatt sind aber atmega8 und atmega88 von den Speichern her 
gleich groß. Tja Sachen gibts...

Danke für die Info

Viele Grüße
C.Alex

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.
Jetzt sind wieder alle 3 Schalter in der Lib zu benutzbar.
Zudem einige Verbesserungen.
Lesend ist bis zu 230 KBytes/s möglich. Beim Roh lesen, also ohne 
Dateisystem kommt man ungefähr auf 300 KBytes/s. Das ist nur ein relativ 
geringer Overhead.
Schreiben geht jetzt bis zu 140 KBytes/s trotz 
überschreiben-Funktionalität.

Bisschen Doku gibts auch hier :
http://www.mikrocontroller.net/articles/AVR_FAT32

PS: Die Zeilenumbruch Funktion wird erstmal nicht aufgenommen, 
allerdings sind weitere Anregungen erwünscht.

Viel Spaß damit :)

Grüße Daniel

von C.Alex (Gast)


Lesenswert?

Hallo Daniel,

die neue Version passt mit 94% Flash-Auslastung wunderbar auf dem 
atmega88.


Beim ersten Compilieren hat er mit smallFileSys 1 die Funktion 
fat_str(datei) nicht gefunden.

Ich hab dann einfach die Präprozessoranweisung in fat.c geänder in:
1
#if (smallFileSys==1)
2
// *****************************************************************************************************************
3
// bereitet str so auf, dass man es auf die mmc/sd karte schreiben kann.
4
// wandelt z.b. "t.txt" -> "T        TXT" oder "main.c" in "MAIN    C  " => also immer 8.3 und upper case letter
5
// VORSICHT es werden keine Prüfungen gemacht !
6
// *****************************************************************************************************************
7
char * fat_str(char *str){
8
.
9
.
10
.
11
}
12
13
#endif

Viele Grüße
C.Alex

von C.Alex (Gast)


Lesenswert?

Hallo,

mit welchem Programm muss ich meine SD-Karte formatieren, damit ich 
sicher gehen kann, dass es fehlerfrei formatiert ist.

Hintergrund ist, dass ich ein LowLevel-Format gemacht hab um den 
Speichervorgang nachvollziehen zu können. Anschließen mit Windows 
formatiert in FAT16. Seit dem schlägt die Fat-Initialisierung fehl. 
Also: Boot...

Vorher ging es.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
4
#include "main.h"
5
#include "file.h"
6
#include "fat.h"            
7
#include "hardware.h"
8
9
void beispiele(void);      // kleine datei operations-beispiele
10
11
//*****************************************************************************************************************
12
void main(void){
13
14
  uinit();              // uart initialisierung
15
 
16
  uputs((unsigned char*)"\nBoot");
17
18
  while (mmc_init() !=0){     //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten  
19
  ;  
20
  }  
21
  
22
  uputs((unsigned char*)"... ");    
23
24
  if(0==fat_initfat()){        //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten  
25
26
   uputs((unsigned char*)"Ok\n");    // wenn auf dem terminal "Boot... OK" zu lesen ist, ist init ok. jetzt kann man schreiben/lesen
27
28
    beispiele();                // beispiel 0-4 , da nur atmega8, keine ordner anlegen und ordner rekursiv löschen...
29
  }
30
31
32
}
33
34
// *****************************************************************************************************************
35
void beispiele(void){
36
37
  char datei[12]="test.txt";    // hier muss platz für 11 zeichen sein (8.3), da fat_str diesen string benutzt !!
38
  fat_str(datei);            // wandelt "test.txt" in das fat format 8.3 der form: "TEST    TXT" muss immer dieses Format haben, auch ordner !!
39
40
  // 1.) ______________anlegen und schreiben____________________________________________________________________
41
  /*   öffnet datei, wenn nicht vorhanden, legt ffopen datei an (rückgabewert = 1 datei existiert, also nur öffnen, 2 = angelegt). */  
42
  uputc('\n');
43
  uputs((unsigned char*)"Datei anlegen\n");
44
  ffopen( datei );            
45
46
  /* schreibt string  */
47
  ffwrites((char*)"Hallo Datei :)");
48
  // neue zeile in der datei
49
  ffwrite(0x0D);
50
  ffwrite(0x0A);
51
52
  /* schließt datei */
53
  ffclose();
54
  uputs((unsigned char*)"Ende\n");
55
  
56
}
57
//*****************************************************************************************************************


Ich hab doch im Prinzip nichts falsch gemacht? oder?


C.Alex

von Sucher (Gast)


Lesenswert?

Hallo

@Daniel weiter oben schreibst Du, dass Du einen HC4050 als Levelshifter 
verwendest. Ist der wirklich geignet? Im Datenblatt steht das VCC -0,5 
bis 7V sein kann (also VCC=3,3V). DC Input Voltage -0,5V to Vcc+0,5V. 
Das wären dann aber bis 3,8V, also keine 5 V. Das der das eventuell ohne 
kaputt zu gehen kann ist ne andere Sache!
Oder habe ich da was falsch verstanden?

Danke für ne Klärung
Achim

von Daniel R. (zerrome)


Lesenswert?

Hallo zusammen.

@Alex
Wahrscheinlich ist die Karte jetzt nicht mehr partitioniert, du musst 
also in der fat.h "superfloppy  1" ändern.

@sucher

Ausschnitt Datenblatt:

"The 74HC4050 provides six non-inverting buffers with a
modified input protection structure, which has no diode connected to 
VCC. Input voltages of up to 15 V may therefore be used. This feature 
enables the non-inverting buffers to be used as logic level translators, 
which will convert high level logic to low level logic, while operating 
from a low voltage power supply. For example 15 V logic
(“4000B series”) can be converted down to 2 V logic."

Das verstehe ich so, dass da eine irgendwie geartete Eingangssicherung 
besteht, damit der Eingang nicht kaputt geht. Deshalb kann man bis zu 
15V auf den Eingang machen selbst wenn das Ding nur mit 2V betrieben 
wird.
Rest vom Datenblatt gibt das auch so her...

Grüße Daniel

von Sucher (Gast)


Lesenswert?

Hallo

@Daniel, Danke für die Antwort. Es gibt da wohl verschieden Datenblätter 
( Deins ist Philips?).
Bei Reichelt könnte man das nich rauslesen
http://www.reichelt.de/?;ACTION=6;LA=3;ARTICLE=3228;GROUPID=2933;GROUP=A2235;SID=31XMMj3qwQAR8AAApHlEkae535059485831c5f64f055c1b01bd7a 
(Thomson)

Es geht mir nicht ums rechthaben, sondern ich möchte es verstehen.

MfG
Achim

von C.Alex (Gast)


Lesenswert?

Hallo Daniel,

die Initialisierung der Karte und FAT funktionieren jetzt wieder, 
allerdings bleibt das Beilspielprogramm gleich in dem ersten 
Funktionsaufruf hängen. Also bei:
1
.
2
.
3
.
4
char datei[12]="TEST    TXT";
5
ffrm(datei);
6
.
7
.
8
.

Daraufhin hab ich die Signalwandlung mit dem SN74LS07 geprüft, es ist 
aber alles OK.

Hast du eine Idee warum der uC da hängen bleibt? Gleiche Reaktion mit 2 
versch. Karten.

Danke!

C.Alex

von Daniel R. (zerrome)


Lesenswert?

Hallo.


@Achim

Tatsache, in dem Datenblatt von Thomson steht nur ein schlanker Satz 
dazu, im Rest der Daten finde ich das auch nicht so bestätigt..

"The VCC side diodes are designed to allow logic-level convertion from 
high-level voltages (up to 15 V) to low-level voltages."



@C.Alex

So wie es aussieht, gibt es möglicherweise Probleme mit FAT16 und nur 
einem Sektor pro Cluster... hatte ich nicht getestet, sorry.
Werd ich aber schleunigst beheben.
Bis zum erbrechen hatte ich FAT32 mit mehreren Sektoren pro Cluster 
getestet...
Als workaround, meine Empfehlung: FAT32 mit mehreren Sektoren pro 
Cluster.

Grüße Daniel

von C.Alex (Gast)


Lesenswert?

Hallo Daniel,

ich habe beide Karten mit FAT32 formatiert; kein Unterschied zu vorher. 
Bedenken habe ich im Zusammenhang mit der Formatierung der Karten. Kann 
man davon ausgehen, dass das Windows Formatier-Tool alles richtig macht?

Weil: ich hab die Karte mit Windows formatiert und hatte danach das 
Problem, dass es nicht mehr gebootet hat :Boot...
Daraufhin hab ich es in meine Digicam reingesteckt, der kein System 
erkannt hat und formatieren wollte, und siehe da: Boot...OK

Ich kenn mich nur zuwenig mit FAT aus um dem auf den Grund zu gehen.

C.Alex

von Daniel R. (zerrome)


Lesenswert?

Hallo,

also das einzige Problem ist die Formatierung mit Linux, da dabei, warum 
auch immer, das root-Dir wenn es nur 1 Cluster groß ist als Ende 
Markierung nicht 0xfffffff0 erhält, sondern 0xffffff80.
Ich hatte einfach keine Lust mich mit 3 Ende Markierungen 
herumzuschlagen.

Windows ist manchmal etwas eigen beim Formatieren, da wird schon mal aus 
einer partitionierten Karte eine unpartitionierte ohne Kommentar ^^
Muss man nachsehen und in der Lib umstellen.

Andere Probleme gibt es eigentlich nicht im Zusammenhang mit 
Formatierungen.

Was haben die Karten, die nicht durch den Boot Vorgang kommen, denn für 
Eckdaten? MB Größe, Sektoren/Cluster und partitioniert oder 
unpartitioniert?

Grüße Daniel

von C.Alex (Gast)


Lesenswert?

Hallo,

da wäre:
Lexar Media
File System: FAT16
Total capacity: 127.090.176 byte
Sector count: 248.223
Bytes per Sector: 512
Bytes per Cluster: 2.048
Total Clusters: 61.925


Lexar Platinum II
File System: FAT16
Total capacity: 512.880.128 byte
Sector count: 1.001.719
Bytes per Sector: 512
Bytes per Cluster: 8.192
Total Clusters: 62.574

Woran kann ich erkennen, ob nach dem formatieren eine Karte 
partinioniert ist oder nicht?


C.Alex

von Daniel R. (zerrome)


Lesenswert?

Also einmal steht im Sektor 0 die Partitionstabelle oder die Fat Daten.

Bei beiden von Dir geposteten Karten sollte angesprochenes Problem mit 
nur einem Sektor pro Cluster nicht auftreten.
Bleibt nur noch die Partitionierung und das Formatieren mit Linux.
Das mit der Partitionierung ist schnell getestet... einfach mal 
umstellen in der Lib und schauen ob es geht. Allerdings besser nur ein 
lese Test (also auch kein ffrm !).

Es kann auch vorkommen, dass die Initialisierung der Fat durchläuft, 
aber keine sinnvollen Daten enthält. Dann würde sich z.B. ffrm ziemlich 
aufhängen. Würde zu Deinem Problem Passen. Wäre aber zurückzuführen auf 
die Falsche Vorgabe des Schalters "superfloppy" in fat.h

Grüße Daniel

von C.Alex (Gast)


Lesenswert?

Hallo Daniel,

ich hab den Parameter SUPERFLOPPY mit beiden Einstellungen ausprobiert 
und versucht einer vorher unter Windows erstelle TEST.TXT nur zu lesen 
und auf dem Terminal darzustellen.

Bei einer Einstellung ist der Bootvorgang nicht beendet worden: Boot... 
und es wurde auch nichts weiteres angezeigt.
Mit der anderen Einstellung wurde der Bootvorgang abgeschlossen und das 
ganze Terminal wurde mit irgendwelchen Daten vollgeschrieben.


Unter Linux hab ich noch nicht formatiert.


C.Alex

von Daniel R. (zerrome)


Lesenswert?

Hallo,

kann ich absolut nicht bestätigen. Hast du irgendwo den Code geändert?
Habe nochmal alles durchgesehen und getestet, dabei ist mir noch ein 
anderer Bug aufgefallen..in Zusammenhang mit ffseek und dem 
überschreiben von Daten. Sonst ist da alles im grünen Bereich !

Grüße Daniel

von Johannes N. (strangeman)


Lesenswert?

Hallo!

Ich bin begeistert von der Lib! Wer hätte gedacht, dass das SD-benutzen 
so einfach wird? =)

Alles funktioniert soweit ok. Zum Testen habe ich eine AgfaPhoto 1GB 
genommen. Ich schreibe mit einem Delay von 10ms 2000 uint_16t Werte und 
ihre Nummer als String auf eine Textdatei. Geht sauber und schnell. 
Allerdings scheint es so, dass ich nochmal warten muss (ich hab jetzt 
100ms) bevor ich ffclose aufrufe, da sonst die Datei nicht vollständig 
ist. Vermutlich wegens des Hardware SPI? Vielleicht könnte ffclose 
selbst solange warten, bis die Datei komplett ist!

Bei mir gings auch auf einer 16MB FAT12 Karte, aber da gab es Probleme 
mit dem Schreiben (hatte keinen delay vor ffclose(), aber es fehlten am 
Ende 400 Werte!). Zudem wurden andere Dateien durch das Schreiben der 
Werte verändert. Ich kann ja mal das Image schicken, wenn Interesse für 
FAT12 Support besteht. (Und mir jemand erklärt, vo unter dev die Datei 
für meinen SD-Leser steht...)

Danke für deine Mühen!
StrangeMan

PS: Verwende 0.5.2

von Daniel (Gast)


Lesenswert?

Hallo,

also die SPI Routinen sind blockend geschrieben, die warten solange bis 
das
Byte das geschrieben werden soll auch raus ist.
Deshalb ist ein delay unnötig.
Wenn es aber mit einem delay klappt, klingt das für mich eher so, als ob 
die SPI Strecke anfällig ist. Vielleicht schwingt da was mit oder so 
(und beruhigt sich bei einem delay?!?)...
Wie steuerst Du die Karten an? Direkt oder über irgendwelche 
Pegelwandler?


Komme momentan nicht richtig zum weiter entwickeln.
Was aber definitiv geht ist einfaches lesen und schreiben ohne die etwas 
ausgefalleneren Funktionalitäten wie ffseek() und überschreiben von 
Daten.

Wobei ffseek() an sich tadellos funktioniert, nur in Zusammenhang mit 
ffwrite() und dem überschreiben welches über einen Sektor hinaus geht 
gibt es Probleme, da dann ja der Sektor in dem man jetzt weiter 
überschreiben möchte noch geladen werden muss...

Grüße Daniel

von Onit (Gast)


Lesenswert?

Noch zum Thema Zeilenumbruch:
Wichtig ist das die Angabe der Zeichenanzahl beim Schreiben auf die 
SD-Karte!!!!
"\r\n" sind nur 2 Zeichen nicht 4!!!!!
Bei der Angabe, das es 4 Zeichen sind, werden die letzten 2 Zeichen 
(nach dem Zeilenumbruch)irgendwelcher Käse. Meist sind da 4ecke 
enthalten, oder der Inhalt anderer Daten.

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.