Forum: Compiler & IDEs C und Assembler


von Max  . (ueps)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche seit geraumer Zeit zu meinem C Code einen Assembler-Code 
hinzu zu fügen.
Ich kenne die Ansicht vieler hier, dass das Schwachsinn ist zu mischen. 
Entweder C oder Assembler.
Mein Problem ist, ich bin ein absoluter Assembler-Neuling, möchte also 
nicht mehr machen als unbedingt notwendig.
Ich soll für einen Microcontroller eine Demoapplikation programmieren 
und dabei gleichzeitig Selbsttests einführen (Maschinensicherheit, 
etc.). Diese Selbsttests liegen mir als Assembler vor (allerdings für 
einen anderen µC), daher portiere ich sie nur. Das geht soweit auch ganz 
gut, ich kann sie in AVR Studio simulieren lassen und sie laufen wie sie 
sollen. Ist zwar einiges an Aufwand sie auf den AVR ATMega169 zu 
portieren aber das soll nicht eure Sorge sein ;)
Ein Bsp. findet ihr in der Beispiel.asm.

Nun möchte ich die Datei aus einem meiner C-Dateien aus aufrufen. Ich 
habe schon viel versucht, allerdings werde ich nicht so ganz schlau wie 
das genau geht. Einige Tutorials konnten mir auch nicht helfen.
Ich habe jetzt die *.asm-Datei in *.S umbenannt, in das selbe 
Verzeichnis wie meine restlichen Dateien verschoben und in der Makefile 
verlinkt mittels:
1
"# List Assembler source files here.
2
# Make them always end in a capital .S.  Files ending in a lowercase .s
3
# will not be considered source files but generated files (assembler
4
# output from the compiler), and will be deleted upon "make clean"!
5
# Even though the DOS/Win* filesystem matches both .s and .S the same,
6
# it will preserve the spelling of the filenames, and gcc itself does
7
# care about how the name is spelled on its command-line.
8
ASRC = Selftest"

wobei die Datei natürlich Selftest.S heißt.

Allerdings bekomme ich beim kompilieren etliche Fehler.
Habe jetzt auch schon das .include <***> in #include <avr/io.h> geändert 
und aus LOW und HIGH entsprechend lo8 & hi8 gemacht.
1
#include <avr/io.h>
2
3
4
;Stack Initializieren
5
PPR_TEST:    LDI    R16, lo8(RAMEND)  
6
        OUT    SPL , R16
7
        LDI    R16, hi8(RAMEND)  
8
        OUT    SPH , R16      
9
                
10
;Beginn des Tests  
11
;Inkrementstest, wird der Stack-Pointer korrekt Inkrementiert?                  
12
PPR_PUSHPOP:  IN    R26, SPL  ;StackPointer in Register X & Y schreiben      
13
        IN    R27, SPH
14
        IN    R28, SPL      
15
        IN    R29, SPH          
16
        LDI    R16, 0xAA  ;0xAA auf den Stack pushen (dabei wird SP dekrementiert)
17
        PUSH  R16                
18
        LD    R16, -Y   ;Anpassen des erwarteten Wertes.
19
        IN    R16, SPL   ;aktuellen SP-Wert in Vergleichsvariablen schreiben
20
        IN    R17, SPH  
21
        CP    R28, R16  ;Vergleich des aktuellen Stackpointers mit dem vorgesehenen Stackpointers  
22
        BRNE  PPR_err1  
23
        CP    R29, R17  
24
        BRNE  PPR_err1      
25
26
        CLR    R31    
27
        IN    R28, SPL  ;Stackpointer in Register Y schreiben  
28
        IN    R29, SPH      
29
        LD    R31, Y+    ;Anpassen des erwarteten Wertes
30
        LD    R31, Y
31
        CPI    R31, 0xAA  ;Vergleich    
32
        BRNE  PPR_err1      
33
34
        CLR    R31          
35
        POP    R31      ;Wert vom Stack holen
36
        CPI    R31, 0xAA  ;Vergleich mit Erwartung
37
        BRNE  PPR_err1      
38
39
      
40
        IN    R30, SPL   ;aktuellen Stackpointerwert holen
41
        IN    R31, SPH
42
        CP    R30, R26  ;Vergleichen der Werte
43
        BRNE  PPR_err1      
44
        CP    R31, R27      
45
        BRNE  PPR_err1
46
47
PPR_RET:    LDI   ZH, HIGH(PPR_RET1)  
48
        LDI   ZL, LOW(PPR_RET1)  
49
        PUSH   ZL          
50
        PUSH   ZH          
51
        RET            
52
        NOP              
53
        NOP              
54
        NOP              
55
        JMP    PPR_err1      
56
57
PPR_RET1:    JMP    PPR_ENDE      
58
        NOP              
59
        NOP               
60
        NOP              
61
        NOP              
62
        NOP              
63
PPR_err1:    JMP    PPR_err1      
64
65
PPR_ENDE:    RET

trotzdem verbleiben folgende Fehler:
1
Selftest.s: Assembler messages:
2
Selftest.s:6: Error: constant value required
3
Selftest.s:8: Error: constant value required
4
Selftest.s:12: Error: constant value required
5
Selftest.s:13: Error: constant value required
6
Selftest.s:14: Error: constant value required
7
Selftest.s:15: Error: constant value required
8
Selftest.s:19: Error: constant value required
9
Selftest.s:20: Error: constant value required
10
Selftest.s:27: Error: constant value required
11
Selftest.s:28: Error: constant value required
12
Selftest.s:40: Error: constant value required
13
Selftest.s:41: Error: constant value required
14
Selftest.s:47: Error: constant value required
15
Selftest.s:47: Error: register number above 15 required
16
Selftest.s:47: Warning: expression possibly out of 8-bit range
17
Selftest.s:47: Error: garbage at end of line
18
Selftest.s:48: Error: constant value required
19
Selftest.s:48: Error: register number above 15 required
20
Selftest.s:48: Warning: expression possibly out of 8-bit range
21
Selftest.s:48: Error: garbage at end of line
22
Selftest.s:49: Error: constant value required
23
Selftest.s:50: Error: constant value required
24
Selftest.s:55: Error: illegal opcode jmp for mcu avr2
25
Selftest.s:57: Error: illegal opcode jmp for mcu avr2
26
Selftest.s:63: Error: illegal opcode jmp for mcu avr2
27
Selftest.s:64: Warning: partial line at end of file ignored

gibt es keine einfachere Methode, so dass ich quasi den ASM-Code aus dem 
AVR-Studio 1:1 übernehmen kann und nur einen aufruf aus einer C-Datei zu 
starten? Wenn ja, wie muss ich das einbinden, linken, etc.?

Vielen Dank schonmal für die Mühe!

Ueps

von Michael U. (amiga)


Lesenswert?

Hallo,

nur so am Rande: wenn der Stackpointer falsch oder garnicht 
incrementiert dann kommt Dein C-Programm mit an Sicherheit grenzender 
Wahrscheinlichkeit nie an die Stelle, die Dein Testprogramm aufruft...

Gruß aus Berlin
Michael

von Max  . (ueps)


Lesenswert?

das mag wohl sein, allerdings ist es halt voraussetzung für einige 
maschinen solche selbsttests durchzuführen ;) es ist auch nicht meine 
entscheidung welche selbsttest implementiert werden und das ich jetzt 
gerade diesen heraus gegriffen habe liegt auch einfach nur daran, dass 
ich diesen grade zufällig als letzten portiert habe

von yalu (Gast)


Lesenswert?

> Ich habe jetzt die *.asm-Datei in *.S umbenannt, ...

Das sieht aber nicht so aus:

> Selftest.s:6: Error: constant value required

Wichtig ist das große 'S' am Ende. Nur denn wendet der GNU-Assembler den
C-Päprozesser auf die Datei an, so dass im Header-File definierte Makros
wie SPH und SPL richtig umgesetzt werden.

von Max  . (ueps)


Lesenswert?

hallo,

danke für die Idee, leider war bzw. ist das S bereits groß geschrieben. 
Aber es ist doch richtig, dass ich die Datei einfach UMBENANNT habe, ich 
muss sie nicht irgendwie konvertieren oder so?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Am besten gibst du für asm-Dateien die Spreche explizit beim gcc-Aufruf 
mit an:
1
-x assembler-with-cpp datei.asm

Dann ist die Endung egal. Ausserdem willst du ja nicht Assembler 
übersetzen, sondern vorher noch den Präprozessor drüberrauschen lassen.

Zu dem undefined:

Wo wird ZL definiert? Wo ZH? SPL? SPH? ...

Wenn du das innerhalb von C verwenden willst, brauchst du noch 
Prototypen und die Symbole müssen global sein.

Und beachte die C-ABI. Sonst fliegt dir alles um die Ohren!

von (prx) A. K. (prx)


Lesenswert?

GNU-C und Atmel-Assembler kombiniert sich nicht und der GNU-Assembler 
ist nicht mit dem Atmel-Assembler kompatibel. Also müssen Programme für 
Atmels Assembler erst umgeschrieben werden.

von Max  . (ueps)


Lesenswert?

Johann L. wrote:
> Am besten gibst du für asm-Dateien die Spreche explizit beim gcc-Aufruf
> mit an:
>
>
1
> -x assembler-with-cpp datei.asm
2
>
>
> Dann ist die Endung egal. Ausserdem willst du ja nicht Assembler
> übersetzen, sondern vorher noch den Präprozessor drüberrauschen lassen.

Wo mache ich das genau in der makefile? gibts da einen bestimmten punkt 
in den das rein muss?

> Zu dem undefined:
>
> Wo wird ZL definiert? Wo ZH? SPL? SPH? ...

Diese Variablen werden doch in der *.inc definiert, welche von der *.h 
<avr/io.h> aufgerufen werden. oder irre ich da? In meiner 
Assembler-Datei hatte ich die *.inc explizit aufgerufen.

>
> Wenn du das innerhalb von C verwenden willst, brauchst du noch
> Prototypen und die Symbole müssen global sein.
>
> Und beachte die C-ABI. Sonst fliegt dir alles um die Ohren!

C-ABI? Entschuldige bitte aber ich bin leider noch nicht so tief im 
ganzen drin, erläutere bitte was du damit meinst damit ich mir das mal 
anschauen kann


