Hallo, hat jemand von euch Erfahrung mit dem sdcc und STM8. Hintergrund meiner Frage ist, dass ich hier gerade ein ganz kleines Beispielprogramm habe und der Compiler mir hier offensichtlich falschen Code erzeugt. Wenn das jetzt die einzige Stelle ist, dann würde ich den Bug evtl. versuchen zu patchen. Auf der Suche nach dem Bug in der Bug-Datenbank, bin ich dann wieder über einen Bugreport gestolpert, bei dem jemand versucht hat, den von mir gefundenen Bug zu umschiffen und ist dabei wieder auf einen Bug gestoßen. Kann man den sdcc benutzen oder guckt man da ständig nur noch ins assembler listing? mfg Torsten
Also sdcc kenn ich jetzt persöhnlich nicht, aber normalerweise ist ein compilerbug die letzte Möglichkeit für den fehler... Sind alle anderen Komponenten (source, header-files, usw) sicher 100% fehlerfrei ? Was genau ist der bug ? Ich wette der compiler ist unschuldig.
Das ist der Bug: https://sourceforge.net/p/sdcc/bugs/2290/ getriggered wird er durch z.b. folgenden C-Code
1 | if (clock() % 2000 <= 1000) |
2 | {
|
3 | PE_ODR &= 0x7f; |
4 | PC_ODR &= 0x7f; |
5 | }
|
6 | else
|
7 | {
|
8 | PE_ODR |= 0x80; |
9 | PC_ODR |= 0x80; |
10 | }
|
daraus wird folgender ASM Code:
1 | 189 ; /sensorlager.c: 48: if (clock() % 2000 <= 1000) |
2 | 00005E CDr00r00 [ 4] 190 call _clock |
3 | 000061 90 AE 07 D0 [ 2] 191 ldw y, #0x07d0 |
4 | 000065 65 [ 2] 192 divw x, y |
5 | 000066 90 A3 03 E8 [ 2] 193 cpw y, #0x03e8 |
6 | 00006A 22 0D [ 1] 194 jrugt 00102$ |
7 | 195 ; /sensorlager.c: 50: PE_ODR &= 0x7f; |
8 | 00006C 72 17 50 14 [ 1] 196 bres 0x5014, #7 |
9 | 197 ; /sensorlager.c: 51: PC_ODR &= 0x7f; |
10 | 000070 AE 50 0A [ 2] 198 ldw x, #0x500a |
11 | 000073 F6 [ 1] 199 ld a, (x) |
12 | 000074 A4 7F [ 1] 200 and a, #0x7f |
13 | 000076 F7 [ 1] 201 ld (x), a |
14 | 000077 20 E5 [ 2] 202 jra 00105$ |
15 | 000079 203 00102$: |
16 | 204 ; /sensorlager.c: 55: PE_ODR |= 0x80; |
17 | 000079 72 17 50 14 [ 1] 205 bset 0x5014, #7 |
18 | 206 ; /sensorlager.c: 56: PC_ODR |= 0x80; |
19 | 00007D AE 50 0A [ 2] 207 ldw x, #0x500a |
20 | 000080 F6 [ 1] 208 ld a, (x) |
21 | 000081 AA 80 [ 1] 209 or a, #0x80 |
22 | 000083 F7 [ 1] 210 ld (x), a |
23 | 000084 20 D8 [ 2] 211 jra 00105$ |
24 | 000086 81 [ 4] 212 ret |
Sobald man 2 Bit-Manipulationen hat, generiert der Compiler für die erste eine BRES oder BSET instruction (bei nur einer Manipulation nimmt er den längeren code). Laut "Programming Manual" müsst die Bitposition mit 2*pos codiert sein (und +1, wenn das bit reseted werden soll). Beide Bit-Operationen resultieren hier aber im gleichen opcode (72 17 50 14). Das kann ja wohl nicht richtig sein ;-) mfg Torsten
hast du wie in dem bugreport geraten eine neue version installiert ? Wurde ja anscheinend erst ende '14 gefixed.
Ich habe das aktuellste release installiert, da ist der Bug noch/wieder vorhanden. Ich habe den compiler jetzt aus den aktuellen sourcen gebaut und da funktioniert es. Aber mir geht es geht es jetzt weniger um diesen einen, konkreten Bug, sonder eher darum, ob der Compiler zu gebrauchen ist. mfg Torsten p.S. hier das gleiche Listing mit heilem compiler:
1 | 161 ; /sensorlager.c: 48: if (clock() % 2000 <= 1000) |
2 | 000044 CDr00r00 [ 4] 162 call _clock |
3 | 000047 90 AE 07 D0 [ 2] 163 ldw y, #0x07d0 |
4 | 00004B 65 [ 2] 164 divw x, y |
5 | 00004C 90 A3 03 E8 [ 2] 165 cpw y, #0x03e8 |
6 | 000050 22 0D [ 1] 166 jrugt 00102$ |
7 | 167 ; /sensorlager.c: 50: PE_ODR &= 0x7f; |
8 | 000052 72 1F 50 14 [ 1] 168 bres 0x5014, #7 |
9 | 169 ; /sensorlager.c: 51: PC_ODR &= 0x7f; |
10 | 000056 AE 50 0A [ 2] 170 ldw x, #0x500a |
11 | 000059 F6 [ 1] 171 ld a, (x) |
12 | 00005A A4 7F [ 1] 172 and a, #0x7f |
13 | 00005C F7 [ 1] 173 ld (x), a |
14 | 00005D 20 E5 [ 2] 174 jra 00105$ |
15 | 00005F 175 00102$: |
16 | 176 ; /sensorlager.c: 55: PE_ODR |= 0x80; |
17 | 00005F 72 1E 50 14 [ 1] 177 bset 0x5014, #7 |
18 | 178 ; /sensorlager.c: 56: PC_ODR |= 0x80; |
19 | 000063 AE 50 0A [ 2] 179 ldw x, #0x500a |
20 | 000066 F6 [ 1] 180 ld a, (x) |
21 | 000067 AA 80 [ 1] 181 or a, #0x80 |
22 | 000069 F7 [ 1] 182 ld (x), a |
23 | 00006A 20 D8 [ 2] 183 jra 00105$ |
24 | 00006C 81 [ 4] 184 ret |
sdcc mag zwar nicht das Niveau von gcc oder llvm erreichen, aber unter den Compilern für 8-Bit-Architekturen würde ich ihn auf jeden Fall zu den besseren zählen. sdcc hat umfagreiche regression tests, die auch einen Großteil der Tests von gcc umfassen. Er ist Referenzcompiler für das Betriebssystem FUZIX, und ist für manche Mikrocontroller der vom Hersteller empfohlene Compiler. Das STM8-Backend war zum ersten Mal in sdcc 3.4.0 enthalten, und hatte demnach zu jenem Zeitpunkt nur wenige Nutzer, und damit auch mehr noch ungefundene Bugs. Inzwischen gibt es release candidate 1 von sdcc 3.5.0. Gegenüber 3.4.0 gibt es in 3.5.0 unter anderen zahlreiche Bugfixes und Verbesserungen im STM8-Backend. Philipp 3.5.0 rc1: https://sourceforge.net/projects/sdcc/files/
Hallo Philipp, Philipp Krause schrieb: > Das STM8-Backend war zum ersten Mal in sdcc 3.4.0 enthalten, und hatte > demnach zu jenem Zeitpunkt nur wenige Nutzer, und damit auch mehr noch > ungefundene Bugs. Na, nun hat der sdcc noch einen Nutzer mehr :-) Ich finde es ja immer total toll, wenn Leute in Ihrer Freizeit professionelle Software entwickeln und andere dann an dem Ergebnis Teil haben lassen. Für uns war es auf jeden Fall toll, das wir einen Compiler für das Target gefunden haben, der unter Unix läuft. Ich konnte mir gar nicht vorstellen, dass das ein Problem werden könnte. mfg Torsten
Interessant finde ich, dass die im Schema gleichen Statements
PE_ODR &= 0x7f;
PC_ODR &= 0x7f;
zu völlig unterschiedlichem Code führen.
A. K. schrieb: > Interessant finde ich, dass die im Schema gleichen Statements > PE_ODR &= 0x7f; > PC_ODR &= 0x7f; > zu völlig unterschiedlichem Code führen. Möglicherweise sind die gar nicht so gleich. Es war schießlich kin kompilierbares Beispiel, wir wissen nicht, welche Präprozessormakros da gelten, und wie die Variablen deklariert sind. Ich habe gerade versucht, ein kleines kompilierbares Odebsispiel dauas zu machen: #include <stdint.h> #define PC_ODR (*(volatile uint8_t *)0x500a) #define PE_ODR (*(volatile uint8_t *)0x5014) unsigned int clock(void); void f(void) { if (clock() % 2000 <= 1000) { PE_ODR &= 0x7f; PC_ODR &= 0x7f; } else { PE_ODR |= 0x80; PC_ODR |= 0x80; } } und erhalte für f (Kommentare entfernt): _f: call _clock ldw y, #0x07d0 divw x, y cpw y, #0x03e8 jrugt 00102$ bres 0x5014, #7 bres 0x500a, #7 jra 00104$ 00102$: bset 0x5014, #7 bset 0x500a, #7 00104$: ret
Was nutzt Ihr als IDE für den SDCC ? Mir ist die nahtlose Einbindung der Debuggers wichtig. Geht das mit freien Tools (Link / Beschreibung erbeten).
Michael Knoelke schrieb: > Was nutzt Ihr als IDE für den SDCC ? > Mir ist die nahtlose Einbindung der Debuggers wichtig. Ich habe noch keine Möglichkeit gefunden, überhaupt unter OS/X einen STM8 zu debuggen. LED / UART war mein Freund. Ansonsten mag ich Sublime als Editor ganz gerne für kleiner Projekte.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.