Forum: Mikrocontroller und Digitale Elektronik [AVR] ATmega16 startet neu bei EEPROM-Zugriff auf 0x1F0?


von Tobias Hagemeier (Gast)


Lesenswert?

Hi!
Ich habe einen ATMega16 der auf die 512 Byte internes EEPROM zugreifen 
soll. Zumindest das Schreiben funktioniert im Moment noch nicht (nicht 
sicher weshalb) aber das schlimmste ist das Problem mit dem Lesen.

Der 16er hat ja 512 Byte EEPROM - ich sollte also theoretisch bis zur 
Adresse 0x1FF hoch lesen können. Ein BASCOM-Programm was vorher auf dem 
Atmel lief (nicht von mir) konnte diese Speicherbereiche auch korrekt 
adressieren.

Mein C-Variante stürzt jedoch NUR bei Adresse 0x1F0 ab, in der Form, das 
der Mikrocontroller direkt neu startet.
Was stimmt da nicht? Habe ich in meinem Code ein "Problemchen" eingebaut 
oder liegt es am EEPROM?

Code (Includes usw raus gelöscht):
1
/*
2
#define EEPROM_READ      EECR |= (1 << EERE)
3
#define EEPROM_WRITE    EECR |= (1 << EEMWE); EECR |= (1 << EEWE)
4
#define EEPROM_SET_DATA(x)  EEDR = x
5
#define EEPROM_GET_DATA    EEDR
6
#define EEPROM_READY    (EECR & (1 << EEWE)) ? 0 : 1
7
#define EEPROM_ADDRESS(x)  EEAR = x
8
#define EEPROM_READ_READY  (EECR & (1 << EERE)) ? 0 : 1
9
*/
10
11
unsigned char ee_readByte(unsigned short address) {
12
  while (!EEPROM_READY) { }
13
  EEPROM_ADDRESS(address);
14
  EEPROM_READ;
15
  while (!EEPROM_READ_READY) { }
16
  return EEPROM_GET_DATA;
17
}
18
19
void ee_writeByte(unsigned short address, unsigned char byte) {
20
  while (!EEPROM_READY) { }
21
  EEPROM_ADDRESS(address);  
22
  EEPROM_SET_DATA(byte);
23
  EEPROM_WRITE;
24
}
== Code-Ende ==

von Tobias Hagemeier (Gast)


Lesenswert?

Ach so.. der WDT ist aus, der löst den Reset also nicht aus..

von Tobias Hagemeier (Gast)


Lesenswert?

Noch was neues zum aktuellen Fall:
Ich habe jetzt eine Testroutine aufgebaut, der ich per USART 
Speicherposition und Daten senden kann, die Routine schreibt die Daten 
an der gewünschten Stelle ins EEPROM und versucht sie danach wieder 
auszulesen.

Folgender Fehler tritt dabei auf: Der Absturz des Atmels wird durch das 
auslesen des EEPROMs verursacht und zwar NUR DANN, wenn im Byte welches 
im EEPROM abgelegt ist, das 0x08 Bit gesetzt ist.

Dazu fällt mir jetzt garnichts mehr ein..

Ich hoffe es kommen vielleicht noch Vorschläge.

von dummy (Gast)


Lesenswert?

>Ich hoffe es kommen vielleicht noch Vorschläge.

Sicher nicht wenn du deinen Code nicht rausrückst.

von Tobias Hagemeier (Gast)


Angehängte Dateien:

Lesenswert?

Was noch an Code?

Hier erstmal die main(), die den Testaufruf enthält. Die UART-Funktionen 
habe ich nicht dabei, die sind aber von vorne bis hinten getestet und es 
gab nie Probleme damit.

Kurze Erklärung dazu:

1
void init_uart(void);
Schnittstelle auf 9600,8,N,1 (Asynchron); Interrupts einrichten.

1
unsigned char rx_chars(void);
Abrufen wie viele Zeichen im Empfangspuffer sind (Ring-Puffer)

1
unsigned char uart_puts(unsigned char *s);
String (bis \0) in den Sendepuffer schreiben (Ring-Puffer)

1
unsigned char uart_getc(void);
Zeichen abrufen und aus dem Empfangspuffer löschen.

1
unsigned char uart_putc(unsigned char zeichen);
Zeichen in den Sendepuffer schreiben.


Gibt noch ein Paar mehr aber die benutze ich nicht..

von Tobias Hagemeier (Gast)


Lesenswert?

Oh, und das Wichtigste natürlich.. Die gesendeten Daten und die Antwort:

