Forum: Mikrocontroller und Digitale Elektronik speicher reservieren?


von crazychriz (Gast)


Lesenswert?

Hallo zusammen,

versuche ne sogenannte verkettete liste nach first in first out auf nem 
PIC18
mit MCC18 zu realiesieren.
Das ganze Funktioniert auch schon...aber halt in Visual Studio und nicht 
in mplap...

denke das es an der speicherreservierung liegt

hat jem von euch schon mal mit malloc und free auf nem PIC gearbeitet 
und könnt mir posten

a) ob das überhaupt möglich ist
b) welche headers ich verwenden muss
c) vll ein paar zeilen code ;-)

danke

mfg
crazychriz

von Arc N. (arc)


Lesenswert?

Afaik gibt's malloc/free nicht in den Standardbibliotheken für den C18.
Also entweder größeren PIC(24,dsPIC,32), was einfaches selber schreiben,
oder z.B. AN914 
http://ww1.microchip.com/downloads/en/AppNotes/00914a.pdf "Dynamic 
Memory Allocation for the MPLAB® C18 C Compiler" nehmen.
Bleibt die Frage: Warum kommt keine andere Lösung ohne malloc und 
Konsorten in Frage?

von crazychriz (Gast)


Lesenswert?

andere lösung? bin relativ neu in c und pic und mir fällt mom nichts ein 
wie ich noch ne fifo liste einfach realisieren kann. ausser vll mit 
arrays und paar zeigern ???

von crazychriz (Gast)


Lesenswert?

vielen dank für den link. denke das hilft mir weiter ;-)

jetzt kann ich ahhhh schlafen gehn.

;-)

von Peter D. (peda)


Lesenswert?

Auf nem MC laufen ja keine verschiedenen Applikationen.
Daher reservierst Du einfach soviel SRAM, wie maximal nötig.
Freigegebener SRAM nützt Dir nichts.

Malloc und Free braucht man garnicht. Sie belegen nur zusätzlichen SRAM 
für die Verwaltung. D.h. Du hast damit noch weniger SRAM zur Verfügung.


Peter

von crazychriz (Gast)


Lesenswert?

aber durch das freimachen des speichers mit free rücken meine elemente 
automatisch nach. wie könnte ich dieses ansonsten möglichst unkomplizert 
realieseren.

von Arc N. (arc)


Lesenswert?


von Peter D. (peda)


Lesenswert?

crazychriz schrieb:
> aber durch das freimachen des speichers mit free rücken meine elemente
> automatisch nach.

Nein, da rückt nichts nach, es wird nur eine Lücke frei.

Für Garbage-Collection brauchts ein OS und der Speicher darf nur über 
Handle zugegriffen werden. Wird damit auch deutlich langsamer gegenüber 
einem Pointer.


Peter

von crazychriz (Gast)


Lesenswert?

hmmm solangsam wirds krass... hab leider bisher net viel in richtung 
mikrocontroller gemacht und zu jedem thema sich einlesen und kapieren 
wird für mich grad richtig heftig weil mir da halt die fortgeschrittenen 
kenntnisse einfach fehlen.

also noch mal von vorne.

hab nen sensor der am beginn einer förderstrecke einkommende teile in 
unterschiedlichen abständen erkennt und eine bildverarbeiung die im 
abstand von ca nem meter steht und immer im richtigen zeitpunkt ein foto 
machen soll.

also sozusagen fist in first out

wie würdet ihr sowas auf nem pic18 realiesieren in c???

von Peter D. (peda)


Lesenswert?

crazychriz schrieb:
> also sozusagen fist in first out

Ein FIFO reserviert Platz für n Elemente.
Und dazu gibt es 2 Indexe die auf ein Element zeigen.
Kommen Daten rein, werden sie abgelegt und der Eingansgindex 
hochgezählt.
Die nächsten Daten kommen somit auf den nächsten Platz, nach dem letzten 
geht wieder mit 0 weiter.
Die Ausgabe prüft, ob beide Indexe ungleich sind und liest dann aus und 
zählt den Ausgabeindex hoch.

