Au cours de la recherche du chargeur de démarrage pour le microcontrôleur STM8S103F3, il a été constaté que les chargeurs de démarrage disponibles sont principalement écrits en "C", "volent" une quantité importante de mémoire FLASH et transfèrent la table des vecteurs d'interruption.
Le chargeur de démarrage était nécessaire pour certains appareils auxquels il est impossible de connecter le programmeur.
Il a été décidé d'essayer d'écrire un chargeur de démarrage vous-même avec les exigences suivantes:
- le chargeur doit être appelé STM8uLoader;
- Le code doit être écrit en assembleur (le bénéfice de l'assembleur n'est pas encore légalement interdit);
- le chargeur de démarrage doit occuper la plus petite quantité possible dans la mémoire FLASH, la quantité occupée dans l'ordinateur sera considérée comme illimitée;
- le chargeur ne doit pas déplacer la table des vecteurs d'interruption;
- le chargeur de démarrage doit avoir une fonctionnalité minimale, toutes les fonctionnalités principales doivent être prises en charge par l'ordinateur;
- le chargeur de démarrage doit transférer le contrôle au programme d'application dans un délai raisonnable après une réinitialisation / mise sous tension s'il n'y a pas de connexion à l'ordinateur.
La première condition a été
remplie instantanément, mais les exigences subséquentes ont dû être travaillées.
Première étape. Code de 65 octets dans la mémoire FLASH
Pour sauvegarder la table vectorielle à sa place, il a été décidé de placer le code à la fin de la mémoire FLASH et d'y basculer immédiatement à partir du vecteur de vidage 8000 $.
Au démarrage, le contrôle est transféré au code du chargeur de démarrage à 9 $ CF2. Le chargeur de démarrage configure l'UART 9600 8N1, attend deux octets sur l'UART, et sans attendre, transfère le contrôle au programme d'application à l'adresse stockée dans la paire $ 9FFE: $ 9FFF.
Si le chargeur reçoit les octets haut et bas de la taille du vidage attendu du programme hôte, il prend le vidage lui-même, place le vidage dans la mémoire RAM et lui transfère le contrôle.
De plus, tout le soin réside dans le programme de l'ordinateur et le vidage qu'il envoie. Il doit envoyer exactement les vidages nécessaires pour terminer la tâche en cours (lecture / effacement / écriture / copie des cellules de mémoire STM8). Les vidages doivent pouvoir se remplacer mutuellement dans la mémoire RAM et transférer le contrôle au programme d'application.
L'adresse de transition vers l'application est $ 9FFE: $ 9FFF.
Le fichier 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 ;
Deuxième étape. Taille de code 21 octets en FLASH et 52 octets en mémoire EEPROM
La sélection de 65 octets dans la mémoire FLASH (dans STM8S103F3 c'est seulement 8192 octets) n'est pas humaine. Après tout, la mémoire EEPROM inutile avec ses 640 octets se trouve à proximité. Divisons le code du chargeur de démarrage en deux parties boot_FLASH et boot_EEPROM.
Lors du chargement, le contrôle est transféré vers le code boot_FLASH à $ 9FEF. boot_FLASH copie l'image de code boot_EEPROM de l'EEPROM dans la mémoire RAM et lui transfère le contrôle.
Maintenant, boot_EEPROM configure l'UART 9600 8N1, attend les octets UART, et sans attendre, transfère le contrôle au programme d'application (nous laisserons l'adresse au même endroit $ 9FFE: $ 9FFF).
Si boot_EEPROM reçoit un octet de la taille du vidage attendu pour la mémoire RAM, il prend ensuite un vidage, place le vidage dans une autre zone de mémoire RAM et lui transfère le contrôle.
De plus, tout est comme dans la première étape.
Fichier 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 ;
Exécutez le fichier
runSTM8uLoader.bat , appuyez sur le bouton de réinitialisation sur la carte, le chargeur de démarrage envoie l'octet 0x01. Un vidage avec le code du fichier main_RAM.hex est envoyé à RAM STM8 via UART. La carte commence à clignoter la LED et envoie les octets 0x20 et 0x02. Appuyez à nouveau sur le bouton de réinitialisation. Le programme d'application de la mémoire FLASH est lancé, la LED commence à clignoter plus rapidement et envoie les octets 0x80 et 0x08.
La troisième étape. Taille du code 18 octets en mémoire FLASH et 52 octets en OPTION Octets
Bien sûr, nous nous sommes précipités avec la mémoire EEPROM. Où stocker les sinus et autres tables maintenant? Et avec la mémoire FLASH, tout n'est pas clair. Qui a décidé de stocker l'adresse de contrôle de transfert du programme d'application dans la mémoire FLASH? Et le même octet de la version du chargeur de démarrage est généralement stocké à deux endroits à la fois. Où compresser 52 octets destinés à l'EEPROM?
Ici, la lithographie nous aide. La mémoire EEPROM se compose de 10 blocs de 64 octets chacun. Ajouter un autre bloc à ces blocs, mais avec une taille différente, n'est pas économiquement réalisable. STMicroelectronics a fait exactement cela, a ajouté un autre bloc de 64 octets, a nommé cette zone OPTION Bytes et y stocke d'importants paramètres de microcontrôleur non volatils (pour STM8S103F3, il peut atteindre 11 octets). Et bien sûr, la STM a oublié de mentionner qu'il reste encore 53 cellules fonctionnelles dans cette zone. Apparemment, il existe de nombreux modèles STM8, vous devez laisser de la place pour les futurs paramètres importants.
Notre chargeur de démarrage ne revendique que le modèle STM8 sans chargeur de démarrage intégré. Par conséquent, nous prenons jusqu'à présent les cellules de sauvegarde du bloc OPTION Bytes. Certes, il y a un petit inconvénient,
mais résolu . Un programmeur conventionnel ne vous permettra pas d'écrire des informations dans ces cellules.
Lors du chargement, le contrôle est transféré vers le code copy_boot_FLASH initial à 9FF2 $. boot_FLASH transfère l'image du chargeur de démarrage boot_OPTION de la zone OPTION Bytes vers la RAM.
boot_OPTION configure l'UART 9600 8N1, envoie l'octet UART avec sa version, attend les octets UART du programme hôte et sans attendre 0,2 seconde transfère le contrôle au programme d'application à l'adresse située dans la paire $ 4831: $ 4832.
Si boot_OPTION, après avoir envoyé un octet avec sa version, prend un octet de la taille du vidage attendu, alors il prend le vidage lui-même, place le vidage dans la mémoire RAM et lui transfère le contrôle.
De plus, tout le soin réside dans le programme de l'ordinateur et le vidage qu'il envoie. Il doit envoyer exactement les vidages nécessaires pour terminer la tâche en cours (lecture / effacement / écriture / copie des cellules de mémoire STM8). Les vidages doivent pouvoir se remplacer mutuellement dans la mémoire RAM et transférer le contrôle au programme d'application.
L'adresse de transition vers l'application est de 4831 $: 4832 $.
Chargeur et code d'application à exécuter dans la mémoire FLASH: 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 ;
Code d'application à exécuter dans la mémoire RAM: 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
Exécutez le fichier
runSTM8uLoader.bat , appuyez sur le bouton de réinitialisation de la carte, le chargeur de démarrage envoie l'octet 0x25. Un vidage avec le code du fichier main_RAM.hex est envoyé à RAM STM8 via UART. La carte commence à clignoter la LED et envoie les octets 0x20 et 0x02. Appuyez à nouveau sur le bouton de réinitialisation. Le programme d'application de la mémoire FLASH est lancé, la LED commence à clignoter plus rapidement et envoie les octets 0x80 et 0x08.
À la dernière étape, pour écrire l'image du chargeur de démarrage dans la zone OPTION Bytes, vous devez utiliser la
méthode . L'essence de la méthode est que vous devez d'abord que le programmeur écrive le fichier du firmware boot_OPTION_rev25.hex dans la mémoire FLAH STM8, redémarrez le microcontrôleur, la zone OPTION Bytes sera remplie avec les informations nécessaires et la LED s'allumera. Là encore, le programmeur écrit dans le fichier du firmware FLASH à partir de cet article
boot_FLASH_OPTION.hex .
Ajout de la version de code de chargeur d'amorçage «propre» 0x14 sans code d'application. Déployé l'image boot_OPTION dans le code source. Commentaires corrigés. Contrairement à la version 25 $, l'adresse de transfert de contrôle de l'application se trouve dans les cellules FLASH $ 9FFE: $ 9FFFF. La taille en FLASH est de 20 octets, respectivement.
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 ;
Ajout d'un code de chargeur d'amorçage «propre» version 0x25 sans code d'application. Déployé l'image boot_OPTION dans le code source. Commentaires corrigés. Contrairement à la version $ 14, l'adresse de transfert de contrôle de l'application se trouve dans les cellules $ 4831: $ 4832 de la zone OPTION Bytes. La taille occupée dans la mémoire FLASH, respectivement, a diminué à 18 octets. La taille occupée dans la zone OPTION Bytes n'a pas changé (52 octets + 1 réserve).
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 ;
L'adresse de transfert de contrôle de l'application dans la mémoire FLASH peut être sélectionnée dans la plage de 8004 $ ... 9FF1 $. Pour une image de code d'application de la mémoire EEPROM, le transfert de contrôle n'est possible qu'à l'adresse $ 0000 dans la mémoire RAM.
Le programme hôte peut transmettre n'importe quelle adresse de transfert de contrôle comme deuxième argument de ligne de commande.
Le code source du programme hôte peut être trouvé
ici . Il existe également des contacts pour une communication plus détaillée.
Je demande aux lecteurs des critiques ciblées et des suggestions pour une réduction supplémentaire du code.
Je propose également de lire l'article
«Comment compresser le bootloader pour STM8 à 8 octets dans la mémoire FLASH» .