[pre]
Gesendet: 0x00 0x01 0x05
Antwort: "Writing & Reading: Adr0001=ABCDE05(" + 0x05 + ")"

Gesendet: 0x00 0x01 0xF7
Antwort: "Writing & Reading: Adr0001=ABCDEF7(" + 0xF7 + ")"

Gesendet: 0x00 0xFF 0x05
Antwort: "Writing & Reading: Adr00FF=ABCDE05(" + 0x05 + ")"

Gesendet: 0x00 0x01 0x08
Antwort: "Writing & Reading: Adr0001=ABFAULT"

Gesendet: 0x00 0x08 0x16
Antwort: "Writing & Reading: Adr0008=ABCDE16(" + 0x16 + ")"

Gesendet: 0x00 0x01 0xFF
Antwort: "Writing & Reading: Adr0001=ABFAULT"



Immer wenn das 0x08er-Bit gesetzt ist (bzw 3er bei 0-Zählweise) startet 
er nachdem er die Adresse gesetzt hat (danach kommt der "B"-Status) ab 
und sendet den "FAULT"-String der in der main() ganz am Anfang geschickt 
wird..

von Nico E. (masta79)


Lesenswert?

Hast du denn einmal mal einen anderen Mega probiert? Man kann ja nicht 
ausschliessen das deiner einfach kaputt ist. (Hab mir den Code jetzt 
nicht angeschaut)

von Tobias Hagemeier (Gast)


Lesenswert?

Nein, habe ich nicht. Ich bin leider in der dummen Lage das die Hardware 
nicht von mir ist. Ich hab das HEX-File allerdings an den Kollegen 
geschickt der die Platte entwickelt - der soll bei sich mal gucken ob da 
was ähnliches raus kommt. Kann sich nur noch um Stunden handeln ;)
Ich vermute auch das am EEPROM was hinüber ist; das Problem ist eben das 
es bis gestern noch einwandfrei lief (dann aber über BASCOM 
angesprochen)..

von Stefan E. (sternst)


Lesenswert?

@ Tobias Hagemeier:

Poste bitte mal den Asm-Output des Compilers für die Funktion 
ee_readByte.

von Tobias Hagemeier (Gast)


Lesenswert?

Hui.. die ist ziemlich aufgebläht. Vielleicht doch lieber inline-ASM 
benutzen ;)
1
00001530 <ee_writeByte>:
2
}
3
4
void ee_writeByte(unsigned short address, unsigned char byte) {
5
    1530:  cf 93         push  r28
6
    1532:  df 93         push  r29
7
    1534:  cd b7         in  r28, 0x3d  ; 61
8
    1536:  de b7         in  r29, 0x3e  ; 62
9
    1538:  24 97         sbiw  r28, 0x04  ; 4
10
    153a:  0f b6         in  r0, 0x3f  ; 63
11
    153c:  f8 94         cli
12
    153e:  de bf         out  0x3e, r29  ; 62
13
    1540:  0f be         out  0x3f, r0  ; 63
14
    1542:  cd bf         out  0x3d, r28  ; 61
15
    1544:  9a 83         std  Y+2, r25  ; 0x02
16
    1546:  89 83         std  Y+1, r24  ; 0x01
17
    1548:  6b 83         std  Y+3, r22  ; 0x03
18
  unsigned char cSREG;
19
  while (!EEPROM_READY) { }
20
    154a:  80 91 3c 00   lds  r24, 0x003C
21
    154e:  99 27         eor  r25, r25
22
    1550:  82 70         andi  r24, 0x02  ; 2
23
    1552:  90 70         andi  r25, 0x00  ; 0
24
    1554:  00 97         sbiw  r24, 0x00  ; 0
25
    1556:  09 f0         breq  .+2        ; 0x155a <ee_writeByte+0x2a>
26
    1558:  f8 cf         rjmp  .-16       ; 0x154a <ee_writeByte+0x1a>
27
  EEPROM_ADDRESS(address);  
28
    155a:  89 81         ldd  r24, Y+1  ; 0x01
29
    155c:  9a 81         ldd  r25, Y+2  ; 0x02
30
    155e:  90 93 3f 00   sts  0x003F, r25
31
    1562:  80 93 3e 00   sts  0x003E, r24
32
  EEPROM_SET_DATA(byte);
33
    1566:  8b 81         ldd  r24, Y+3  ; 0x03
34
    1568:  80 93 3d 00   sts  0x003D, r24
35
  cSREG = SREG;
36
    156c:  80 91 5f 00   lds  r24, 0x005F
37
    1570:  8c 83         std  Y+4, r24  ; 0x04
38
  cli();
39
    1572:  f8 94         cli
40
  EEPROM_WRITE;
41
    1574:  84 e0         ldi  r24, 0x04  ; 4
42
    1576:  80 93 3c 00   sts  0x003C, r24
43
    157a:  86 e0         ldi  r24, 0x06  ; 6
44
    157c:  80 93 3c 00   sts  0x003C, r24
45
  SREG = cSREG;
46
    1580:  8c 81         ldd  r24, Y+4  ; 0x04
47
    1582:  80 93 5f 00   sts  0x005F, r24
48
    1586:  24 96         adiw  r28, 0x04  ; 4
49
    1588:  0f b6         in  r0, 0x3f  ; 63
50
    158a:  f8 94         cli
51
    158c:  de bf         out  0x3e, r29  ; 62
52
    158e:  0f be         out  0x3f, r0  ; 63
53
    1590:  cd bf         out  0x3d, r28  ; 61
54
    1592:  df 91         pop  r29
55
    1594:  cf 91         pop  r28
56
    1596:  08 95         ret
57
58
00001598 <ee_writeByteEx>:
59
}

