Forum: Mikrocontroller und Digitale Elektronik Code von Bascom nach C


von Mathias D. (darkfirefighter)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich sitze mittlerweile seit einem Tag an einer Übersetzung von Bascom 
nach C und bekomme es einfach nicht ans laufen.
Das Programm ist für einen Empfänger, der mit einem RFM12 arbeitet. Es 
soll die Zahl 88 erkennen, dann einen Pin auf High ziehen und wenn eine 
12 hinterher kommt einen anderen Pin ebenfalls auf High. Mit der 
Bascomversion funktioniert das auch einwandfrei nur wenn ich das mit 
meiner C Übersetzung laufen lasse geht es nicht mehr.
Ich hoffe einer von euch findet woran es hängt. Wäre sehr froh wenn es 
zum laufen gebracht werden kann, da ich das Projekt eigentlich in C 
schreiben wollte und nicht Bascom.
Der verwendete µC ist ein Mega168 und die IDE für C das AVR Studio.
Hoffe ihr könnt mir helfen

Gruß
Mathias

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>       If Data_in(n + 1) = 12 Then

Hier ist ein Bug: Buffer Overflow.

von Mathias D. (darkfirefighter)


Lesenswert?

Tatsächlich Danke. Aber das erklärt leider noch nicht warum die C 
Variante nicht geht, in Bascom geht es ja (der Bug trat vermutlich 
deshalb nicht auf weil die 88 am Anfang gesendet wird.

Gruß

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

> int main(void)
> ...
>  Freq_rfm12(868.300);
> ...
> void Freq_rfm12(double freq)

Hier sollte eine Warnung kommen.

Die C Source ist ja keine 1:1 Übernahme (Abweichung z.B. Freq_rfm12).
Funktioniert die 1:1 Übersetzung (s. Anhang)?

von Mathias D. (darkfirefighter)


Lesenswert?

Ich werd sie nachher ausprobieren bin nur grad in der Arbeit und habe so 
keine Möglichkeit zum testen.
Bin aber so gegen halb 4 daheim.
Danke schonmal

Gruß

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ein Problem in deiner C-Source ist die Indizierung der Arrays und die 
Anzahl der Schleifendurchläufe mbei Berechnungen mit diesen Arrays.

Du hast oft FOR N=1 TO 10 (BASCOM) nach for (N=0; N<=10; N++) umgesetzt: 
Das sind in C aber 11 Durchläufe!

In meiner 1:1 Übersetzung ist das Array um +1 vergrössert und das 
Element mit Index 0 wird nicht benutzt, dafür sind die Schleifen 1:1 von 
1 bis <=10 d.h. 10 Durchläufe.

von Paul Baumann (Gast)


Lesenswert?

OT:
Würdest Du, wenn das Programm in C dann fertig umgesetzt ist mal
posten, wieviel Speicherplatz die beiden Versionen jeweils benutzen?
Das wäre mal eine gute Chance, zu sehen, ob bei gleichem Algorithmus
deutlich andere Platzbedarfe entstehen.

(Ich will hier keinen Streit über die Vorteile dieser oder jener Sprache
 vom Zaun brechen; es interessiert mich eben nur mal)

MfG Paul

von Mathias D. (darkfirefighter)


Lesenswert?

@Paul: ja werde ich machen
@Stefan: Ja stimmt das habe ich nicht bedacht daran könnte es liegen. 
Wie gesagt werde es so bald wie möglich testen.

Danke und Gruß

von Mathias D. (darkfirefighter)


Lesenswert?

Also erstmal vielen vielen Dank an Stefan! Der Code läuft und die Zahlen 
werden erkannt. Habe mich wohl doch mit den Arrays vertan.
Zur Frage der Code größe:

AVR Studio liefert mir, wenn ich Stefans Code kompiliere ohne vorher 
aufzuräumen:

Programm: 4090 bytes (25.0% Full)
(.text + .data + .bootloader)

Data: 36 bytes (3.5% Full)
(.data + .bss + .noinit)

Bascom sagt mir beim kompilieren nur 18% Flash used.
Meiner Rechnung nach mit 16Kbyte Flash sind 18% 2880 byte. Kann das 
sein? Damit wäre ja die Bascomversion deutlich kleiner als die mit C??

Gruß

von Hannes L. (hannes)


Lesenswert?

> Bascom sagt mir beim kompilieren nur 18% Flash used.
> Meiner Rechnung nach mit 16Kbyte Flash sind 18% 2880 byte. Kann das
> sein?

Bascom erzeugt eine Report-Datei (*.RPT), darin kannst Du das genau 
nachlesen.

...

von Mathias D. (darkfirefighter)


Lesenswert?

Ok da steht unter anderem folgendes:

Compiler     : BASCOM-AVR LIBRARY V 1.11.9.8,  DEMO Edition
Processor    : M168
SRAM         : 400 hex
EEPROM       : 200 hex
ROMSIZE      : 4000 hex

ROMIMAGE     : B98 hex  -> Will fit into ROM
ROMIMAGE     :  2968 dec
FLASH USED   :  18  %
BAUD         : 9600 Baud
XTAL         : 20000000 Hz
BAUD error   : 0.16%

Stack start  : 4FF hex
Stack size   : 80 hex
S-Stacksize  : 80 hex
S-Stackstart : 480 hex
Framesize    : 80 hex
Framestart   : 3FF hex
Space left   :  614  dec

Ist der Code dann quasi 2968 byte groß? Wäre immer noch kleiner als die 
C Variante

von Hannes L. (hannes)


Lesenswert?

Auch in C kann man uneffizienten Code schreiben. Und nein, ich habe mir 
den Code nicht angesehen, beide nicht. Ich bevorzuge die direkte Art. 
;-)

