Forum: Mikrocontroller und Digitale Elektronik 8051: Interrupts umbiegen? SDCC


von ben utzer (Gast)


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

: Verschoben durch Moderator
von Thomas Z. (usbman)


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.

von georg (Gast)


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

von Marc V. (Firma: Vescomp) (logarithmus)


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.

von Peter D. (peda)


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

von John Doe (Gast)


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.

von ben utzer (Gast)


Lesenswert?

georg schrieb:
> platziert man da einen Jump, kann
> die ISR an beliebiger Stelle stehen.

Und genau wie man das am günstigsten in SDCC macht war die Frage im 
Ausgangpost.

von Thomas Z. (usbman)


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

von ben utzer (Gast)


Lesenswert?

Danke.
Habe hier ein Anleitung gefunden, wie man das bei SDCC macht:
https://sourceforge.net/p/sdcc/mailman/message/11632509/

von Peter D. (peda)


Lesenswert?

Wir wissen immer noch nicht, um welchen 8051 es geht. Die Unterschiede 
im Bootloadersupport sind doch schon erheblich.
Man kann sich das Leben viel leichter machen, wenn man einen geeigneten 
Typ wählt. Die AT89LP51 Typen sind außerdem noch sauschnell.

von Thomas Z. (usbman)


Lesenswert?

Naja ich vermute mal ein CH559
Beitrag "Re: uC für 0,20€ CH552 / CH554 von WCH Billig Micro mit USB Funktion, Chip vorstellung"

Der bietet die von dir genannten Optionen nicht. Er will das Update von 
einem USB-Stick einspielen.

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.