von Tobias Hagemeier (Gast)


Lesenswert?

... Sorry, heute ist einfach nicht mein Tag.
Bitte sehr:
1
000014ca <ee_readByte>:
2
#include "main.h"
3
4
unsigned char ee_readByte(unsigned short address) {
5
    14ca:  cf 93         push  r28
6
    14cc:  df 93         push  r29
7
    14ce:  cd b7         in  r28, 0x3d  ; 61
8
    14d0:  de b7         in  r29, 0x3e  ; 62
9
    14d2:  23 97         sbiw  r28, 0x03  ; 3
10
    14d4:  0f b6         in  r0, 0x3f  ; 63
11
    14d6:  f8 94         cli
12
    14d8:  de bf         out  0x3e, r29  ; 62
13
    14da:  0f be         out  0x3f, r0  ; 63
14
    14dc:  cd bf         out  0x3d, r28  ; 61
15
    14de:  9a 83         std  Y+2, r25  ; 0x02
16
    14e0:  89 83         std  Y+1, r24  ; 0x01
17
  unsigned char tmp;
18
  while (!EEPROM_READY) { }
19
    14e2:  80 91 3c 00   lds  r24, 0x003C
20
    14e6:  99 27         eor  r25, r25
21
    14e8:  82 70         andi  r24, 0x02  ; 2
22
    14ea:  90 70         andi  r25, 0x00  ; 0
23
    14ec:  00 97         sbiw  r24, 0x00  ; 0
24
    14ee:  09 f0         breq  .+2        ; 0x14f2 <ee_readByte+0x28>
25
    14f0:  f8 cf         rjmp  .-16       ; 0x14e2 <ee_readByte+0x18>
26
//  uart_putc('A'); wait(500);
27
  EEPROM_ADDRESS(address);
28
    14f2:  89 81         ldd  r24, Y+1  ; 0x01
29
    14f4:  9a 81         ldd  r25, Y+2  ; 0x02
30
    14f6:  90 93 3f 00   sts  0x003F, r25
31
    14fa:  80 93 3e 00   sts  0x003E, r24
32
//  uart_putc('B'); wait(500);
33
  EEPROM_READ;
34
    14fe:  81 e0         ldi  r24, 0x01  ; 1
35
    1500:  80 93 3c 00   sts  0x003C, r24
36
//  uart_putc('C'); wait(500);
37
  while (!EEPROM_READ_READY) { }
38
    1504:  80 91 3c 00   lds  r24, 0x003C
39
    1508:  99 27         eor  r25, r25
40
    150a:  81 70         andi  r24, 0x01  ; 1
41
    150c:  90 70         andi  r25, 0x00  ; 0
42
    150e:  00 97         sbiw  r24, 0x00  ; 0
43
    1510:  09 f0         breq  .+2        ; 0x1514 <ee_readByte+0x4a>
44
    1512:  f8 cf         rjmp  .-16       ; 0x1504 <ee_readByte+0x3a>
45
//  uart_putc('D'); wait(500);
46
  tmp = EEPROM_GET_DATA;
47
    1514:  80 91 3d 00   lds  r24, 0x003D
48
    1518:  8b 83         std  Y+3, r24  ; 0x03
49
//  uart_putc('E'); wait(500);
50
  return tmp;
51
    151a:  8b 81         ldd  r24, Y+3  ; 0x03
52
    151c:  99 27         eor  r25, r25
53
    151e:  23 96         adiw  r28, 0x03  ; 3
54
    1520:  0f b6         in  r0, 0x3f  ; 63
55
    1522:  f8 94         cli
56
    1524:  de bf         out  0x3e, r29  ; 62
57
    1526:  0f be         out  0x3f, r0  ; 63
58
    1528:  cd bf         out  0x3d, r28  ; 61
59
    152a:  df 91         pop  r29
60
    152c:  cf 91         pop  r28
61
    152e:  08 95         ret
62
63
00001530 <ee_writeByte>:
64
}

