Cara memampatkan bootloader untuk STM8 ke ukuran 8 byte dalam memori FLASH

Sejak penulisan artikel sebelumnya, "Cara Mengompresi Boot Loader STM8 hingga 18 Bytes dalam Memori FLASH" , dua versi bootloader STM8uLoader telah muncul . STM8uLoader bootloader versi $ 36 mempelajari cara mentransfer kontrol program aplikasi ke alamat mana pun dalam memori RAM tanpa partisipasi dari program host. Ukuran 18 byte dari bootloader di memori FLASH tidak berubah, di area OPTION Bytes, ukurannya meningkat menjadi 53 byte (mengambil semua ruang yang tersedia).

Cabang terpisah dari bootloader $ 0D dialokasikan. Persyaratan utama untuk versi ini adalah mengompres kode sebanyak mungkin. Sampai saat ini, ukuran kode dalam memori FLASH adalah 8 byte dalam memori EEPROM 35 byte.

Biarkan saya mengingatkan Anda arsitektur bootloader STM8uLoader. Bootloader terdiri dari program host boot_PC dan kode bootloader boot_uC di memori STM8. Yang terakhir ini dibagi menjadi kode copy awal boot_FLASH yang terletak di memori FLASH dan kode bootloader boot_EEPROM (atau boot_OPTION) yang terletak di memori EEPROM (atau area Byte OPSI).

Setelah acara RESET, mesin fotokopi awal boot_FLASH diluncurkan, mentransfer gambar kode bootloader boot_EEPROM (atau boot_OPTION) ke memori RAM dan mentransfer kendali ke sana. Bootloader mengkonfigurasi UART mentransfer byte host ke program dengan nomor versinya dan, jika tidak menerima informasi dari program host selama batas waktu, transfer kontrol ke program aplikasi dalam memori FLASH. Atau mentransfer kode aplikasi dari memori EEPROM (atau area OPTION Bytes) ke memori RAM dan mentransfer kontrol ke sana.

Jika, setelah mengirim byte dengan nomor versi ke program host, bootloader menerima dump dengan kode melalui UART, kemudian menempatkannya dalam memori RAM dan mentransfer kontrol. Dump yang diterima dengan kode melakukan tugasnya saat ini: membaca / menyalin / menghapus / menulis sel STM8, mentransfer kontrol ke alamat yang ditentukan dengan inisialisasi awal register kernel STM8, mentransfer kontrol ke bootloader untuk mengubah dump saat ini dalam memori RAM oleh program host.

Rev boot_FLASH mesin fotokopi awal. $ 0D terletak di alamat $ 8000 ... $ 8007 dan sepenuhnya menempati vektor RESET dan TRAP (Software interrupt). Sisa ruang $ 8008 ... $ 9FFF memori FLASH sepenuhnya dapat diakses oleh program aplikasi. Tabel vektor interupsi juga ada di tempatnya.

Pertimbangkan kode penyalin:

;   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 

Kode dua perintah berpotongan di sini: perintah ldw X, # $ 4088 (ldw X, # $ 4188) dan perintah push A. Ketika Anda pertama kali memasukkan loop, perintah ldw X, # $ 4088 (ldw X, # $ 4188) dijalankan, dan perintah push A tidak dieksekusi . Solusi ini menghemat satu byte, tetapi menyebabkan penyempitan area penyimpanan tabel dengan gambar kode bootloader. Byte rendah $ 88 dari alamat tabel tidak memungkinkan menempatkannya di area OPTION Bytes. Untuk model STM8S103F3, hanya $ 4088 dan $ 4188 alamat yang tersedia di memori EEPROM untuk mengakomodasi tabel yang ditentukan. Untuk pemilik STM8S003F3 dengan memori EEPROM 128 byte ($ 4000 ... $ 407F) dan alamat ini tidak tersedia. Masih ada celah untuk mereka.

Anda hanya perlu menukar perintah push A dan 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 


Di sini, ketika Anda pertama kali memasukkan loop, perintah ldw X, # $ 405A ($ 415A, $ 425A) dieksekusi, dan perintah decw X tidak dieksekusi.

Ingatlah bahwa dengan acara RESET, pointer teratas dari tumpukan SP diinisialisasi perangkat keras dengan nilai $ 03FF. Tumpukan tumbuh ke arah penurunan alamat. Untuk mengisi stack dari tail, kita juga akan membaca tabel dengan kode bootloader dari tail, maka perintah decw X. Gambar kode bootloader di memori EEPROM terletak di lokasi yang sesuai.
Untuk menghemat uang, mereka meninggalkan penghitung putaran. Kami sepakat bahwa gambar kode bootloader akan memiliki nol byte hanya pada awal tabel, dan kami akan memindahkan alamat transfer kontrol ke program aplikasi (yang mungkin memiliki nol byte) di luar tabel. Pada setiap iterasi, kita membaca byte dari tabel dan jika tidak nol, dorong ke stack. Baca nol byte - syarat untuk keluar dari loop.