>GNU-C und Atmel-Assembler kombiniert sich nicht und der GNU-Assembler
>ist nicht mit dem Atmel-Assembler kompatibel. Also müssen Programme für
>Atmels Assembler erst umgeschrieben werden.

Wie mache ich das? Was genau meinst du damit?

von (prx) A. K. (prx)


Lesenswert?

Max K. wrote:

> Wie mache ich das? Was genau meinst du damit?

Das heisst es gibt viele Dinge, die sich in beiden Assemblern 
unterschiedlich ausdrücken. Ich kenne die auch nicht alle, da hilft nur: 
Doku vom Atmel-Assembler und Doku vom GNU-Assembler vergleichen.

Auch die Schreibweise von Zugriffen auf I/O-Register unterscheidet sich 
deutlich.

Weitere Falle: Atmel rechnet bei ROM-Adressen in Worten, d.h. die 
Adress-Differenz zweier aufeinander folgender 16-Bit-Worte im Codespace 
ist 1. Der GNU-Assembler hingegen rechnet in Bytes.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Max K. wrote:
> Johann L. wrote:
>> Am besten gibst du für asm-Dateien die Spreche explizit beim gcc-Aufruf
>> mit an:
>>
>>
1
>> -x assembler-with-cpp datei.asm
2
>>
>>
>> Dann ist die Endung egal. Ausserdem willst du ja nicht Assembler
>> übersetzen, sondern vorher noch den Präprozessor drüberrauschen lassen.
>
> Wo mache ich das genau in der makefile? gibts da einen bestimmten punkt
> in den das rein muss?

Wer sich durch die generierten Makefiles durchbeissen will...

Such mal nach des Assembler-Quellen und wie die verwurstet werden.

>> Zu dem undefined:
>>
>> Wo wird ZL definiert? Wo ZH? SPL? SPH? ...
>
> Diese Variablen werden doch in der *.inc definiert, welche von der *.h
> <avr/io.h> aufgerufen werden. oder irre ich da?

Ja. GCC verwendet kaum Quellen von Atmel ;-)

>> Wenn du das innerhalb von C verwenden willst, brauchst du noch
>> Prototypen und die Symbole müssen global sein.
>>
>> Und beachte die C-ABI. Sonst fliegt dir alles um die Ohren!
>
> C-ABI? Entschuldige bitte aber ich bin leider noch nicht so tief im
> ganzen drin, erläutere bitte was du damit meinst damit ich mir das mal
> anschauen kann

Application Binary Interface.

http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna#Registerverwendung

>>GNU-C und Atmel-Assembler kombiniert sich nicht und der GNU-Assembler
>>ist nicht mit dem Atmel-Assembler kompatibel. Also müssen Programme für
>>Atmels Assembler erst umgeschrieben werden.
>
> Wie mache ich das? Was genau meinst du damit?

-- Definiere ZL etc. in avr-as-Syntax.
-- Greife bei IN/OUT mit korrektenm Offset auf SFRs zu
-- Ersetze unbekannte Direktiven durch avr-as-Direktiven

Hilfreich ist sich anzuschauen, was avr-gcc aus ner C-Quelle bastelt.
Die Option heisst -save-temps (erzeugt .i/.ii und .s)

und für den Anfang reicht vielleicht schon Inline Assembler?

Der hat Fallstricke genug.

http://www.roboternetz.de/wissen/index.php/Inline-Assembler_in_avr-gcc

von Max  . (ueps)


Lesenswert?

hallo,

danke werde mich da mal durchhangeln. mit inline-assembler habe ich auch 
schon gearbeitet aber ich dachte es gibt halt eine möglichkeit direkt 
von a nach b zu kopieren.
beim inline-assembler hat man ja auch das problem das diverse sachen 
nicht so leicht ansprechbar sind wie beim direkten assembler..

von yalu (Gast)


Lesenswert?

> Aber es ist doch richtig, dass ich die Datei einfach UMBENANNT habe,

Ja. Aber wichtig ist vor allem, dass der Dateiname auch im Makefile mit
.S endet.

> ich muss sie nicht irgendwie konvertieren oder so?

Nein.

Dein Code wird bei mir fehlerfrei assembliert, wenn

- die verbleibenden HIGH und LOW durch hi8 bzw. lo8 ersetzt und

- alle SPL und SPH in den IN- und OUT-Befehlen durch _SFR_IO_ADDR(SPL)
  bzw. _SFR_IO_ADDR(SPH) ersetzt werden. Mehr dazu hier:

    http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html

Ungeachtet dessen wird es evtl. schwierig, die Testroutine auf übliche
Weise aus dem C-Programm aufzurufen, u.a. deswegen, weil der
Stackpointer verändert wird und Daten ins RAM geschrieben werden. Das
führt leicht zum Crash ;-)

Da der Code sowieso nur ganz zu Anfang der Programmausführung wirklich
sinnvoll ist, ist es wahrscheinlich am geschicktesten, ihn in die
.init0-Section zu schreiben. Was das bedeutet, steht hier:

  http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

Dann brauchst du dich auch nicht um die C-Aufrufkonventionen zu kümmern.
Ob Inline-Assembler oder eigene .S-Datei sollte eigentlich egal sein.

von Max  . (ueps)


Lesenswert?

yalu wrote:
>> Aber es ist doch richtig, dass ich die Datei einfach UMBENANNT habe,
>
> Ja. Aber wichtig ist vor allem, dass der Dateiname auch im Makefile mit
> .S endet.
>
>> ich muss sie nicht irgendwie konvertieren oder so?
>
> Nein.
>
> Dein Code wird bei mir fehlerfrei assembliert, wenn
>
> - die verbleibenden HIGH und LOW durch hi8 bzw. lo8 ersetzt und
>
> - alle SPL und SPH in den IN- und OUT-Befehlen durch _SFR_IO_ADDR(SPL)
>   bzw. _SFR_IO_ADDR(SPH) ersetzt werden. Mehr dazu hier:
>
>     http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html
>

Das hatte ich mir auch schon gedacht, allerdings bringt es bei mir keine 
Besserung!
Mein Code:
1
#include <avr/io.h>
2
3
;Stack Initializieren
4
PPR_TEST:    LDI    R16, lo8(RAMEND)  
5
        OUT    _SFR_IO_ADDR(SPL) , R16
6
        LDI    R16, hi8(RAMEND)  
7
        OUT    _SFR_IO_ADDR(SPH) , R16      
8
                
9
;Beginn des Tests  
10
;Inkrementstest, wird der Stack-Pointer korrekt Inkrementiert?                  
11
PPR_PUSHPOP:  IN    R26, _SFR_IO_ADDR(SPL)  ;StackPointer in Register X & Y schreiben      
12
        IN    R27, _SFR_IO_ADDR(SPH)
13
        IN    R28, _SFR_IO_ADDR(SPL)      
14
        IN    R29, _SFR_IO_ADDR(SPH)          
15
        LDI    R16, 0xAA  ;0xAA auf den Stack pushen (dabei wird SP dekrementiert)
16
        PUSH  R16                
17
        LD    R16, -Y   ;Anpassen des erwarteten Wertes.
18
        IN    R16, _SFR_IO_ADDR(SPL)   ;aktuellen SP-Wert in Vergleichsvariablen schreiben
19
        IN    R17, _SFR_IO_ADDR(SPH)  
20
        CP    R28, R16  ;Vergleich des aktuellen Stackpointers mit dem vorgesehenen Stackpointers  
21
        BRNE  PPR_err1  
22
        CP    R29, R17  
23
        BRNE  PPR_err1      
24
25
        CLR    R31    
26
        IN    R28, _SFR_IO_ADDR(SPL)  ;Stackpointer in Register Y schreiben  
27
        IN    R29, _SFR_IO_ADDR(SPL)      
28
        LD    R31, Y+    ;Anpassen des erwarteten Wertes
29
        LD    R31, Y
30
        CPI    R31, 0xAA  ;Vergleich    
31
        BRNE  PPR_err1      
32
33
        CLR    R31          
34
        POP    R31      ;Wert vom Stack holen
35
        CPI    R31, 0xAA  ;Vergleich mit Erwartung
36
        BRNE  PPR_err1      
37
38
      
39
        IN    R30, _SFR_IO_ADDR(SPL)   ;aktuellen Stackpointerwert holen
40
        IN    R31, _SFR_IO_ADDR(SPH)
41
        CP    R30, R26  ;Vergleichen der Werte
42
        BRNE  PPR_err1      
43
        CP    R31, R27      
44
        BRNE  PPR_err1
45
46
PPR_RET:    LDI   R30, hi8(PPR_RET1)  
47
        LDI   R31, lo8(PPR_RET1)  
48
        PUSH   R30          
49
        PUSH   R31          
50
        RET            
51
        NOP              
52
        NOP              
53
        NOP              
54
        JMP    PPR_err1      
55
56
PPR_RET1:    JMP    PPR_ENDE      
57
        NOP              
58
        NOP               
59
        NOP              
60
        NOP              
61
        NOP              
62
PPR_err1:    JMP    PPR_err1      
63
64
PPR_ENDE:    RET

und die dazu gehörende Fehlermeldung
1
Selftest.s: Assembler messages:
2
Selftest.s:0: Warning: end of file not at end of a line; newline inserted
3
Selftest.s:5: Error: constant value required
4
Selftest.s:5: Error: `,' required
5
Selftest.s:5: Error: constant value required
6
Selftest.s:5: Error: garbage at end of line
7
Selftest.s:7: Error: constant value required
8
Selftest.s:7: Error: `,' required
9
Selftest.s:7: Error: constant value required
10
Selftest.s:7: Error: garbage at end of line
11
Selftest.s:11: Error: constant value required
12
Selftest.s:11: Error: garbage at end of line
13
Selftest.s:12: Error: constant value required
14
Selftest.s:12: Error: garbage at end of line
15
Selftest.s:13: Error: constant value required
16
Selftest.s:13: Error: garbage at end of line
17
Selftest.s:14: Error: constant value required
18
Selftest.s:14: Error: garbage at end of line
19
Selftest.s:18: Error: constant value required
20
Selftest.s:18: Error: garbage at end of line
21
Selftest.s:19: Error: constant value required
22
Selftest.s:19: Error: garbage at end of line
23
Selftest.s:26: Error: constant value required
24
Selftest.s:26: Error: garbage at end of line
25
Selftest.s:27: Error: constant value required
26
Selftest.s:27: Error: garbage at end of line
27
Selftest.s:39: Error: constant value required
28
Selftest.s:39: Error: garbage at end of line
29
Selftest.s:40: Error: constant value required
30
Selftest.s:40: Error: garbage at end of line
31
Selftest.s:54: Error: illegal opcode jmp for mcu avr2
32
Selftest.s:56: Error: illegal opcode jmp for mcu avr2
33
Selftest.s:62: Error: illegal opcode jmp for mcu avr2
34
make.exe: *** [Selftest] Error 1