von Stefan E. (sternst)


Lesenswert?

Das Problem ist hier:
>    1500:  80 93 3c 00   sts  0x003C, r24

Der ATmega16 (und noch diverse andere) hat einen Hardware-Bug, der einen 
EEPROM-Interrupt auslösen kann, wenn das EECR-Register per STS 
beschrieben wird.
Schalte die Optimierungen ein. Das sollte nicht nur den Code deutlich 
kürzer machen, sondern auch das Problem beheben.

von Jochen M. (taschenbuch)


Lesenswert?

Nur mal so auf den ersten Blick:

Es werden Register versaut, die nicht gerettet wurden.
Der Global-Interupt wird mehrfach abgeschaltet (CLI), aber nicht mehr 
eingeschaltet (kein SEI). Oder hat das im Gesamtkontext seinen Sinn?

Jochen Müller

von Stefan E. (sternst)


Lesenswert?

Jochen Müller wrote:

> Es werden Register versaut, die nicht gerettet wurden.

Und? Das sind die "call-clobbered" Register.

> Der Global-Interupt wird mehrfach abgeschaltet (CLI), aber nicht mehr
> eingeschaltet (kein SEI).

Enabled werden die Interrupts dann wieder durch das Zurückschreiben des 
gesicherten SREGs, sofern sie auch vorher enabled waren. So schützt man 
einen Bereich vor Interrupts, wenn nicht feststeht, ob die Interrupts zu 
diesem Zeitpunkt enabled sind, oder nicht.

von Jochen M. (taschenbuch)


Lesenswert?

>>Und? Das sind die "call-clobbered" Register.
>>...

Ok, registriert. Ich programmiere auf Controllern nicht in C, kenne 
daher das  ganze Trara des Compilers nicht.
Wenn ich allerdings sehe, was für einen gigantischen Zirkus der Compiler 
für das simple Lesen eines Bytes aus dem EEprom veranstaltet, dann weiss 
ich echt nicht ob ich lachen oder weinen soll. Das ist doch wohl ein 
Witz, oder?
Sowas benötigt in ASM eine Hand voll Befehle und 2-3 Lichtjahre weniger 
Performance.

Interessehalber: Bringt da die o.g. Codeoptimierung einen wirklichen 
Durchbruch? Warum muss die erst zugeschaltet werden?

Jochen Müller

von Stefan E. (sternst)


Lesenswert?

Jochen Müller wrote:

> Interessehalber: Bringt da die o.g. Codeoptimierung einen wirklichen
> Durchbruch?

Ja. Mit Optimierung sieht der Code so aus:
1
unsigned char ee_readByte(unsigned short address) {
2
  5e:  e1 99         sbic  0x1c, 1  ; 28
3
  60:  fe cf         rjmp  .-4        ; 0x5e <ee_readByte>
4
  while (!EEPROM_READY) { }
5
  EEPROM_ADDRESS(address);
6
  62:  9f bb         out  0x1f, r25  ; 31
7
  64:  8e bb         out  0x1e, r24  ; 30
8
  EEPROM_READ;
9
  66:  e0 9a         sbi  0x1c, 0  ; 28
10
  while (!EEPROM_READ_READY) { }
11
  68:  e0 99         sbic  0x1c, 0  ; 28
12
  6a:  fe cf         rjmp  .-4        ; 0x68 <ee_readByte+0xa>
13
  return EEPROM_GET_DATA;
14
  6c:  8d b3         in  r24, 0x1d  ; 29
15
}
16
  6e:  08 95         ret
Das bekommst du auch in Assembler nicht kürzer hin.

> Warum muss die erst zugeschaltet werden?

Weil es unterschiedliche Level der Optimierung gibt und weil Optimierung 
nicht immer erwünscht ist.

von Tobias Hagemeier (Gast)


Lesenswert?

