www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MMC karte adressieren 32bit will nicht


Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander

Ich habe jetzt nach 3 Tagen endlich meine 32mb MMC karte angesteuert 
bekommen. Ich benutze einen ATmega32. Ich habe die lib von roland riegel 
verwendet und versuche nun mit sd_raw_read immer 1024 byte Päckchen 
auszulesen.

Aber irgendwie habe ich das Gefühl, dass er mit nach 64 päckchen wieder 
von vorne anfängt, so als ob das offset nur 16 bit wäre. Hier die Stelle 
im Code:

...
offset_t frame;
for(frame=0;1;frame+=1024){

  if(sd_raw_read(frame,mmc_buf,1024) == 0)
    usart_write_str("rfail\r\n");
...

Ich habe als for-Bedingung provisorisch 1 eingetragen, um das als 
Problem auszuschließen.

offset_t ist im nicht-SDHC Modus als uint32_t definiert.

Hier der Prototyp der raw_read:

uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length);

Ich hoffe ihr wisst was! Danke Schonmal!

Autor: Jonas Mitschang (jonen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hatte mal ein ähnliches problem, da war der compiler schuld. versuch 
mal ne andere optimierung (-O0  -O2  -Os). hatte schon code/avr-gcc 
versionen, da ging 32bit code mit -O2 nicht und sogar auch schon, dass 
es mit -O0 nicht ging aber mit -O2.

vielleicht startet auch der watchdog nach ner zeit neu?

Autor: 1.8T-Passat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:
> for(frame=0;1;frame+=1024){

Überprüf mal die for-Schleife. Meiner Meinung nach hast Du da eine 
Endlosschleife, da Du in der Abbruchbedingung eine konstante stehen 
hast.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah Danke, das mit der Compileroption kann sein, hab -Os drin. Bin grad 
nicht bei meiner Hardware, das kann also sein.

Ich hab n UART dran hängen und bekomm debug ausgaben, der watchdog und 
somit ein Neustart ist es nicht.

Ich probier das nachher mal aus.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm also irgendwas stimmt da nicht. Hab die Optimierung jetzt ganz aus 
gemacht. Das ding ist von 3 auf 14kb gewachsen dadurch.

Ich hab jetzt mal die Warnungen durchgeschaut. Hier z.B. mal was 
auffälliges:

sd_raw.c: In function 'sd_raw_send_command':
sd_raw.c:404: warning: right shift count >= width of type
sd_raw.c:405: warning: right shift count >= width of type

Die Stelle im Code:

uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
{
    uint8_t response;

    /* wait some clock cycles */
    sd_raw_rec_byte();

    /* send command via SPI */
    sd_raw_send_byte(0x40 | command);
--> sd_raw_send_byte((arg >> 24) & 0xff);
--> sd_raw_send_byte((arg >> 16) & 0xff);
    sd_raw_send_byte((arg >> 8) & 0xff);
    sd_raw_send_byte((arg >> 0) & 0xff);
    switch(command)

macht sinn, dass da keine höheren Adressen ankommen dann...
Aber das ist ja ne 32 bit!

Jemand ne Idee?

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab jetzt alle Optimierungsoptionen durchprobiert, und auch 
ganz ohne das selbe Ergebnis, nur dass es sau langsam ist.

Genau nach 64 Päckchen a 1024 Byte fängt er einfach wieder von vorne an.

Ich wäre sehr dankbar für jegliche Hilfe.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Obwohl die variable arg schon uint32_t ist, hab ich mal versucht,
sd_raw_send_byte((((uint32_t)arg) >> 24) & 0xff);
    sd_raw_send_byte((((uint32_t)arg) >> 16) & 0xff);

zu machen. Selbes Ergebnis, selbe Warnmeldungen.

Ich weiß nicht mehr weiter.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du bist sicher, dass nirgends in Deinem Code etwas der Art
#define uint32_t unsigned int
steht (wie es für andere Architekturen passen würde und manchmal auch zu 
sehen ist)?  Ist ein
#include <stdint.h>
in derselben Datei?  Falls nicht, mach den mal rein.

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst dir in sd_raw_send_command einmal die sizeof(uint32_t) 
ausgeben lassen.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdint.h>
ist in der Header-Datei der c-Datei wo die sd_raw_send_command drin 
steht und in der main.h enthalten.

also uint32_t wird nicht neu definiert, nur das, was ich verwende, also 
offset_t, wird so definiert:
#if SD_RAW_SDHC
    typedef uint64_t offset_t;
#else
    typedef uint32_t offset_t;
#endif

sizeof(uint32_t) gibt 2 zurück. Das ist wohl das Problem. Was nun ?

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falsche <stdint.h>?  Sind auf der Kommandozeile -I - Anweisungen, die 
die stdint.h des Systems einbinden?

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze code:blocks als IDE. Wo kann ich herausfinden, was genau 
ausgeführt wurde, um den code zu compilen ?

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist bei den Compileroptionen ein "-mint8" dabei?

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:
> Ich benutze code:blocks als IDE. Wo kann ich herausfinden, was genau
> ausgeführt wurde, um den code zu compilen ?

Zeigt diese IDE die Kommandozeile nicht?  Das würde ich als ziemlich 
daneben empfinden.  Wird das Kommando nicht in dem Fenster angezeigt, wo 
auch die Fehlermeldungen erscheinen?  Vielleicht kann jemand etwas dazu 
sagen, der dieselbe IDE verwendet.

(Option -mint8 kann es nicht sein.  Da brauchst Du nicht zu suchen, denn 
die hat mit der Größe einer uint32_t nix am Hut.)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was Du auch machen könntest:  Schreibe in Deinen Code rein:
typedef unsigned long int uint32_t;
Dann sollte Dir der gcc sagen, woher er die andere Definition hat (mit 
der es dann kollidiert).

Autor: Torsten S. (tse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
32MB MMC Karte?

Die ist bestimmt mit FAT12 anstatt FAT16 formatiert.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten S. schrieb:
> 32MB MMC Karte?
>
> Die ist bestimmt mit FAT12 anstatt FAT16 formatiert.

Die ist bestimmt nicht mit FAT12 formatiert, denn das kann höchstens 
16 MiB verwalten.

Autor: Frank K. (fchk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:

> uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
> {
>     uint8_t response;
>
>     /* wait some clock cycles */
>     sd_raw_rec_byte();
>
>     /* send command via SPI */
>     sd_raw_send_byte(0x40 | command);
> --> sd_raw_send_byte((arg >> 24) & 0xff);
> --> sd_raw_send_byte((arg >> 16) & 0xff);
>     sd_raw_send_byte((arg >> 8) & 0xff);
>     sd_raw_send_byte((arg >> 0) & 0xff);

Probier das mal:

union
{
  uint32_t long;
  uint8_8 byte[4];
} addr;

addr.long=arg;
sd_raw_send_byte(0x40 | command);
// eventuell die Reihenfolge ändern, je nach endianess
sd_raw_send_byte(addr.byte[0]);
sd_raw_send_byte(addr.byte[1]);
sd_raw_send_byte(addr.byte[2]);
sd_raw_send_byte(addr.byte[3]);

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank K. schrieb:
> union
> {
>   uint32_t long;
>   uint8_8 byte[4];
> } addr;

Wenn sizeof(uint32_t) = 2 ist wie oben geschrieben, wird diese Union 
nichts daran ändern und nichts nützen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wenn sizeof(uint32_t) = 2 ist wie oben geschrieben, wird diese Union
>nichts daran ändern und nichts nützen.

Richtig. Was steht denn in der stdint.h für uint32_t?
Dann könnte man mal in der Compilerhilfe nachsehen
was der denn da so anbietet;)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deshalb ja mein Vorschlag, einen typedef für uint32_t einfach mal so 
reinzuschreiben.  Dann wird der Compiler schon zeigen, wo er die erste 
Definition gefunden hat und man kann sie nachprüfen.

In der <stdint.h> der avr-libc ist uint32_t ein typedef nach unsigned 
long.

Autor: Torsten S. (tse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir funktioniert der sd-reader des o.g. Autors sehr zuverlässig 
schon über Jahre. Sowohl mit SD als auch SDHC. Warum man nur die 
sd_raw-Funktionen nutzen möchte verstehe ich nicht ganz.

Der GCC spuckt bei mir keine einzige Warnung aus. Vielleicht ist es eine 
gute Idee, das ganze Projekt als solches zuerst mal auszuprobieren. Beim 
copy&paste kann man schnell etwas übersehen.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also auf die MMC-Karte schreibe ich einfach mit dd direkt meine Daten 
rein, das reicht mir. Mit FAT hab ich es zuerst probiert, in der 
live-shell hat ls aber nur Müll angezeigt. Ich dachte zuerst ich hätte 
was falsch formatiert und wollte deshalb das raw nehmen, da weiß ich, wo 
ich dran bin. Außerdem ist der Code viel kleiner und wahrscheinlich auch 
schneller.
Ich denke aber, dass der Müll bei ls am selben Problem liegt.

In der stdint.h habe ich schon selbst nachgeschaut, da steht korrekt 
unsigned long int drin.
typedef unsigned long int uint32_t;

Ich versuch jetzt mal das im code typedefinieren.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich glaube ich habe den fehler:

main.h:16: error: conflicting types for 'uint32_t'
/usr/include/stdint.h:52: note: previous declaration of 'uint32_t' was here


anstatt in /usr/avr/include nimmt er die normalen. Mal schauen, wo ich 
das ändern kann.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok habs. Man konnte auch einstellen, ob man nur ne "task description" 
oder die ganze commandline haben will. Jetzt sehe ich auch die Befehle.
Dass der avr mit den Libs aus /usr/libs funktioniert hat wundert mich 
allerdings ein wenig. Aber macht ja durchaus Sinn, soviel Unterschied 
sollte es da ja nicht geben. Wo er bei den eingestellten Pfaden 
allerdings die richtige stdio mit den Port-Definitionen herbekommen hat 
ist mir dann aber ein Rätsel.

Ich hab mein uC Board grad nicht in der Nähe, aber die Compilerwarnung 
mit den zu kleinen Variablen beim Shiften ist jetzt weg. Ich denke, das 
Problem ist behoben.

Vielen Dank an alle! Hier wird einem wirklich gut geholfen (war mein 
erstes Mal hier).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.