...

von Karl H. (kbuchegg)


Lesenswert?

Hst du dem C Compiler das Optimieren erlaubt?

von Mathias D. (darkfirefighter)


Lesenswert?

Hannes Lux schrieb:
> Auch in C kann man uneffizienten Code schreiben. Und nein, ich habe mir
> den Code nicht angesehen, beide nicht. Ich bevorzuge die direkte Art.
> ;-)

:D ja da stimme ich dir zu. Ich habe auch nie behauptet, dass der Bascom 
Code effizient ist. Und der C Code ist ja nur ne 1:1 Übersetzung. Da ich 
aber keine zeitkritische Anwendung hab ist es mir um ehrlich zu sein 
wurscht ^^ ich werde noch ein bisschen aufräumen und Funktionen 
auslagern aber das soll mehr die Lesbarkeit erhöhen ;)

von Mathias D. (darkfirefighter)


Lesenswert?

Karl heinz Buchegger schrieb:
> Hst du dem C Compiler das Optimieren erlaubt?

Bei den Optionen steht bei Optimization -Os was immer das auch heißen 
mag?

von Karl H. (kbuchegg)


Lesenswert?

> D = Freq / 0.0050;

Mit dieser einen Berechnung ziehst du dir wahrscheinlich Unmengen von 
Code rein.

Ersetzt das durch

  D = Freq * 200;

(rechnet sich auch schneller)

von Karl H. (kbuchegg)


Lesenswert?

Mathias Dubdidu schrieb:
> Karl heinz Buchegger schrieb:
>> Hst du dem C Compiler das Optimieren erlaubt?
>
> Bei den Optionen steht bei Optimization -Os was immer das auch heißen
> mag?

-Os  ist ok.
Das ist ein oftmals vernünftiger Kompromiss in der Optimierung

von Peter D. (peda)


Lesenswert?

Mathias Dubdidu schrieb:
> Programm: 4090 bytes (25.0% Full)
> (.text + .data + .bootloader)

Ja, die default Compiler Optimierung ist nicht so dolle.
Man muß ihm etwas auf die Sprünge helfen.
Nimm mal diese Optionen:
1
-Os
2
-std=gnu99
3
-lm
4
-fno-inline-small-functions
5
-fno-move-loop-invariants
6
-Wl,--relax
7
--combine
8
-fwhole-program