Zumindest war das das Problem :) Vorsichtshalber werde ich auch den 
EEPROM-Interrupt noch definieren und aber leer lassen. Falls da "nochmal 
jemand hinspringt" ;)

Danke für die Hilfe!

- Tobi

von Jochen M. (taschenbuch)


Lesenswert?

Ok, trotzdem das eigentliche Problem nun wohl gelöst ist,
möchte ich das doch noch mal kurz aufgreifen.

1) Die optimierte Fassung liegt wirklich sehr nahe an dem, was Assembler 
schaffen kann. Vielleicht 1-2 Opcodes könnte ich da noch sparen. Aber 
so, wie es ist, ist es ok.
Aber Ihr müsst zugeben, dass die un-optimierte Fassung ein 
himmelschreiendes Elend war, für das es überhaupt keinen Grund gibt. 
Auch eine abgeschaltete Optimierung kann SO EINEN SCHEISS-CODE nicht 
rechtfertigen.
Oder wird der unoptimierte Code absichtlich so dermassen krank 
generiert, damit irgendwelche Optimizer dann in besserem Licht stehen?

Oder anders gefragt:
WIESO muss der Compiler erst auf Optimierung geschaltet werden, damit er 
so einen Scheiss unterlässt. Es kann doch wohl erwartet werden, dass er 
das auch ohne Optimierung ETWAS BESSER hinbekommt.

2) Aus welchem Grund kann eine Optimierung NICHT erwünscht sein?

3) Und das ist mir am wichtigsten:
Habe ich das jetzt richtig verstanden, dass OHNE Codeoptimierung ein 
Code erzeugt wird, der nicht lauffähig ist. Mit Optimierung funktioniert 
der Code  bei sonst gleichen Umgebungsbedingungen dann?
Was für eine hinterhältige Falle ist DAS DENN BITTE?

Jochen Müller

von Stefan E. (sternst)


Lesenswert?

Jochen Müller wrote:

> 1) Die optimierte Fassung liegt wirklich sehr nahe an dem, was Assembler
> schaffen kann. Vielleicht 1-2 Opcodes könnte ich da noch sparen.

Nein, kannst du nicht. Jedenfalls nicht bei gleicher Funktionalität.

> 3) Und das ist mir am wichtigsten:
> Habe ich das jetzt richtig verstanden, dass OHNE Codeoptimierung ein
> Code erzeugt wird, der nicht lauffähig ist. Mit Optimierung funktioniert
> der Code  bei sonst gleichen Umgebungsbedingungen dann?
> Was für eine hinterhältige Falle ist DAS DENN BITTE?

Du lastest den Hardware-Bug dem Compiler an?

Du kannst übrigens aufhören herumzuschreien, ich habe längst kapiert, 
dass du keinen blassen Schimmer davon hast, wie Compiler arbeiten, und 
dass du eine vorgefasste Meinung dazu hast. Auch die Tatsache, dass du 
dich für einen ober-coolen Assemblerprogrammierer hältst, der für die 
C-Weicheier nur ein müdes Lächeln übrig hat, kommt sehr deutlich raus. 
Du musst das nicht näher ausführen.

von Nico E. (masta79)


Lesenswert?

Jochen Müller wrote:

> Aber Ihr müsst zugeben, dass die un-optimierte Fassung ein
> himmelschreiendes Elend war, für das es überhaupt keinen Grund gibt.
> Auch eine abgeschaltete Optimierung kann SO EINEN SCHEISS-CODE nicht
> rechtfertigen.
> Oder wird der unoptimierte Code absichtlich so dermassen krank
> generiert, damit irgendwelche Optimizer dann in besserem Licht stehen?

(Vorsicht, stark vereinfachte Erklärung)

Das ist einfach eine Folge dessen wie Compiler heutzutage arbeiten. Die 
C-Anweisung wird parsed und dann in einen Metacode übersetzt, der 
versucht das ganze auf den kleinsten gemeinsamen Nenner runterzubrechen. 
Der Optimizer fasst diesen Metacode dann zusammen und wirft Redundanzen 
raus, etc.

Der Vorteil des Metacodes ist einfach das man möglichst lange ohne 
Architekturspezifische Sachen arbeiten kann. Ausserdem hat die jeweilige 
Optimierungsstufe dann auch wirklich Freiraum in jede Richtung. 
Optimizer laufen normalerweise besser wenn sie Code vorgeworfen bekommen 
an dem sie sich austoben können.

