Forum: Mikrocontroller und Digitale Elektronik AVR: Pointer in Register - wie definieren?


von Alexander Tetzlaff (Gast)


Lesenswert?

Ich möchte für einen RAM-Test in einer Routine einen Pointer aus dem RAM 
in ein (bzw. zwei) Register kopieren. In etwa so:
1
uint8_t* pointerImRam;
2
...
3
void Routine()
4
{
5
    uint8_t* register pointerImRegister = pointerImRam;
6
    ...
7
}

Allerdings mag der Compiler den Qualifier "register" an dieser Stelle 
nicht und sagt "expected unqualified-id before 'register'" und "expected 
initializer before 'register'".

Ich kann mir zwar behelfen, indem ich anstatt eines Pointer ein uint16_t 
verwende und später umcaste, aber gibt es denn keine Möglichkeit, einen 
lokalen Pointer in ein Register zu kopieren?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klingt irgendwie konfus.

Warum interessiert es dich, wo der Compiler die Zeiger anlegt?
In aller Regel wird er das ohnehin in Registern tun, er wär' ja
blöd, das nicht so zu machen.

Das Schlüsselwort „register“ war auch schon früher nur eine
Empfehlung.  Seit die Compiler selbst gelernt haben, die Verwendung
der Variablen zu optimieren, ist es völlig überflüssig geworden.

Nitpick: „register“ ist eine storage class, kein qualifier.
Daher muss es auch am Anfang der Deklaration/Definition stehen.
Aber wie geschrieben, das Schlüsselwort ist überflüssig.

: Bearbeitet durch Moderator
von Veit D. (devil-elec)


Lesenswert?

Hallo,

vielleicht hilft dir das weiter ...

Beitrag "Wie Stackermittlung ?"

von Alexander Tetzlaff (Gast)


Lesenswert?

Jörg W. schrieb:
> Klingt irgendwie konfus.
Es geht um einen RAM-Test. Dabei werden zyklisch alle Adressen im RAM 
nacheinander mit bestimmten Mustern beschrieben und diese Muster 
zurückgelesen.
Natürlich muß vorher der Inhalt der RAM-Adresse in ein CPU-Register 
gesichert und danach wieder hergestellt werden, und natürlich muss das 
ganz unter Interruptsperre erfolgen.
Die zu prüfende RAM-Adresse muss innerhalb des kritischen Abschnitts 
ebenfalls in einem (bzw. beim AVR in mehreren) CPU-Register(n) liegen, 
damit sie nicht während des Tests verfälscht wird.


>Nitpick: „register“ ist eine storage class, kein qualifier.
>Daher muss es auch am Anfang der Deklaration/Definition stehen.
Hmmm... wenn ich
1
register uint8_t* pointer;
definiere, wäre das dann nicht ein Zeiger auf ein "register uint8_t*"?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander Tetzlaff schrieb:
> Natürlich muß vorher der Inhalt der RAM-Adresse in ein CPU-Register
> gesichert und danach wieder hergestellt werden, und natürlich muss das
> ganz unter Interruptsperre erfolgen.

Wenn du ganz sicher gehen willst, dann schreib' das als inline asm.

Im von Veith verlinkten Thread findest du Beispiele.

Ansonsten einfach in C schreiben und danach verifizieren, dass der
Compiler in der Umsetzung wirklich nur Register benutzt.

> wäre das dann nicht ein Zeiger auf ein "register uint8_t*"?

Ja, wäre es nicht.

Aber wie schon geschrieben: „register“ ist (mit Ausnahme von
hartverdrahteten Registervariablen, einer GCC-eigenen Erweiterung)
überflüssig.  Der Compiler benutzt es einfach nur als alternatives
Schlüsselwort für „auto“.

> Es geht um einen RAM-Test.

Über Sinn und Unsinn solcher Maßnahmen lässt sich streiten.  Wer
sagt denn, wenn der RAM fehlerhaft ist, dass nicht auch Register
oder Rechenwerk gleichermaßen fehlerhaft sein könnten und daher
ein „pass“ für den RAM-Test ergeben, obwohl in Wirklichkeit doch
was kaputt ist?

von Alexander Tetzlaff (Gast)


Lesenswert?

