كيفية ضغط محمل الإقلاع لـ STM8 إلى حجم 8 بايت في ذاكرة فلاش

منذ كتابة المقال السابق ، "كيفية ضغط STM8 Boot Loader إلى 18 بايت في ذاكرة FLASH" ، ظهر إصداران من STM8uLoader bootloader. تعلم الإصدار 36 دولارًا من برنامج STM8uLoader bootloader كيفية نقل التحكم في برنامج تطبيق إلى أي عنوان في ذاكرة الوصول العشوائي دون مشاركة برنامج مضيف. لم يتغير حجم 18 بايت من برنامج bootloader في ذاكرة FLASH ؛ في منطقة OPTION Bytes ، زاد الحجم إلى 53 بايت (استهلك كل المساحة المتاحة).

تم تخصيص فرع منفصل لمحمل الإقلاع $ 0D . الشرط الرئيسي لهذا الإصدار هو ضغط الكود قدر الإمكان. حتى الآن ، حجم الرمز في ذاكرة فلاش هو 8 بايت في ذاكرة EEPROM من 35 بايت.

دعني أذكرك ببنية محمل إقلاع STM8uLoader. يتكون برنامج bootloader من برنامج مضيف boot_PC ورمز برنامج boot_uC bootloader في ذاكرة STM8. وينقسم هذا الأخير إلى رمز النسخ الأولي boot_FLASH الموجود في ذاكرة FLASH ورمز برنامج boot_EEPROM (أو boot_OPTION) الموجود في ذاكرة EEPROM (أو منطقة OPTION بايت).

بعد حدث RESET ، يتم تشغيل ناسخ boot_FLASH الأولي ، وينقل صورة رمز bootloadEEPROM (أو boot_OPTION) إلى ذاكرة RAM وينقل التحكم إليها. يقوم محمل الإقلاع بتهيئة UART لنقل بايت البرنامج المضيف برقم إصداره ، وإذا لم يتلق معلومات من البرنامج المضيف أثناء المهلة ، فإنه ينقل التحكم إلى برنامج التطبيق في ذاكرة FLASH. أو ينقل رمز التطبيق من ذاكرة EEPROM (أو منطقة OPTION Bytes) إلى ذاكرة RAM وينقل التحكم إليها.

إذا ، بعد إرسال البايت مع رقم الإصدار إلى البرنامج المضيف ، يتلقى محمل الإقلاع تفريغًا برمز عبر UART ، ثم يضعه في ذاكرة RAM والتحكم في النقل. يؤدي التفريغ المقبول مع الرمز مهمته الحالية: قراءة / نسخ / مسح / كتابة خلايا STM8 ، ونقل التحكم إلى العنوان المحدد مع التهيئة الأولية لسجلات نواة STM8 ، ونقل التحكم إلى أداة تحميل التشغيل لتغيير التفريغ الحالي في ذاكرة الوصول العشوائي من قبل البرنامج المضيف.

مراجعة boot_FLASH للناسخة الأولية. يقع $ 0D في العناوين $ 8000 ... $ 8007 ويحتل تمامًا متجهات RESET و TRAP (مقاطعة البرنامج). بقية المساحة $ 8008 ... $ 9FFF من ذاكرة FLASH يمكن الوصول إليها بالكامل لبرنامج التطبيق. يوجد أيضًا جدول متجه المقاطعة.

ضع في اعتبارك كود الناسخ:

;   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) والدفعة A. . حفظ هذا الحل بايت واحد ، لكنه أدى إلى تضييق مساحة تخزين الجدول مع صورة رمز أداة تحميل التشغيل. البايت المنخفض من $ 88 من عنوان الجدول لا يسمح بوضعه في منطقة OPTION Bytes. بالنسبة لطراز STM8S103F3 ، تتوفر فقط عناوين 4088 و 4188 دولارًا في ذاكرة EEPROM لاستيعاب الجدول المحدد. لمالكي STM8S003F3 مع ذاكرة EEPROM 128 بايت ($ 4000 ... $ 407F) وهذه العناوين غير متاحة. لا يزال هناك ثغرة لهم.

ما عليك سوى تبديل أمري الدفع 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 هنا يعني تمرير التحكم إلى العنوان الموجود في البايتين اللذين كانا مؤخرًا على المكدس. الآن فكر في كود برنامج 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] 


