Desde la redacción del artículo anterior,
"Cómo comprimir el cargador de arranque
STM8 a 18 bytes en la memoria FLASH" , han
aparecido dos versiones del
cargador de arranque
STM8uLoader . La versión del cargador de arranque STM8uLoader
$ 36 aprendió cómo transferir el control de un programa de aplicación a cualquier dirección en la memoria RAM sin la participación de un programa host. El tamaño de 18 bytes del gestor de arranque en la memoria FLASH no cambió; en el área de Bytes de OPCIÓN, el tamaño aumentó a 53 bytes (ocupó todo el espacio disponible).
Se asignó una rama separada del gestor de arranque
$ 0D . El requisito principal para esta versión es comprimir el código tanto como sea posible. Hasta la fecha, el tamaño del código en la memoria FLASH es de 8 bytes en la memoria EEPROM de 35 bytes.
Déjame recordarte la arquitectura del cargador de arranque STM8uLoader. El gestor de arranque consta del programa de host boot_PC y el código del gestor de arranque boot_uC en la memoria STM8. Este último se divide en el código de copia inicial boot_FLASH ubicado en la memoria FLASH y el código boot_EEPROM (o boot_OPTION) ubicado en la memoria EEPROM (o el área de Bytes OPTION).
Después del evento RESET, se inicia la copiadora inicial boot_FLASH, transfiere la imagen del código del cargador de arranque boot_EEPROM (o boot_OPTION) a la memoria RAM y le transfiere el control. El gestor de arranque configura el UART transfiere el byte del host al programa con su número de versión y, si no recibe información del programa del host durante el tiempo de espera, transfiere el control al programa de aplicación en la memoria FLASH. O transfiere el código de la aplicación desde la memoria EEPROM (o el área de Bytes de OPCIÓN) a la memoria RAM y le transfiere el control.
Si, después de enviar el byte con el número de versión al programa host, el gestor de arranque recibe un volcado con un código a través de UART, lo coloca en la memoria RAM y transfiere el control. El volcado aceptado con el código realiza su tarea actual: leer / copiar / borrar / escribir celdas STM8, transferir el control a la dirección especificada con la inicialización preliminar de los registros del núcleo STM8, transferir el control al gestor de arranque para cambiar el volcado actual en la memoria RAM por el programa host.
Copiadora inicial boot_FLASH rev. $ 0D se encuentra en las direcciones $ 8000 ... $ 8007 y ocupa completamente los vectores RESET y TRAP (interrupción de software). El resto del espacio $ 8008 ... $ 9FFF de memoria FLASH es totalmente accesible para el programa de aplicación. La tabla de vectores de interrupción también está en su lugar.
Considere el código de copista:
; boot_FLASH $0D($88) ; $4087($4187) ; $00 ; segment byte at 8000-8007 'bootF_rev0D' ; $8000 RESET Reset vector dc.b $AE, $40 ; [AE 40 88] ldw X,#$4088 ; dc.b $AE, $41 ; [AE 41 88] ldw X,#$4188 cycle: ; ; push A ldw X,#$4088($4188) push A ; [88] decw X ; [5A] ; $8004 TRAP Software interrupt ld A, (X) ; [F6] jrne cycle ; [26 FB] ret ; [81] ; $8008 TLI IRQ0 External top level interrupt
El código de dos comandos se cruza aquí: los comandos ldw X, # $ 4088 (ldw X, # $ 4188) y el push A. . Esta solución ahorró un byte, pero condujo a un estrechamiento del área de almacenamiento de la tabla con la imagen del código del cargador de arranque. El byte bajo de $ 88 de la dirección de la tabla no permite colocarlo en el área de Bytes de OPCIÓN. Para el modelo STM8S103F3, solo las direcciones $ 4088 y $ 4188 están disponibles en la memoria EEPROM para acomodar la tabla especificada. Para los propietarios de STM8S003F3 con memoria EEPROM de 128 bytes ($ 4000 ... $ 407F) y estas direcciones no están disponibles. Todavía hay una escapatoria para ellos.
Solo necesita intercambiar los comandos push A y decw X:
; boot_FLASH $0D($5A) ; $405A($415A, $425A) ; $00 ; segment byte at 8000-8007 'bootF_rev0D' ; $8000 RESET Reset vector dc.b $AE, $40 ; [AE 40 5A] ldw X,#$405A STM8S003F3 ; dc.b $AE, $41 ; [AE 41 5A] ldw X,#$415A ; dc.b $AE, $41 ; [AE 42 5A] ldw X,#$425A cycle: ; ; decw X ldw X,#$405A($415A, $425A) decw X ; [5A] push A ; [88] ; $8004 TRAP Software interrupt ld A, (X) ; [F6] jrne cycle ; [26 FB] ret ; [81] ; $8008 TLI IRQ0 External top level interrupt
Aquí, cuando ingresa al bucle por primera vez, se ejecuta el comando ldw X, # $ 405A ($ 415A, $ 425A), y el comando decw X no se ejecuta.
Recuerde que con el evento RESET, el puntero superior de la pila SP se inicializa por hardware con el valor $ 03FF. La pila está creciendo en la dirección de direcciones decrecientes. Para llenar la pila desde la cola, también leeremos la tabla con el código del gestor de arranque desde la cola, de ahí el comando decw X. La imagen del código del gestor de arranque en la memoria EEPROM se encuentra en consecuencia.
Para ahorrar dinero, abandonaron el contador de bucles. Acordamos que la imagen de código del gestor de arranque tendrá un byte cero solo al comienzo de la tabla, y trasladaremos la dirección de transferencia de control al programa de aplicación (que puede tener un byte cero) fuera de la tabla. En cada iteración, leemos el byte de la tabla y, si no es cero, lo insertamos en la pila. Lectura de byte cero: condición para salir del bucle.
El comando ret aquí significa pasar el control a la dirección que está contenida en los dos bytes que fueron los últimos en la pila. Ahora considere el código del gestor de arranque:
; boot_EEPROM $0D($88) segment byte at 4067-4089 'bootE_rev0D_88' ; segment byte at 417B-4189 'bootE_rev0D_88' ; $4067 terminator RAM dc.b $00 ; [00] ; $4068 ($03E0) {RAM END - 31} ; {$0400 - (bootE_go_adr - bootE_start) } dc.w $03E2 ; [03 E2] $4067 - $3C85 = $03E2 ; UART 96001N8 ; BREAK $0D bootE_start: ; $406A ($03E2) {RAM END - 29} ld A, #%00001101 ; [A6 0D] ld UART1_BRR1, A ; [C7 52 32] ld UART1_CR2, A ; [C7 52 35] ld UART1_DR, A ; [C7 52 31] ; 243 ; n ; $4075 ($03ED) {RAM END - 18} bootE_rx_byte: incw X ; [5C] jreq bootE_exit ; [27 0C] btjf UART1_SR, #5, bootE_rx_byte ; [72 0B 52 30 F8] push UART1_DR ; [3B 52 31] ; clrw X ; [5F] inc A ; [4C] jrne bootE_rx_byte ; [26 F2] ; ; $02F1 ( $FE $02) ret ; [81] ; $4084 ($03FC) {RAM END - 3} bootE_exit: jp [bootE_go_adr] ; [72 CC 40 88] RAM END ; ; $4088 RAM bootE_go_adr: dc.w main_flash ; [80 08]
Las direcciones del código después de copiar a la pila se muestran entre paréntesis. El primero es un byte cero; la RAM no se copia en la memoria. La siguiente es la dirección de la transferencia de control al gestor de arranque, de hecho, esta es la dirección de la siguiente celda en la RAM. Este par se pone en la pila, pero luego es sobrescrito por el código del próximo volcado del programa host como innecesario. Todo el código posterior también se copia en la pila, excepto un par con la dirección de transferencia de control de la aplicación.
A continuación se muestra la inicialización de UART. Aquí en los tres registros se coloca el mismo número $ 0D. En el primer caso, esta es la velocidad UART (16000000/8/9600/16 = 13). En el segundo caso, este es el permiso de transmisión / recepción, aquí una locomotora de vapor captó una generación única del evento BREAK. En el último caso, esto está enviando la versión del host del cargador al programa. De hecho, el programa host recibirá dos bytes $ 00 (evento BREAK) y $ 0D (número de versión del gestor de arranque): esta es una señal de que puede enviar un volcado con un código.
El registro A con el contenido de $ 0D realiza las funciones de un contador de bytes recibidos y los cuenta con un incremento a cero, lo que equivale a 243 bytes recibidos. Es con este tamaño que el programa host debe enviar volcados con código.
El índice de registro X en el copista inicial contó hasta $ 4068. Ahora también se incrementará a cero (49048 restantes), contando el tiempo asignado al gestor de arranque. Durante este tiempo, el gestor de arranque debe tener tiempo para aceptar un volcado con un código de 243 bytes de tamaño y colocarlo más en la pila y transferirle el control. De lo contrario, el control se transferirá al programa de aplicación y deberá presionar el botón de reinicio nuevamente y reiniciar el programa host.
Después de transferir el control al volcado recibido, el código del gestor de arranque permanece en la pila y toma el control nuevamente cuando el programa host decide reemplazar el volcado con el código. Cualquier volcado recibido con un código se encuentra en la pila en las direcciones $ 02ED ... $ 03DF y toma el control en la dirección $ 02F0. El código del gestor de arranque se encuentra en la pila en las direcciones $ 03E0 ... $ 03FF, inicialmente toma el control en la dirección $ 03E0 y, si es necesario, se llama al volcado con el código en la dirección $ 03E8.
El comando de transferencia de control a la aplicación está en la pila a $ 03FB.
El volcado actual puede usar una celda con la dirección $ 03FF.
El código fuente completo de la copiadora inicial y el cargador de arranque en la versión STM8 $ 0D con una tabla en la memoria EEPROM en las direcciones $ 4039 ... $ 405C ($ 4139 ... $ 415C, $ 4239 ... $ 425C).
Archivo bootF_rev0D_5A.asm: stm8/ TITLE “bootF_rev0D_5A.asm” MOTOROLA WORDS .NOLIST ; #include "STM8S003F.inc" #include "STM8S103F.inc" .LIST ; boot_EEPROM $0D($5A) segment byte at 4039-405C 'bootE_rev0D_405A' ; STM8S003F ; segment byte at 4139-415C 'bootE_rev0D_415A' ; segment byte at 4239-425C 'bootE_rev0D_425A' ; $403A9 ($03DD) {RAM END - 34} terminator RAM ????? dc.b $00 ; [00] ; $403A ($03DE) {RAM END - 33} ; {$0400 - (bootE_go_adr - bootE_start - 1) } dc.w $03E0 ; [03 E0] ; UART 96001N8 ; BREAK $0D bootE_start: ; $403C ($03E0) {RAM END - 31} ld A, #%00001101 ; [A6 0D] ld UART1_BRR1, A ; [C7 52 32] ld UART1_CR2, A ; [C7 52 35] ; $4044 ($03E8) {RAM END - 23} ld UART1_DR, A ; [C7 52 31] ; 243 ; n ; $40487 ($03EB) {RAM END - 20} bootE_rx_byte: incw X ; [5C] jreq bootE_exit ; [27 0C] btjf UART1_SR, #5, bootE_rx_byte ; [72 0B 52 30 F8] push UART1_DR ; [3B 52 31] clrw X ; [5F] inc A ; [4C] jrne bootE_rx_byte ; [26 F2] ; ; $02EF ( $EF $02) ; $4056 ($03FA) {RAM END - 5} ret ; [81] ; $4057 ($03FB) {RAM END - 4} bootE_exit: jp [bootE_go_adr] ; [72 CC 40 5B] {RAM END - 1} ; ($03FF) RAM END ; ; $405B RAM bootE_go_adr: dc.w main_flash ; [80 08] ; boot_FLASH $0D($5A) ; $405A($415A,$425A) ; $00 ; segment byte at 8000-8007 'bootF_rev0D' ; $8000 RESET Reset vector dc.b $AE, $40 ; [AE 40 5A] ldw X,#$405A ; STM8S003F ; dc.b $AE, $41 ; [AE 41 5A] ldw X,#$415A ; dc.b $AE, $42 ; [AE 42 5A] ldw X,#$425A cycle: ; ; dec X ldw X,#$405A($415A,$425A) decw X ; [5A] push A ; [88] ; $8004 TRAP Software interrupt ld A, (X) ; [F6] jrne cycle ; [26 FB] ret ; [81] ; $8008 TLI IRQ0 External top level interrupt ; segment byte at 8008 'main_flash' main_flash: jra * ; [20 FE] ; end ; bootF_rev0D_5A.asm
El código fuente completo del copista inicial y el gestor de arranque en la versión STM8 $ 0D con una tabla en la memoria EEPROM en las direcciones $ 4065 ... $ 4088 ($ 4165 ... $ 4188).
Archivo bootF_rev0D_88.asm: stm8/ TITLE “bootF_rev0D_88.asm” MOTOROLA WORDS .NOLIST ; #include "STM8S003F.inc" #include "STM8S103F.inc" .LIST ; boot_EEPROM $0D($88) segment byte at 4065-4088 'bootE_rev0D_88' ; segment byte at 4165-4188 'bootE_rev0D_88' ; $4065 terminator RAM dc.b $00 ; [00] ; $4066 ($03DE) {RAM END - 33} ; {$0400 - (bootE_go_adr - bootE_start) } dc.w $03E0 ; [03 E0] ; UART 9600 1N8 ; BREAK $0D bootE_start: ; $4068 ($03E0) {RAM END - 31} ld A, #%00001101 ; [A6 0D] ld UART1_BRR1, A ; [C7 52 32] ld UART1_CR2, A ; [C7 52 35] ; $4070 ($03E8) {RAM END - 23} ld UART1_DR, A ; [C7 52 31] ; 243 ; n ; $4073 ($03EB) {RAM END - 20} bootE_rx_byte: incw X ; [5C] jreq bootE_exit ; [27 0C] btjf UART1_SR, #5, bootE_rx_byte ; [72 0B 52 30 F8] push UART1_DR ; [3B 52 31] clrw X ; [5F] inc A ; [4C] jrne bootE_rx_byte ; [26 F2] ; ; $02EF ( $EF $02) ; $4082 ($03FA) {RAM END - 5} ret ; [81] ; $4083 ($03FB) {RAM END - 4} bootE_exit: jp [bootE_go_adr] ; [72 CC 40 87] {RAM END - 1} ; ($03FF) RAM END ; ; $4087 ($4088 ) RAM bootE_go_adr: dc.w main_flash ; [80 08] ; boot_FLASH $0D($88) ; $4087($4187) ; $00 ; segment byte at 8000-8007 'bootF_rev0D' ; $8000 RESET Reset vector dc.b $AE, $40 ; [AE 40] ldw X,#$4088 ; dc.b $AE, $41 ; [AE 41] ldw X,#$4188 cycle: ; ; push A ldw X,#$4088($4188) push A ; [88] decw X ; [5A] ; $8004 TRAP Software interrupt ld A, (X) ; [F6] jrne cycle ; [26 FB] ret ; [81] ; $8008 TLI IRQ0 External top level interrupt ; segment byte at 8008 'main_flash' main_flash: jra * ; [20 FE] end ; bootF_rev0D_88.asm
Describimos el programa de aplicación más simple para ejecutar en la memoria FLASH de STM8.
Archivo main_rev0D.asm: stm8/ TITLE “main_rev0D.asm” MOTOROLA WORDS .NOLIST #include "STM8S103F.inc" .LIST ; segment byte at 8008-9FFF 'main_flash' main_flash: main_cycle: ; bset PB_DDR,#5 ; bset PB_CR1,#5 ; callr flash_delay ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; callr flash_delay jra main_cycle flash_delay: ldw X, #35000 flash_delay_cycle: decw X jrne flash_delay_cycle ret end ; main_rev0D.asm
Coser el gestor de arranque del programador en STM8. Conectamos la placa al adaptador USB-TTL (UART). Ejecute el archivo por lotes
runSTM8uLoader.bat . Presione el botón de reinicio en el tablero. Observamos el resultado:

