SRAM bei Start löschen

Gast #364903
Lesenswert?

Hallo

ich möchte das interne SRAM des m8515 bei Programmstart löschen lassen.
In Assembler habe ich es folgendermaßen gelöst:
 ldi r26, LOW(start_sram)
 ldi r27, HIGH(start_sram)
löschen:
 ldi temp, 0
 st X+, temp
 cpi XH, HIGH(ende_sram)
 brne löschen
 cpi XL, LOW(ende_sram)
 brne löschen

Jetzt will ich das in C machen aber mir fehlt der Durchblick mit den
Pointern. So wird das doch gemacht oder? Gibts dort auch die sache mit
dem X+ und den reservierten Registern 26 und 27 ?

Eigentlich wäre das mit einer while Schleife doch machbar. Hat jeman
einen Ansatz für mich? Danke!
Gast #364905
Lesenswert?

hatte immermal das Problem dass nach dem einschalten das auslesen des
SRAMs nicht immer Nullen waren. Wahrscheinlich waren durch
Spannungsreste noch Werte in einigen Registern.
Aber auch später müsste ich diese Pointer nutzen, weil ich das SRAM
anschließend beschreiben will. Und das ginge ja dann in ähnlicher
Weise.
Moderator Persönliche Seite #364906
Lesenswert?

> hatte immermal das Problem dass nach dem einschalten das auslesen
> des SRAMs nicht immer Nullen waren.

Das ist normal.  SRAM-Zellen fallen mit einer hohen Wahrscheinlichkeit
auf einen technologisch bedingten Vorzugswert beim Zuschalten der
Betriebsspannung.

> Aber auch später müsste ich diese Pointer nutzen, weil ich das SRAM
> anschließend beschreiben will.

Du sprichst in Rätseln.  Vielleicht zäumst du mal bitte nicht das
Pferd von hinten auf und fängst mit dem Unwesentlichen an, sondern
beschreibst lieber, was du insgesamt tun möchtest.  Mir scheint es, du
willst in C so eine Art Assemblerprogrammierung erledigen.  Das ist
nicht der richtige Ansatz.  Ich weiß, ``Real programmers are able to
program FORTRAN in any language.'', aber das ist kein sinnvoller
Stil.
Gast #364907
Lesenswert?

Ich krieg das mit den Pointern nicht hin. Ich meine ein SRAM Register
hat ja eine zugehörige Adresse. Beginnend bei 0x60.
Angenommen ich will den SRAM in einem Rutsch löschen.


for (adr_sram=0x60,adr_sram=<0x25F,adr_sram++)
{
 register_sram = 0x00;
 register_sram++;
}

nur wie verknüpfe ich die Register mit den jeweiligen Adressen?
Das wäre doch die Sache mit den Pointer, wenn ich irre. (?)
Gast #364908
Lesenswert?

Bevor hier noch mehr über Sinn und Unsinn deines Unterfanges diskutiert
wird, probier's mal folgendermaßen:

uint8_t *ptr;
uint8_t start = (uint8_t *)0x060, ende = (uint8_t *)0x25f;
for (ptr=start, ptr<=ende, ptr++)
  *ptr = 0x00;

oder

#include <string.h>
memset(start, 0x00, 0x200);

Wenn's crasht, hast Du wahrscheinlich ein paar Speicherzellen
überschrieben, die das C-Laufzeitsystem benutzt.
#364909
Lesenswert?

> Sinn und Unsinn deines Unterfanges

Genau das ist aber der springende Punkt:
Es macht keinen Sinn.
Globale Variablen zu initialisieren erledigt
bereits der Compiler. Für den C-Programmierer
heisst das einfach nur: die Variable definieren
und ev. eine Intialisierung hinschreiben, wenn der
Default von 0 nicht passend ist.
Gast #364910
Lesenswert?

Hi,

> Globale Variablen zu initialisieren erledigt
> bereits der Compiler. Für den C-Programmierer

Nicht ganz richtig! Sozusagen eine Urban legend der Programmierer! :-))
Erledigt wird das im crt0.o-Objekt. Warum: die main-Funktion ist
keinesfalls der erste Code, der sofort nach dem Reset ausgeführt wird.
Das ist, auch beim GCC, ein Stück Assemblercode, das Stack etc. und
u.a. auch den VERWENDETEN RAM initialisiert, bei Vorbelegung durch
kopieren aus dem .data-Segment, ohne Vorbelegung (.bss-Segment) durch
eine Routine, die alles zu "0" schreibt (siehe anderes Posting oben!)
Wer's nicht glaubt: Dump machen oder in's Map schauen!