تظهر عناوين الشفرة بعد النسخ إلى المكدس بين قوسين. الأول هو صفر بايت ؛ لا يتم نسخ ذاكرة الوصول العشوائي إلى الذاكرة. فيما يلي عنوان نقل التحكم إلى أداة تحميل التشغيل ، في الواقع ، هذا هو عنوان الخلية التالية في ذاكرة الوصول العشوائي. يحصل هذا الزوج على المكدس ، ولكن بعد ذلك يتم استبداله برمز التفريغ التالي من البرنامج المضيف باعتباره غير ضروري. يتم أيضًا نسخ كافة التعليمات البرمجية اللاحقة على المكدس ، باستثناء زوج له عنوان نقل التحكم الخاص بالتطبيق
فيما يلي تهيئة UART. هنا في جميع السجلات الثلاثة يتم وضع نفس الرقم $ 0D. في الحالة الأولى ، هذه هي سرعة UART (16000000/8/9600/16 = 13). في الحالة الثانية ، هذا هو إذن الإرسال / الاستقبال ، هنا قاطرت قاطرة بخارية جيلًا لمرة واحدة من حدث BREAK. في الحالة الأخيرة ، يتم إرسال إصدار المضيف من برنامج التحميل إلى البرنامج. في الواقع ، سيستقبل البرنامج المضيف وحدتي بايت $ 00 (الحدث BREAK) و $ 0 D (رقم إصدار برنامج تحميل التشغيل) - هذه إشارة أنه يمكنك إرسال تفريغ باستخدام رمز.

التسجيل A بمحتويات $ 0D ثم يؤدي وظائف عداد وحدات البايت المستلمة ويحسبها بزيادة إلى الصفر ، وهو ما يعادل 243 بايتة مستلمة. بهذا الحجم يجب أن يرسل البرنامج المضيف مقالب برمز.

بلغ مؤشر التسجيل X في الناسخ الأولي ما يصل إلى 4068 دولارًا. الآن سيزداد أيضًا إلى صفر (49048 لا يزال متبقيًا) ، مع حساب الوقت المخصص لمحمّل التمهيد. خلال هذا الوقت ، يجب أن يكون لدى محمل الإقلاع الوقت لقبول تفريغ برمز حجمه 243 بايت ووضعه بشكل أكبر على المكدس والتحكم في النقل إليه. خلاف ذلك ، سيتم نقل التحكم إلى البرنامج التطبيقي وسيكون عليك الضغط على زر إعادة التعيين مرة أخرى وإعادة تشغيل البرنامج المضيف.

بعد نقل التحكم إلى التفريغ المستلم ، يظل رمز أداة تحميل التشغيل على المكدس ويسيطر مرة أخرى عندما يقرر البرنامج المضيف استبدال التفريغ بالتعليمة البرمجية. يقع أي تفريغ تم استلامه برمز على المكدس في العناوين $ 02ED ... $ 03DF ويتحكم في العنوان $ 02F0. يقع رمز أداة تحميل التشغيل على المكدس في العناوين $ 03E0 ... $ 03FF ، في البداية يتحكم في العنوان $ 03E0 ، وإذا لزم الأمر ، يتم استدعاء التفريغ مع الرمز على العنوان $ 03E8.
أمر نقل التحكم إلى التطبيق موجود على المكدس عند $ 03FB.
يمكن استخدام خلية بعنوان $ 03FF بواسطة التفريغ الحالي.

كود المصدر الكامل للناسخة الأولية والناسخة التمهيدية في إصدار STM8 $ 0D مع جدول في ذاكرة EEPROM في العناوين $ 4039 ... $ 405C ($ 4139 ... $ 415C ، $ 4239 ... $ 425C).

ملف التمهيد F_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 



نلخص أبسط برنامج تطبيقي للتنفيذ في ذاكرة FLASH لـ STM8.

ملف 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:

قراءة الملف _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 



ملف الكتابةكتل_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 



إعادة تعيين الملف _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 



في شفرة المصدر للبرنامج المضيف ، توجد هذه المقالب نفسها في النموذج التالي:

  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 لحجم 18 بايت في ذاكرة FLASH . "
الموقع مع المشروع http://nflic.ru/STM8/STM8uLoader/000.html .
المشروع على https://sourceforge.net/projects/ovsp .
المشروع على https://github.com/ovsp/STM8uLoader .

أطلب من القراء الانتقادات الموجهة والاقتراحات لمزيد من تخفيض التعليمات البرمجية.

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


All Articles