Und die meisten Leute die mit gcc arbeiten wissen eigentlich das sie 
Optimierung aktivieren sollten. -Os ist im µC/embedded bereich ja sehr 
verbreitet, -O2 auf "normalen" Systemen. (Wobei -Os auf modernen kleinen 
CPU wie VIA C7 etc. auch oft mehr Sinn macht, da der Cache dort eher 
begrenzt ist)

von Jochen M. (taschenbuch)


Lesenswert?

>>Du kannst übrigens aufhören herumzuschreien, ich habe längst kapiert,
>>dass du keinen blassen Schimmer davon hast, wie Compiler arbeiten, und
>>dass du eine vorgefasste Meinung dazu hast. Auch die Tatsache, dass du
>>dich für einen ober-coolen Assemblerprogrammierer hältst, der für die
>>C-Weicheier nur ein müdes Lächeln übrig hat, kommt sehr deutlich raus.
>>Du musst das nicht näher ausführen.

Du schreibst Unsinn.
Ich habe konkret nach einigen Punkten gefragt, die absolut begründet 
sind.
Wenn das alles Quatsch ist, was ich schreibe, müsste das ja SEHR LEICHT 
zu widerlegen sein, also antworte einfach sachbezogen.

Übrigens kann ich Dir SEHR GENAU erklären wie Compiler arbeiten, danke.
GENAU DESHALB darf ich auch mal nachfragen, wenn es offensichtlich ist, 
das DIESER Compiler Mist baut oder überaus ineffizient ist.

Ich halte C-Leute auch nicht für Weicheier, das ist Quatsch.
Weicheier sind UNKRITISCHE DEPPEN wie Du, die auch angesichts konkreter 
Probleme oder begründeter Zweifel keine Rückfrage zulassen, weil sonst 
jemand vielleicht ihr faschistisch verehrtes Heiligtum vom Sockel 
stürzen könnten.

Bisher konntest Du keine einzige der o.g. begründeten Fragen 
beantworten.
Darüber solltest Du nachdenken, über nichts anderes.

Jochen Müller

von Falk B. (falk)


Lesenswert?

@ Jochen Müller (taschenbuch)

>Wenn das alles Quatsch ist, was ich schreibe, müsste das ja SEHR LEICHT
>zu widerlegen sein, also antworte einfach sachbezogen.

>Aber Ihr müsst zugeben, dass die un-optimierte Fassung ein
>himmelschreiendes Elend war, für das es überhaupt keinen Grund gibt.

Doch, aber das kann ich auch nciht wirklich erklären. Ohne Optimierung 
wird der Code "hirnlos-formal" übersetzt. Das ist gängige Praxis. 
Wahrscheinlich um Plausiilitätscheks etc. zu machen.

>so einen Scheiss unterlässt. Es kann doch wohl erwartet werden, dass er
>das auch ohne Optimierung ETWAS BESSER hinbekommt.

Nicht notwendigerweise. Kann ich aber nciht wirklich erklären.

>2) Aus welchem Grund kann eine Optimierung NICHT erwünscht sein?

Um  linearen Ablauf der Sourcecodes zu erreichen. Optimierung kann die 
Reihenfolge verdrehen, solange das Ergebnis gleich bleibt.

>Übrigens kann ich Dir SEHR GENAU erklären wie Compiler arbeiten, danke.

Naja . . .

>das DIESER Compiler Mist baut oder überaus ineffizient ist.

Du lehnst dich WEIT aus dem Fenster . . .

>Habe ich das jetzt richtig verstanden, dass OHNE Codeoptimierung ein
>Code erzeugt wird, der nicht lauffähig ist.

Ja.

> Mit Optimierung funktioniert
>der Code  bei sonst gleichen Umgebungsbedingungen dann?
>Was für eine hinterhältige Falle ist DAS DENN BITTE

Keine Falle, sondern ein Hardwarefehler EINES  EINZELNEN AVR-Typens.
Der Compiler ist OK.

MfG
Falk

von Torsten S. (tse)


Lesenswert?

Mal sachte ihr beide, vertragt euch wieder.

Diesen Hardware-Bug wg. Eeprom kannte ich bis heute nicht. Danke für die 
Info!

von Stefan E. (sternst)


Lesenswert?

Jochen Müller wrote:

> Wenn das alles Quatsch ist, was ich schreibe, müsste das ja SEHR LEICHT
> zu widerlegen sein, also antworte einfach sachbezogen.

Da du ganz offensichtlich eine vorgefasste Meinung hast, wäre jede 
detaillierte Ausführung einfach nur Zeitverschwendung.