Das ist der Woodoo des Bootstrap-Codes! Und sicher auch die Lösung
Deines Rätsels! RAM, der nicht verwendet wird, wird auch nicht
initialisiert! Wäre Verschwendung von Rechenzeit! ;-) Wenn Du ihn
verwenden willst, definier ihn in einem C-Modul, dann ist er auch
"genullt". Oder ... ;-) schreib einen eigenen Bootstrap-Code! Denk
dann aber bitte auch an die Linker-Description, sonst fährt Dein Code
mit Dir U-Boot! (i.d.R. mein Tipp: laß die Finger davon, wenn Du nicht
genau weißt, was Du da machst!)

Schönen Tag noch,
Thomas
Gast #364911
Lesenswert?

>>uint8_t *ptr;
uint8_t start = (uint8_t *)0x060, ende = (uint8_t *)0x25f;
for (ptr=start, ptr<=ende, ptr++)
  *ptr = 0x00;

Ja, und wenn eine dieser Variablen im SRAM liegt (was ziemlich
wahrscheinlich ist, denn sowohl der Stack als auch der Heap liegen im
SRAM, wo auch sonst), dürfte das nicht funktionieren. Sicherlich dürfte
der Compiler für die Schleife nur Register benutzen, aber etwas unsicher
ist das doch. Wenn mich nicht alles täuscht, gab es das Schlüsselwort
register, mit dem man den Compiler bitten kann, eine Variable im
Register zu halten. Muß er aber nicht, wenn er nicht will.

BTW, insgesamt zweckfreies Vorhaben...

Gruß,
Matthias
Moderator Persönliche Seite #364912
Lesenswert?

>> Globale Variablen zu initialisieren erledigt bereits der
>> Compiler. Für den C-Programmierer

> Nicht ganz richtig! Sozusagen eine Urban legend der Programmierer!
> :-))

Naja, ,,der Compiler'' in diesem Sinne meint eher das, was der
Standard als ,,the implementation'' bezeichnet, d. h. das
Zusammenspiel aus Compiler und Standardbibliothek.  In diesem Sinne
stimmt die Aussage natürlich, dass sich das gesamte System um die
Initialisierung globaler und statischer Variablen selbst kümmert.

Klar kann man ein memset(..., 0, ...) irgendwo reinbauen, aber Sinn
hat das so keinen, und man riskiert, dass man sich dabei was zermüllt
(je nachdem, wo man es reinbaut).
Gast #364913
Lesenswert?

> Wenn's crasht, hast Du wahrscheinlich ein paar Speicherzellen
> überschrieben, die das C-Laufzeitsystem benutzt.

Warum sollten im Bereich 0x60 bsi 0x25F was anderes als
anwenderdefinierte Inhalte stehen? Das Laufzeitsystem wird hier wohl
kaum etwas reinspeichern.
#364914
Lesenswert?

Auch das Laufzeitsystem benutzt ein paar globale
Variablen.
zb. malloc muss irgendwie den Speicher verwalten.
rand() muss irgendwo den Seed halten

Eine der Grundregeln in der Programmierung mit einer
Hochsprache lautet nicht umsonst:

Speicher der Dir nicht gehört(*): Finger weg.

(*) damit ist gemeint: Der nicht explizit durch Variablen
belegt wurde, bzw. mittels malloc() und Konsorten angefordert
wurde.
Gast #364917
Lesenswert?

ach verstehe. In ASM (ganz oben) hab ich es aber wie es aussieht auch
nach meinem Willen gemacht. Lief aber.

Wenn ich es dem Compiler überlasse, weis ich dann wieviel Platz ich im
SRAM habe? Das muss ich dringen wissen, um rechtzeitig, wenn der voll
ist, die Daten wieder auszulesen um keine Daten zu verlieren.
#364918
Lesenswert?

Damit ist gemeint:

Du schreibst ganz einfach


int irgendwas;

int main( void )
{
  /* und hier garantiert dir der C-Sprachstandard, dass
     'irgendwas' zuverlässig den Wert 0 enthält */
}

Der restliche SRAM Speicher steht nicht unter Deiner Kontrolle
und daher sollst du den Ruhe lassen.
In einer Hochsprache zu programmieren heisst auch, dass man
etwas Kontrolle abgeben muss und an das Laufzeitsystem delegiert.
#364919
Lesenswert?

> Wenn ich es dem Compiler überlasse, weis ich dann wieviel Platz
> ich im SRAM habe?

Das kommt drauf an.