Was hat das aber mit Deinem Text davor (bildverarbeiung usw.) zu tun?


crazychriz schrieb:
> wie würdet ihr sowas auf nem pic18 realiesieren in c???

Was soll denn der PIC machen?


Peter

von crazychriz (Gast)


Lesenswert?

jupp und ich möchte nun ne fifo liste auf nem pic in der alle mom auf 
dem band vorhandenen teile enthalten sind und die anzahl der impulse bis 
zur kamera.

neues teil am sensor -> neues teil in liste

aber als mechaniker ohne informatik studium ist das halt schon bissel 
hart, bin auf jeden fall lernbereit aber mir feht grad irgendwie nen 
denkansatz.

von Purzel H. (hacky)


Lesenswert?

Der Ansatz heisst Circular Buffer. Man reserviert sich ein array von 2^N 
Plaetzen, zB 16, oder 32. Jetzt braucht man nur noch 2 indices, die man 
jeweile incrementiert und abschneidet.
increment : WP:=WP+1; WP:=WP and 0x1F; // fuer wrap 32
CircularBuffer[WP]:=DataIn;

Dieser Index geht immer rund herum.

DataOut:=CircularBuffer[RP];
increment : RP:=RP+1; RP:=RP and 0x1F; // fuer wrap 32

Man muss sich natuerlich erst ueberlegen wieviele Plaetze man wirklich 
braucht.

von crazychriz (Gast)


Lesenswert?

vielen dank werd mich jetz mal einlesen falls jemand noch ein link für 
paar gute deutsche seiten hat wo da vll erklährt wird währe super. ich 
versuchs derzeit mal in englisch.
dankle euch allen nochmals

von Karl H. (kbuchegg)


Lesenswert?

crazychriz schrieb:
> vielen dank werd mich jetz mal einlesen falls jemand noch ein link für
> paar gute deutsche seiten hat wo da vll erklährt wird währe super. ich
> versuchs derzeit mal in englisch.


Überleg einfach wie du das machen würdest wenn du es händisch machst.

Du hast einen linierten Zettel.
Wenn ein neuer Wert dazukommt, dann schreibst du ihn unten an die 
bisherigen Einträge drann. Wenn ein Wert rauskommt, dann radierst du ihn 
oben weg.
Bist du mit deinen Einträgen unten am Ende des Zettels angekommen, dann 
fängst du ganz einfach oben wieder an und benutzt die (mitlerweile 
ausradierten) Zeilen erneut.

Du musst dir nur merken, in welche Zeile der nächste Eintrag geschrieben 
wird, bzw. von wo der nächste Eintrag gelesen weren kann.

Und schon geht alles wie geschmiert.

Und im Rechner machst du genau dasselbe. Nur dass dein Zettel ein Array 
ist.

von crazychriz (Gast)


Lesenswert?

okay bin mir nur noch net im klaren wie ich das in c schreiben soll mit 
arrays und zeiger und was ich mach wenn sich die impuls zahlen verändern 
aber das ist jetz noch ne andere geschichte...
danke nochmals

von Karl H. (kbuchegg)


Lesenswert?

crazychriz schrieb:
> okay bin mir nur noch net im klaren wie ich das in c schreiben soll mit
> arrays und zeiger

Du brauchst keine Zeiger.

Jetzt bin ich aber doch verwundert. Du stehst mit einfacher Array 
Indizierung auf Kriegsfuss und willst dich an einer dynamischen FIFO 
versuchen?

> und was ich mach wenn sich die impuls zahlen verändern

Dann musst du eben das Array gross genug dimensionieren, so dass es zu 
keinen Problemen kommt. Du kannst das Array ja so groß machen, dass es 
gerade noch in den Speicher passt.

von crazychriz (Gast)


Lesenswert?