> Ungeachtet dessen wird es evtl. schwierig, die Testroutine auf übliche
> Weise aus dem C-Programm aufzurufen, u.a. deswegen, weil der
> Stackpointer verändert wird und Daten ins RAM geschrieben werden. Das
> führt leicht zum Crash ;-)
>
> Da der Code sowieso nur ganz zu Anfang der Programmausführung wirklich
> sinnvoll ist, ist es wahrscheinlich am geschicktesten, ihn in die
> .init0-Section zu schreiben. Was das bedeutet, steht hier:
>
>   http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
>
> Dann brauchst du dich auch nicht um die C-Aufrufkonventionen zu kümmern.
> Ob Inline-Assembler oder eigene .S-Datei sollte eigentlich egal sein.

wie gesagt, es ist nicht meine entscheidung wann der test ausgeführt 
wird. das da nochmal probleme auf mich zukommen werden habe ich schon 
fast befürchtet, allerdings möchte ich jetzt den code erst ans laufen 
bekommen. so langsam bin ich dran einfach mein ganzes programm in 
assembler zu schreiben da ich keine lust auf dieses heckmeck habe von 
wegen portieren, umschreiben, etc.pp.
klaut mir nur tage von meiner knappen zeit für meine bachelor-arbeit

von yalu (Gast)


Lesenswert?

Korrektur zu oben:

> ... ihn in die .init0-Section zu schreiben.

Besser: .init1-Section, da diese offiziell "user definable" ist.

Zu den Fehlermeldungen:

> Selftest.s: Assembler messages:
> ...

Der Compiler/Assembler meint immer noch, er müsste eine Datei namens
Selftest.s (und nicht Selftest.S, wie es richtig wäre) assemblieren.
Poste doch mal das Makefile.

von Max  . (ueps)


Lesenswert?

also das makefile ist nicht von mir. habe damals in den prozessor 
reingeschnuppert mit dem buch von joe pardue (C Programming for 
microcontrollers). dementsprechend habe ich auch sein makefile genommen. 
und da bisher alles klappte und ich sowieso nicht ganz 100% 
nachvollziehen konnte was da gemacht wird (läuft? läuft!, never touch a 
running system und so) habe ich es einfach mal gelassen.. jedoch wird 
auch dort explizit auf das große .S hingewiesen.
1
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
2
# Released to the Public Domain
3
# Please read the make user manual!
4
#
5
# Additional material for this makefile was submitted by:
6
#  Tim Henigan
7
#  Peter Fleury
8
#  Reiner Patommel
9
#  Sander Pool
10
#  Frederik Rouleau
11
#  Markus Pfaff
12
#
13
# On command line:
14
#
15
# make all = Make software.
16
#
17
# make clean = Clean out built project files.
18
#
19
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
20
#
21
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
22
#                4.07 or greater).
23
#
24
# make program = Download the hex file to the device, using avrdude.  Please
25
#                customize the avrdude settings below first!
26
#
27
# make filename.s = Just compile filename.c into the assembler code only
28
#
29
# To rebuild project do "make clean" then "make all".
30
#
31
32
33
# MCU name
34
MCU = atmega169
35
36
# Output format. (can be srec, ihex, binary)
37
FORMAT = ihex
38
39
# Target file name (without extension).
40
TARGET = Blinky
41
42
43
# List C source files here. (C dependencies are automatically generated.)
44
SRC = $(TARGET).c
45
46
47
# List Assembler source files here.
48
# Make them always end in a capital .S.  Files ending in a lowercase .s
49
# will not be considered source files but generated files (assembler
50
# output from the compiler), and will be deleted upon "make clean"!
51
# Even though the DOS/Win* filesystem matches both .s and .S the same,
52
# it will preserve the spelling of the filenames, and gcc itself does
53
# care about how the name is spelled on its command-line.
54
ASRC = Selftest
55
56
57
# Optimization level, can be [0, 1, 2, 3, s]. 
58
# 0 = turn off optimization. s = optimize for size.
59
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
60
OPT = s
61
62
63
# List any extra directories to look for include files here.
64
#     Each directory must be seperated by a space.
65
EXTRAINCDIRS = 
66
67
68
# Compiler flag to set the C Standard level.
69
CSTANDARD_C89 = c89
70
CSTANDARD_GNU89 = gnu89
71
CSTANDARD_C99 = c99
72
CSTANDARD_GNU99 = gnu99
73
CSTANDARD = -std=$(CSTANDARD_GNU99)
74
75
76
77
# Compiler flags.
78
#  -g:           generate debugging information
79
#  -O*:          optimization level
80
#  -f...:        tuning, see GCC manual and avr-libc documentation
81
#  -Wall...:     warning level
82
#  -Wa,...:      tell GCC to pass this to the assembler.
83
#    -adhlns...: create assembler listing
84
CFLAGS = -g
85
CFLAGS += -O$(OPT)
86
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
87
CFLAGS += -Wall -Wstrict-prototypes
88
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
89
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
90
CFLAGS += $(CSTANDARD)
91
92
93
94
# Assembler flags.
95
#  -Wa,...:   tell GCC to pass this to the assembler.
96
#  -ahlms:    create listing
97
#  -gstabs:   have the assembler create line number information; note that
98
#             for use in COFF files, additional information about filenames
99
#             and function names needs to be present in the assembler source
100
#             files -- see avr-libc docs [FIXME: not yet described there]
101
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
102
103
104
105
#Additional libraries.
106
107
PRINTF_LIB_NONE = 
108
109
# Minimalistic printf version
110
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
111
112
# Floating point printf version (requires MATH_LIB = -lm below)
113
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
114
115
PRINTF_LIB = $(PRINTF_LIB_NONE)
116
117
MATH_LIB = -lm
118
119
120
121
# Linker flags.
122
#  -Wl,...:     tell GCC to pass this to linker.
123
#    -Map:      create map file
124
#    --cref:    add cross reference to  map file
125
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref $(PRINTF_LIB) $(MATH_LIB)
126
127
128
129
130
# Programming support using avrdude. Settings and variables.
131
132
# Programming hardware: alf avr910 avrisp bascom bsd 
133
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
134
#
135
# Type: avrdude -c ?
136
# to get a full listing.
137
#
138
AVRDUDE_PROGRAMMER = stk500
139
140
# com1 = serial port. Use lpt1 to connect to parallel port.
141
AVRDUDE_PORT = com1    # programmer connected to serial device
142
143
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
144
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
145
146
147
# Uncomment the following if you want avrdude's erase cycle counter.
148
# Note that this counter needs to be initialized first using -Yn,
149
# see avrdude manual.
150
#AVRDUDE_ERASE_COUNTER = -y
151
152
# Uncomment the following if you do /not/ wish a verification to be
153
# performed after programming the device.
154
#AVRDUDE_NO_VERIFY = -V
155
156
# Increase verbosity level.  Please use this when submitting bug
157
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
158
# to submit bug reports.
159
#AVRDUDE_VERBOSE = -v -v
160
161
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
162
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
163
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
164
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
165
166
167
168
# ---------------------------------------------------------------------------
169
170
# Define directories, if needed.
171
DIRAVR = c:/winavr
172
DIRAVRBIN = $(DIRAVR)/bin
173
DIRAVRUTILS = $(DIRAVR)/utils/bin
174
DIRINC = .
175
DIRLIB = $(DIRAVR)/avr/lib
176
177
178
# Define programs and commands.
179
SHELL = sh
180
CC = avr-gcc
181
OBJCOPY = avr-objcopy
182
OBJDUMP = avr-objdump
183
SIZE = avr-size
184
NM = avr-nm
185
AVRDUDE = avrdude
186
REMOVE = rm -f
187
COPY = cp
188
189
190
191
192
# Define Messages
193
# English
194
MSG_ERRORS_NONE = Errors: none
195
MSG_BEGIN = -------- begin --------
196
MSG_END = --------  end  --------
197
MSG_SIZE_BEFORE = Size before: 
198
MSG_SIZE_AFTER = Size after:
199
MSG_COFF = Converting to AVR COFF:
200
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
201
MSG_FLASH = Creating load file for Flash:
202
MSG_EEPROM = Creating load file for EEPROM:
203
MSG_EXTENDED_LISTING = Creating Extended Listing:
204
MSG_SYMBOL_TABLE = Creating Symbol Table:
205
MSG_LINKING = Linking:
206
MSG_COMPILING = Compiling:
207
MSG_ASSEMBLING = Assembling:
208
MSG_CLEANING = Cleaning project:
209
210
211
212
213
# Define all object files.
214
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
215
216
# Define all listing files.
217
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
218
219
220
# Compiler flags to generate dependency files.
221
GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
222
223
224
# Combine all necessary flags and optional flags.
225
# Add target processor to flags.
226
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
227
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
228
229
230
231
232
233
# Default target.
234
all: begin gccversion sizebefore build sizeafter finished end
235
236
build: elf hex eep lss sym
237
238
elf: $(TARGET).elf
239
hex: $(TARGET).hex
240
eep: $(TARGET).eep
241
lss: $(TARGET).lss 
242
sym: $(TARGET).sym
243
244
245
246
# Eye candy.
247
# AVR Studio 3.x does not check make's exit code but relies on
248
# the following magic strings to be generated by the compile job.
249
begin:
250
  @echo
251
  @echo $(MSG_BEGIN)
252
253
finished:
254
  @echo $(MSG_ERRORS_NONE)
255
256
end:
257
  @echo $(MSG_END)
258
  @echo
259
260
261
# Display size of file.
262
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
263
ELFSIZE = $(SIZE) -A $(TARGET).elf
264
sizebefore:
265
  @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
266
267
sizeafter:
268
  @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
269
270
271
272
# Display compiler version information.
273
gccversion : 
274
  @$(CC) --version