Und wer Posts schreibt, in denen kaum ein Satz ohne GROßGESCHRIEBENE 
Worte ist, hat eh nur die Absicht rumzustänkern. Die Wortwahl 
unterstreicht das noch. Also wieder: jedes detaillierte Eingehen darauf 
wäre reine Zeitverschwendung.

> Übrigens kann ich Dir SEHR GENAU erklären wie Compiler arbeiten, danke.
> GENAU DESHALB darf ich auch mal nachfragen, wenn es offensichtlich ist,
> das DIESER Compiler Mist baut oder überaus ineffizient ist.

Genau, deshalb wusstest du auch so genau, was "call-clobbered" Register 
sind.

> Weicheier sind UNKRITISCHE DEPPEN wie Du, die auch angesichts konkreter
> Probleme oder begründeter Zweifel keine Rückfrage zulassen, weil sonst
> jemand vielleicht ihr faschistisch verehrtes Heiligtum vom Sockel
> stürzen könnten.

Es besteht ein himmelweiter Unterschied zwischen "begründeter Zweifel" 
und "Rückfrage" auf der einen Seite, und rausgeschrienen Geschimpfe à la 
"SCHEISS-CODE" auf der anderen.

> Bisher konntest Du keine einzige der o.g. begründeten Fragen
> beantworten.

Wie bereits geschrieben, an dir wären diese Antworten schlicht 
verschwendet.

von CCUser (Gast)


Lesenswert?

@Stefan Ernst (sternst)
Also, was ist los mit Dir, was soll der Unsinn?
Für mich waren das schon sehr begründete und berechtigte Fragen, die 
taschenbuch da stellte.
Wenn ein Code den ein Compiler auswirft Mist ist, muss man das auch so 
sagen dürfen. Alles andere ist willfähriges und unkritisches Gejubel.
Und der Code, den ich da oben sah, ist eben Scheisse, da gibt es nichts 
zu beschönigen. Warum willst Du den unbedingt so verherrlichen?

Und mit dem Begriff HEUTZUTAGE zu kommen ist, das wirklich lustig.
Damit rechtfertigt man dann jeden Mist. Dann sind eben HEUTZUTAGE die 
Compiler schlecht, mehr kann man daraus nicht schliessen.

Mir sind jedenfalls Leute, die Schwachstellen mal hinterfragen sehr viel 
lieber, als Jubelheinis, die alles schlucken aus ideologischen Gründen. 
So entsteht Rückschritt und kein Fortschritt, das solltest Du Jüngelchen 
Dir mal merken. Mir scheint eher, dass DU hier der Faschist und Ideologe 
bist.
Sachlich hast Du jedenfalls nichts beigetragen, das steht ausser 
Zweifel.

Übrigens hatte tb in seinem Posting doch den optimierten Code als gut 
und brauchbar anerkannt, das Lesen fällt Dir auch schwer?

Nichts für ungut, aber sowas unkritisches konnte ich nicht stehen 
lassen.

Udo

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jochen Müller wrote:
> Ok, trotzdem das eigentliche Problem nun wohl gelöst ist,
> möchte ich das doch noch mal kurz aufgreifen.
>
> 1) Die optimierte Fassung liegt wirklich sehr nahe an dem, was Assembler
> schaffen kann. Vielleicht 1-2 Opcodes könnte ich da noch sparen. Aber
> so, wie es ist, ist es ok.
> Aber Ihr müsst zugeben, dass die un-optimierte Fassung ein
> himmelschreiendes Elend war, für das es überhaupt keinen Grund gibt.
> Auch eine abgeschaltete Optimierung kann SO EINEN SCHEISS-CODE nicht
> rechtfertigen.
> Oder wird der unoptimierte Code absichtlich so dermassen krank
> generiert, damit irgendwelche Optimizer dann in besserem Licht stehen?
>
> Oder anders gefragt:
> WIESO muss der Compiler erst auf Optimierung geschaltet werden, damit er
> so einen Scheiss unterlässt. Es kann doch wohl erwartet werden, dass er
> das auch ohne Optimierung ETWAS BESSER hinbekommt.

Nein. Das eigentliche Problem ist nicht in avr-gcc, sondern in der 
avr-libc. In der 3er Version von avr-gcc (die mit einer anderen avr-libc 
Version zusammenarbeitete) gabs diesen Horror-Code noch nicht, aber die 
avr-libc-Leute haben sich für eine "bequeme" Implementierung der 
EE-Routinen über indirecte Calls entschieden. Und wenn der Compiler 
nicht optimiert, wird das sau teuer.