Jörg W. schrieb:
>> wäre das dann nicht ein Zeiger auf ein "register uint8_t*"?
> Ja, wäre es nicht.
Okay, danke, das war mir nicht klar.
Bitte weiter nitpicken!

>Über Sinn und Unsinn solcher Maßnahmen lässt sich streiten.
Da hast Du recht, und streiten mag ich nicht.
(Die CPU muss in einem separaten Test geprüft werden.)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander Tetzlaff schrieb:
> Die CPU muss in einem separaten Test geprüft werden.

Schon klar.  Mir ging's darum: ein sinnvoller Test müsste diese
Dinge von außen testen, nicht mit sich selbst.  Das geht eben nur
in eine Controller praktisch nicht.

Wenn deine CPU kaputt ist und bei der Addition von 5 + 5 das Ergebnis
20 bringt, dann aber beim Vergleich auf 10 behauptet „ist gleich“
(schließlich ist sie ja kaputt), was hast du jetzt mit dem Test genau
gewonnen?

Solange nicht gerade statistisch erwiesen ist, dass der SRAM in
einem Controller sehr viel häufiger kaputt geht als die CPU
selbst, ist der RAM-Test daher ziemliche Augenauswischerei: so ein
RAM würde ja nicht mir nichts, dir nichts kaputt gehen, sondern
durch einen äußeren Einfluss.  Dann ist es aber genauso zweifelhaft,
ob nicht der gleiche äußere Einfluss dazu geführt haben könnte, dass
die CPU ebenfalls geschädigt ist und den RAM-Test positiv erscheinen
lässt.

von Peter II (Gast)


Lesenswert?

Jörg W. schrieb:
> Solange nicht gerade statistisch erwiesen ist, dass der SRAM in
> einem Controller sehr viel häufiger kaputt geht als die CPU
> selbst, ist der RAM-Test daher ziemliche Augenauswischerei: so ein
> RAM würde ja nicht mir nichts, dir nichts kaputt gehen, sondern
> durch einen äußeren Einfluss.  Dann ist es aber genauso zweifelhaft,
> ob nicht der gleiche äußere Einfluss dazu geführt haben könnte, dass
> die CPU ebenfalls geschädigt ist und den RAM-Test positiv erscheinen
> lässt.

also bei normales PCs ist ein RAM Fehler eine sehr häufige 
Fehlerursache. Dort mache ich auch bei merkwürdigen Fehlern zu erst ein 
Ram-Test.

Beim Ram sind es doch die meisten Transistoren, damit ist die 
Wahrscheinlichkeit sehr hoch das auch dort ein Defekt auftritt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter II schrieb:
> also bei normales PCs ist ein RAM Fehler eine sehr häufige
> Fehlerursache.

Das ist aber DRAM, der ist pingelig im Timing der Ansteuerung.

Kann man mit dem im Controller verbauten SRAM nicht vergleichen.

Beim DRAM steckt die Information in einem (verdammt kleinen)
Kondensator, und die Ansteuerung benutzt pro Bit gerade mal einen
Transistor.  Beim SRAM hat man (wimre) sechs Transistoren pro Bit,
und die Information steckt in einem statischen Spannungspegel, der
die Gates der Speicherzelle ansteuert.

Ich habe in der Tat schon kaputte Controller gesehen, aber noch
keinen, bei dem RAM oder CPU geschädigt worden wären.  Was es schon
gab: Schädigung in den IO-Zellen bis hin zum Kurzschluss, zu hohe
Sleep-Ströme, lässt sich nicht mehr programmieren (vermutlich interne
Vpp-Erzeugung geschossen) und dergleichen Dinge.

Wogegen der RAM-Test ohnehin nicht helfen würde ist, dass durch
irgendeine Ursache (Spike auf der Versorgung oder sowas) eins oder
mehrere Bits kippen, obwohl die Zelle an sich in Ordnung ist.

: Bearbeitet durch Moderator
von Alexander Tetzlaff (Gast)


Lesenswert?

