Wie Du an "var" bei der Übergabe siehst, wird nicht das Array übergeben, sondern die Referenz auf das Array (für C-Freaks: der Pointer). Das ist wichtig, sonst baut der Compiler einer Routine ein, die das Array an eine andere Speicherstelle kopiert, unnötigerweise.
Folgendes funktioniert auf dem
AVR mit
const und
var.
Code: Alles auswählen
type
TPara = record
start, stop: Int16;
end;
var
ar1: array[0..2] of TPara = ((start: 10; stop: 20), (start: 20; stop: 30), (start: 40; stop: 50));
ar2: array[0..0] of TPara = ((start: 111; stop: 222));
ar3: array[0..1] of TPara = ((start: 3333; stop: 4444), (start: 5555; stop: 6666));
procedure Test(const p: array of TPara);
var
i: Int16;
s: ShortString = '';
begin
for i := 0 to Length(p) - 1 do begin
str(p[i].start: 6, s);
UARTSendString(s);
str(p[i].stop: 6, s);
UARTSendString(s);
end;
end;
begin
Test(ar1);
Test(ar2);
Test(ar3);
Mache ich aber
kommt nur ein
"Internal error 2017091103".
Nehme ich in der Procedure auch auch eine statisch Array, dann gest es ohne var/const, so wie du es geschrieben hast.
Code: Alles auswählen
type
TPara = array[0..3] of Byte;
var
ar1: TPara = (1,2,3,4);
ar2: TPara = (5,6,7,8);
procedure Test(p: TPara);
var
i: Int16;
s: ShortString = '';
begin
for i := 0 to Length(p) - 1 do begin
str(p[i]: 6, s);
UARTSendString(s);
end;
end;
begin
Test(ar1);
Test(ar2);
Anscheinend ist in einem var/const Parameter der einzige Ort, wo
AVR mit dynamischen Arrays umgehen kann.
Wobei dynamisch ist sie ja nicht, da nur die Referenz übergeben wird.
Dies hatte ich zuerst auch nicht gewusst, deshalb hatte ich am Anfang eine Array via Pointer der Procedure übergebeben, dies hatte ich erst in deinem SPI-Tutorial gesehen.
Wen ich var/const weglasse, müsste innerhalb der Procedure eine dynamische Array erzogen werden, aber die geht nicht, da der
AVR kein Speicher dynamisch verwalten kann.
Stimmt diese Behauptung,
AVR kann mit allem nicht umgehen, was einen Heap braucht ?
Aber einen Stack kennt er ?
So arbeitet der Compiler mit dem originalen Array, in meinem Fall ein Buffer für den nRF-Sender / Empfänger. Dieses Array ist 32 Byte lang. Manchmal wird aber nur die Adresse von 5 Byte gesendet. Die Daten werden als dynamische Payload gesendet, die kann 2 bis 32 Byte haben.
Dies ist natürlich ein Argument.
Wie findest du diese Lösung ?
Dies wäre flexibler, da man x-beliebig Daten übergeben kann.
Wobei die dynamische Array auf dem
AVR nicht geht.
Code: Alles auswählen
procedure Ausgabe(p: PByte; len: integer);
var
i: integer;
begin
for i := 0 to len - 1 do begin
Write(p[i], ' ');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
s = '12345678';
a: array[0..3] of byte = (65, 66, 67, 68);
a2: array[0..1, 0..1] of Char = ((#97, #98), (#99, #100));
var
ad: array of byte;
i: integer;
begin
Ausgabe(@s[1], Length(s));
WriteLn();
Ausgabe(@a, SizeOf(a));
WriteLn();
Ausgabe(@a2, SizeOf(a2));
WriteLn();
SetLength(ad, 10);
for i := 0 to Length(ad) - 1 do begin
ad[i] := i;
end;
Ausgabe(Pointer(ad), Length(ad));
end;