Aus RN-Wissen.de
Wechseln zu: Navigation, Suche


Bascom Speicherstrukturen

Das Bascom keine Datenstrukturen bilden läßt, ist zwar bedauerlich, es gibt aber durchaus Möglichkeiten, sich zu helfen.

Einfache Strukturen

Da Bascom die Datenfelder im SRAM und im ERAM geschlossen in der Reihenfolge anlegt, wie sie dimensioniert werden, legt man die Felder von, sagen wir, eines Datenrecords auch hintereinander an.

DIM Rec_Header AS BYTE
DIM Rec_Length AS BYTE
DIM Rec_Usrdata AS STRING * 23
DIM Rec_Trailer AS BYTE

Und wenn wir nun diesen Bereich redefinieren, wobei wir die Gesamtlänge leider ausrechnen müssen,

DIM Record(27) AS BYTE AT Header OVERLAY

können wir dieses Speicherbereich sowohl als "Record" als Byte-Array in der Länge 27 verwenden, aber auch die Felder einzeln ansprechen, was beim byte-seriellen Input/Output recht praktisch ist.

Natürlich ist das noch kein Ersatz für vordefinierte Strukturen, die dann auch mehrfach an beliebigen Stellen deklariert bzw. verwendet werden können, wie es z.B. bei C (GCC) üblich ist. Da hilft leider nur Cut & Paste und ein anderer Prefix (statt "Rec_").

Mehrfache Strukturen a la malloc/new

Aber für den Fall, daß wir sagen können, wieviele dieser "Strukturen" im Programm maximal verwendet werden (was meisten doch der Fall ist) können wir aus einfachen Tabellen auch mehrfache Strukturen bilden. Nicht so elegant wie "malloc(sizeof(Record))", aber immerhin:
wir definieren

 CONST Maxindex = nn         ' Die Anzahl, die benötigt wird

DIM Usage_Index(Maxindex) AS BYTE     ' Hilfstablle der benützen Elemente
DIM Temp  AS BYTE     ' Hilfswert
' -------------- die "struktur"--------------------
DIM Rec_Header(Maxindex) AS BYTE
DIM Rec_Length(Maxindex) AS BYTE
DIM Rec_Usrdata(Maxindex) AS STRING * 23
DIM Rec_Trailer(Maxindex) AS BYTE

und wenn nun an einer Stelle eine neue Instanz der Struktur gebraucht wird:

   FOR Temp = 1 to Maxindex
      IF Usage_Index(Temp) = 0 then      ' da ist was frei
          Usage_Index(Temp) = 1          ' reservieren
          EXIT FOR
      END IF
   NEXT
' und nun haben wir einen Bereich und können ihn exklusiv verwenden
    Rec_Header(Temp) = nn
    Rec_Length(Temp) = nn
    Rec_Usrdata(Temp) = "aaaaaaa"
    Rec_Trailer(Temp) = nn

Die reservierende Funktion wird sich "Temp" natürlich als "pointer" merken und kann ihr Bereich dann auch mal freigeben

  Usage_Index(Temp) = 0          ' unreserve

Für die "C"-Kundigen User:

   Rec_Length(pointer)         <entspricht>           pointer->Rec_Length

Anmerkung

Von einer wirklichen "Heap" Verwaltung kann man wohl nicht sprechen. Aber vielleicht kann sich dieser oder jener User etwas von der Methodik für seine Zwecke adaptieren und verwenden.
Der größte Unterschied zu "malloc" ist natürlich, daß der aktuell nicht genutzte Bereich NICHT ohne Weiteres für andere Zwecke genutzt werden kann, wie es ja beim original "malloc" der Fall ist. Aber letzterer handelt sich auch eine Menge Probleme damit ein.



Autor

Siehe auch