Ich möchte mir erlauben, anzumerken, dass ein RAM-Test bei externem SRAM 
durchaus sinnvoll ist (aus eigener leidvoller Erfahrung). Allerdings 
muss dabei darauf geprüft werden, dass alle Leitung korrekt verbunden 
sind, sprich ein Zugriff auf eine Adresse tatsächlich an dieser Adresse 
rauskommt und nicht an einer anderen (z.B. wegen kalter Lötstelle an 
einer Adressleitung).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander Tetzlaff schrieb:
> Ich möchte mir erlauben, anzumerken, dass ein RAM-Test bei externem SRAM
> durchaus sinnvoll ist (aus eigener leidvoller Erfahrung).

Ja, bei externem RAM: keine Frage.  Dann muss man aber keinerlei
Zirkus im Code veranstalten, solange die normalen Variablen alle
im internen RAM liegen.

von Stefan F. (Gast)


Lesenswert?

Letztendlich liegen bei AVR Mikrocontrollern alle CPU Register im RAM, 
und ich meine, dass das beim 8051 auch so war.

Dann ist es völlig egal, wie der Compiler den Speicher und die Register 
nutzt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Alexander Tetzlaff schrieb:
>
1
 register uint8_t* pointer;
> wäre das dann nicht ein Zeiger auf ein "register uint8_t*"?

Nein, "register" ist kein Qualifier sondern eine Speicherklasse wie 
"static" oder "extern".
1
static uint8_t* pointer;

ist kein Zeiger auf einen static sondern pointer selbst ist static.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Letztendlich liegen bei AVR Mikrocontrollern alle CPU Register im RAM

Nein.  Sie sind nur über den RAM-Adressbereich zugreifbar, aber
trotzdem ist implementierungsmäßig ein Register etwas anderes als
RAM.

von Stefan F. (Gast)


Lesenswert?

Das ist mir schon klar. Es gibt ASM Befehle für Register und es gibt 
andere für RAM Zugriff.

Der TO möchte aber das RAM Testen und dabei sicherstellen, dass die 
einige Pointer (CPU Register sind und) nicht im internen RAM liegen. 
Genau das geht zumindestes bei AVR nicht, da alle Register über RAM 
Adressen erreichbar sind, also (auch) im RAM liegen.

Wenn ich das GANZE RAM mit Testdaten überschreibe, dann überschreibe ich 
auch die CPU Register und störe somit den Proghrammablauf.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Genau das geht zumindestes bei AVR nicht, da alle Register über RAM
> Adressen erreichbar sind,

IO-Register sind auch über RAM-Adressen erreichbar, und die stehen
noch nach den CPU-Registern.

Die kann man unmöglich in einen RAM-Test mit einbeziehen, da es darin
einerseits oft Lücken gibt, andererseits genügend IO-Register, bei
denen man nicht 1:1 das wieder auslesen kann, was man reingeschrieben
hat.

> also (auch) im RAM liegen.

Nein.  Nochmals: die Adressierungsmöglichkeit bedeutet nicht, dass
die Register deshalb „im RAM liegen“ würden.

Wo der RAM anfängt und wo er aufhört, ist für jeden AVR sauber genug
beschrieben, als dass man dies in einem RAM-Test berücksichtigen kann.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Noch ein Beispiel: bei einem ARM mit flachem 32-Bit-Adressraum
kommst du doch auch nicht auf die Idee, dass man beim RAM-Test alle
2^32 Adressen durchklingeln müsste …

von Herbert (Gast)


Lesenswert?

Also mach es doch einfach in asm. Also wen für was asm gut ist dann für 
sowas, die asm funtion kannst du eh in C verwenden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sehe ich auch so.  Den Krempel muss man sowieso in eine der .init<N>
sections stopfen.

von Pandur S. (jetztnicht)


Lesenswert?

Allenfalls waere die Anwendung noch interessant.
Wenn man nur beim Powerup pruft, was erwartet man ? Dass der Speicher 
nur bei Power off/down kaputt geht ? Was soll die Laufzeit denn sein ?

Ich habe Controller in meinen Produkten im Betrieb, die laufen Monate, 
oder sogar jahrelang durch.

Dann sollte man sich ueberlegen, welche Fehler erwartet man. Weshalb 
sollten Fehler waehren des Abschaultens, oder ausgeschaltet seins 
haeufer sein wie waehrend dem Betrieb ?

Erwartet man Fehler waehrend des Betriebes ? Dann muesste man den Test 
periodisch machen. Dann sind wir aber bei den 3 Controllern, die sich 
gegenseitig kontrollieren.