Beitrag "Re: avr-gcc: 3.4.6 contra 4.3.0"

Ausserdem ist der EERE-Fehler bekannt und in den Errata der betroffenen 
AVR ganz klar beschrieben. Gleichwohl wird der Fehler von der Toolchain 
nicht umschifft (in anderen Toolchains ist es üblich, auch die 
Errata-Sheets eines µC zu lesen und Silicon-Bus, falls möglich, in 
Compiler, Assembler oder Libs zu umschiffen).

> 2) Aus welchem Grund kann eine Optimierung NICHT erwünscht sein?

Optimierung erschwert Debugging. Bei manchen Compilern schliesst sich 
Debugging und Optimierung sogar aus. Bei gcc jedoch nicht, aber die 
Debug-Info wird zunehmend übel, zB ist eine asm-Instruktion nicht mehr 
unbedingt einer bestimmten Quellezeile zuzuordnen oder eine Quellzeile 
kann mehrfach in asm umgesetzt sein.

> 3) Und das ist mir am wichtigsten:
> Habe ich das jetzt richtig verstanden, dass OHNE Codeoptimierung ein
> Code erzeugt wird, der nicht lauffähig ist. Mit Optimierung funktioniert
> der Code  bei sonst gleichen Umgebungsbedingungen dann?
> Was für eine hinterhältige Falle ist DAS DENN BITTE?

Wie gesagt, ein nicht beachtetes, gleichwohl bekanntes, klar in den 
Sheets beschriebens Erratum, das in der avr-libc nicht umschifft wird. 
Also, ein Bugreport schreiben. Ein Workaround kann ohne vertretbaren 
Aufwand nicht in avr-gcc geschehen. In der avr-libc wäre ein Workaround 
möglich, und mit der EE-Implementierung wie in der 3er Toolchain wäre 
dieser Silicon-Bug nie zum Tragen gekommen.

Immerhin hast Du noch Glück, wenn man sich die Odyssee anderer 
AVR-Benutzer anschaut... Originalton

Beitrag "Riesige Änderungen zwischen WinAVR 030913 und der aktuellen Version?"

> Auf EECR darf nicht mittels ST oder STS zugegriffen werden,
> (wahrscheinlich auch nicht über STD), sondern es muss via IN/OUT
> zugegriffen werden.

> Mit dem leeren EE_READY sollte das Problem erst mal aus der Welt sein,
> bis der nächste drüber stolpert und sich den Wolf sucht...


Johann

von BeidesNutzer (Gast)


Lesenswert?

Also ich nutze beides, C-Compiler und auch Assembler. Je nach Anwendung.
Das ist ja nun wie bei Religionen, da scheiden sich die Geister.
Aber Stefan E. überzieht da absolut. Auf eine berechtigte Frage reagiert 
man nicht mit dem Vorwurf das der Frager sich für besser hält, das kann 
ich aus dessen Text auch nicht absolut herauslesen. Sowas ist pubertär 
und kindisch.

Aber nachzuhaken, wenn ein (unberechtigt) göttlich verehrtes Produkt mal 
hakt, wie der Compiler in obigem Fall, das muss erlaubt sein. Stefan 
scheint eine falsche Ideologie über das Ergebnis zu stellen und das ist 
m.E. verwerflich.

Also -im Sinne der Religion ASM und C-
Friede sei mit Euch.

Grüsse von Frank

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Stefan Ernst wrote:
>
> Du lastest den Hardware-Bug dem Compiler an?
>

Ich sag mal so: Es gibt Controller (etwa der, der unter der Haube nicht 
weniger PKWs in diesem Lande sitzt (BMW, VW, Daimler, ...) die Du ohne 
Berücksichtigung der Silicon-Bugs im Compiler/Toolchain direkt in die 
Tonne treten kannst. Übrigens nicht der Controller für's CD-Laufwerk.

Die Errata-Sheets dieses µC sind nicht wie bei AVR auf einer 
DIN-A4-Seiten abgehandelt, sondern haben einen Umfang von weit mehr als 
1/3 des Handbuchs!

...soviel zu dem Thema...

von Stefan E. (sternst)


Lesenswert?

CCUser wrote:

> Sachlich hast Du jedenfalls nichts beigetragen, das steht ausser
> Zweifel.

Richtig, ich habe ja nur dem OP geholfen, sein Problem zu beseitigen, so 
was Nebensächliches aber auch. :-D

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.