Hallo,
ich denke dass ich einfach irgendwas übersehe, aber ich suche jetzt
schon ein paar Stunden und finde den Fehler nicht darum möcht ich gern
jemand Außenstehenden um Hilfe fragen.
Folgendes Problem:
Unten geposteter Code soll irgendwann mal ein Bootloader werden,
momentan versuche ich einfach eine Echoschleife für die USART zu machen
(als Test).
Wenn ich jetzt die Funktion init_uart aufrufe mittels rcall wird diese
ausgeführt und dann springt der PC irgendwohin im Speicher bis der
Prozessor dann wieder resettet und von vorn anfängt. Verhalten konnte
mit AVR Sim und alternativ JTAGICE direkt am Prozessor beobachtet
werden. Schreibe ich die richtige Rücksprungadresse manuell beim
Debuggen in den Speicher, auf den der Stackpointer zeigt, läuft das
Programm tadellos (auch Interruptabarbeitung etc. funktioniert).
Stackpointer hat beim Programmstart den Wert 0x0000 und wenn dann zwei
weggezählt (wg. 2 Byte PC am Stack ablegen, siehe AVR-ISM rcall) werden
kommt natürlich ein Überlauf (dann zeigt er auf 0x0ffe) - das ist das
einzige was mir derzeit komisch erscheint?
1
/*
2
* assBootloader.asm
3
*
4
* Created: 28.01.2012 19:52:00
5
* Author: tbergmueller
6
*/
7
8
.include "m32def.inc"
9
10
.def mp=R16
11
.equ INT_TAB_LENGTH=100 ; Länge der Interrupttabelle (für Tests mal lang genug...)
12
.equ APP_STARTADDR=0 ; Start der Applikation, 0 wegen Debugmöglichkeit, später dann 0x03f00
13
.equ BOOTLOADER_STARTADDR=APP_STARTADDR+INT_TAB_LENGTH ; start der Eigentlichen Bootloadersoftware
14
15
16
.cseg
17
18
.org APP_STARTADDR
19
rjmp main ; reset handler
20
.org URXCaddr+APP_STARTADDR
21
rjmp recByte ; RXC Handler
22
23
24
25
;.org BOOTLOADER_STARTADDR
26
27
main: ;call Move_interrupts
28
rcall init_uart
29
30
; Testweise 8 LED an Port einschalten
31
ldi mp, 0xff
32
out DDRA, mp
33
ldi mp, 0
34
out PORTA, mp
35
36
loop: rjmp loop ; endlosschleife
37
jmp 0 ; start normal (später für Bootloader)
38
39
40
41
; ################### FUNCTIONS
42
init_uart: ldi mp, 0x98 ; load registers
43
out UCSRB, mp ; RXIE enabled, RXEN, TXEN test
44
ldi mp, 103 ; load ubrrl
45
out UBRRL, mp
46
sei
47
ret
48
49
; Interrupthandler RXC
50
recByte: in mp, UDR
51
call USART_Transmit
52
53
reti
54
55
; Senden via USART
56
USART_Transmit:
57
sbis UCSRA,UDRE
58
rjmp USART_Transmit
59
60
out UDR,mp
61
ret
62
63
; Interrupts in den Bootloaderbereich verschieben
64
Move_interrupts:
65
; Enable change of interrupt vectors
66
ldi mp, (1<<IVCE)
67
out GICR, mp
68
; Move interrupts to boot Flash section
69
ldi mp, (1<<IVSEL)
70
out GICR, mp
71
ret
Vielen Dank schonmal für die Hilfe und ich mir ist der vermutlich extrem
dumme Fehler jetzt schon peinlich...
Thomas
Wusst ich's doch dass es ein peinlicher Fehler ist...
Dankeschön für die rasche Hilfe! Muss zugeben, hab Assembler das letzte
Mal glaub ich vor 5 Jahren benutzt und das am 8051, da war wurde
StackPtr per default initialisiert, soweit hab ich nicht gedacht.
Hi
>...und das am 8051, da war wurde>StackPtr per default initialisiert, soweit hab ich nicht gedacht.
Ist bei neueren AVR auch so. Der ATMega32 ist halt schon ein
Dinosaurier.
MfG Spess
War der einzige den ich in DIL-Bauform zuhause hatte und am Steckbrett
is doch am Einfachsten JTAG anzuschließen für ein paar schnelle Tests ;)
Aber auf alle Fälle gut zu wissen dass es Controller gibt die das nicht
selbst machen.
Hi
Auch wenn es vielleicht jetzt noch nicht zum tragen kommt, aber ich würd
die ISR so nicht stehen lassen...
1
; Interrupthandler RXC
2
recByte: in mp, UDR
3
call USART_Transmit
4
5
reti
In einer ISR macht es Sinn, grad bei Assembler, verwendete Register zu
sichern. Das Status- als auch das mp-Register kann wichtige Inhalte
haben, die dann u.U. beim Eintreten eines Interrupts futsch sind.
Gruß oldmax
Das Statusregister MUSS bei Interruptroutinen gesichert werden.
Ansonsten gibts schwere Probleme wenn ein Interrupt zwischen einem
Compare und der nachfolgenden Branch-If-Irgendwas-Anweisung auftritt.
Schade daß die Dinger kein PUSHF/POPF können wie die x86...