Perintah ret di sini berarti memberikan kontrol ke alamat yang terdapat dalam dua byte yang terakhir di stack. Sekarang pertimbangkan kode bootloader:

 ;   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] 


Alamat kode setelah menyalin ke tumpukan ditunjukkan dalam tanda kurung. Yang pertama adalah nol byte, RAM tidak disalin ke memori. Berikut ini adalah alamat transfer kontrol ke bootloader, pada kenyataannya, ini adalah alamat sel berikutnya dalam RAM. Pasangan ini masuk stack, tetapi kemudian ditimpa oleh kode dump berikutnya dari program host sebagai tidak perlu. Semua kode selanjutnya juga disalin ke tumpukan, kecuali pasangan dengan alamat transfer kontrol aplikasi
Berikut ini adalah inisialisasi UART. Di sini, di ketiga register nomor yang sama $ 0D ditempatkan. Dalam kasus pertama, ini adalah kecepatan UART (16000000/8/9600/16 = 13). Dalam kasus kedua, ini adalah izin transmisi / penerimaan, di sini lokomotif uap menangkap satu kali peristiwa BREAK. Dalam kasus terakhir, ini mengirimkan versi host loader ke program. Faktanya, program host akan menerima dua byte $ 00 (event BREAK) dan $ 0D (nomor versi dari bootloader) - ini adalah sinyal bahwa Anda dapat mengirim dump dengan kode.

Daftarkan A dengan isi $ 0D lalu jalankan fungsi penghitung byte yang diterima dan hitung dengan kenaikan nol, yang setara dengan 243 byte yang diterima. Dengan ukuran ini program host harus mengirim dump dengan kode.

Register indeks X dalam penyalin awal dihitung hingga $ 4068. Sekarang juga akan bertambah menjadi nol (49048 masih tersisa), menghitung waktu yang dialokasikan untuk bootloader. Selama waktu ini, bootloader harus memiliki waktu untuk menerima dump dengan kode 243 byte dalam ukuran dan menempatkannya lebih jauh di stack dan mentransfer kontrol ke sana. Jika tidak, kontrol akan ditransfer ke program aplikasi dan Anda harus menekan tombol reset lagi dan memulai kembali program host.

Setelah mentransfer kontrol ke dump yang diterima, kode bootloader tetap berada di stack dan mengambil kendali lagi ketika program host memutuskan untuk mengganti dump dengan kode. Setiap dump yang diterima dengan kode terletak di tumpukan di alamat $ 02ED ... $ 03DF dan mengambil kendali di alamat $ 02F0. Kode bootloader terletak di tumpukan di alamat $ 03E0 ... $ 03FF, awalnya dibutuhkan kontrol di alamat $ 03E0, dan jika perlu, dump dengan kode dipanggil di alamat $ 03E8.
Perintah transfer kontrol ke aplikasi ada di tumpukan di $ 03FB.
Sel dengan alamat $ 03FF dapat digunakan oleh dump saat ini.

Seluruh kode sumber mesin fotokopi dan bootloader awal dalam versi STM8 $ 0D dengan sebuah tabel di memori EEPROM di alamat $ 4039 ... $ 405C ($ 4139 ... $ 415C, $ 4239 ... $ 425C).

File 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 



Seluruh kode sumber penyalin awal dan bootloader dalam versi STM8 $ 0D dengan sebuah tabel di memori EEPROM di alamat $ 4065 ... $ 4088 ($ 4165 ... $ 4188).

File 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 



Kami menguraikan program aplikasi paling sederhana untuk dieksekusi dalam memori FLASH STM8.

File 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 



Jahit programmer bootloader di STM8. Kami menghubungkan papan ke adaptor USB-TTL (UART). Jalankan file batch runSTM8uLoader.bat . Tekan tombol reset di papan tulis. Kami mengamati hasilnya:



Kode aplikasi di-flash oleh loader ke memori FLASH, perangkat melakukan reboot. LED mulai berkedip.

Contoh kode sumber dump yang dikirimkan oleh program host ke loader untuk dieksekusi dalam memori RAM:

File 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 



File Reset_128000v0D.asm:
 stm8/ TITLE "Reset_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: ;        RESET ldw X, #$03FF ldw SP, X clrw X clrw Y clr A jp $8000 SKIP 230, $00 end ; Reset_128000v0D.asm 



Dalam kode sumber program host, kesedihan yang sama ini hadir dalam bentuk berikut:

  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 }; 


Artikel sebelumnya: "Cara mengompres bootloader untuk STM8 ke ukuran 18 byte dalam memori FLASH . "
Situs web dengan proyek http://nflic.ru/STM8/STM8uLoader/000.html .
Proyeksikan di https://sourceforge.net/projects/ovsp .
Proyeksikan di https://github.com/ovsp/STM8uLoader .

Saya meminta pembaca untuk kritik dan saran yang ditargetkan untuk pengurangan kode lebih lanjut.

Source: https://habr.com/ru/post/id418483/


All Articles