275
276
277
278
# Program the device.  
279
program: $(TARGET).hex $(TARGET).eep
280
  $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
281
282
283
284
285
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
286
COFFCONVERT=$(OBJCOPY) --debugging \
287
--change-section-address .data-0x800000 \
288
--change-section-address .bss-0x800000 \
289
--change-section-address .noinit-0x800000 \
290
--change-section-address .eeprom-0x810000 
291
292
293
coff: $(TARGET).elf
294
  @echo
295
  @echo $(MSG_COFF) $(TARGET).cof
296
  $(COFFCONVERT) -O coff-avr $< $(TARGET).cof
297
298
299
extcoff: $(TARGET).elf
300
  @echo
301
  @echo $(MSG_EXTENDED_COFF) $(TARGET).cof
302
  $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
303
304
305
306
# Create final output files (.hex, .eep) from ELF output file.
307
%.hex: %.elf
308
  @echo
309
  @echo $(MSG_FLASH) $@
310
  $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
311
312
%.eep: %.elf
313
  @echo
314
  @echo $(MSG_EEPROM) $@
315
  -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
316
  --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
317
318
# Create extended listing file from ELF output file.
319
%.lss: %.elf
320
  @echo
321
  @echo $(MSG_EXTENDED_LISTING) $@
322
  $(OBJDUMP) -h -S $< > $@
323
324
# Create a symbol table from ELF output file.
325
%.sym: %.elf
326
  @echo
327
  @echo $(MSG_SYMBOL_TABLE) $@
328
  $(NM) -n $< > $@
329
330
331
332
# Link: create ELF output file from object files.
333
.SECONDARY : $(TARGET).elf
334
.PRECIOUS : $(OBJ)
335
%.elf: $(OBJ)
336
  @echo
337
  @echo $(MSG_LINKING) $@
338
  $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
339
340
341
# Compile: create object files from C source files.
342
%.o : %.c
343
  @echo
344
  @echo $(MSG_COMPILING) $<
345
  $(CC) -c $(ALL_CFLAGS) $< -o $@
346
347
348
# Compile: create assembler files from C source files.
349
%.s : %.c
350
  $(CC) -S $(ALL_CFLAGS) $< -o $@
351
352
353
# Assemble: create object files from assembler source files.
354
%.o : %.S
355
  @echo
356
  @echo $(MSG_ASSEMBLING) $<
357
  $(CC) -c $(ALL_ASFLAGS) $< -o $@
358
359
360
361
# Target: clean project.
362
clean: begin clean_list finished end
363
364
clean_list :
365
  @echo
366
  @echo $(MSG_CLEANING)
367
  $(REMOVE) $(TARGET).hex
368
  $(REMOVE) $(TARGET).eep
369
  $(REMOVE) $(TARGET).obj
370
  $(REMOVE) $(TARGET).cof
371
  $(REMOVE) $(TARGET).elf
372
  $(REMOVE) $(TARGET).map
373
  $(REMOVE) $(TARGET).obj
374
  $(REMOVE) $(TARGET).a90
375
  $(REMOVE) $(TARGET).sym
376
  $(REMOVE) $(TARGET).lnk
377
  $(REMOVE) $(TARGET).lss
378
  $(REMOVE) $(OBJ)
379
  $(REMOVE) $(LST)
380
  $(REMOVE) $(SRC:.c=.s)
381
  $(REMOVE) $(SRC:.c=.d)
