Definieren von Variablen mit Wert für {$IF} ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Definieren von Variablen mit Wert für {$IF} ?

Beitrag von fliegermichl »

Hallo,

für ein AVR Projekt benötige ich abhängig von der CPU Frequenz unterschiedlichen Programmcode.
wenn ich -dF_CPU=16000000 bei Benutzerdefinierte Einstellungen schreibe, bekomme ich die Fehlermeldung "malformed Parameter"

Wie muß das definiert werden, daß ich Auswertungen in der Art

Code: Alles auswählen

{$IF (F_CPU >= 14000000) and (F_CPU <= 18000000)}
 ...
{$ELSE}
{$error unsupported CPU frequency}
{$ENDIF}
definieren kann?

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von sstvmaster »

Bei mir funktioniert folgendes:

Code: Alles auswählen

program project1;

begin
  {$IF (F_CPU >= 14000000) and (F_CPU <= 18000000)} 
     WriteLn('Supported');
  {$ELSE}
     WriteLn('Unsupported');
  {$ENDIF}

  ReadLn;
end.
Aufruf erfolgt mit:

Code: Alles auswählen

fpc test.pas -dF_CPU:=19000000
Du musst den Doppelpunkt mit schreiben.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von fliegermichl »

Ah, Danke!

Kann ich mit dem Wert auch irgenwie rechnen?. Z.b. Wenn ich wissen möchte, wieviele Takte macht der Prozessor in x ms?
Wo ist das denn alles dokumentiert?

Mit Tante Goggle bin ich da nicht wirklich weitergekommen.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von theo »

fliegermichl hat geschrieben:
Sa 6. Feb 2021, 11:20
Wo ist das denn alles dokumentiert?
https://www.freepascal.org/docs-html/prog/progch2.html
S.a. Macros, Compile time expressions

https://wiki.freepascal.org/Conditional_compilation

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von fliegermichl »

theo hat geschrieben:
Sa 6. Feb 2021, 11:47
fliegermichl hat geschrieben:
Sa 6. Feb 2021, 11:20
Wo ist das denn alles dokumentiert?
https://www.freepascal.org/docs-html/prog/progch2.html
S.a. Macros, Compile time expressions

https://wiki.freepascal.org/Conditional_compilation
Danke theo für die Links. Zum rechnen konnte ich da aber nicht viel finden.
Kann man denn den Wert, der mittels -dF_CPU:=16000000 definiert wurde, irgendwie an eine normale Pascalkonstante bzw. Variable übertragen?

Code: Alles auswählen

{$ifndef F_CPU}
 {$error you must define an CPU frequency} // Das klappt. Wenn F_CPU nicht definiert wurde, kommt hier die Fehlermeldung
{$endif}
procedure wait(ms : dword);
var frequency : dword;
begin
 frequency := {$F_CPU}; // illegal expression. Irgendwie muss man doch an den übergebenen Wert rankommen?
 ...
end;

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von theo »

fliegermichl hat geschrieben:
Sa 6. Feb 2021, 12:46
Kann man denn den Wert, der mittels -dF_CPU:=16000000 definiert wurde, irgendwie an eine normale Pascalkonstante bzw. Variable übertragen?
Ist mir nicht bekannt. Vielleicht weiss ein Compiler Guru da mehr.

Aber kannst du das Problem nicht zur Laufzeit lösen, oder wenn du schon unterschiedliche Executables compilierst, wenigstens mit einer wechselnden Konstante im Code, statt mit defines?

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von sstvmaster »

Funktionieren tut das nur wenn der Define in Code selber gemacht wird. Über Kompiler kommando nicht.
Wie theo schon sagt, warten bis einer der Guru's hier auftaucht.

Code: Alles auswählen

program project1;

{$MACRO ON}
{$DEFINE F_CPU:=15000000}

procedure wait(ms : dword);
var
  frequency : dword;
begin
  frequency := ms;
  WriteLn('wait:  ', frequency);
end;

begin
  {$IF (F_CPU >= 14000000) and (F_CPU <= 18000000)}
    WriteLn('Supported');
  {$ELSE}
     WriteLn('Unsupported');
  {$ENDIF}

  WriteLn('F_CPU: ', F_CPU);
  wait(F_CPU);

  ReadLn;
end. 
Zuletzt geändert von sstvmaster am Sa 6. Feb 2021, 16:18, insgesamt 1-mal geändert.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von fliegermichl »

theo hat geschrieben:
Sa 6. Feb 2021, 14:08
Aber kannst du das Problem nicht zur Laufzeit lösen, oder wenn du schon unterschiedliche Executables compilierst, wenigstens mit einer wechselnden Konstante im Code, statt mit defines?
Eine wechselnde Konstante im Code wäre eine Möglichkeit. Zur Laufzeit geht leider nicht.

Für normale Anwendungen ist das nicht kritisch. Ich bin hier aber gerade dabei die Adafruit Neopixel mit Daten zu versorgen. Da gibt es für beliebig viele hintereinander geschaltete strips nur eine einzige Datenleitung.
Man muß dann für jedes Pixel 24 Bits mit Farbinformationen auf die Leitung setzen und zwar möglichst exakt 1,8 Mikrosekunden/Bit lang.

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von PascalDragon »

fliegermichl hat geschrieben:
Sa 6. Feb 2021, 12:46
Kann man denn den Wert, der mittels -dF_CPU:=16000000 definiert wurde, irgendwie an eine normale Pascalkonstante bzw. Variable übertragen?
Du musst die Makrounterstützung auf der Kommandozeile mittels -Sm einschalten (Achtung: dieser Parameter muss vor deiner Makrodeklaration kommen). Dann kannst du es einfach wie jedes im Code definierte Makro verwenden:

Code: Alles auswählen

program tmacro;

var
  freq: LongInt = F_CPU;
begin
  Writeln(freq);
end.
FPC Compiler Entwickler

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von sstvmaster »

Ahh, Danke PascalDragon!

Code: Alles auswählen

program test;
// compile with:
// fpc test.pas -Sm -dF_CPU:=15000000
var
  freq: LongInt = F_CPU;
begin
  {$IF (F_CPU >= 14000000) and (F_CPU <= 18000000)} 
     WriteLn('Supported');
  {$ELSE}
     WriteLn('Unsupported');
  {$ENDIF}
  WriteLn('F_CPU: ', F_CPU);
  WriteLn('CALC : ', freq + 15);
end. 
Ergibt:

Code: Alles auswählen

Supported
F_CPU: 15000000
CALC : 15000015
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von Timm Thaler »

Nur warum?

Eh ich das in den Compileraufruf schreibe, wo es dann übersehen wird schreibe ich das direkt ins Programm als Konstante.

Ich hab in meinen Programmen eine Unit, die nur Typ-, Variablen- und Konstantendeklarationen aufnimmt.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Definieren von Variablen mit Wert für {$IF} ?

Beitrag von fliegermichl »

Danke, so klappt das.
Wenn ich jetzt z.B. die Anzahl Takte für eine Millisekunde brauche, dann kann ich das jetzt so machen:

Code: Alles auswählen

program test;
{$IFNDEF F_CPU}
  {$error you must declare -Sm and -dF_CPU:=xxxx}
{$endif}
 const
  millis = F_CPU div 1000;
 begin
  writeln(millis);
 end.
 

Antworten