El cargador carga el código de la aplicación en la memoria FLASH y el dispositivo se reinicia. El LED comienza a parpadear.
Ejemplos de códigos fuente de volcado que el programa host envía al cargador para su ejecución en la memoria RAM:
Archivo Read_128000v0D.asm: stm8/ TITLE "Read_128000v0D.asm" MOTOROLA WORDS .NOLIST #include "STM8S103F3P.inc" .LIST ; 243 ; $02EE...$03DF ; ( $03DF:$03E0 ) ; $02F0 ; $03E1...$03FE ; $03E1 ( 9600, A<=$0D SP<=$03E0 X<=$0000) ; $03E9 ( , A<=$0D SP<=$03E8 X<=$0000) ; $03FB segment byte at 0000-00F2 'ram0' dc.w $02F0 start: ; UART1 / 9600, (8 , , 1 ) mov UART1_BRR2, #0 ; [35 00 52 33] Fmaster=16/8=2 128000 mov UART1_BRR1, #1 ; [35 0D 52 32] Fmaster=16/8=2 128000 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 / main_cycle: wait_byte_adrH_cmnd: btjf UART1_SR, #5, wait_byte_adrH_cmnd ld A, UART1_DR cp A, #$EF JRUGT wait_byte_cmd_test ; Relative jump if Unsigned Greater Than ld XH, A ; XH ld UART1_DR, A ; tx_echo_adrH: btjf UART1_SR, #7, tx_echo_adrH ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty wait_byte_adrL: btjf UART1_SR, #5, wait_byte_adrL ld A, UART1_DR ld XL, A ; XL wait_byte_cntr: btjf UART1_SR, #5, wait_byte_cntr ld A, #$00 ld YH, A ; ld A, UART1_DR ld YL, A ; ; bset PB_DDR,#5 ; bset PB_CR1,#5 ; ; read_block_cycle: ld A, (X) ld UART1_DR, A wait_tx: btjf UART1_SR, #7, wait_tx ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty incw X decw Y jrne read_block_cycle ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; jra main_cycle ; $F0 wait_byte_cmd_test: cp A, #$F5 ; jreq echo_F5cmd wait_tx_err: mov UART1_DR, #$F1 ; btjf UART1_SR, #7, wait_tx_err ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty jra main_cycle echo_F5cmd: ld UART1_DR, A ; wait_tx_echo_F5cmd: btjf UART1_SR, #7, wait_tx_echo_F5cmd ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty ; GoAdr wait_byte_adrH_toM; btjf UART1_SR, #5, wait_byte_adrH_toM mov $03E7, UART1_DR wait_byte_adrL_toM; btjf UART1_SR, #5, wait_byte_adrL_toM mov $03E8, UART1_DR ; SP wait_byte_adrH_toSP; btjf UART1_SR, #5, wait_byte_adrH_toSP ld A, UART1_DR ld XH, A wait_byte_adrL_toSP; btjf UART1_SR, #5, wait_byte_adrL_toSP ld A, UART1_DR ld XL, A ldw SP, X ; Y wait_byte_adrH_toY; ; btjf UART1_SR, #5, wait_byte_adrH_toY ; ld A, UART1_DR ; ld YH, A wait_byte_adrL_toY; ; btjf UART1_SR, #5, wait_byte_adrL_toY ; ld A, UART1_DR ; ld YL, A ; X wait_byte_adrH_toX; btjf UART1_SR, #5, wait_byte_adrH_toX ld A, UART1_DR ld XH, A wait_byte_adrL_toX; btjf UART1_SR, #5, wait_byte_adrL_toX ld A, UART1_DR ld XL, A ; A wait_byte_cntr_toA; btjf UART1_SR, #5, wait_byte_cntr_toA ld A, UART1_DR jp [$03E7.w] SKIP 59, $00 ; dc.b $00 dc.b $00 end ; Read_128000v0D.asm
File WriteBlocks_FLASH_128000v0D.asm: stm8/ TITLE "WriteBlocks_FLASH_128000v0D.asm" MOTOROLA WORDS .NOLIST #include "STM8S103F3P.inc" .LIST ; 243 ; $02EE...$03DF ; ( $03DF:$03E0 ) ; $02F0 ; $03E1...$03FE ; $03E1 ( 9600, A<=$0D SP<=$03E0 X<=$0000) ; $03E9 ( , A<=$0D SP<=$03E8 X<=$0000) ; $03FB segment byte at 0000-00F2 'ram0' dc.w $02F0 start: ; UART1 / 9600, (8 , , 1 ) mov UART1_BRR2, #0 ; [35 00 52 33] Fmaster=16/8=2 128000 mov UART1_BRR1, #1 ; [35 0D 52 32] Fmaster=16/8=2 128000 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 / main_cycle: wait_byte_adrH_cmnd: btjf UART1_SR, #5, wait_byte_adrH_cmnd ld A, UART1_DR cp A, #$F0 JRUGE wait_byte_cmd_test ; Relative jump if Unsigned Greater or Equal ld XH, A ; XH ld UART1_DR, A ; tx_echo_adrH: btjf UART1_SR, #7, tx_echo_adrH ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty wait_byte_adrL: btjf UART1_SR, #5, wait_byte_adrL ld A, UART1_DR ld XL, A ; XL wait_byte_cntr: btjf UART1_SR, #5, wait_byte_cntr ; mov $03FF, UART1_DR write_block_cycle: ldw Y, #64 ; ; unlock FLASH memory (writing the correct MASS keys) mov FLASH_PUKR, #$56 ; Write $56 then $AE in FLASH_PUKR($5062) mov FLASH_PUKR, #$AE ; If wrong keys have been entered, another key programming sequence can be issued without resetting the device. ; FLASH Block programming mode mov FLASH_CR2, #$01 mov FLASH_NCR2, #$FE ; ; FLASH Word programming mode ; mov FLASH_CR2, #$40 ; mov FLASH_NCR2, #$BF ; else FLASH byte programming ; bset PB_DDR,#5 ; bset PB_CR1,#5 ; ; ; wait_rx_byte: btjf UART1_SR, #5, wait_rx_byte ld A, UART1_DR ld (X), A incw X decw Y jrne wait_rx_byte mov UART1_DR, #$FA ; OK wait_tx_OK_FA: btjf UART1_SR, #7, wait_tx_OK_FA ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty ; bres PB_DDR,#5 ; bres PB_CR1,#5 ; dec $03FF jrne write_block_cycle jra main_cycle ; $F0 wait_byte_cmd_test: cp A, #$F5 ; boot_OPTION jreq echo_F5cmd wait_tx_err: mov UART1_DR, #$F1 ; wait_tx_err_F1: btjf UART1_SR, #7, wait_tx_err_F1 ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty jra main_cycle echo_F5cmd: ld UART1_DR, A ; boot_OPTION wait_tx_echo_F5cmd: btjf UART1_SR, #7, wait_tx_echo_F5cmd ; skip if UART1_SR.TXE = 0 TXE: Transmit data register empty ; GoAdr wait_byte_adrH_toM; btjf UART1_SR, #5, wait_byte_adrH_toM mov $03E7, UART1_DR wait_byte_adrL_toM; btjf UART1_SR, #5, wait_byte_adrL_toM mov $03E8, UART1_DR ; SP wait_byte_adrH_toSP; btjf UART1_SR, #5, wait_byte_adrH_toSP ld A, UART1_DR ld XH, A wait_byte_adrL_toSP; btjf UART1_SR, #5, wait_byte_adrL_toSP ld A, UART1_DR ld XL, A ldw SP, X ; Y wait_byte_adrH_toY; ; btjf UART1_SR, #5, wait_byte_adrH_toY ; ld A, UART1_DR ; ld YH, A wait_byte_adrL_toY; ; btjf UART1_SR, #5, wait_byte_adrL_toY ; ld A, UART1_DR ; ld YL, A ; X wait_byte_adrH_toX; btjf UART1_SR, #5, wait_byte_adrH_toX ld A, UART1_DR ld XH, A wait_byte_adrL_toX; btjf UART1_SR, #5, wait_byte_adrL_toX ld A, UART1_DR ld XL, A ; A wait_byte_cntr_toA; btjf UART1_SR, #5, wait_byte_cntr_toA ld A, UART1_DR jp [$03E7.w] SKIP 28, $00 ; dc.b $00 dc.b $00 end ; WriteBlocks_FLASH_128000v0D.asm
Archivo Reset_128000v0D.asm: stm8/ TITLE MOTOROLA WORDS .NOLIST #include .LIST ; 243 ; $02EE...$03DF ; ( $03DF:$03E0 ) ; $02F0 ; $03E1...$03FE ; $03E1 ( 9600, A<=$0D SP<=$03E0 X<=$0000) ; $03E9 ( , A<=$0D SP<=$03E8 X<=$0000) ; $03FB segment byte at 0000-00F2 'ram0' dc.w $02F0 start: ; RESET ldw X, #$03FF ldw SP, X clrw X clrw Y clr A jp $8000 SKIP 230, $00 end ; Reset_128000v0D.asm
En el código fuente del programa host, estos mismos volcados están presentes en la siguiente forma:
public readonly static byte[] Read_128000v0D = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x03, 0xCC, 0x72, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x95, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x94, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x95, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xE8, 0x03, 0x31, 0x52, 0x55, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xE7, 0x03, 0x31, 0x52, 0x55, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xC7, 0xA5, 0x20, 0xF7, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xF1, 0x35, 0x0B, 0x27, 0xF5, 0xA1, 0xB4, 0x20, 0x08, 0x50, 0x1B, 0x72, 0x07, 0x50, 0x1B, 0x72, 0xF2, 0x26, 0x5A, 0x90, 0x5C, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xC7, 0xF6, 0x08, 0x50, 0x1A, 0x72, 0x07, 0x50, 0x1A, 0x72, 0x97, 0x90, 0x31, 0x52, 0xC6, 0x95, 0x90, 0x00, 0xA6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xC7, 0x95, 0x40, 0x22, 0xEF, 0xA1, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x35, 0x52, 0x0C, 0x35, 0x32, 0x52, 0x01, 0x35, 0x33, 0x52, 0x00, 0x35, 0xF0, 0x02 };
public readonly static byte[] WriteBlocks_FLASH_128000v0D = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x03, 0xCC, 0x72, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x95, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x94, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x95, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xE8, 0x03, 0x31, 0x52, 0x55, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xE7, 0x03, 0x31, 0x52, 0x55, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xC7, 0x86, 0x20, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xF1, 0x35, 0x0B, 0x27, 0xF5, 0xA1, 0x95, 0x20, 0xBF, 0x26, 0xFF, 0x03, 0x5A, 0x72, 0x08, 0x50, 0x1B, 0x72, 0x07, 0x50, 0x1B, 0x72, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xFA, 0x35, 0xF2, 0x26, 0x5A, 0x90, 0x5C, 0xF7, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x08, 0x50, 0x1A, 0x72, 0x07, 0x50, 0x1A, 0x72, 0x5C, 0x50, 0xFE, 0x35, 0x5B, 0x50, 0x01, 0x35, 0x62, 0x50, 0xAE, 0x35, 0x62, 0x50, 0x56, 0x35, 0x40, 0x00, 0xAE, 0x90, 0xFF, 0x03, 0x31, 0x52, 0x55, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x97, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0xFB, 0x30, 0x52, 0x0F, 0x72, 0x31, 0x52, 0xC7, 0x95, 0x5F, 0x24, 0xF0, 0xA1, 0x31, 0x52, 0xC6, 0xFB, 0x30, 0x52, 0x0B, 0x72, 0x35, 0x52, 0x0C, 0x35, 0x32, 0x52, 0x01, 0x35, 0x33, 0x52, 0x00, 0x35, 0xF0, 0x02 };
public readonly static byte[] Reset_128000v0D = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCC, 0x4F, 0x5F, 0x90, 0x5F, 0x94, 0xFF, 0x03, 0xAE, 0xF0, 0x02 };
Artículo anterior:
"Cómo comprimir el gestor de arranque para STM8 a un tamaño de 18 bytes en la memoria FLASH" .
Sitio web con el proyecto
http://nflic.ru/STM8/STM8uLoader/000.html .
Proyecto en
https://sourceforge.net/projects/ovsp .
Proyecto en
https://github.com/ovsp/STM8uLoader .
Pido a los lectores críticas específicas y sugerencias para una mayor reducción del código.