Wenn du ne Menge Variablen definierst, dann sagt dir der
Compiler beim Übersetzen, wieviele Bytes die belegen. Was
der Compiler natürlich nicht einrechnen kann, ist wieviel
Speicher zur Laufzeit durch dynamische Allokierung bzw. den
Stack verbraucht werden.

Wenn du dynamisch allokierst und kein Speicher mehr da ist,
dann meldet Dir das malloc() indem es eine 0 zurückliefert.
Gast #364920
Lesenswert?

Ich seh schon, der interne(!) SRAM ist wohl wirklich zu heiss um dort
anzufassen.
Zumal ich dann auch nicht weis wie ich die Speicherzellen adressieren
soll, wenn ich nicht weis welche verfügbar sind.
Ich müsste ja immer nachfragen: für nächstes Byte adressiere nächste
FREIE SRAM-Adresse.
Hat das hier noch niemand gemacht? In der Suche ergibt sich dort so
wenig dazu.

Werd wohl doch auf extern umsteigen müssen.
#364921
Lesenswert?

> In ASM (ganz oben) hab ich es aber wie es aussieht auch
> nach meinem Willen gemacht

In ASM bist du auch der alleinige Herr über die Maschine.
In einer Hochsprache übernimmt das Laufzeitsystem die
Verwaltung von Resourcen.

Stell Dir mal folgende Analogie vor:
Du hast eine Festplatte. Jetzt kommt Dein Programm daher
und beschreibt irgendwelche Sektoren. Einfach so. Ging
ja immer.
Super. Nur gibts da halt noch die Kleinigkeit eines Dateisystems,
dass sich um die Zuordnung von Sektoren zu Dateien, um die
Verwaltung von Dateien, etc. kümmert. Was denkst du wird passieren,
wenn du ohne Koordination mit diesem Dateisystem einfach irgend-
welche Sektoren beschreibst?

Genauso im Speicher. In ASM bist du als Programmierer für diese
Verwaltung zuständig. In einer Hochsprache gibt es dafür
über Mechanismen, mit denen man kooperieren muss, damit da
kein Durcheinander entsteht.
#364922
Lesenswert?

> Ich müsste ja immer nachfragen: für nächstes Byte adressiere
> nächste FREIE SRAM-Adresse.
> Hat das hier noch niemand gemacht?

Diese Frage stellt sich so in einer Hochsprache nicht.
In einer Hochsprache lautet das ganz einfach:
"Gib mir mal ein Byte oder Bytefeld mit der und der Größe.
 Wo du dieses Feld anlegst ist mir Wurscht, ich will nur einen
 Pointer drauf oder eben 0, wenn nichts mehr da ist."
Gast #364923
Lesenswert?

In C sagst Du einfach:
1
unsigned char blub[256];

Und schon hast Du die Variable "blub" zur alleinigen Verfügung.

Wo sie steht, interessiert Dich nicht die Bohne. Denn das ist Sache des
Compilers, wo immer er den Namen "blub" findet, ihn durch die
entsprechende Adresse zu ersetzten.
Und da die Variable 256 Elemente groß ist, ist ein Zugriff auf blub[0]
... blub[255] erlaubt.

Und jetzt kommts:

Ist die Variable global oder lokal statisch, wird sie genullt, ist sie
lokal, dann nicht !


Vergiß das Denken in Adressen, denke in Variablen.


Peter
Moderator Persönliche Seite #364927
Lesenswert?

> Wenn ich mich nicht irre, initialisiert

>   char foo[150] = {0};

> nur das erste Element des Arrays.

Selten, aber (zum Glück) irrst du dich diesmal.

6.7.8 Initialization
...
Semantics
...

21 If there are fewer initializers in a brace-enclosed list than there
   are elements or members of an aggregate, or fewer characters in a
   string literal used to initialize an array of known size than there
   are elements in the array, the remainder of the aggregate shall be
   initialized implicitly the same as objects that have static storage
   duration.
Moderator Persönliche Seite #364929
Lesenswert?

> Dagegen hat auch niemand was.

Es sei denn, man hat's eilig.  Man sollte nicht den Zeitaufwand für
diese Tätigkeit unterschätzen.  Ich habe mal eine zeitkritische
Funktion optimieren müssen.  Die Laufzeit war 700 µs, gefordert waren
200 µs.  Der größte Block, den ich ,am Stück' wegoptimieren konnte,
war ein memset(), mit dem ein etwas übereifriger Programmierer einen
internen Puffer erstmal ,,vorsichtshalber'' komplett genullt hat.
Das
war nicht nur zeitaufwändig, sondern eigentlich auch völlig
überflüssig, da 95 % dieses Puffers anschließend sowieso mit richtigen
Daten gefüllt worden sind.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren