Desde a redação do artigo anterior,
“Como compactar o carregador de inicialização
STM8 para 18 bytes na memória FLASH” , duas versões do
carregador de inicialização
STM8uLoader apareceram . O carregador de inicialização STM8uLoader versão
$ 36 aprendeu como transferir o controle de um programa de aplicativo para qualquer endereço na memória RAM sem a participação de um programa host. O tamanho de 18 bytes do carregador de inicialização na memória FLASH não foi alterado; na área OPTION Bytes, o tamanho aumentou para 53 bytes (ocupou todo o espaço disponível).
Uma ramificação separada do carregador de inicialização
$ 0D foi alocada. O principal requisito para esta versão é compactar o código o máximo possível. Até o momento, o tamanho do código na memória FLASH é de 8 bytes na memória EEPROM de 35 bytes.
Deixe-me lembrá-lo da arquitetura do carregador de inicialização STM8uLoader. O carregador de inicialização consiste no programa host boot_PC e no código do carregador de inicialização boot_uC na memória STM8. Este último é dividido no código de cópia inicial do boot_FLASH localizado na memória FLASH e no código do carregador de inicialização boot_EEPROM (ou boot_OPTION) localizado na memória EEPROM (ou na área OPTION Bytes).
Após o evento RESET, a copiadora inicial boot_FLASH é iniciada, transfere a imagem de código do carregador de inicialização boot_EEPROM (ou boot_OPTION) para a memória RAM e transfere o controle para ela. O carregador de inicialização configura o UART transfere o byte do programa host com seu número de versão e, se não receber informações do programa host durante o tempo limite, transfere o controle para o programa aplicativo na memória FLASH. Ou transfere o código do aplicativo da memória EEPROM (ou da área OPTION Bytes) para a memória RAM e transfere o controle para ele.
Se, após enviar o byte com o número da versão para o programa host, o carregador de inicialização recebe um despejo com um código via UART, o coloca na memória RAM e transfere o controle. O dump aceito com o código executa sua tarefa atual: ler / copiar / apagar / gravar as células STM8, transferir o controle para o endereço especificado com a inicialização preliminar dos registros do kernel STM8, transferir o controle para o gerenciador de inicialização para alterar o dump atual na memória RAM pelo programa host.
Copiadora inicial boot_FLASH rev. $ 0D está localizado nos endereços $ 8000 ... $ 8007 e ocupa completamente os vetores RESET e TRAP (interrupção de software). O restante do espaço $ 8008 ... $ 9FFF de memória FLASH é totalmente acessível ao programa aplicativo. A tabela de vetores de interrupção também está em vigor.
Considere o código 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
Aqui, o código de dois comandos se cruza: os comandos ldw X, # $ 4088 (ldw X, # $ 4188) e o push A. . Essa solução salvou um byte, mas levou a um estreitamento da área de armazenamento da tabela com a imagem do código do gerenciador de inicialização. O byte baixo de $ 88 do endereço da tabela não permite colocá-lo na área Bytes de OPÇÃO. Para o modelo STM8S103F3, apenas os endereços $ 4088 e $ 4188 estão disponíveis na memória EEPROM para acomodar a tabela especificada. Para proprietários de STM8S003F3 com memória EEPROM 128 bytes ($ 4000 ... $ 407F) e esses endereços não estão disponíveis. Ainda há uma brecha para eles.
Você só precisa trocar os comandos push A e 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
Aqui, quando você insere o loop pela primeira vez, o comando ldw X, # $ 405A ($ 415A, $ 425A) é executado e o comando decw X não é executado.
Lembre-se de que, com o evento RESET, o ponteiro superior da pilha SP é inicializado por hardware com o valor $ 03FF. A pilha está crescendo na direção da diminuição de endereços. Para preencher a pilha da cauda, também leremos a tabela com o código do carregador de inicialização da cauda, daí o comando decw X. A imagem do código do carregador de inicialização na memória EEPROM está localizada em conformidade.
Para economizar dinheiro, eles abandonaram o contador de loops. Concordamos que a imagem de código do carregador de inicialização terá um byte zero apenas no início da tabela e moveremos o endereço de transferência de controle para o programa de aplicativo (que pode ter zero byte) fora da tabela. A cada iteração, lemos o byte da tabela e, se não for zero, empurre-o para a pilha. Leia zero byte - condição para sair do loop.
O comando ret aqui significa passar o controle para o endereço que está contido nos dois bytes que foram os últimos na pilha. Agora considere o código do carregador de inicialização:
; 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]
Os endereços do código após copiar para a pilha são mostrados entre parênteses. O primeiro é um byte zero; a RAM não é copiada para a memória. A seguir está o endereço da transferência de controle para o carregador de inicialização, na verdade, este é o endereço da próxima célula na RAM. Esse par entra na pilha, mas é substituído pelo código do próximo dump do programa host como desnecessário. Todo o código subsequente também é copiado para a pilha, exceto um par com o endereço de transferência de controle do aplicativo
A seguir está a inicialização do UART. Aqui, nos três registros, o mesmo número $ 0D é colocado. No primeiro caso, essa é a velocidade do UART (16000000/8/9600/16 = 13). No segundo caso, esta é a permissão de transmissão / recepção, aqui uma locomotiva a vapor capturou uma geração única do evento BREAK. No último caso, isso está enviando a versão host do carregador para o programa. De fato, o programa host receberá dois bytes $ 00 (evento BREAK) e $ 0D (número da versão do gerenciador de inicialização) - este é um sinal de que você pode enviar um dump com um código.
O registro A com o conteúdo de $ 0D executa as funções de um contador de bytes recebidos e as contabiliza com um incremento para zero, o que equivale a 243 bytes recebidos. É com esse tamanho que o programa host deve enviar dumps com código.
O registro de índice X no copista inicial contava até US $ 4068. Agora, ele também aumentará para zero (49048 ainda restante), contando o tempo alocado para o carregador de inicialização. Durante esse período, o carregador de inicialização deve ter tempo para aceitar um despejo com um código de tamanho de 243 bytes e colocá-lo ainda mais na pilha e transferir o controle para ele. Caso contrário, o controle será transferido para o programa aplicativo e você precisará pressionar o botão de reset novamente e reiniciar o programa host.
Após transferir o controle para o dump recebido, o código do carregador de inicialização permanece na pilha e assume o controle novamente quando o programa host decide substituir o dump pelo código. Qualquer despejo recebido com um código está localizado na pilha nos endereços $ 02ED ... $ 03DF e assume o controle no endereço $ 02F0. O código do carregador de inicialização está localizado na pilha nos endereços $ 03E0 ... $ 03FF, inicialmente assume o controle no endereço $ 03E0 e, se necessário, o dump com o código é chamado no endereço $ 03E8.
O comando de transferência de controle para o aplicativo está na pilha em $ 03FB.
Uma célula com o endereço $ 03FF pode ser usada pelo despejo atual.
Todo o código-fonte da copiadora e carregador de inicialização inicial no STM8 versão $ 0D com uma tabela na memória EEPROM nos endereços $ 4039 ... $ 405C ($ 4139 ... $ 415C, $ 4239 ... $ 425C).
Arquivo 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
Todo o código-fonte do copiador e carregador de inicialização inicial na versão STM8 $ 0D com uma tabela na memória EEPROM nos endereços $ 4065 ... $ 4088 ($ 4165 ... $ 4188).
Arquivo 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
Descrevemos o programa aplicativo mais simples para execução na memória FLASH do STM8.
Arquivo 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
Costure o programa de inicialização do programador no STM8. Conectamos a placa ao adaptador USB-TTL (UART). Execute o arquivo em lote
runSTM8uLoader.bat . Pressione o botão de reset no quadro. Observamos o resultado:

O código do aplicativo é piscado pelo carregador na memória FLASH, o dispositivo é reiniciado. O LED começa a piscar.
Exemplos de códigos-fonte de despejo que o programa host envia ao carregador para execução na memória RAM:
Arquivo 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
Arquivo 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
Arquivo 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
No código fonte do programa host, esses mesmos dumps estão presentes no seguinte formato:
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 };
Artigo anterior:
"Como compactar o carregador de inicialização do STM8 no tamanho 18 bytes na memória FLASH .
"Site com o projeto
http://nflic.ru/STM8/STM8uLoader/000.html .
Projeto em
https://sourceforge.net/projects/ovsp .
Projeto em
https://github.com/ovsp/STM8uLoader .
Peço aos leitores críticas direcionadas e sugestões para redução adicional do código.