ne steh eigendlich zu den arrays besser als zu den pics haahahhahahaha
aber ich kann grad irgendwie nicht mehr folgen
ich glaub ich brauch jetzt mal ne auszeit
und vll steh ich dann nicht mehr so auf em schlauch

von Karl H. (kbuchegg)


Lesenswert?

crazychriz schrieb:
> ne steh eigendlich zu den arrays besser als zu den pics haahahhahahaha
> aber ich kann grad irgendwie nicht mehr folgen


Du hast 3 Variablen:
Das Array und 2 integer.
Der eine integer sagt dir, wo im Array der nächste eingehende Wert 
abzulegen ist und der andere sagt dir, von wo aus der nächste ausgehende 
Wert zu lesen ist.

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |        |          |   0   |    |   0  |
  +--------+          +-------+    +------+
  |        |
  +--------+
  |        |
  +--------+
  |        |
  +--------+


Ein Wert kommt in die FIFO rein: 8

Ergebnis deiner Manipulation

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   0   |    |   1  |
  +--------+          +-------+    +------+
  |        |
  +--------+
  |        |
  +--------+
  |        |
  +--------+

der nächste Wert kommt rein: 25

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   0   |    |   2  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |        |
  +--------+
  |        |
  +--------+

Und noch einer: 12

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   0   |    |   3  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |  12    |
  +--------+
  |        |
  +--------+

Ein Wert gaht aus der Fifo raus. nextRead sagt uns welcher das ist: Der 
an Indexposition 0.  Der Wert ist daher 8

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   1   |    |   3  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |  12    |
  +--------+
  |        |
  +--------+

Und wieder kommt ein Wert rein: 49

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   1   |    |   0  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |  12    |
  +--------+
  |  49    |
  +--------+

Beachte wie nextRead jetzt nicht auf 4 ggangen ist, sondern auf 0!

Ein Wert soll aus dem FIFO raus: nextRead sagt wieder welcher. Nämlich 
der an der Arrayposition 1. Das sind die 25
(und das ist auch richtig so. Denn in dieser Reihenfolge wurden sie ja 
eingestellt. 8, 25 ...
Die 8 wurde schon ausgelesen, also ist als nächstes die 25 drann)

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |   8    |          |   2   |    |   0  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |  12    |
  +--------+
  |  49    |
  +--------+

Wert kommt dazu: 14

                      nextRead     nextWrite
  +--------+          +-------+    +------+
  |  14    |          |   2   |    |   1  |
  +--------+          +-------+    +------+
  |  25    |
  +--------+
  |  12    |
  +--------+
  |  49    |
  +--------+

Die 14 überschreiben die 8. Aber das ist ok. denn die 8 wurde ja schon 
aus dem FIFO ausgelesen.


> ich glaub ich brauch jetzt mal ne auszeit
> und vll steh ich dann nicht mehr so auf em schlauch

Zwischen dem nextRead und dem nextWrite gibt es Zusammenhänge, die dir 
sagen ob das Array voll ist, bzw. ob noch etwas im FIFO auf Abholung 
wartet. Aber da kommst du sicher selber auch drauf.

Wie gesagt: ISt ganz simpel. Hast du sicher im realen Leben (in 
Abwandlungen) schon hundert mal gemacht.

von Purzel H. (hacky)


Lesenswert?

Buffer :array[0..32]of word;
WP:byte;  // write index
RP:byte;  // read index
count:byte;

init :
 WP:=0; RP:=0; count:=0;

Schreiben : // erst schreiben, dann incrementieren
 Buffer[WP]:=InData;
 inc(WP);
 WP:=WP and 0x1F;
 inc(count);

Lesen : // erst Lesen, dann incrementieren
 OutData:=Buffer[RP];
 inc(RP);
 RP:=RP and 0x1F;
 Dec(count);

Das isses schon fast. Jetzt muss man noch beim Schreiben auf Voll 
testen, und beim Lesen auf Leer.

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.