ASM: Rücksprung aus Funktion fehlerhaft (Mega32)

OP #2544501
Lesenswert?

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
Gast #2545038
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren