8051: Interrupts umbiegen? SDCC

Gast #6419675
Lesenswert?

Hallo,

schreibe gerade einen Bootloader für einen 8051 basierenden prozessor.
Ich verwende SDCC

Nach dem Reset soll immer zunächst der Bootloader laufen, der dann 
gegebenenfalls das flash beschreibt, aber sonst in das Hauptprogramm 
springt. Der Bootloader sitzt daher an Addresse 0x0000. Grund ist, dass 
so selbst im Fall eines Fehlerhaften Updates immer noch der Bootloader 
installiert ist.

Wenn ich nun das Hauptprogramm über --code-loc an Adresse 0x5000 
plaziere und vom Bootloader dort hin springe, läuft das Haupprogramm, 
jedoch nicht dessen Interrupts.
Ich verstehe das so, dass SDCC zwar die Interrupt Tabelle ab 0x5000 
plaziert, jedoch die Hardware beim Interrupt nach wie vor an die 
Originalen Adressen springt. (Also z.B. 0xB für Timer1)

Scheinbar kann man das nicht ändern?

Da ich im Bootloader keine Interrupts verwende, frage ich mich, ob man 
hier nicht direkt Sprünge an die richtige Stelle plazieren kann.
Aber wie würde man so etwas in SDCC bewerkstelligen?

Das Beste was mir dazu eigefallen ist, ist für jeden Interrupt eine 
Funktion der Form
1
void int_uart1(void)  __interrupt (INT_NO_UART1)
2
{
3
    _asm
4
    ljmp 0500B$
5
    _endasm
6
}

Im Bootloader zu platzieren. Nicht getestet, aber scheint mir auch nicht 
die Beste Möglichkeit zu sein. Geht das besser?

Dank
#6419754
Lesenswert?

ben utzer schrieb:
> Scheinbar kann man das nicht ändern?
Nein das kann man nicht ändern. Die Vektoren beginnen immer ab 0x000.

ben utzer schrieb:
> void int_uart1(void)  __interrupt (INT_NO_UART1)
> {
>     _asm
>     ljmp 0500B$
>     _endasm
> }
Das ist die übliche Methode, wobei 0x0b kein uart ist.

Alternativ wenn einzelne Interrupts auch im Loader gebraucht werden kann 
man irq Addresse auch auf den Stack Puschen ein ret startet dann den 
irq.
Diese Lösung braucht dann 2 zusätzliche Bytes in __data die in boot und 
App die gleiche Position haben müssen.
Bevor der interrupt benutzt werden kann müssen diese Bytes mit der 
Addresse der Interruptfunktio geladen werden.
Gast #6419949
Lesenswert?

ben utzer schrieb:
> Scheinbar kann man das nicht ändern?

Das ist ja keine echte Einschränkung, platziert man da einen Jump, kann 
die ISR an beliebiger Stelle stehen.

Konzepte, bei denen man extra programmieren kann, wo die 
Interrupt-Tabelle steht, wie etwa beim Z80, sind demgegenüber nur 
kompliziert und fehleranfällig, fix adressierte Interrupttabellen haben 
sich daher weitgehend durchgesetzt.

Georg
(Firma: Vescomp) #6419985
Lesenswert?

georg schrieb:
> Konzepte, bei denen man extra programmieren kann, wo die
> Interrupt-Tabelle steht, wie etwa beim Z80, sind demgegenüber nur
> kompliziert und fehleranfällig, fix adressierte Interrupttabellen haben

 Ja, aber man könnte dadurch in eigenem Programm die Interrupt-Vektors
 ändern, eigene ISR benutzen und erst danach in die eigentliche ISR
 springen - dadurch wurde BIOS ausgetrickst oder geändert/verbessert.
#6419994
Lesenswert?

Um welches 8051-Derivat geht es denn?

Bei den AT89LP51 kann man über das SBV-Register den Resetvektor irgendwo 
oberhalb der Applikation plazieren, z.B. an 0xF000. D.h. die Applikation 
wird ganz normal an 0x0000 compiliert und kann die Interrupts benutzen.
Ein Bootloader hat ja nicht vieles gleichzeitig zu tun und kommt somit 
ohne Interrupts aus.
Nach dem Reset wird der Bootloader an 0xF000 ausgeführt und hat er 
nichts weiter zu tun, springt er zur Applikation nach 0x0000.

https://www.microchip.com/wwwproducts/en/AT89LP51RD2
Gast #6419996
Lesenswert?

georg schrieb:
> Konzepte, bei denen man extra programmieren kann, wo die
> Interrupt-Tabelle steht, wie etwa beim Z80, sind demgegenüber nur
> kompliziert und fehleranfällig, fix adressierte Interrupttabellen haben
> sich daher weitgehend durchgesetzt.

Das ist natürlich Unsinn. Moderne Controller wie die STM32 lassen 
selbstverständlich eine Relokation der Interrupt Vector Tabelle zu.
#6420101
Lesenswert?

Ich denke du musst in deinem Bootloader ein abs. Assembler Modul 
dazulinken was die entsprechenden Weiterleitungen macht.
Da ich den SDCC Asm Syntax nicht kenne ein Beispiel in Keil  a51.
1
AppCode EQU 5000h
2
cseg at 3
3
    LJMP AppCode +3
4
org 0Bh
5
   LJMP AppCode +0Bh
6
....
7
end

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