自从上一篇文章
“如何在闪存 中将STM8引导加载程序
压缩 到18个字节” 撰写以来,
出现了
STM8uLoader引导加载程序的两个版本。 STM8uLoader引导加载程序版本
$ 36学习了如何在没有主机程序参与的情况下将应用程序的控制权转移到RAM存储器中的任何地址。 闪存中引导加载程序的18个字节的大小没有改变;在OPTION Bytes区域中,大小增加到53个字节(占用了所有可用空间)。
分配了
$ 0D引导加载程序的单独分支。 此版本的主要要求是尽可能地压缩代码。 迄今为止,FLASH存储器中的代码大小为35字节的EEPROM存储器中的8字节。
让我提醒您STM8uLoader引导程序的体系结构。 引导加载程序由boot_PC主机程序和STM8存储器中的boot_uC引导加载程序代码组成。 后者分为位于FLASH存储器中的boot_FLASH初始副本代码和位于EEPROM存储器(或OPTION Bytes区域)中的boot_EEPROM(或boot_OPTION)引导加载程序代码。
RESET事件后,boot_FLASH初始复印机启动,将boot_EEPROM(或boot_OPTION)引导加载程序代码映像传输到RAM存储器,并将控制权转移给它。 引导加载程序配置UART,以其版本号将主机字节传输到程序,如果在超时期间未从主机程序接收信息,则将控制权传输到闪存中的应用程序。 或者将应用程序代码从EEPROM存储器(或OPTION Bytes区域)传输到RAM存储器,然后将控制权转移给它。
如果在将带有版本号的字节发送到主机程序后,引导加载程序通过UART接收到包含代码的转储,则它将其放入RAM存储器并进行控制。 接受的带有代码的转储执行其当前任务:读取/复制/擦除/写入STM8单元,通过STM8内核寄存器的初步初始化将控制转移到指定地址,将控制转移到引导加载程序以通过主机程序更改RAM存储器中的当前转储。
初始复印机boot_FLASH修订版。 $ 0D位于地址$ 8000 ... $ 8007上,并且完全占据RESET和TRAP(软件中断)向量。 $ 8008 ... $ 9FFF的其余空间可供应用程序完全访问。 中断向量表也就位。
考虑复制者代码:
; 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
这两个命令的代码在这里相交:ldw X,#$ 4088(ldw X,#$ 4188)命令和pushA。 。 此解决方案节省了一个字节,但导致表存储区的空间与引导加载程序代码的映像缩小了。 表地址的低字节$ 88不允许将其放在OPTION Bytes区域中。 对于STM8S103F3型号,EEPROM存储器中只有$ 4088和$ 4188地址可用于容纳指定的表。 对于具有EEPROM存储器128个字节($ 4000 ... $ 407F)的STM8S003F3的所有者,这些地址不可用。 他们仍然有漏洞。
您只需要交换push A和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
在这里,当您第一次进入循环时,将执行ldw X,#$ 405A($ 415A,$ 425A)命令,而不执行decw X命令。
回想一下,通过RESET事件,SP堆栈的顶部指针用值$ 03FF进行了硬件初始化。 堆栈朝着地址减少的方向增长。 为了从尾部填充堆栈,我们还将从尾部读取带有引导程序代码的表,从而读取decw X命令,从而定位EEPROM存储器中的引导程序代码的映像。
为了省钱,他们放弃了循环计数器。 我们同意,引导加载程序的代码映像仅在表的开头具有零字节,并且将控制传输地址移至表外的应用程序(可能具有零字节)。 在每次迭代时,我们从表中读取该字节,如果该字节不为零,则将其压入堆栈。 读取零字节-退出循环的条件。
ret命令在这里意味着将控制权传递到堆栈中最后两个字节中包含的地址。 现在考虑引导加载程序代码:
; 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]
复制到堆栈后的代码地址显示在括号中。 第一个是零字节; RAM不会复制到内存。 接下来是将控制转移到引导加载程序的地址,实际上,这是RAM中下一个单元的地址。 这对进入堆栈,但随后不必要地被来自主机程序的下一个转储代码覆盖。 除了带有应用程序的控制传输地址的一对以外,所有后续代码也都将复制到堆栈中
以下是UART的初始化。 在这三个寄存器中都放置了相同的编号$ 0D。 在第一种情况下,这是UART速度(16000000/8/9600/16 = 13)。 在第二种情况下,这是发送/接收的许可,此处蒸汽机车捕获了一次BREAK事件。 在后一种情况下,这会将加载程序的主机版本发送到程序。 实际上,主机程序将接收两个字节$ 00(事件BREAK)和$ 0D(引导加载程序的版本号)-这是一个信号,您可以使用代码发送转储。
$ 0D内容的寄存器A然后执行接收字节计数器的功能,并以0为增量对它们进行计数,这等于243个接收字节。 主机程序应以此大小发送带有代码的转储。
初始抄写员中的索引寄存器X达到$ 4068。 现在,它还将增加到零(仍剩余49048),计算分配给引导加载程序的时间。 在这段时间内,引导加载程序应该有时间接受大小为243字节的代码的转储,并将其进一步放在堆栈上并转移控制权。 否则,控制权将转移到应用程序,您将不得不再次按下复位按钮并重新启动主机程序。
将控制权转移到接收到的转储后,引导加载程序代码将保留在堆栈上,并在主机程序决定用该代码替换转储时再次控制。 任何接收到的带有代码的转储都位于$ 02ED ... $ 03DF地址的堆栈上,并控制着$ 02F0地址。 引导加载程序代码位于堆栈上,地址为$ 03E0 ... $ 03FF,最初它控制地址为$ 03E0,并且,如有必要,带有代码的转储将在地址$ 03E8处调用。
向应用程序的控制传递命令位于$ 03FB的堆栈中。
当前转储可以使用地址为$ 03FF的单元格。
STM8版本$ 0D中初始复印机和引导程序的整个源代码,并在EEPROM存储器中有一个表,地址为$ 4039 ... $ 405C($ 4139 ... $ 415C,$ 4239 ... $ 425C)。
文件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
初始复制器和引导程序在STM8版本$ 0D中的完整源代码,在EEPROM存储器中有一个表,地址为$ 4065 ... $ 4088($ 4165 ... $ 4188)。
文件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
我们概述了在STM8的FLASH存储器中执行的最简单的应用程序。
文件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
在STM8中缝制程序员的引导程序。 我们将开发板连接到USB-TTL适配器(UART)。 运行批处理文件
runSTM8uLoader.bat 。 按下板上的重置按钮。 我们观察到结果:

加载程序将应用程序代码闪存到闪存中,然后设备重启。 LED开始闪烁。
主机程序发送到加载程序以在RAM内存中执行的转储源代码示例:
文件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
文件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
文件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
在主机程序的源代码中,这些相同的转储以以下形式存在:
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 };
上一篇文章:
“如何将STM8的引导程序压缩为FLASH存储器中的18个字节 。
”带有项目的网站
http://nflic.ru/STM8/STM8uLoader/000.html 。
在
https://sourceforge.net/projects/ovsp上进行项目。
项目位于
https://github.com/ovsp/STM8uLoader 。
我要求读者有针对性的批评和建议,以进一步减少代码。