von Axel L. (axel_5)


Lesenswert?

Jörg W. schrieb:
> Stefan U. schrieb:
>> Genau das geht zumindestes bei AVR nicht, da alle Register über RAM
>> Adressen erreichbar sind,
>
> IO-Register sind auch über RAM-Adressen erreichbar, und die stehen
> noch nach den CPU-Registern.
>
> Die kann man unmöglich in einen RAM-Test mit einbeziehen, da es darin
> einerseits oft Lücken gibt, andererseits genügend IO-Register, bei
> denen man nicht 1:1 das wieder auslesen kann, was man reingeschrieben
> hat.
>
>> also (auch) im RAM liegen.
>
> Nein.  Nochmals: die Adressierungsmöglichkeit bedeutet nicht, dass
> die Register deshalb „im RAM liegen“ würden.
>
> Wo der RAM anfängt und wo er aufhört, ist für jeden AVR sauber genug
> beschrieben, als dass man dies in einem RAM-Test berücksichtigen kann.

Wie das in der Hardware realisiert ist, lässt sich aus den Unterlagen 
nicht erkennen. Die Ansteuerung muss ja nichts mit der Realisierung zu 
tun haben. Gerade bei so hochvolumigen Micros werden die spannensten 
Tricks umgesetzt, um die Fläche zu reduzieren.

Grundsätzlich ist es effizienter, das in einem SRAM zu realisieren, die 
Speicher dort sind einfach kleiner als bei einer Realisierung mit 
Flip-Flops. Das führt aber dann auch dazu, dass die leichter kaputt 
gehen. Ausserdem ist der Zugriff über FF schneller.
Mag also sein, dass die 16MHz Variante das mit FF und die 8MHz Variante 
mit SRAM hat. Mag auch sein, dass das sich über die Jahre ändert.

Aber grundsätzlich spricht ja nichts dagegen, das RAM mit so einem Test 
zu testen, man ist zwar nicht sicher, ob alles in Ordnung ist, wenn der 
Test funktioniert, aber wenn er nicht funktioniert, weiss man sicher das 
etwas nicht in Ordnung ist. Was ja auch schon mal hilfreich ist.

Gruss
Axel

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Axel L. schrieb:
> Mag also sein, dass die 16MHz Variante das mit FF und die 8MHz Variante
> mit SRAM hat.

Nein, das sind stets die gleichen Dies.

Wie es realisiert ist, ist auch ziemlich egal: dass man die Register
selbst nicht durch einen RAM-Test testen kann, sollte ziemlich
offensichtlich sein.  Irgendwas braucht der Prozessor ja auf jeden
Fall zum Arbeiten, das kann man ihm nicht für einen Test unterm Popo
wegziehen.

p.s.: Beim Xmega hat man das memory mapping der CPU-Register dann
übrigens fallen gelassen.  Dadurch ist dort auch der Offset 0x20
bei den IO-Registern verschwunden, den man sonst beim AVR zwischen
Adressierung per IN/OUT und Adressierung per STS/LDS hatte.

: Bearbeitet durch Moderator
von Jobst M. (jobstens-de)


Lesenswert?

Axel L. schrieb:
> Grundsätzlich ist es effizienter, das in einem SRAM zu realisieren, die
> Speicher dort sind einfach kleiner als bei einer Realisierung mit
> Flip-Flops.

SRAM sind FlipFlops.


Gruß

Jobst

von Axel L. (axel_5)


Lesenswert?

Jobst M. schrieb:
> Axel L. schrieb:
>> Grundsätzlich ist es effizienter, das in einem SRAM zu realisieren, die
>> Speicher dort sind einfach kleiner als bei einer Realisierung mit
>> Flip-Flops.
>
> SRAM sind FlipFlops.
>
>
> Gruß
>
> Jobst

Jain.

SRAMs sind ganz anders optimiert, werden wesentlich dichter gepackt, und 
nicht zuletzt ganz anders getestet.

Daher sind sie auch empfindlicher als "normale" FF. Sie reagieren auch 
viel empfindlicher auf Bitkipper im Betrieb durch Störeinstrahlung als 
FF.

