Bei der Suche nach dem Bootloader für den STM8S103F3-Mikrocontroller wurde festgestellt, dass die verfügbaren Bootloader hauptsächlich in "C" geschrieben sind, eine erhebliche Menge an FLASH-Speicher "stehlen" und die Tabelle der Interruptvektoren übertragen.
Der Bootloader war für einige Geräte erforderlich, an die der Programmierer nicht angeschlossen werden kann.
Es wurde beschlossen, selbst einen Bootloader mit den folgenden Anforderungen zu schreiben:
- Der Loader sollte STM8uLoader heißen.
- Der Code muss in Assembler geschrieben sein (der Nutzen von Assembler ist noch nicht gesetzlich verboten);
- Der Bootloader sollte die kleinstmögliche Menge im FLASH-Speicher belegen. Die im Computer belegte Menge wird als unbegrenzt angesehen.
- Der Lader sollte die Tabelle der Interruptvektoren nicht verschieben.
- Der Bootloader sollte nur über minimale Funktionen verfügen. Alle Hauptfunktionen sollten vom Computer übernommen werden.
- Der Bootloader muss die Kontrolle innerhalb einer angemessenen Zeit nach einem Zurücksetzen / Einschalten an das Anwendungsprogramm übertragen, wenn keine Verbindung zum Computer besteht.
Die erste Bedingung wurde sofort
erfüllt , aber die nachfolgenden Anforderungen mussten bearbeitet werden.
Erste Stufe. 65-Byte-Code im FLASH-Speicher
Um die Vektortabelle an ihrem Platz zu speichern, wurde beschlossen, den Code am Ende des FLASH-Speichers zu platzieren und sofort vom Speicherauszugsvektor $ 8000 darauf zu wechseln.
Beim Booten wird die Kontrolle bei $ 9FC2 auf den Bootloader-Code übertragen. Der Loader konfiguriert den UART 9600 8N1, wartet zwei Bytes auf UART und überträgt ohne Wartezeit die Steuerung an das Anwendungsprogramm unter der im Paar $ 9FFE: $ 9FFF gespeicherten Adresse.
Wenn der Loader die hohen und niedrigen Bytes der Größe des erwarteten Speicherauszugs vom Host-Programm empfängt, nimmt er den Speicherauszug selbst, legt den Speicherauszug im RAM-Speicher ab und überträgt die Steuerung an ihn.
Darüber hinaus liegt alle Sorgfalt beim Programm im Computer und dem von ihm gesendeten Speicherauszug. Es sollte genau die Speicherauszüge senden, die zum Ausführen der aktuellen Aufgabe erforderlich sind (Speicherzellen STM8 lesen / löschen / schreiben / kopieren). Dumps sollten sich im RAM-Speicher gegenseitig ersetzen und die Steuerung an das Anwendungsprogramm übertragen können.
Die Übergangsadresse zur Anwendung lautet $ 9FFE: $ 9FFF.
Die Datei boot_FLASH.asm:stm8/ TITLE "boot_FLASH.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 8000 'boot_start' boot_start: jp boot_FLASH_start dc.b $00 ; boot_FLASH ; ******************************************************** ; 0x8004...0x9FC1 WORDS ; segment byte at 8004 'main_FLASH' main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ; bset PB_DDR,#5 bset PB_CR1,#5 ; byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; ; byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret segment byte at 9FC2 'boot_FLASH' boot_FLASH_start: mov UART1_BRR1, #13; Fmaster=16/8=2/9600/16 mov UART1_CR2, #%00001100; / ; UART1 RST_SR boot_FLASH_RST_SR_tx: mov UART1_DR, RST_SR ; , ; ; X ( 200 ) ldw X,#0 boot_FLASH_wait_byte1: decw X jreq boot_FLASH_exit; btjf UART1_SR, #5, boot_FLASH_wait_byte1 ; , , ; X ld A, UART1_DR ld XH, A ; boot_FLASH_wait_byte2: btjf UART1_SR, #5, boot_FLASH_wait_byte2 ; ld A, UART1_DR ld XL, A ; X - ; X ldw Y, #$0400 ; Y 0x0400 (RAM_END + 1) ; boot_FLASH_rx_block_wait: btjf UART1_SR, #5, boot_FLASH_rx_block_wait boot_EEPROM_rx_block_entry: decw Y ; Y ld A, UART1_DR ld (Y), A decw X ; X jrne boot_FLASH_rx_block_wait ; jp (Y) ; () boot_FLASH_exit: dc.b $CC boot_FLASH_exit_addr: dc.w main_FLASH_start end ;
Zweite Stufe. Codegröße 21 Byte im FLASH und 52 Byte im EEPROM-Speicher
Die Auswahl von 65 Bytes aus dem FLASH-Speicher (in STM8S103F3 sind es nur 8192 Bytes) ist nicht human. Immerhin liegt der unnötige EEPROM-Speicher mit seinen 640 Bytes in der Nähe. Teilen wir den Bootloader-Code in zwei Teile auf: boot_FLASH und boot_EEPROM.
Beim Laden wird die Steuerung bei $ 9FEF in den boot_FLASH-Code übertragen. boot_FLASH kopiert das boot_EEPROM-Code-Image vom EEPROM in den RAM-Speicher und überträgt die Steuerung darauf.
Jetzt konfiguriert boot_EEPROM den UART 9600 8N1, wartet auf UART-Bytes und überträgt ohne zu warten die Kontrolle an das Anwendungsprogramm (wir lassen die Adresse an derselben Stelle $ 9FFE: $ 9FFF).
Wenn boot_EEPROM ein Byte mit der Größe des erwarteten Speicherauszugs für den RAM-Speicher empfängt, wird als nächstes ein Speicherauszug erstellt, der Speicherauszug in einem anderen Bereich des RAM-Speichers abgelegt und die Steuerung an ihn übertragen.
Weiter ist alles wie in der ersten Stufe.
Datei boot_FLASH_EEPROM.asm: stm8/ TITLE "boot_FLASH_EEPROM.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 4000 'eeprom' ; boot_EEPROM dc.b $35, $0D, $52, $32, $35, $0C, $52, $35 dc.b $35, $01, $52, $31, $5A, $27, $16, $72 dc.b $0B, $52, $30, $F8, $C6, $52, $31, $72 dc.b $0B, $52, $30, $FB, $3B, $52, $31, $4A dc.b $26, $F5, $96, $5C, $FC, $CE, $9F, $FE dc.b $2B, $FA, $90, $AE, $42, $7F, $AE, $02 dc.b $7F, $CC, $9F, $F4 segment byte at 8000 'boot_start' boot_start: jp boot_FLASH_start dc.b $01 ; boot_FLASH_EEPROM ; ******************************************************** ; 0x8004...0x9FEE segment byte at 8004 'main_FLASH' ; main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ; bset PB_DDR,#5 bset PB_CR1,#5 ; byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; ; byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret ; EEPROM -> RAM segment byte at 9FEF 'boot_FLASH' boot_FLASH_start: ldw X, SP ; Y <- { EEPROM_START + RAM_END} ; Y <- { $4000 + $03FF = $43FF } ldw Y, #$43FF boot_FLASH_copy: ld A, (Y) ld (X), A decw Y decw X jrpl boot_FLASH_copy incw X jp (X) boot_FLASH_exit_address: dc.w main_FLASH_start end ;
Führen Sie die Datei
runSTM8uLoader.bat aus , drücken Sie die Reset-Taste auf der Karte, der Bootloader sendet das Byte 0x01. Ein Speicherauszug mit dem Code aus der Datei main_RAM.hex wird über UART an RAM STM8 gesendet. Die Karte beginnt zu blinken und sendet die Bytes 0x20 und 0x02. Drücken Sie die Reset-Taste erneut. Das Anwendungsprogramm aus dem FLASH-Speicher wird gestartet, die LED beginnt schneller zu blinken und sendet die Bytes 0x80 und 0x08.
Die dritte Stufe. Codegröße 18 Bytes im FLASH-Speicher und 52 Bytes in OPTION-Bytes
Natürlich haben wir uns mit dem EEPROM-Speicher beeilt. Wo können Sinus und andere Tische jetzt aufbewahrt werden? Und mit dem FLASH-Speicher ist nicht alles klar. Wer hat beschlossen, die Übertragungssteuerungsadresse des Anwendungsprogramms im FLASH-Speicher zu speichern? Das gleiche Byte der Bootloader-Version wird in der Regel an zwei Stellen gleichzeitig gespeichert. Wo werden 52 Bytes für das EEPROM komprimiert?
Hier hilft uns die Lithographie. Der EEPROM-Speicher besteht aus 10 Blöcken mit jeweils 64 Bytes. Das Hinzufügen eines weiteren Blocks zu diesen Blöcken, jedoch mit einer anderen Größe, ist wirtschaftlich nicht machbar. STMicroelectronics hat genau das getan, einen weiteren 64-Byte-Block hinzugefügt, diesen Bereich OPTION Bytes genannt und dort wichtige nichtflüchtige Mikrocontroller-Einstellungen gespeichert (für STM8S103F3 sind es bis zu 11 Bytes). Und natürlich hat STM vergessen zu erwähnen, dass in diesem Bereich noch 53 funktionelle Zellen vorhanden sind. Anscheinend gibt es viele STM8-Modelle, Sie müssen Platz für zukünftige wichtige Einstellungen lassen.
Unser Bootloader beansprucht nur das STM8-Modell ohne eingebaute Bootloader. Daher nehmen wir die Sicherungszellen des OPTION Bytes-Blocks, die bisher niemand sieht. Es stimmt, es gibt eine kleine,
aber gelöste Unannehmlichkeit. Mit einem herkömmlichen Programmierer können Sie keine Informationen in diese Zellen schreiben.
Beim Laden wird die Steuerung bei $ 9FF2 auf den ursprünglichen copy_boot_FLASH-Code übertragen. boot_FLASH überträgt das Bootloader-Image boot_OPTION aus dem Bereich OPTION Bytes in den RAM.
boot_OPTION konfiguriert den UART 9600 8N1, sendet das UART-Byte mit seiner Version, wartet auf UART-Bytes vom Host-Programm und überträgt die Steuerung ohne Wartezeit von 0,2 Sekunden an das Anwendungsprogramm unter der Adresse im Paar $ 4831: $ 4832.
Wenn boot_OPTION nach dem Senden eines Bytes mit seiner Version ein Byte der Größe des erwarteten Speicherauszugs verwendet, nimmt es den Speicherauszug selbst, legt den Speicherauszug im RAM-Speicher ab und überträgt die Steuerung an ihn.
Darüber hinaus liegt alle Sorgfalt beim Programm im Computer und dem von ihm gesendeten Speicherauszug. Es sollte genau die Speicherauszüge senden, die zum Ausführen der aktuellen Aufgabe erforderlich sind (Speicherzellen STM8 lesen / löschen / schreiben / kopieren). Dumps sollten sich im RAM-Speicher gegenseitig ersetzen und die Steuerung an das Anwendungsprogramm übertragen können.
Die Übergangsadresse für die Anwendung lautet $ 4831: $ 4832.
Loader und Anwendungscode, die im FLASH-Speicher ausgeführt werden sollen: stm8/ TITLE "boot_FLASH_OPTION.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 4800 'boot_OPTION' ; boot_OPTION dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00 dc.b $FF, $00, $FF, $35, $0D, $52, $32, $35 dc.b $0C, $52, $35, $35, $25, $52, $31, $5A dc.b $27, $16, $72, $0B, $52, $30, $F8, $C6 dc.b $52, $31, $72, $0B, $52, $30, $FB, $3B dc.b $52, $31, $4A, $26, $F5, $96, $5C, $FC dc.b $AE, $80, $04, $2B, $FA, $90, $AE, $42 dc.b $7F, $AE, $02, $7F, $CC, $9F, $F6, $00 segment byte at 8000 'boot_start' boot_start: ldw X, SP jp boot_FLASH_start ; ******************************************************** ; 0x8004...0x9FF1 segment byte at 8004 'main_FLASH' ; main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ; bset PB_DDR,#5 bset PB_CR1,#5 ; byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; ; byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret ; OPTION -> RAM segment byte at 9FF2 'boot_FLASH' boot_FLASH_start: ; Y <- { OPTION_START + RAM_END} ; Y <- { $4800 + $03FF = $43FF } ldw Y, #$43FF boot_FLASH_copy: ld A, (Y) ld (X), A decw Y decw X jrpl boot_FLASH_copy incw X jp (X) boot_FLASH_exit_address: dc.w main_FLASH_start end ;
Anwendungscode zur Ausführung im RAM-Speicher: stm8/ TITLE “boot_RAM.asm” MOTOROLA #include "STM8S103F3P.inc" BYTES segment byte at 0000 'boot_RAM_data' boot_RAM_start: ; pull-up ( ) , , 14 ; ld A, #%01001100 ; [A6 4C] ; cpl A ; [43] ; ld PA_CR1, A ; [C7 50 03] ; ld PB_CR1, A ; [C7 50 08] ; ld PC_CR1, A ; [C7 50 0D] ; ld PD_CR1, A ; [C7 50 12] PD6(UART1_RX), PD2, PD1 ; UART1 / 9600, (8 , , 1 ) ; mov UART1_BRR2, #0 ; [35 00 52 33] Fmaster=16/8=2 9600 mov UART1_BRR1, #13 ; [35 0D 52 32] Fmaster=16/8=2 9600 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 / ; UART1 boot_RAM_byte1_tx: mov UART1_DR, #$02 boot_RAM_byte1_wait_tx btjf UART1_SR, #7, boot_RAM_byte1_wait_tx ldw X,#0 ; [AE 00 00] boot_FLASH X boot_RAM_wait1: decw X ; [5A] jreq boot_RAM_exit1 ; jra boot_RAM_wait1 boot_RAM_exit1: ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; ; UART1 boot_RAM_byte2_tx: mov UART1_DR, #$20 ; [35 11 52 31] boot_RAM_byte2_wait_tx btjf UART1_SR, #7, boot_RAM_byte2_wait_tx ldw X,#0 ; [AE 00 00] boot_FLASH X boot_RAM_wait2: decw X ; [5A] jreq boot_RAM_exit2 ; jra boot_RAM_wait2 boot_RAM_exit2: ; bset PB_DDR,#5 ; bset PB_CR1,#5 ; jra boot_RAM_byte1_tx end
Führen Sie die Datei
runSTM8uLoader.bat aus , drücken Sie die Reset-Taste auf der Karte, der Bootloader sendet das Byte 0x25. Ein Speicherauszug mit dem Code aus der Datei main_RAM.hex wird über UART an RAM STM8 gesendet. Die Karte beginnt zu blinken und sendet die Bytes 0x20 und 0x02. Drücken Sie die Reset-Taste erneut. Das Anwendungsprogramm aus dem FLASH-Speicher wird gestartet, die LED beginnt schneller zu blinken und sendet die Bytes 0x80 und 0x08.
In der letzten Phase müssen Sie die
Methode verwenden , um das Bootloader-Image in den Bereich OPTION Bytes zu schreiben. Das Wesentliche der Methode ist, dass der Programmierer zuerst die Firmware-Datei boot_OPTION_rev25.hex in den STM8 FLAH-Speicher schreiben muss, den Mikrocontroller neu starten muss, der Bereich OPTION Bytes mit den erforderlichen Informationen gefüllt wird und die LED aufleuchtet.
Andererseits schreibt der Programmierer aus diesem Artikel
boot_FLASH_OPTION.hex in die FLASH-Firmware-Datei.
"Clean" Bootloader Code Version 0x14 ohne Anwendungscode hinzugefügt. Bereitstellen des boot_OPTION-Images für den Quellcode. Kommentare korrigiert. Im Gegensatz zur $ 25-Version befindet sich die Steuerübertragungsadresse der Anwendung in den $ 9FFE: $ 9FFFF FLASH-Zellen. Die Größe in FLASH beträgt jeweils 20 Byte.
boot_uC_rev14.asm: stm8/ TITLE "boot_uC_rev14.asm" ; boot_uC = boot_OPTION + boot_FLASH MOTOROLA .NOLIST #include "STM8S103F3P.inc" .LIST WORDS ; ******************************************************** segment byte at 4800 'boot_O_IMG' ;0000FF00FF00FF00FF00FF350D523235 ;0C5235351452315A2716720B5230F8C6 ;5231720B5230FB3B52314A26F5965CFC ;CE9FFE2BFA90AE427FAE027FCC9FF400 ; ; $4800 RAM dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF ; OPTION (RAM) ; $480B ($0000) boot_O boot_O_start: ; UART 96008N1 Fmaster=16/8=2/9600/16 ; mov UART1_BRR2, #0 ; [35 00 52 33] mov UART1_BRR1, #13 ; [35 0D 52 32] ; UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 / mov UART1_CR2, #%00001100 ; [35 0C 52 35] ; $4813 ($0008) boot_E_byte1_tx: ; $14 mov UART1_DR, #$14 ; [35 14 52 31] ; , ; ; X ( 200 ) ; clrw X ; [5F] X boot_F ; $4817 ($000C) boot_O_rx_wait_byte: decw X ; [5A] jreq boot_O_exit ; [27 16] btjf UART1_SR, #5, boot_O_rx_wait_byte ; [72 OB 52 30 F8] ; , , A ; $481F ($0014) ld A, UART1_DR ; [C6 52 31] ; $4822 ($0017) boot_O_rx_wait_block: btjf UART1_SR, #5, boot_O_rx_wait_block ; [72 OB 52 30 FB] push UART1_DR ; [3B 52 31] dec A ; [4A] ; A jrne boot_O_rx_wait_block ; [26 F5] ; $482D ($0022) ldw X, SP ; [96] incw X ; [5C] boot_O_exit_to_FLASH: jp (X) ; [FC] ; $4830 ($0025) boot_O_exit: ldw X, boot_F_exit_address ; [CE 9F FE] jrmi boot_O_exit_to_FLASH ; [2B FA] ; if X < $8000 $0000 ; EEPROM boot_O_exit_to_EEPROM: ; Y <- { EEPROM_END} ldw Y, #$427F ; [90 AE 42 7F] ; X <- { EEPROM_END - EEPROM_START } ; EEPROM RAM ldw X, #$027F ; [AE 02 7F] jp boot_F_copy ; [CC 9F F4] ; $483F ($0034) dc.b $00 ; boot_O_end: ; ******************************************************** segment byte at 8000 'RESET_vector' ;96CC9FF0 ldw X, SP ; [96] X <- RAM_END jp boot_F_start ; [CC 9F F0] ; ******************************************************** ; 0x8004...0x9FEF segment byte at 8004 'main_FLASH' ;20FE jra * ; [20 FE] ; ******************************************************** ; boot_FLASH segment byte at 9FF0 'boot_F' ;90AE4C0A90F6F7905A5A2AF85CFC8004 boot_F_start: ; Y <- { boot_O_START + RAM_END} { $480B + $03FF = $4C0A } ldw Y, #$4C0A ; [90 AE 4C 0A] ; ; boot_FLASH, boot_OPTION boot_F_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_F_copy ; [2A F8] X(Y) >= RAM_START(boot_O_START) incw X ; [5C] jp (X) ; [FC] boot_F_exit_address: dc.w $8004 ; [80 04] ; dc.w $0000 ; [00 00] end ;
Es wurde ein "sauberer" Bootloader-Code Version 0x25 ohne Anwendungscode hinzugefügt. Bereitstellen des boot_OPTION-Images für den Quellcode. Kommentare korrigiert. Im Gegensatz zur $ 14-Version befindet sich die Steuerübertragungsadresse der Anwendung in den Zellen $ 4831: $ 4832 des Bereichs OPTION Bytes. Die belegte Größe im FLASH-Speicher verringerte sich auf 18 Bytes. Die belegte Größe im Bereich OPTION Bytes hat sich nicht geändert (52 Bytes + 1 Reserve).
boot_uC_rev14.asm: stm8/ TITLE "boot_uC_rev25.asm" ; boot_uC = boot_OPTION + boot_FLASH MOTOROLA .NOLIST #include "STM8S103F3P.inc" .LIST BYTES ; ******************************************************** ; EEPROM ; boot_O_exit_address $0000 ( <$8000) ; ; segment byte at 0000 'boot_O_IMG' main_ram: ;20FE jra * ; [20 FE] WORDS ; ******************************************************** segment byte at 4800 'boot_O_IMG' ;0000FF00FF00FF00FF00FF350D523235 ;0C5235351452315A2716720B5230F8C6 ;5231720B5230FB3B52314A26F5965CFC ;AE80042BFA90AE427FAE027FCC9FF600 ; ; $4800 RAM dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF ; OPTION (RAM) ; $480B ($0000) boot_OPTION boot_O_start: ; UART 96008N1 Fmaster=16/8=2/9600/16 ; mov UART1_BRR2, #0 ; [35 00 52 33] mov UART1_BRR1, #13 ; [35 0D 52 32] ; UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 / mov UART1_CR2, #%00001100 ; [35 0C 52 35] ; $4813 ($0008) boot_E_byte1_tx: ; $14 mov UART1_DR, #$14 ; [35 14 52 31] ; , ; ; X ( 200 ) ; clrw X ; [5F] X boot_F ; $4817 ($000C) boot_O_rx_wait_byte: decw X ; [5A] jreq boot_O_exit ; [27 16] btjf UART1_SR, #5, boot_O_rx_wait_byte ; [72 OB 52 30 F8] ; , , A ; $481F ($0014) ld A, UART1_DR ; [C6 52 31] ; $4822 ($0017) boot_O_rx_wait_block: btjf UART1_SR, #5, boot_O_rx_wait_block ; [72 OB 52 30 FB] push UART1_DR ; [3B 52 31] dec A ; [4A] ; A jrne boot_O_rx_wait_block ; [26 F5] ; $482D ($0022) ldw X, SP ; [96] incw X ; [5C] boot_O_exit_to_FLASH: jp (X) ; [FC] ; $4830 ($0025) boot_O_exit: dc.b $AE ; ldw X, #boot_O_exit_address ; [AE 80 04] ; $4831 ($0026) ; boot_O_exit_address: dc.w main_flash ; [80 04] ; dc.w main_ram ; [00 00] jrmi boot_O_exit_to_FLASH ; [2B FA] ; if X < $8000 $0000 ; EEPROM boot_O_exit_to_EEPROM: ; Y <- { EEPROM_END} ldw Y, #$427F ; [90 AE 42 7F] ; X <- { EEPROM_END - EEPROM_START } ; EEPROM RAM ldw X, #$027F ; [AE 02 7F] jp boot_F_copy ; [CC 9F F4] ; $483F ($0034) dc.b $00 ; boot_O_end: ; ******************************************************** segment byte at 8000-8003 'RESET_vector' ;96CC9FF2 ldw X, SP ; [96] X <- RAM_END jp boot_F_start ; [CC 9F F2] ; ******************************************************** ; 0x8004...0x9FF1 segment byte at 8004 'main_FLASH' main_flash: ;20FE jra * ; [20 FE] ; ******************************************************** ; boot_FLASH segment byte at 9FF2-9FFF 'boot_F' ;90AE4C0A90F6F7905A5A2AF85CFC boot_F_start: ; Y <- { boot_O_START + RAM_END} { $480B + $03FF = $4C0A } ldw Y, #$4C0A ; [90 AE 4C 0A] ; ; boot_FLASH, boot_OPTION boot_F_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_F_copy ; [2A F8] X(Y) >= RAM_START(boot_O_START) incw X ; [5C] jp (X) ; [FC] end ;
Die Steuerübertragungsadresse der Anwendung im FLASH-Speicher kann aus dem Bereich von $ 8004 ... $ 9FF1 ausgewählt werden. Für ein Anwendungscode-Image aus dem EEPROM-Speicher ist eine Steuerübertragung nur an der Adresse $ 0000 im RAM-Speicher möglich.
Das Host-Programm kann eine beliebige Steuerübertragungsadresse als zweites Befehlszeilenargument übergeben.
Den Quellcode des Host-Programms finden Sie
hier . Es gibt auch Kontakte für eine detailliertere Kommunikation.
Ich bitte die Leser um gezielte Kritik und Vorschläge zur weiteren Code-Reduzierung.
Ich schlage auch vor, den Artikel
„Komprimieren des Bootloaders für STM8 auf die Größe von 8 Byte im FLASH-Speicher“ zu lesen.