382
  $(REMOVE) .dep/*
383
384
385
386
# Include the dependency files.
387
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
388
389
390
# Listing of phony targets.
391
.PHONY : all begin finish end sizebefore sizeafter gccversion \
392
build elf hex eep lss sym coff extcoff \
393
clean clean_list program

Danke euch nochmal, dass ihr hier zu helfen versucht!!!

(und meine Datei ist 100% *.S)


btw. arbeite unter Win2k, vllt. ist ja das von Windows aus, dass er das 
case-sensitive ein wenig verschmeißt?!

von ... .. (docean) Benutzerseite


Lesenswert?

räusper
1
#include <avr/io.h>

hat da wohl nix zu suchen...
Besser ist
1
.include "m8def.inc"
Bzw. natürlich anpassen...

Oder versteh ich dich jetzt falsch?

EDIT
schon mal probiert

ASRC = Selftest.S
(im Makefile)

zu verwende?n

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


Lesenswert?

... ... wrote:
> *räusper*
>
>
1
> #include <avr/io.h>
2
>
>
> hat da wohl nix zu suchen...

Doch.

> Besser ist
>
>
1
> .include "m8def.inc"
2
>

Gibb's nich.

> schon mal probiert
>
> ASRC = Selftest.S
> (im Makefile)

Allerdings, das sollte man.

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


Lesenswert?

p.s.: Ich kann das zweite oben zitierte File, wenn ich es selftest.S
nenne, problemlos durch den Compiler schicken.

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


Lesenswert?

pps: Was noch fehlt, ist ein globaler Einsprungpunkt.  Vermutlich also
ein
1
.global PPR_TEST

Warum muss man Assemblercode eigentlich mit gedrückter CAPS LOCK-Taste
schreiben? ;-)

von Max  . (ueps)


Lesenswert?

Yieks.. das .S ist wirklich ein saudummer fehler.. warum ich das 
vergessen habe weiß ich nicht.. *kopf=>tisch*
das mit dem einstiegspunkt schau ich mir jetzt noch an ;)
und das mit dem CAPSLOCK.. naja.. meine vorlagen sind in 
CAPSLOCK-Schrift, ich habs selber nicht gemacht und ein kollege meinte 
dann nur das sei konvention und ich soll mich dran halten..

danke für eure großartige hilfe ;)

von Klaus (Gast)


Lesenswert?

Frage: Was spricht gegen die Benutzung des Inlineassemblers? Damit 
dürfte das ganze doch wesentlich einfacher sein, oder?

von Max  . (ueps)


Lesenswert?

mich sträubt es dagegen Tests, welche ich bereits auf den avr portiert 
habe, jetzt nochmal komplett umschreiben zu müssen, damit sie als 
inline-assembler laufen.
oder gibts da einen Kniff wie das ganze sehr einfach wird?

eine andere frage: warum gibt mir der befehl:
1
PPR_RET:    LDI   ZH, hi8(PPR_RET1)  
2
        LDI   ZL, lo8(PPR_RET1)  
3
        PUSH   ZL          
4
        PUSH   ZH          
5
        RET
einen falschen Wert für was Label PPR_RET1 zurück? er springt an einen 
völlig falsche Stelle, warum?

von ... .. (docean) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> ... ... wrote:
>> *räusper*
>>
>>
1
>> #include <avr/io.h>
2
>>
>>
>> hat da wohl nix zu suchen...
>
> Doch.
>
>> Besser ist
>>
>>
1
>> .include "m8def.inc"
2
>>
>
> Gibb's nich.
>

Aber unter
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Anwendung
stehts so...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mal ne Frage: Wozu ist dsa tolle Programm überhaupt gut?

von Stefan E. (sternst)


Lesenswert?

... ... wrote:
> Aber unter
> http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Anwendung
> stehts so...

Das dort ist Atmel-Assembler. Hier geht es aber um GCC-Assembler.

von Falk B. (falk)


Lesenswert?

@  Stefan Ernst (sternst)

>Das dort ist Atmel-Assembler. Hier geht es aber um GCC-Assembler.

Mit dem bist recht allein. Den nutzt so gut wie keiner (direkt).

MFG
Falk

von Stefan E. (sternst)


Lesenswert?

Falk Brunner wrote:

>>Das dort ist Atmel-Assembler. Hier geht es aber um GCC-Assembler.
>
> Mit dem bist recht allein. Den nutzt so gut wie keiner (direkt).

Ich kann dir nicht folgen. Was denkst du denn, um welchen Assembler es 
hier geht, wenn nicht den AVR-Assembler des GCC?

von Max  . (ueps)


Lesenswert?

also ich hatte das .include "µC.inc" (angepasst halt) in meinem 
assembler-code den ich über avr-studio auch ausführen konnte. allerdings 
geht das nicht, wenn ich es dem projekt hinzu linken möchte, dann kann 
er damit nichtsmehr anfangen.
aber in der avr/io.h wird ja auch eine datei eingebunden, welche wohl 
ähnliche elemente beinhaltet, da ich ja nun auf SPL etc. zugreifen kann.

@Johann L.: Es handelt sich dabei um einen Selbsttest (von einer ganzen 
Reihe) den Sicherheitssteuerungen während des Betriebes ausführen müssen 
um die korrekte Funktion des µC sicher zu stellen.

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


Lesenswert?

Klaus wrote:

> Frage: Was spricht gegen die Benutzung des Inlineassemblers?

Alles.

> Damit
> dürfte das ganze doch wesentlich einfacher sein, oder?

Nein, es wird um eine Größenordnung komplizierter.  Wenn du's nicht
glaubst, dann versuche einfach mal den obenstehenden Quelltext darin
umzuformen und poste ihn hier.

Der Inline-Assembler ist extrem stark mit dem Compiler verzahnt.  Das
macht ihn einerseits zu einem sehr mächtigen Werkzeug für den
erfahrenen Anwender und vor allem für die Autoren der Systembiblio-
thek(en), da man letztlich Assemblercode einbinden lassen kann, der
sich nahtlos in die Optimierungskonzepte des Compilers integriert.
Andererseits ist die Lernkurve, die man dafür auf sich nimmt, doch
recht steil, und der resultierende Codeschnipsel oftmal nahezu
unleserlich.

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


Lesenswert?

Max K. wrote:

> eine andere frage: warum gibt mir der befehl:
>
>
1
> PPR_RET:    LDI   ZH, hi8(PPR_RET1)
2
>         LDI   ZL, lo8(PPR_RET1)
3
>         PUSH   ZL
4
>         PUSH   ZH
5
>         RET
6
>
> einen falschen Wert für was Label PPR_RET1 zurück? er springt an einen
> völlig falsche Stelle, warum?

Weil du die um ein Bit verschobene Adressierung zwischen dem Flash-ROM
als Quelle von Daten und dem Flash-ROM als Quelle von Code-Zeigern
nicht berücksichtigt hast.

Was diese Verrenkungen allerdings überhaupt bezwecken sollen, vermag
ich mir nicht vorzustellen.  Du hast nur gerade bemerkt, dass das
offenbar zur Gruppe von "101 ways how to shoot into your foot" gehört.

von Peter D. (peda)


Lesenswert?

Wer denkt sich denn überhaupt solche unsinnigen Tests aus?
Das muß ein Beamter gewesen sein, der noch nie nen MC gesehen hat.
Hast Du mal nen Link darauf?


Der Test, ob PUSH/POP funktioniert, sagt nämlich überhaupt nichts über 
die Gesundheit des Programms aus.

Du mußt testen, ob der Stackpointer auf einen gültigen Wert zeigt, d.h. 
zwischen "__bss_end" und "__stack".
Und dann noch, ob im Stack eine genügend große Reserve nicht 
unterschritten wurde (Stack mit Muster füllen und prüfen, wieviel Bytes 
mit dem Muster noch übrig sind).

Dieser Test würde wenigstens etwas Sinn machen und braucht auch kein 
Assembler.


Peter

von Max  . (ueps)


Lesenswert?

die tests findet man in einer publikation des BGIAs, genauer gesagt im 
Report7 2006, welcher sich auf der Webseite des BGIAs befindet (diese 
ist am einfachsten über www.dguv.de zu erreichen).

Der direkte Link ist hier: 
http://www.dguv.de/bgia/de/pub/rep/rep05/bgia0706/index.jsp


>Weil du die um ein Bit verschobene Adressierung zwischen dem Flash-ROM
>als Quelle von Daten und dem Flash-ROM als Quelle von Code-Zeigern
>nicht berücksichtigt hast.

Damit ich bei solchen Sachen nicht immer Fragen muss, wie man das am 
besten löst, gibts ein geeignetes Tutorial, was mir solche Sachen 
genauer erklärt?

habe meine Lösung von hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack

Dort steht genau das beschrieben, was ich in meinem Code auch mache.
1
  ldi ZH, high(testRoutine)
2
  ldi ZL, low(testRoutine)
3
  rcall indirectZCall
4
  ...
5
 
6
 
7
indirectZCall:
8
  push ZL
9
  push ZH
10
  ret

was ja auch im reinen assembler-code unter avrstudio wunderbar 
funktioniert hat.

es gibt noch eine weitere frage die mir unter den fingernägeln brennt, 
da ich diese probleme auch bestimmt in meine abschlussarbeit aufnehmen 
werde: worin unterschreidet sich denn nun genau der reine assembler von 
dem wie ich ihn verwende (quasi die linkung zum projekt)? Müsste er 
nicht theoretisch die gleichen Befehle unterstützen wie der reine?
Warum ist InlineASM so grundlegend anders? Warum ist es bei dieser Art 
nicht möglich eine Datei mit den Definitionen anzugeben damit man auf 
den gleichen Befehlssatz zurück greifen kann?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ich versteh das Programm immer noch net.

Es wär wohl angebracht, sich über den Sinn des Programms zu unterhalten, 
was es machen sollte und nicht, anstatt darüber, wie man Syntaxfehler in 
einem unsinnigen Programm behebt...

Falls getestet werden soll, ob aufm Stack noch Platz ist, bzw wieviel 
Speicher noch frei ist, mach ich das wie in

http://www.roboternetz.de/wissen/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc#Dynamischer_RAM-Verbrauch

von Max  . (ueps)


Lesenswert?

Das Programm führt mehrere, sehr simple Tests aus.
1. Es wird geprüft ob der Stackpointer bei PUSH korrekt dekrementiert 
wird
2. Es wird geprüft ob der korrekte Wert auf den Stack gepusht wird
3. Es wird geprüft ob der korrekte Wert durch POP vom Stack geholt wird
4. Es wird geprüft ob der Stackpointer bei POP korrekt inkrementiert 
wird
5. Es wird geprüft ob der RET-Befehl korrekt funktioniert (Sprung zur 
Adresse auf Stack)

beachte: Die Stackinitializierung war nur für den Stand-Alone-Test da, 
bei der Implementierung in ein festes Programm (bzw. in eine 
Testroutinenbibliothek) wird dieser Teil natürlich gestrichen!

von Peter D. (peda)


Lesenswert?

Max K. wrote:
> die tests findet man in einer publikation des BGIAs, genauer gesagt im
> Report7 2006, welcher sich auf der Webseite des BGIAs befindet (diese
> ist am einfachsten über www.dguv.de zu erreichen).
>
> Der direkte Link ist hier:
> http://www.dguv.de/bgia/de/pub/rep/rep05/bgia0706/index.jsp

Das beschreibt leider nur, wie mal irgend jemand meinte, seinen 8051 
testen zu müssen.
Es sagt aber überhaupt nichts über die Sinnhaftigkeit und Notwendigkeit 
oder Verbindlichkeit aus.

Insbesondere die Überprüfung aller Maschinebefehle halte ich für äußerst 
fragwürdig. Auch Testsoftware kann nur funktionieren, wenn die Befehle 
funktionieren, sonst ist deren Verhalten unbestimmt.
Liegt ein Hardwaredefekt im MC selber vor, kann diesen nur ein anderer 
funktionsfähiger MC sicher detektieren.

Ein Stummer kann eben nicht sagen, daß er nicht sprechen kann.


Peter

von Max  . (ueps)


Lesenswert?

das wird durch ein redunantes bzw. mehrkanaliges system überprüft in dem 
sich die systeme gegenseitig überprüfen. es geht hier aber explizit um 
die tests eines systems.
ich kann es nur nochmal wiederholen, es ist bestandteil meiner arbeit 
diese tests zu schreiben und auch wenn ihr damit rechthaben könnt, dass 
das testen unsinnig ist (was nicht meine meinung wiederspiegelt), so 
ändert es trotzdem nichts daran, dass ich sie implementieren muss und 
möchte.

von Peter D. (peda)


Lesenswert?

Max K. wrote:
> 5. Es wird geprüft ob der RET-Befehl korrekt funktioniert (Sprung zur
> Adresse auf Stack)

Nö, das wird es eben nicht!

Wenn er nicht an diese Stelle springt, sondern irgendwo anders hin in 
die Applikation hinein, merkt das Testprogramm es ja nicht.
Also ist es vollkommen nutzlos.

Du würdest nur merken, wenn es zufällig genau hinter das RET springt, 
aber das wäre wie ein Sechser im Lotto.


Peter

von Max  . (ueps)


Lesenswert?

er soll ja nicht irgendwo hin springen sondern in PPR_RET1, das macht er 
zur zeit noch nicht und ich habe keine ahnung wie ich das fixen soll.

und wenn er irgendwo anders hinspringt, dann merkst du das spätestens 
dann wenn der watchdog alarm schlägt oder die synchronisation mit dem 
anderen gerät ansteht..

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Max K. wrote:
> das wird durch ein redunantes bzw. mehrkanaliges system überprüft in dem
> sich die systeme gegenseitig überprüfen. es geht hier aber explizit um
> die tests eines systems.
> ich kann es nur nochmal wiederholen, es ist bestandteil meiner arbeit
> diese tests zu schreiben und auch wenn ihr damit rechthaben könnt, dass
> das testen unsinnig ist (was nicht meine meinung wiederspiegelt), so
> ändert es trotzdem nichts daran, dass ich sie implementieren muss und
> möchte.

Sag jetzt bitte nicht, daß ihr SIL-4 Applikationen auf AVR 
implementiert.

Wenn Du fragen zur Syntax von avr-as hast, ist auch avr-gcc eine gute 
Adresse, um Fragen zu stellen.

Folgende Module testen deine indirekten Sprünge ohne Assembler. In 
getrennten Modulen separat übersetzen.
1
// Modul 1
2
extern void test_ijmp (void **);
3
4
char i = 0;
5
6
int goto_label()
7
{
8
    test_ijmp (&&L);
9
10
    if (i == 0)
11
        return 0;
12
13
 L:
14
    return 1;
15
}
16
17
// Modul 2
18
extern int goto_label();
19
void test_ijmp (void ** label)
20
{
21
    goto *label;
22
}
23
24
int main()
25
{
26
    if (!goto_label())
27
        abort();
28
29
    exit (1);
30
31
    return 0;
32
}

Wie man die Adresse eines Labes nimmt, siehst du in der gcc-Ausgabe 
(schau in die gcc-Ausgabe an, nicht irgendein Disassemble oder ein 
as-Dump) zu Modul 2.

Entsprechende Vorlagen kannst Du fü die anderen Testfälle erhalten.

von Helmut L. (helmi1)


Lesenswert?

>er soll ja nicht irgendwo hin springen sondern in PPR_RET1, das macht er
>zur zeit noch nicht und ich habe keine ahnung wie ich das fixen soll.

Versuchs mal so:

PPR_RET:    LDI   ZH, HIGH(PPR_RET1>>1)
            LDI   ZL, LOW(PPR_RET1>>1)

Gruss Helmi

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nein.

Rumraten bringt doch nix...
1
ZL = 30
2
ZH = 31
3
    ...
4
    ldi ZL, lo8(pm(PPR_RET1))
5
    ldi ZH, hi8(pm(PPR_RET1))
6
    ...

von Max  . (ueps)


Lesenswert?

vielen dank johann, das funktioniert. allerdings würde ich auch gerne 
verstehen warum dem so ist. vielleicht hast du ja eine gute quelle wo 
ich das nachvollziehen kann.

im groben gesagt: wir wollen damit kein steuerungssystem aufbauen, es 
geht um die erforschung des verhaltens von homogen-redundanten systemen. 
dazu schien uns einfach ein system aus zwei einfach zu programmierenden 
AVR-Controllern geeignet. nichtsdestotrotz wollen wir realistische 
bedingungen haben und implementieren daher alle notwendigen 
softwarestücke.

von gast (Gast)


Lesenswert?

Lies die oben gennanten Links endlich.

Dann wirst du irgendwann feststellen dass der AVR einer Harvard 
Architektur hat.
D.h. Flash und Ram beginnen jeweils bei addresse 0

Dem Compiler muss man deshalb sagen welchen speicher man will.

--> obengennantelinks lesen ;-)

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


Lesenswert?

Max K. wrote:

> Das Programm führt mehrere, sehr simple Tests aus.

Ich halte das alles für extrem theoretisch.  Gibt es eigentlich
Hinweise darauf, dass es jemals auch nur einen einzigen Fall von
kaputter CPU gegeben hätte, bei der diese Tests einen tatsächlich
existierenden Fehler aufgedeckt haben, obwohl ansonsten die CPU
noch in der Lage war, die ihr aufgetragenen Befehle abzuarbeiten?
Das kann ich mir nicht vorstellen.  Wenn eine CPU so kaputt ist, dass
sie diese primitiven Dinge nicht mehr ausführen kann, warum sollte
sie dann noch in der Lage sein, die entsprechenden Befehle überhaupt
auszuführen?

Was ich mir vorstellen kann, ist dass ein Prozessor mit externem
RAM Probleme in der Verbindung zwischen CPU und RAM hat.  Aber
erstens hat er dann wohl auch externen ROM, zu dem er mit wenigstens
gleicher Wahrscheinlichkeit Verbindungsprobleme hat (ergo den
eigentlich implementierten Code nicht mehr richtig rückliest und
daher sowieso nur noch Unsinn ausführt), und zweitens testet man
einen RAM nicht, indem man gezielt immmer nur das gleiche Bitmuster
schreibt.  Die Wahrscheinlichkeit, dass der RAM dennoch kaputt ist,
ist dann immer noch ziemlich groß.

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


Lesenswert?

Max K. wrote:

> worin unterschreidet sich denn nun genau der reine assembler von
> dem wie ich ihn verwende (quasi die linkung zum projekt)?

Was ist der ,,reine'' Assembler?  Hat der sich gewaschen? :-)

Oder meinst du den eher primitiven Atmel-Assembler im Vergleich
zum GNU-Assembler, der beim GCC mit geliefert wird?

> Müsste er
> nicht theoretisch die gleichen Befehle unterstützen wie der reine?

Der GNU-Assembler (gas) für den AVR unterstützt ja auch die gleichen
Befehle wie der Atmel-Assembler.  Er unterstützt nur nicht die
gleichen Pseudo-Befehle, und die Definition der IO-Register in
den Include-Dateien ist bei der avr-libc primär auf die Benutzung
im C-Code ausgerichtet, sodass man für die Benutzung im Assemblercode
dieses Einschließen in _SFR_IO_ADDR() machen muss.  (Alterantive
Varianten, die ohne diese Maßnahme auskommen, stehen in der Doku
zur avr-libc.)

> Warum ist InlineASM so grundlegend anders?

Weil der Inline-Assembler, wie schon beschrieben, als Ergänzung
für den Compiler realisiert ist, um dem geübten Anwender oder dem
Lieferanten der Systembibliothek ein möglichst universelles
Werkzeug in die Hand geben zu können, mit dem er allerlei Sonder-
funktionen seiner Umgebung in den C-Code integrieren kann, ohne
dabei den Optimierungsschritten des Compilers übermäßig im Weg herum
zu stehen.  Dies geschieht, indem man nicht irgendwo stur auf den
Hardwareregister herum opert, wobei dem Compiler dann nichts anderes
übrig bleibt, als sie für den geneigten Inline-Assembler-Hacker
passend frei zu schaufeln, sondern man drückt seine Daten stattdessen
mit den gleichen sogenannten constraints aus, die der Compiler
intern ohnehin verwendet.  Auf den AVR bezogen sagt man also
beispielsweise nicht: ,,Lieber Compiler, der Code hier befummelt
Register r22 und gibt sein Ergebnis in r24 aus, nun kümmere dich
mal!'', sondern man sagt: ,,Lieber Compiler, lege mir die Variable
für mein Zwischenergebnis an, wobei ich sie in einem der Register
oberhalb r16 benötige (nach dem Ende des inline asm statements
gehört die Variable dann wieder dir für beliebige Zwecke einschließ-
lich der geflissentlichen Entsorgung), und gib mir eine beliebige
Registervariable für mein Rechenergebnis, aus der du das dann gleich
1:1 weiter benutzen kannst.''

> Warum ist es bei dieser Art
> nicht möglich eine Datei mit den Definitionen anzugeben damit man auf
> den gleichen Befehlssatz zurück greifen kann?

Die Befehle sind die gleichen!  Was nicht symbolisch direkt
zugreifbar ist, sind die Namen der IO-Register.  Das liegt einfach
daran, dass diese in einem C-Programm vom Präprozessor durch
relativ umständlich anmutende Konstrukte ersetzt werden (Dereferen-
zieren eines Zeigers auf ein "volatile" ausgewiesenes uint8_t-Objekt),
denn es muss ja syntaktisch irgendwo in C hineinpassen.  Damit sind
sie aber im inline-Assembler nicht mehr symbolisch verfügbar.  Man
kann sie trotzdem symbolisch in das inline asm statement hineinfüttern,
aber halt über den Umweg eines constraints ("I" in diesem Falle).
Das wiederum sieht dann alles zusammen doch viel unlesbarer aus, als
wenn man gleich das direkte Assemblerprogramm nimmt.

von Peter D. (peda)


Lesenswert?

Max K. wrote:
> und wenn er irgendwo anders hinspringt, dann merkst du das spätestens
> dann wenn der watchdog alarm schlägt oder die synchronisation mit dem
> anderen gerät ansteht..

Du stimmst mir also zu, daß das Testprogramm selber nicht merkt, wenn er 
woanders hin springt.
D.h. nicht das Testprogramm bemerkt den fehlerhaften Ablauf, sondern 
(eventuell) der Watchdog.
Damit ist doch klar das Testprogramm als völlig nutzlos und überflüssig 
erkannt. Wozu also diese Mühe?


Ob das Testprogramm bei fehlerfreier CPU funktioniert, interessiert 
keinen.
Es ist nur dann funktional, wenn es den fehlerhaften Zustand eindeutig 
erkennt oder wenigstens in den meisten Fällen. Und das schafft dieses 
Testprogramm eben nicht, also ist es überflüssig.

Ich bezweifle auch stark, ob man überhaupt ein Testprogramm schreiben 
kann, welches einen Defekt der eigenen CPU erkennt.


Ein CPU-Defekt kann bewirken:
1. daß ein Befehl falsch dekodiert wird und z.B. als 2Word-Befehl 
ausgeführt wird.
2. ein Befehl auf falsche Adressen, Register ausgeführt wird
3. ein Befehl mit falschen Werten ausgeführt wird
4. Ein Befehl falsch ausgeführt wird (z.B. Flags falsch setzt).
Und nun frage ich Dich, ob Dein Testprogramm diese Fehlerarten alle 
erkennen kann.


Ein ernsthafter Testansatz wäre, daß ein zweiter MC den ersten per JTAG 
in den Debug-Modus versetzt, eine Testsuite ausführt und dann per 
Memory- und Registerdump überprüft, ob diese Testsuite einwandfrei 
ausgeführt wurde.
Wobei allein das Erstellen der Testsuite schon anspruchsvoll genug ist.


Peter


P.S.:
Das richtige Erstellen einer funktionierenden Watchdogroutine ist auch 
keine leichte Aufgabe.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

gast wrote:

> Dann wirst du irgendwann feststellen dass der AVR einer Harvard
> Architektur hat.
> D.h. Flash und Ram beginnen jeweils bei addresse 0
>
> Dem Compiler muss man deshalb sagen welchen speicher man will.

Nein.

Hier geht es nicht um einen Compiler, sondern um einen Assembler ;-)

Daß AVR eine Hardvard-Architektur ist, spielt hier ausnahmnweise mal 
keine Rolle. Was jedoch wichtig ist, ist wie ein Symbol verwendet 
wird. CALL legt nämlich nicht die Byte-Adresse eines Symbols auf den 
Stapel, sondern die Wort-Adresse. lo8(pm()) fügt andere RELOCs ein als 
lo8(). Obwohl mit LPM zu lesende Daten auch im Flash stehen, benutzt LPM 
ne andere Darstellung als CALL/IJMP/RET/RTI. Wenn ich mich recht 
erinnere ist das RTI-Format auch anders als das von RET.

lo8(main>>1) funktioniert übrigens nicht, weil es dafür keine RELOCs 
gibt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Max K. wrote:
>
> Ich halte das alles für extrem theoretisch.  Gibt es eigentlich
> Hinweise darauf, dass es jemals auch nur einen einzigen Fall von
> kaputter CPU gegeben hätte, bei der diese Tests einen tatsächlich
> existierenden Fehler aufgedeckt haben, obwohl ansonsten die CPU
> noch in der Lage war, die ihr aufgetragenen Befehle abzuarbeiten?
> Das kann ich mir nicht vorstellen.  Wenn eine CPU so kaputt ist, dass
> sie diese primitiven Dinge nicht mehr ausführen kann, warum sollte
> sie dann noch in der Lage sein, die entsprechenden Befehle überhaupt
> auszuführen?

Ich sag mal so: Die AVR-Gemeinde ist gesegnet mir einem µC, der 
praktisch bugfrei ist und sich schlichtweg nicht mit dem Thema 
Silicon-Bugs auseinandersetzen muss. Aber schau mal, was unter der Haube 
Deines KFZ' tickt: vermutlich u.a. ein TriCore.

Ohne Compiler/Assembler/Linker, die die Armada an Silicon-Bugs 
umschiffen, könnst den SI-Käfer in die Tonne treten.

Die Errata sind mehrere 100 Seiten dick, dazu im Vergleich hat AVR 
maximal eine A4-Seite zu bieten. Da sind so Leckerli dabei, daß mache 
Arithmetikbefehle nicht funzen, das PSW falsch gesetzt wird, hier und da 
mal ein Trap erzeugt wird, Sprünge falsch ausgeführt werden oder falsche 
Ergebnisse aus dem Speicher gelesen werden, wenn dort zu viele Bits der 
gleichen Sorte stehen (Busleitung zu dünn ausgelegt).

Gleichwohl bin ich Deiner Auffassung, daß solche Tests zu einer Erhöhung 
der Sicherheit nichts beitragen. Sie erhöhen eher das Risiko einer 
abschmierenden Applikation durch unsauber imlementierte Tests. Errate 
auf dem einen Exemplar verhalten sich vermutlich ebenso wie auf dem 
anderen, und sporadische Fehler kann man weder aussschliessen, noch 
bietet AVR Sicherheitskonzepte wie unterschiedliche Benutzerprioritäten 
oder ein MPU (Memory Protection Unit).

Was AVR-Errata angeht, dürften zwei gleiche AVRs (das System ist homogen 
ausgelegt) bei

http://sourceforge.net/tracker/index.php?func=detail&aid=2264356&group_id=68108&atid=520074

ununterscheidbar reagieren.

von Max  . (ueps)


Lesenswert?

Guten Morgen,

danke für eure Anregungen. Ich kann eure Ansichten nachvollziehen, da 
ich in gewissem Maße auch der Meinung bin, dass manche Tests so gesehen 
keinen Sinn ergeben. Jedoch wurden am BGIA einige Nachforschungen 
angestellt um diese Tests zu erstellen, daher werden diese nicht 
komplett sinnlos sein.
Ich kann nur betonen, dass es nicht meine Aufgabe ist denn Sinn dieser 
Tests zu belegen oder zu widerlegen, sie sind ein bestandteil der 
Software, also meines Programms, welches ich auf den µC implementieren 
werde.
Dies ist durch die Spezifikation meiner Abschlussarbeit festgehalten.

Ein nettes "Feature" von den Selbsttests ist aber, dass ich mich mit 
Assembler beschäftige, was mich irgendwie fasziniert. Ich habe bis jetzt 
nur mit hochsprachen ala Java etc. gewerkelt und steige gerade zum 
ersten mal in die Programmierung eines µC ein. Auch den AVR habe ich 
zuerst mit C bearbeitet und so ein Programm zur Synchronisation 
geschrieben. Jedoch sah ich mich nicht in der Lage die hardwarenahen 
Tests in dieser Sprache zu implementieren. Sogesehen sind die Tests 
nicht ganz ohne Nutzen.

Außerdem seht ihr nur einen der vielen Tests aus dem Report. Da der 
Report öffentlich ist könnt ihr ihn euch alle gerne anschauen (Link 
weiter oben) und dann über die sinnhaftigkeit der Tests im einzelnen 
sprechen. Ich bin mir sicher, dass meine Kollegen und meine Vorgesetzen 
für Anmerkungen und Hinweise bezüglich dieser Tests dankbar sein werden. 
Kontaktadressen findet ihr ebenso auf der Seiten oben.

@Jörg: Natürlich mein ich den ATMEL und den GCC-Assembler, wie gesagt 
die definierung meiner Probleme fällt mir manchmal ein wenig schwer, da 
ich den Überblick über die verschiedenen "Assembler"-Arten (wenn man es 
so nennen darf) verliere. Das Problem habe ich auch wenn ich mir 
tutorials anschaue. Ich kann leider oft nicht ersehen zu welcher Art das 
Tutorial nun gehört.

Ich werde mich nun nochmal genauer mit dem GCC-Assembler auseinander 
setzen, da es scheinbar dieser sein wird, mit welchem ich arbeiten 
werde. Dies scheint mir die einfachste Lösung für meine Probleme zu 
sein.

von Peter D. (peda)


Lesenswert?

Max K. wrote:
> Jedoch wurden am BGIA einige Nachforschungen
> angestellt um diese Tests zu erstellen, daher werden diese nicht
> komplett sinnlos sein.

Das jemand irgendwas macht, begründet in keinster Weise die 
Sinnhaftigkeit seine Tuns.
Sei mir nicht böse, aber auf mich macht der oben verlinkte Artikel einen 
sehr laienhaften Eindruck. Nirgends wird auf die Fehlerhäufigkeit oder 
die Erkennungssicherheit eingegangen.



> Ich kann nur betonen, dass es nicht meine Aufgabe ist denn Sinn dieser
> Tests zu belegen oder zu widerlegen, sie sind ein bestandteil der
> Software, also meines Programms, welches ich auf den µC implementieren
> werde.
> Dies ist durch die Spezifikation meiner Abschlussarbeit festgehalten.

Das ist Vogel-Strauß-Politik (Augen zu und durch):
Ich bastele einfach irgendwelche Tests rein und dann wird das ganze 
schon (hoffentlich) sicher sein.
Damit wird sich keine Stelle, die eine SIL-Klassifizierung vornehmen 
soll, zufrieden geben.

Du mußt erstmal überlegen, welche Fehlerquellen haben welche Signifikanz 
und dann mußt Du das auch an konkreten Zahlen nachweisen.
Und dann erst kannst Du darangehen, die mit hoher Signifikanz als erstes 
zu lösen.
Fehlfunktionen der CPU werden dabei an allerletzter Stelle stehen.
Und wenn, dann werden sie zu 99% Folgefehler sein (Fehler in der 
Stromversorgung, Entkopplung, Kühlung usw.).



Peter

von Max  . (ueps)


Lesenswert?

was heißt den vogel-strauß poliktik? Ich habe nicht die Aufgabe ein 
absolut sicheres system aufzubauen. Meine aufgabe ist eben ein system 
mit aktuellen sicherheitsmaßnahmen auszustatten. genau das werde ich 
machen, auch wenn es in euren (und zum teil in meien augen) keinen 
richtigen sinn hat. ich bin davon überzeugt, dass die arbeiten und 
reports keineswegs laienhaft erstellt wurden.
aber selbst wenn, meine anweisung (bzw. die definition in der 
spezifikation) steht und ich kann und möchte nicht davon abweichen, da 
alles andere einen erfolg meiner abschlußarbeit gefährden würde!

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


Lesenswert?

Max K. wrote:

> aber selbst wenn, meine anweisung (bzw. die definition in der
> spezifikation) steht und ich kann und möchte nicht davon abweichen, da
> alles andere einen erfolg meiner abschlußarbeit gefährden würde!

Was für eine Art von Arbeit ist das denn?  Vielleicht kannst du ja die
durchaus begründeten Zweifel (ich stimme hier mit Peter komplett
überein) wenigstens in einer Art Schlussbetrachtung oder Thesen oder
dergleichen anbringen?  Bei einer wissenschaftlichen Arbeit sollte
ja die Benotung nun nicht davon abhängen, ob der Inhalt komplett die
(u. U. halt fehlerhaften) Erwartungen der Aufgabenstellung stützt
oder aber sie sauber widerlegt, solange die Beweisführung schlüssig
ist.

von Max  . (ueps)


Lesenswert?

Jörg Wunsch wrote:
> Max K. wrote:
>
>> aber selbst wenn, meine anweisung (bzw. die definition in der
>> spezifikation) steht und ich kann und möchte nicht davon abweichen, da
>> alles andere einen erfolg meiner abschlußarbeit gefährden würde!
>
> Was für eine Art von Arbeit ist das denn?  Vielleicht kannst du ja die
> durchaus begründeten Zweifel (ich stimme hier mit Peter komplett
> überein) wenigstens in einer Art Schlussbetrachtung oder Thesen oder
> dergleichen anbringen?  Bei einer wissenschaftlichen Arbeit sollte
> ja die Benotung nun nicht davon abhängen, ob der Inhalt komplett die
> (u. U. halt fehlerhaften) Erwartungen der Aufgabenstellung stützt
> oder aber sie sauber widerlegt, solange die Beweisführung schlüssig
> ist.

Möglich ist ein aufgreifen während des Resumee, allerdings darf ich 
nicht einfach die hälfte der Tests weglassen mit der Begründung "Bringt 
eh nichts"..
Es handelt sich hierbei um eine Bachelor-Abschlussarbeit, somit liegst 
du mit wissenschaftlich schon richtig.

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


Lesenswert?

Max K. wrote:

> Möglich ist ein aufgreifen während des Resumee, allerdings darf ich
> nicht einfach die hälfte der Tests weglassen mit der Begründung "Bringt
> eh nichts"..

Es wäre ja eher darum gegangen, sie durch sinnvollere Tests zu
ersetzen, nachdem man demonstriert, dass sie in der ursprünglich
gedachten Form sowieso zwecklos sind.

von Max  . (ueps)


Lesenswert?

wie gesagt, es hat seinen grund warum diese tests gewählt worden sind, 
daran wird sich nichts ändern. es würde auch den rahmen einer 3monatigen 
bachelor-arbeit sprengen wenn ich jetzt neben dem system noch die 
selbsttests erstellen müsste, das könnte man vielleicht im rahmen einer 
master-thesis (knapp 1 jahr mit vorhergehenden praktika) machen aber so 
ist das schlicht und einfach zuviel.
ich danke euch für eure hilfe mit assembler, bitte euch jedoch nun das 
thema mit dem selbsttests ruhen zu lassen, da ich da eh nichts dran 
ändern kann / werde. Sollt ihr euch trotzdem noch dazu gezwungen fühlen 
dort was zu verändern, ihr findet die adressen zu den verantwortlichen 
leuten alle auf der öffentlichen DGUV respektive BGIA-Seite (links sind 
schon weiter oben vorhanden).

In diesem Sinne: Danke euch, ihr habt toll geholfen, sollte noch was 
sein werde ich mich melden aber bitte keine diskussion über sinn und 
unsinn der selftests.. ;)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Max K. wrote:
> Guten Morgen,
>
> danke für eure Anregungen. Ich kann eure Ansichten nachvollziehen, da
> ich in gewissem Maße auch der Meinung bin, dass manche Tests so gesehen
> keinen Sinn ergeben. Jedoch wurden am BGIA einige Nachforschungen
> angestellt um diese Tests zu erstellen, daher werden diese nicht
> komplett sinnlos sein.

Immerhin haben die Tests ne psychologische Funktion:

Sie geben dem, der so ein System baut/beauftragt, das Gefühl und die 
Beruhigung, was für die Sicherheit getan zu haben und einer Spez gefolgt 
zu sein.

Zu deiner Arbeit:

Wenn du solche Tests implementierst, dann ist der WDT nicht gut 
geeignet, um Instruktionen wie zB RET zu testet. Der WDT ist einfach zu 
ungenau. Wenn ein RET in die Hose geht, passieren danach noch 1000 
andere Instruktionen.

Also: Nicht den WDT nehmen, sondern eine Timer-IRQ, die auf genau so 
viele Ticks getrimmt wird, wie bis zum Abarbeiten des RET erwartet 
werden. Nach dem RET schlägt die IRQ zu, und in dieser liest du (bzw. 
lässt den AVR lesen) den Inhalt des gepushten PC vom Stack und 
vergleichst ihn mit der erwarteten Adresse. Falls ein RET nicht 
funktioniert, ist damit die Nebenwirkung auf das System minimiert (ein 
funktionierendes IRQ-System setzt auch der WDT-Ansatz voraus).

Zu einer Arbeit gehört auch deren Verortung in Raum und Zeit, und in der 
Einleitung und/oder Zusammenfassung gehört auf jeden Fall ein Wort zum 
Stand der Kunst. WDT, Checksummen auf Speicher, etc. und was das Design 
zeitgemässer Systeme angeht. Im Zweifelsfalle in die SIL reinschauen 
oder welche Sicherheitsaspekte Betriebsysteme wie pxros-hr bringen, die 
Speicherschutz und Kapselung/Rückwirkungsfreiheit von Komponenten auf 
Harwareebene garantieren.

von Peter D. (peda)


Lesenswert?

Max K. wrote:
> wie gesagt, es hat seinen grund warum diese tests gewählt worden sind,
> daran wird sich nichts ändern. es würde auch den rahmen einer 3monatigen
> bachelor-arbeit sprengen wenn ich jetzt neben dem system noch die
> selbsttests erstellen müsste

Da hast Du natürlich recht, daß die Anforderungen an eine reale 
Produktentwicklung nicht mehr im Rahmen einer Studienarbeit liegen.

Es sollte Deine Arbeit also nicht beeinflussen, sondern nur mal ein 
Denkanstoß über den Tellerrand hinaus gewesen sein.
Und 2-3 abschließende Sätze in dieser Richtung würden eine sehr gute 
Arbeit auszeichnen.


Der Lösungsansatz von Johann bezüglich des RET-Tests ist gut.

Man könnte es sogar dahingehend optimieren, indem man einen Interrupt 
nimmt, der nicht gebraucht wird, aber ständig getriggert ist, der 
SPM_READY_vect ist ideal.
Und dann unmittelbar vor dem RET ein SEI machen, damit landest Du direkt 
nach dem RET im Interrupt und ein RET in den Wald kann keinen Schaden 
anrichten.

Bei den Rechentests ist zu beachten, daß der AVR keinen ACCU hat, d.h 
zumindest eine Operation muß für alle 32 Register getestet werden.
Und natürlich muß nach jedem Rechentest nicht nur das Ergebnis, sondern 
auch alle beeinflußten Flags (SREG) überprüft werden. Die Flags sollten 
dazu vorher auf den "falschen" Wert gesetzt werden.


Peter

von Max  . (ueps)


Lesenswert?

Hab noch eine kleine Frage hinter die ich leider nicht von alleine 
komme.
Habe jetzt ne ganze Zeit lang wunderbar gearbeitet, jetzt habe ich 
allerdings mein WinAVR geupdatet, da ich einen Bug mit.. ach ich weiß 
nicht genau was es war, jedenfalls war es notwendig, dass ich meine 
Version update.

Nun compiliert er nichtmehr sauber, bzw. er bricht ab mit folgender 
meldung:
1
inking: Blinky.elf
2
avr-gcc -mmcu=atmega169 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Blinky.o  -std=gnu99 -Wp,-M,-MP,-MT,Blinky.o,-MF,.dep/Blinky.elf.d Blinky.o PPR_TEST.o REG_TEST.o ARI_TEST.o LOGI_TEST.o BITLOGI_TEST.o TRAN_TEST.o  --output Blinky.elf -Wl,-Map=Blinky.map,--cref  -lm
3
4
Creating load file for Flash: Blinky.hex
5
avr-objcopy -O ihex -R .eeprom Blinky.elf Blinky.hex
6
7
Creating load file for EEPROM: Blinky.eep
8
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
9
  --change-section-lma .eeprom=0 -O ihex Blinky.elf Blinky.eep
10
c:\WinAVR-20080610\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used

ich habe nun gelesen, dass dies passiert falls man den "eeprom nicht 
nutzt". Man soll darum im makefile einfach eine stelle ändern, was bei 
mir aber schon so der fall ist:
1
%.eep: %.elf
2
  @echo
3
  @echo $(MSG_EEPROM) $@
4
  -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
5
  --change-section-lma .eeprom=0 -O $(FORMAT) $< $@

ich bin ein wenig ratlos, was ich nun noch ändern kann. vielleicht hat 
jemand einen kleinen tipp?

danke euch!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

@ Max K.

> Nun compiliert er nicht mehr sauber, bzw. er bricht ab mit
> folgender Meldung:

Wie ist die komplette Meldung?
Es fehlt oben der letzte, entscheidende Satz.
Bei der gezeigten Meldung ist alles noch normal.

von Max  . (ueps)


Lesenswert?

1
> "make.exe" all
2
3
-------- begin --------
4
avr-gcc (WinAVR 20080610) 4.3.0
5
Copyright (C) 2008 Free Software Foundation, Inc.
6
This is free software; see the source for copying conditions.  There is NO
7
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8
9
10
Compiling: Blinky.c
11
avr-gcc -c -mmcu=atmega169 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Blinky.lst  -std=gnu99 -Wp,-M,-MP,-MT,Blinky.o,-MF,.dep/Blinky.o.d Blinky.c -o Blinky.o
12
13
Assembling: PPR_TEST.S
14
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=PPR_TEST.lst,-gstabs  PPR_TEST.S -o PPR_TEST.o
15
16
Assembling: REG_TEST.S
17
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=REG_TEST.lst,-gstabs  REG_TEST.S -o REG_TEST.o
18
19
Assembling: ARI_TEST.S
20
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=ARI_TEST.lst,-gstabs  ARI_TEST.S -o ARI_TEST.o
21
22
Assembling: LOGI_TEST.S
23
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=LOGI_TEST.lst,-gstabs  LOGI_TEST.S -o LOGI_TEST.o
24
25
Assembling: BITLOGI_TEST.S
26
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=BITLOGI_TEST.lst,-gstabs  BITLOGI_TEST.S -o BITLOGI_TEST.o
27
28
Assembling: TRAN_TEST.S
29
avr-gcc -c -mmcu=atmega169 -I. -x assembler-with-cpp -Wa,-adhlns=TRAN_TEST.lst,-gstabs  TRAN_TEST.S -o TRAN_TEST.o
30
31
Linking: Blinky.elf
32
avr-gcc -mmcu=atmega169 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Blinky.o  -std=gnu99 -Wp,-M,-MP,-MT,Blinky.o,-MF,.dep/Blinky.elf.d Blinky.o PPR_TEST.o REG_TEST.o ARI_TEST.o LOGI_TEST.o BITLOGI_TEST.o TRAN_TEST.o  --output Blinky.elf -Wl,-Map=Blinky.map,--cref  -lm
33
34
Creating load file for Flash: Blinky.hex
35
avr-objcopy -O ihex -R .eeprom Blinky.elf Blinky.hex
36
37
Creating load file for EEPROM: Blinky.eep
38
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
39
  --change-section-lma .eeprom=0 -O ihex Blinky.elf Blinky.eep
40
c:\WinAVR-20080610\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
41
42
Creating Extended Listing: Blinky.lss
43
avr-objdump -h -S Blinky.elf > Blinky.lss
44
45
Creating Symbol Table: Blinky.sym
46
avr-nm -n Blinky.elf > Blinky.sym
47
48
Size after:
49
Blinky.elf  :
50
section            size   addr
51
.text              2338      0
52
.stab             10608      0
53
.stabstr            349      0
54
.debug_aranges       32      0
55
.debug_pubnames      27      0
56
.debug_info         142      0
57
.debug_abbrev        80      0
58
.debug_line         549      0
59
.debug_frame         32      0
60
.debug_str          109      0
61
Total             14266
62
63
64
65
Errors: none
66
-------- end --------
67
68
69
> Process Exit Code: 0
70
> Time Taken: 00:01

makefile siehe oben, angepasst mit den entsprechenden dateien, lief bis 
vor dem update wunderbar..

edit: was ich mit "lief" genau meinte ist, dass ich das programm im 
AVR-Studio wunderbar benutzen konnte. Jetzt aber included er die 
Assembler-Programme nichtmehr und führt nurnoch den C-Teil aus. Der 
Assemblerteil ist im AVR-Studio nicht zu sehen (weder in C-Ansicht, dort 
sind die Funktionsaufrufe einfach weg, als auch im dissasembly, dort 
springt er nach dem letzten befehl in eine schleife aus delay_basic 
(woher die kommt weiß ich nicht) und anschließend wieder zum anfang!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hmm, ich sehe nichts auffällig Falsches in dem Ausgabeprotokoll des 
Makes.

Vielleicht mal das Projekt in ein Archiv packen und als Anhang posten. 
Vielelicht kann jemand das live mit seinem WinAVR 20080610 
nachvollziehen, wenn er in die Listings schauen kann.

von Jörg G. (joergderxte)


Lesenswert?

Bei mir (mit winavr20071221, auch .eep-gepatcht) sieht das im 
(mfile-)Makefile aber so aus:
1
%.eep: %.elf
2
  @echo
3
  @echo $(MSG_EEPROM) $@
4
  -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
5
  --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
(mit "--no-change-warnings" und "|| exit 0 ")

hth. Jörg

von Max  . (ueps)


Lesenswert?

ich verstehe gerade die welt nichtmehr.. ich habe jetzt zum bestimmt 
10en mal die datei kompiliert und bei avr-studio neu geladen. jetzt geht 
es auf einmal. ich bin mir relativ sicher nichts geändert zu haben, auch 
die make-ausgabe sieht wieder genau so aus. jetzt sind aber die 
selbsttests da.

sehr komisch, ich glaube es ist zeit für ein wochenende.. trotzdem danke 
euch ;)

achja, kann ich mit
1
CALL XY

die methode
1
void XY(){ bla }
 aufrufen?

die methode XY liegt in einer anderen, dem projekt angehörigen datei. 
geht das so einfach oder muss ich in die .S datei noch was hinzufügen? 
(bsp. wie header-datei von der *.c datei in welcher XY drin ist?)

von Max  . (ueps)


Lesenswert?

komisch, kann meinen beitrag nicht bearbeiten.. whatever: das habe ich 
schon selber rausgefunden ;) trotzdem danke!

von Stefan E. (sternst)


Lesenswert?

Max K. wrote:
> komisch, kann meinen beitrag nicht bearbeiten..

Das geht nur eine bestimmte Zeit lang.

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.