In kritischen Anwendungen werden SRAMs übrigens durchaus im laufenden 
Betrieb getestet, bei FF habe ich das nur sehr selten gesehen.

Gruss
Axel

von Axel L. (axel_5)


Lesenswert?

Jörg W. schrieb:
> Axel L. schrieb:
>> Mag also sein, dass die 16MHz Variante das mit FF und die 8MHz Variante
>> mit SRAM hat.
>
> Nein, das sind stets die gleichen Dies.
>
Woher weisst Du das ?  Glaubst Du etwa, dass man die Dies selektiert und 
damit dann 8 MHz und 16 MHz Bausteine bekommt ? Das stimmt definitiv 
nicht, dann müsste der Prozess von Atmel grottenschlecht sein (und der 
von TSMC ist garantiert nicht so schlecht).

> Wie es realisiert ist, ist auch ziemlich egal: dass man die Register
> selbst nicht durch einen RAM-Test testen kann, sollte ziemlich
> offensichtlich sein.  Irgendwas braucht der Prozessor ja auf jeden
> Fall zum Arbeiten, das kann man ihm nicht für einen Test unterm Popo
> wegziehen.

Man braucht ja nur zwei bis drei Register zum Arbeiten.

Gilt natürlich wieder mein Satz von oben: Es mag sein, dass der Test 
funktioniert, obwohl der Prozessor defekt ist, aber wenn der Test nicht 
funktioniert, ist der Prozessor auf jeden Fall defekt.

Gruss
Axel

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Axel L. schrieb:
> Glaubst Du etwa, dass man die Dies selektiert und damit dann 8 MHz und
> 16 MHz Bausteine bekommt ?

Ja, hat man so gemacht.  Der Großteil davon dürfte ohnehin beide
Spezifikationen (also L/V oder 5-V-Typ) abgedeckt haben; man hat
auf diese Weise nur die Ausbeute verbessert, da man über die
gesamte Streubreite halt zwei Bereiche legen konnte.

Edit: es ist natürlich möglich, dass für die L/V- und Normaltypen
tatsächlich Prozessparameter leicht variiert worden sind.  Aber
zumindest benutzen alle das gleiche Layout, darauf wollte ich mit
der vorigen Bemerkung hinaus.

Axel L. schrieb:
> und der von TSMC ist garantiert nicht so schlecht

Seit den "A"-Typen, die bei TSMC laufen, gibt's die Unterscheidung
nach L- oder V-Typen ja auch nicht mehr.

: Bearbeitet durch Moderator
von Alexander Tetzlaff (Gast)


Lesenswert?

Herbert schrieb:
> Also mach es doch einfach in asm. Also wen für was asm gut ist dann für
> sowas, die asm funtion kannst du eh in C verwenden.

Mag sein... das entschuldigt aber nicht, dass man den Unterschied 
zwischen einem Modifier und einem Storage Class nicht kennt ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nochmal BTT: ich versteh' die ganze Aufregung gar nicht.

Wenn ich das hier durch den Compiler schiebe:
1
#include <stdint.h>
2
#include <stdbool.h>
3
4
int retval = 42; // trigger external reference, force .data section
5
6
void ramtest(void) __attribute__((used,naked,section(".init3")));
7
void ramtest(void)
8
{
9
   bool fail = false;
10
   volatile uint8_t *p = (uint8_t *)0x200;
11
   while (!fail && p < (uint8_t *)(0x200 + 0x400)) {
12
      *p = 0x55;
13
      if (*p != 0x55) fail = true;
14
      *p = 0xAA;
15
      if (*p != 0xAA) fail = true;
16
      *p = 0x00;
17
      if (*p != 0x00) fail = true;
18
      p++;
19
   }
20
   if (fail) for (;;) { /* block here */ }
21
}
22
23
int
24
main(void)
25
{
26
   return retval;
27
}

dann kommt doch da so ziemlich genau das raus, was meiner Meinung
nach der TE möchte:
1
Disassembly of section .text:
2
3
00000000 <__vectors>:
4
   0:   0c 94 66 00     jmp     0xcc    ; 0xcc <__ctors_end>
5
   4:   0c 94 9a 00     jmp     0x134   ; 0x134 <__bad_interrupt>
