Forum: Mikrocontroller und Digitale Elektronik AT89- bzw. 8051-Bootloader anspringen


von Patrick G. (pgr8051)


Lesenswert?

Hallo,

ich nutze den Atmel AT89*CC02 Controller mit CAN. Ich möchte den 
Bootloader (wohl Adresse 0xf800) gerne durch Umbiegen eines 
Funktionszeigers anspringen, z. B. so:

  void (*func)(void) = 0xf800; // Pointer auf Bootloader klarmachen
  (*func)(); // Pointer anspringen

Mit dem Keil-Kompiler klappte das fast. Eine Connection zum 
CAN-Bootloader gelang, nur das Hochladen blieb immer irgendwo bei 90 % 
stecken. Mit dem freien SDCC geht's gar nicht mehr.

Ziel ist das Starten des Bootloaders über eine bestimmte CAN-Nachricht. 
Ist die Vorgehensweise hier total unorthodox? Kann ich das auch anders 
realisieren, und zwar nur auf Softwareebene?

von Ralf (Gast)


Lesenswert?

Hi,

Hm, dass er sich aufhängt, ist komisch... AUXR1-Flag vorher gesetzt?

Ich arbeite mit dem AT89C51ED2, also auch einer mit Bootloader. Ich 
hab's dort so gelöst, dass ich nicht den Bootloader direkt anspringe, 
sondern das BLJB-Flag setze, dann den Watchdog aktiviere, und den dann 
den Reset triggern lasse. Das heisst, alle Register haben dann auch ihre 
Reset-Werte, wenn der Bootloader startet, evtl. liegt dein Aufhänger ja 
darin begründet. Das könntest du ja auch so machen.

Ralf

von Patrick G. (pgr8051)


Lesenswert?

AUXR1 habe ich vorher nicht gesetzt, die Watchdog-Sache hört sich aber 
gut an. ENBOOT in AUXR1 setzen geht in Ordnung. Den Watchdog aktiviert 
man in WDTRST durch Schreiben einer Sequenz von Werten (0x1e und 0xe1). 
Wie kann ich das Jump Bit aber setzen? Im Atmel-Data-Sheet steht nur was 
von "Hardware Security Byte", aber keine Register-Adresse, wo sich das 
BLJB befindet.

PS: "und den dann den Reset triggern lasse" -- wie ist das gemeint? Geht 
es hier um die Hardware-Condition/Reset, den ich sonst mache, um den 
Bootloader zurückzuholen?

von Ralf (Gast)


Lesenswert?

Das Stichwort ist API. Mit den API-Befehlen kannst du das BLJB setzen 
(zumindest beim ED2). Wie du die API aktivierst, steht im Datenblatt. 
Ausserdem gibts von Atmel bzw. Keil entsprechende C/H-Files, mit denen 
du die API-Befehle realisieren kannst, also nicht alles selber 
entwickeln musst.

Mit Reset triggern meinte ich, den Watchdog zu aktivieren, ihn aber 
nicht zu bedienen. Das löst einen "richtigen" Reset aus. Je nach Derivat 
ist der Resetpin bidirektional, d.h. du musst nachsehen, ob der Resetpin 
bei einem WD-Reset bedient wird, und ob das Probleme mit deiner externen 
Reset-Schaltung geben könne...

Ralf

von Patrick G. (pgr8051)


Lesenswert?

So, mal gestestet:

ENBOOT in AUXR1 habe ich vor dem Sprung gesetzt. Klappt nicht. Ein 
zyklischer Sende-Interrupt läuft sogar weiter nach dem "Sprung". Der 
Code wird auf jeden Fall ausgeführt, da ich eine CAN-Quittung 
programmiert habe. Diese Nachricht bestätigt, daß der Code-Zweig mit dem 
Sprung auch genommen wird.

AUXR1 auf ENBOOT, dann HSB (Register 0xBB) auf 0x40 und anschließend die 
beiden Werte in WDTRST für die Watchdog-Aktivierung. Es scheint sich 
nichts zu tun. Fehlt noch was?

PS: Gerade deine Antwort gelesen: Habe Sfr 0xBB angelegt und wie ein 
übliches Register angesprochen, eine API habe ich nicht genutzt. Ich 
schau nochmal.

von Peter D. (peda)


Lesenswert?

Auf meinem AT89C51CC01:
1
#define CALL(addr)      (((void(*)(void))(char code *)addr)())
2
#define AUXR1_ENBOOT_   0x20
3
4
void flash(void)               // enter bootloader to reprogram
5
{
6
    EA = 0;
7
    AUXR1 |= AUXR1_ENBOOT_;     // enable boot
8
    PSW = 1 << 3;               // Bank 1
9
    *(char data*)0 = 20;        // R0: oscillator freq
10
    *(char data*)1 = 0x0A;      // R1: program BLJB
11
    PSW = 0;
12
    DPTR = 4;                   // specify BLJB
13
    ACC = 0x00;                 // set BLJB
14
    CALL( 0xFFF0 );             // API call
15
16
    WDTPRG = 0;                 // force watchdog reset
17
    WDTRST = 0x1E;
18
    WDTRST = 0xE1;
19
    for(;;);
20
}


Peter

von Patrick G. (pgr8051)


Lesenswert?

@ Peter

Es scheint nicht zu gehen. DPTR ist in meinem Include unbekannt. Laut 
Oszi kommt aber wegen Setzen der WDT-Register eine RESET-Signal über den 
Pin, so daß ich nur noch PORT1 extern auf 0xFE (Hardware Condition) 
ziehen muß. Dann kommt der Bootloader.

Pin 1.6 ist auf Masse gezogen. Ich weiß nicht, ob das ein Problem ist...

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.