Dann komme ich auf 1186 Byte.

Es waren aber noch 3 Fehlermeldungen in dem Programm von Stefan.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
>> D = Freq / 0.0050;
>
> Mit dieser einen Berechnung ziehst du dir wahrscheinlich Unmengen von
> Code rein.
>
> Ersetzt das durch
>
>   D = Freq * 200;
>
> (rechnet sich auch schneller)

Vergiss das.
Freq ist ja auch ein float.

Allerdings erhebt sich die Frage: Warum ist das ein float?
Beim schnellen drüberschauen, hab ich nichts gesehen, was float hier 
rechtfertigen würde.

von Karl H. (kbuchegg)


Lesenswert?

Tausche ich den float gegen einen uint16_t und passe die Berechnungen, 
die mit Freq gemacht werden auf 1 Nachkommastelle fixed Point an, dann 
lande ich mit -Os bei 1490 Bytes

von Peter D. (peda)


Lesenswert?

Karl heinz Buchegger schrieb:
> Allerdings erhebt sich die Frage: Warum ist das ein float?
> Beim schnellen drüberschauen, hab ich nichts gesehen, was float hier
> rechtfertigen würde.

Stimmt und ich habe ich schon gewundert, warum im Assemblerlisting die 
float Lib fehlt.

Die Rand-Lib braucht den meisten Code.


Peter

von Paul Baumann (Gast)


Lesenswert?

@Mathias Dubdidu
Danke für das Mitteilen der entstandenen Codegrößen.

MfG Paul

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:
> Karl heinz Buchegger schrieb:
>> Allerdings erhebt sich die Frage: Warum ist das ein float?
>> Beim schnellen drüberschauen, hab ich nichts gesehen, was float hier
>> rechtfertigen würde.
>
> Stimmt und ich habe ich schon gewundert, warum im Assemblerlisting die
> float Lib fehlt.

Die hat anscheinend deine

-fwhole-program

Option erkannt und eliminiert. Hätt ich dem gcc gar nicht zugetraut.
Nehme ich die Option im Originacode raus, schnalzt der Flash Verbrauch 
wieder in die Höhe.

von Oliver (Gast)


Lesenswert?

2466 Byte kommen nur ohne Optimierung zustande, mit sind es nur 1490. 
Die Größe ohne Optimierung liegt an den delay-Funktionen, die ohne 
Optimierung jede Menge flaoting point library Funktionen hinzulinken 
lassen. Kommentiert man die drei delay-Aufrufe aus, sind es auch ohne 
Optimierung nur noch 1790 Byte.

Oliver

von Oliver (Gast)


Lesenswert?

>2466 Byte kommen nur ohne Optimierung zustande, mit sind es nur 1490.
...
>sind es auch ohne
>Optimierung nur noch 1790 Byte.

Umpf, oder so ähnlich. Alle Zahlen sind falch.

2344 mit Optimierung
4066 ohne Optimierung
2834 ohne Optimierung, ohne delay

WinAVR 2009313

Oliver

von Peter D. (peda)


Lesenswert?

Quelltext von Stefan:
Beitrag "Re: Code von Bascom nach C"

+ oben genannte Optionen
+ im Quelltext:
1
int __attribute__((OS_main)) main(void);

ergibt:
1
WinAVR 20090313
2
GCC 4.3.2
3
AVR Memory Usage
4
----------------
5
Device: atmega168
6
7
Program:    1152 bytes (7.0% Full)
8
(.text + .data + .bootloader)
9
10
Data:         28 bytes (2.7% Full)
11
(.data + .bss + .noinit)


Peter

von Mathias D. (darkfirefighter)


Lesenswert?

Peter Dannegger schrieb:

>
1
> int __attribute__((OS_main)) main(void);
2
>
>

Und was bewirkt dann diese Option?

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.