6
[…]
7
8
000000cc <__ctors_end>:
9
  cc:   11 24           eor     r1, r1
10
  ce:   1f be           out     0x3f, r1        ; 63
11
  d0:   cf ef           ldi     r28, 0xFF       ; 255
12
  d2:   d1 e2           ldi     r29, 0x21       ; 33
13
  d4:   de bf           out     0x3e, r29       ; 62
14
  d6:   cd bf           out     0x3d, r28       ; 61
15
16
000000d8 <ramtest>:
17
  d8:   e0 e0           ldi     r30, 0x00       ; 0
18
  da:   f2 e0           ldi     r31, 0x02       ; 2
19
  dc:   95 e5           ldi     r25, 0x55       ; 85
20
  de:   2a ea           ldi     r18, 0xAA       ; 170
21
  e0:   90 83           st      Z, r25
22
  e2:   30 81           ld      r19, Z
23
  e4:   20 83           st      Z, r18
24
  e6:   80 81           ld      r24, Z
25
  e8:   8a 3a           cpi     r24, 0xAA       ; 170
26
  ea:   29 f4           brne    .+10            ; 0xf6 <ramtest+0x1e>
27
  ec:   81 e0           ldi     r24, 0x01       ; 1
28
  ee:   35 35           cpi     r19, 0x55       ; 85
29
  f0:   19 f4           brne    .+6             ; 0xf8 <ramtest+0x20>
30
  f2:   80 e0           ldi     r24, 0x00       ; 0
31
  f4:   01 c0           rjmp    .+2             ; 0xf8 <ramtest+0x20>
32
  f6:   81 e0           ldi     r24, 0x01       ; 1
33
  f8:   10 82           st      Z, r1
34
  fa:   30 81           ld      r19, Z
35
  fc:   31 11           cpse    r19, r1
36
  fe:   81 e0           ldi     r24, 0x01       ; 1
37
 100:   31 96           adiw    r30, 0x01       ; 1
38
 102:   81 11           cpse    r24, r1
39
 104:   05 c0           rjmp    .+10            ; 0x110 <ramtest+0x38>
40
 106:   e1 15           cp      r30, r1
41
 108:   86 e0           ldi     r24, 0x06       ; 6
42
 10a:   f8 07           cpc     r31, r24
43
 10c:   49 f7           brne    .-46            ; 0xe0 <ramtest+0x8>
44
 10e:   01 c0           rjmp    .+2             ; 0x112 <__do_copy_data>
45
 110:   ff cf           rjmp    .-2             ; 0x110 <ramtest+0x38>
46
47
00000112 <__do_copy_data>:
48
 112:   12 e0           ldi     r17, 0x02       ; 2
49
 114:   a0 e0           ldi     r26, 0x00       ; 0
50
 116:   b2 e0           ldi     r27, 0x02       ; 2
51
 118:   e6 e4           ldi     r30, 0x46       ; 70
52
 11a:   f1 e0           ldi     r31, 0x01       ; 1
53
 11c:   00 e0           ldi     r16, 0x00       ; 0
54
 11e:   0b bf           out     0x3b, r16       ; 59
55
 120:   02 c0           rjmp    .+4             ; 0x126 <__do_copy_data+0x14>
56
 122:   07 90           elpm    r0, Z+
57
 124:   0d 92           st      X+, r0
58
 126:   a2 30           cpi     r26, 0x02       ; 2
59
 128:   b1 07           cpc     r27, r17
60
 12a:   d9 f7           brne    .-10            ; 0x122 <__do_copy_data+0x10>
61
 12c:   0e 94 9c 00     call    0x138   ; 0x138 <main>
62
 130:   0c 94 a1 00     jmp     0x142   ; 0x142 <_exit>
63
64
00000134 <__bad_interrupt>:
65
 134:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
66
67
00000138 <main>:
68
 138:   80 91 00 02     lds     r24, 0x0200
69
 13c:   90 91 01 02     lds     r25, 0x0201
70
 140:   08 95           ret
71
72
00000142 <_exit>:
73
 142:   f8 94           cli
74
75
00000144 <__stop_program>:
76
 144:   ff cf           rjmp    .-2             ; 0x144 <__stop_program>

(Compiliert mal als Beispiel für einen ATmega1281.)

ramtest() benutzt intern ausschließlich Register für den Zugriff,
auf den Speicher wird nur zugegriffen, um ihn zu testen.  Durch
.init3 läuft das Ganze, bevor die reguläre Initialisierung des
RAMs dann angeworfen wird.  Bei Fehlern im Test verbleibt die CPU
am Ende des Tests in einer Endlosschleife.

Über Sinn und Unsinn dieser Maßnahme (insbesondere, wenn man sie
nur beim Start durchführt), wurde ja ausgiebig diskutiert.

von Axel L. (axel_5)


Lesenswert?

Jörg W. schrieb:
> Axel L. schrieb:
>> Glaubst Du etwa, dass man die Dies selektiert und damit dann 8 MHz und
>> 16 MHz Bausteine bekommt ?
>
> Ja, hat man so gemacht.  Der Großteil davon dürfte ohnehin beide
> Spezifikationen (also L/V oder 5-V-Typ) abgedeckt haben; man hat
> auf diese Weise nur die Ausbeute verbessert, da man über die
> gesamte Streubreite halt zwei Bereiche legen konnte.
>
Woher weisst Du das (und hier meine ich wirklich wissen und nicht 
vermuten oder vom Hörensagen). Alle Daten, die ich über Prozesse habe, 
legen nahe, dass es bei einem ausgereiften Prozess niemals eine 
Variation von 50% gibt. Wenn man die Prozessparameter so stark streuen 
liesse, würden auch andere, kritische Werte aus der Toleranz fallen und 
die Ausbeute leidet. Wir reden ja hier nicht von einem 7nm Prozess, wo 
man noch zweistellige Ausfallraten hat, das hier dürfte ja noch eher 
150nm oder ähnliches sein. Da kann man die Prozessparameter deutlich 
genauer kontrollieren.

> Edit: es ist natürlich möglich, dass für die L/V- und Normaltypen
> tatsächlich Prozessparameter leicht variiert worden sind.  Aber
> zumindest benutzen alle das gleiche Layout, darauf wollte ich mit
> der vorigen Bemerkung hinaus.
>
Warum sollte man das tun ? Die Ausbeute bei diesen Prozessen kann man 
damit nicht mehr verbessern. Und man wird nicht an den Parametern 
drehen, weil man damit die Ausbeute gefährdet. So ein Prozess wird in 
der Mitte der Parameter gefahren, damit schön viele heile rauskommen. 
Dagegen kann man durch Verwendung von High Speed bzw. High Density SRAM 
(und evtl. auch Flash) die Chipfläche erheblich reduzieren.

> Axel L. schrieb:
>> und der von TSMC ist garantiert nicht so schlecht
>
> Seit den "A"-Typen, die bei TSMC laufen, gibt's die Unterscheidung
> nach L- oder V-Typen ja auch nicht mehr.

Wie gesagt, ich frage mich, woher dieses Wissen stammt (das interessiert 
mich wirklich). Intel hat das früher so gemacht, aber Intel verwendet 
auch Technologien, die an der Grenze des Machbaren liegen. Und schon 
nach relativ kurzer Zeit liefen dann die "Low Speed" Varianten mit dem 
Takt der  High Speed Prozessoren, da fielen gar nicht mehr genügend 
langsame Prozessoren aus der Fertigung.

Gruss
Axel

von Alexander Tetzlaff (Gast)


Lesenswert?

Jörg W. schrieb:
> Nochmal BTT: ich versteh' die ganze Aufregung gar nicht.

Mein RAM-Test läuft permanent im Hintergrund.
Die Adresse, die ich als nächstes prüfen werde, steht selbst ja auch im 
RAM.
Ich muss daher diese Adresse aus dem RAM in Register kopieren, und auch 
den Inhalt der zu prüfenden Adresse in ein Register sichern.

Das funktioniert auch in C geschrieben perfekt, allerdings muss ich 
sicherheitshalber den erzeugten Assembler-Code von Hand prüfen (was ein 
klares Argument dafür ist, die Routine gleich in Assembler zu 
schreiben).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alexander Tetzlaff schrieb:
> was ein klares Argument dafür ist, die Routine gleich in Assembler zu
> schreiben

Sehe ich auch so.

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.