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

في عملية البحث عن محمل الإقلاع للميكروكونترولر STM8S103F3 ، وجد أن محمل الإقلاع المتاح مكتوب بشكل رئيسي في "C" ، "سرقة" كمية كبيرة من ذاكرة FLASH ، ونقل جدول ناقلات المقاطعة.

كان برنامج bootloader ضروريًا لبعض الأجهزة التي يستحيل توصيل المبرمج بها.

تقرر تجربة كتابة محمل إقلاع بنفسك بالمتطلبات التالية:

- يجب تسمية المحمل STM8uLoader ؛
- يجب كتابة الرمز في المجمع (لم يتم منع فائدة المجمع بعد قانونًا) ؛
- يجب أن يشغل محمل الإقلاع أصغر كمية ممكنة في ذاكرة فلاش ، ويعتبر المبلغ المشغول في الكمبيوتر غير محدود ؛
- يجب ألا يقوم اللودر بتحريك جدول ناقلات المقاطعة ؛
- يجب أن يحتوي محمل الإقلاع على الحد الأدنى من الوظائف ، ويجب أن يتولى الكمبيوتر جميع الوظائف الرئيسية ؛
- يجب أن ينقل محمل الإقلاع التحكم إلى البرنامج التطبيقي في غضون فترة زمنية معقولة بعد إعادة التشغيل / التشغيل إذا لم يكن هناك اتصال بالكمبيوتر.

تم استيفاء الشرط الأول على الفور ، ولكن كان لا بد من العمل على المتطلبات اللاحقة.

المرحلة الأولى. كود 65 بايت في ذاكرة فلاش


لحفظ جدول المتجهات في مكانه ، تقرر وضع الرمز في نهاية ذاكرة FLASH والتبديل إليه على الفور من ناقل التفريغ 8000 دولار.

عند الإقلاع ، يتم نقل التحكم إلى رمز أداة تحميل التشغيل عند 9FC2 دولارًا. يقوم المُحمل بتكوين UART 9600 8N1 ، وينتظر وحدتي بايت لـ UART ، وبدون انتظار ، ينقل التحكم إلى برنامج التطبيق على العنوان المخزن في الزوج $ 9FFE: $ 9FFF.

إذا تلقى المحمل وحدات البايت العالية والمنخفضة لحجم التفريغ المتوقع من البرنامج المضيف ، فإنه يأخذ التفريغ نفسه ، ويضع التفريغ في ذاكرة RAM وينقل التحكم إليه.
علاوة على ذلك ، فإن كل العناية تكمن في البرنامج الموجود في الكمبيوتر والتفريغ الذي يرسله. يجب أن ترسل بالضبط عمليات التفريغ اللازمة لإكمال المهمة الحالية (قراءة / مسح / كتابة / نسخ خلايا الذاكرة STM8). يجب أن تكون المقالب قادرة على استبدال بعضها البعض في ذاكرة RAM والتحكم في النقل إلى برنامج التطبيق.

عنوان الانتقال إلى التطبيق هو $ 9FFE: $ 9FFF.

ملف boot_FLASH.asm:
stm8/ TITLE "boot_FLASH.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 8000 'boot_start' boot_start: jp boot_FLASH_start dc.b $00 ; boot_FLASH ; ******************************************************** ;  0x8004...0x9FC1      WORDS ; segment byte at 8004 'main_FLASH' main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ;   bset PB_DDR,#5 bset PB_CR1,#5 ;   byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ;   bres PB_DDR,#5 ; bres PB_CR1,#5 ; ;   byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret segment byte at 9FC2 'boot_FLASH' boot_FLASH_start: mov UART1_BRR1, #13; Fmaster=16/8=2/9600/16 mov UART1_CR2, #%00001100;  / ;   UART1   RST_SR boot_FLASH_RST_SR_tx: mov UART1_DR, RST_SR ;    ,      ;      ;    X    ( 200 ) ldw X,#0 boot_FLASH_wait_byte1: decw X jreq boot_FLASH_exit;       btjf UART1_SR, #5, boot_FLASH_wait_byte1 ;   ,   , ;  X     ld A, UART1_DR ld XH, A ;      boot_FLASH_wait_byte2: btjf UART1_SR, #5, boot_FLASH_wait_byte2 ;    ld A, UART1_DR ld XL, A ;  X -    ;   X       ldw Y, #$0400 ;  Y   0x0400 (RAM_END + 1) ;    boot_FLASH_rx_block_wait: btjf UART1_SR, #5, boot_FLASH_rx_block_wait boot_EEPROM_rx_block_entry: decw Y ;      Y     ld A, UART1_DR ld (Y), A decw X ;      X      jrne boot_FLASH_rx_block_wait ;      jp (Y) ;    ()  boot_FLASH_exit: dc.b $CC boot_FLASH_exit_addr: dc.w main_FLASH_start end ; 


المرحلة الثانية. حجم الرمز 21 بايت في FLASH و 52 بايت في ذاكرة EEPROM


إن اختيار 65 بايت من ذاكرة فلاش (في STM8S103F3 هو 8192 بايت فقط) ليس أمرا إنسانيا. بعد كل شيء ، ذاكرة EEPROM غير الضرورية مع 640 بايت تقع على مقربة. لنقم بتقسيم كود برنامج bootloader إلى جزأين boot_FLASH و boot_EEPROM.

عند التحميل ، يتم نقل عنصر التحكم إلى رمز boot_FLASH في $ 9FEF. يقوم boot_FLASH بنسخ صورة رمز boot_EEPROM من EEPROM إلى ذاكرة RAM وينقل التحكم إليها.

الآن يقوم boot_EEPROM بتهيئة UART 9600 8N1 ، وينتظر UART bytes ، وبدون انتظار ، ينقل التحكم إلى برنامج التطبيق (سنترك العنوان في نفس المكان $ 9FFE: $ 9FFF).

إذا تلقى boot_EEPROM بايت بحجم التفريغ المتوقع لذاكرة RAM ، فإنه يتلقى تفريغًا ، ويضع التفريغ في منطقة أخرى من ذاكرة RAM وينقل التحكم إليه.

علاوة على ذلك ، كل شيء كما هو في المرحلة الأولى.

ملف boot_FLASH_EEPROM.asm:
 stm8/ TITLE "boot_FLASH_EEPROM.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 4000 'eeprom' ;  boot_EEPROM dc.b $35, $0D, $52, $32, $35, $0C, $52, $35 dc.b $35, $01, $52, $31, $5A, $27, $16, $72 dc.b $0B, $52, $30, $F8, $C6, $52, $31, $72 dc.b $0B, $52, $30, $FB, $3B, $52, $31, $4A dc.b $26, $F5, $96, $5C, $FC, $CE, $9F, $FE dc.b $2B, $FA, $90, $AE, $42, $7F, $AE, $02 dc.b $7F, $CC, $9F, $F4 segment byte at 8000 'boot_start' boot_start: jp boot_FLASH_start dc.b $01 ; boot_FLASH_EEPROM ; ******************************************************** ;  0x8004...0x9FEE      segment byte at 8004 'main_FLASH' ;   main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ;   bset PB_DDR,#5 bset PB_CR1,#5 ;   byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ;   bres PB_DDR,#5 ; bres PB_CR1,#5 ; ;   byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret ;   EEPROM -> RAM segment byte at 9FEF 'boot_FLASH' boot_FLASH_start: ldw X, SP ; Y <- { EEPROM_START + RAM_END} ; Y <- { $4000 + $03FF = $43FF } ldw Y, #$43FF boot_FLASH_copy: ld A, (Y) ld (X), A decw Y decw X jrpl boot_FLASH_copy incw X jp (X) boot_FLASH_exit_address: dc.w main_FLASH_start end ; 


قم بتشغيل الملف runSTM8uLoader.bat ، اضغط على زر إعادة الضبط على اللوحة ، يرسل محمل الإقلاع البايت 0x01. يتم إرسال ملف تفريغ مع الرمز من ملف main_RAM.hex إلى RAM STM8 عبر UART. يبدأ اللوحة في وميض LED ويرسل بايت 0x20 و 0x02. اضغط على زر إعادة الضبط مرة أخرى. يتم تشغيل البرنامج التطبيقي من ذاكرة FLASH ، ويبدأ مصباح LED في الوميض بشكل أسرع ويرسل وحدات البايت 0x80 و 0x08.


المرحلة الثالثة. حجم الرمز 18 بايت في ذاكرة FLASH و 52 بايت في OPTION Bytes


بالطبع ، سارعنا بذاكرة EEPROM. أين يتم تخزين الجيب والطاولات الأخرى الآن؟ ومع ذاكرة فلاش ، ليس كل شيء واضحًا. من قرر تخزين عنوان التحكم في النقل للبرنامج التطبيقي في ذاكرة فلاش؟ ويتم تخزين نفس البايت من إصدار برنامج bootloader بشكل عام في مكانين في وقت واحد. أين يتم ضغط 52 بايت مخصص لـ EEPROM؟

هنا تساعدنا الطباعة الحجرية. تتكون ذاكرة EEPROM من 10 كتل لكل منها 64 بايت. إن إضافة كتلة أخرى إلى هذه الكتل ، ولكن بحجم مختلف ، ليست مجدية اقتصاديًا. قامت شركة STMicroelectronics بذلك ، وأضافت كتلة 64 بايت أخرى ، سميت هذه المنطقة OPTION Bytes وتخزن إعدادات متحكم دقيق غير متطايرة هناك (بالنسبة لـ STM8S103F3 فهي تصل إلى 11 بايت). وبالطبع ، نسيت STM أن تذكر أنه لا يزال هناك 53 خلية وظيفية متبقية في هذا المجال. يبدو أن هناك الكثير من طرازات STM8 ، فأنت بحاجة إلى ترك مساحة لإعدادات مهمة في المستقبل.

يدعي محمل الإقلاع لدينا فقط على طراز STM8 بدون محمل إقلاع مدمج. لذلك ، نأخذ الخلايا الاحتياطية لكتلة OPTION Bytes حتى الآن لا يراها أحد. صحيح ، هناك إزعاج واحد صغير ، ولكن تم حله . لن يسمح لك المبرمج التقليدي بكتابة المعلومات إلى هذه الخلايا.

عند التحميل ، يتم نقل عنصر التحكم إلى رمز copy_boot_FLASH الأولي بسعر $ 9FF2. ينقل boot_FLASH صورة محمل الإقلاع boot_OPTION من منطقة OPTION بايت إلى ذاكرة الوصول العشوائي.

يقوم boot_OPTION بتهيئة UART 9600 8N1 ، ويرسل UART بايت مع إصداره ، وينتظر UART بايت من البرنامج المضيف ، ودون انتظار 0.2 ثانية للتحكم في عمليات النقل إلى برنامج التطبيق على العنوان الموجود في الزوج 4831 دولارًا: 4832 دولارًا.

إذا أخذ boot_OPTION ، بعد إرسال بايت مع نسخته ، بايتًا من حجم التفريغ المتوقع ، فإنه يأخذ التفريغ نفسه ، ويضع التفريغ في ذاكرة RAM وينقل التحكم إليه.
علاوة على ذلك ، فإن كل العناية تكمن في البرنامج الموجود في الكمبيوتر والتفريغ الذي يرسله. يجب أن ترسل بالضبط عمليات التفريغ اللازمة لإكمال المهمة الحالية (قراءة / مسح / كتابة / نسخ خلايا الذاكرة STM8). يجب أن تكون المقالب قادرة على استبدال بعضها البعض في ذاكرة RAM والتحكم في النقل إلى برنامج التطبيق.

عنوان الانتقال إلى التطبيق هو 4831 دولارًا: 4832 دولارًا.

كود التحميل والتطبيق للتنفيذ في ذاكرة FLASH:
 stm8/ TITLE "boot_FLASH_OPTION.asm" .NOLIST #include "STM8S103F3P.inc" .LIST MOTOROLA WORDS segment byte at 4800 'boot_OPTION' ;    boot_OPTION dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00 dc.b $FF, $00, $FF, $35, $0D, $52, $32, $35 dc.b $0C, $52, $35, $35, $25, $52, $31, $5A dc.b $27, $16, $72, $0B, $52, $30, $F8, $C6 dc.b $52, $31, $72, $0B, $52, $30, $FB, $3B dc.b $52, $31, $4A, $26, $F5, $96, $5C, $FC dc.b $AE, $80, $04, $2B, $FA, $90, $AE, $42 dc.b $7F, $AE, $02, $7F, $CC, $9F, $F6, $00 segment byte at 8000 'boot_start' boot_start: ldw X, SP jp boot_FLASH_start ; ******************************************************** ;  0x8004...0x9FF1      segment byte at 8004 'main_FLASH' ;   main_FLASH_start: ldw X, #$03FF ldw SP, X mov UART1_BRR1, #13 mov UART1_CR2, #%00001100 main_FLASH_cycle: callr main_delay ;   bset PB_DDR,#5 bset PB_CR1,#5 ;   byte1_tx: mov UART1_DR, #$80 byte1_wait_tx btjf UART1_SR, #7, byte1_wait_tx callr main_delay boot_RAM_exit1: ;   bres PB_DDR,#5 ; bres PB_CR1,#5 ; ;   byte2_tx: mov UART1_DR, #$08 byte2_wait_tx btjf UART1_SR, #7, byte2_wait_tx jra main_FLASH_cycle main_delay: decw X jrne main_delay ret ;   OPTION -> RAM segment byte at 9FF2 'boot_FLASH' boot_FLASH_start: ; Y <- { OPTION_START + RAM_END} ; Y <- { $4800 + $03FF = $43FF } ldw Y, #$43FF boot_FLASH_copy: ld A, (Y) ld (X), A decw Y decw X jrpl boot_FLASH_copy incw X jp (X) boot_FLASH_exit_address: dc.w main_FLASH_start end ; 


كود التطبيق للتنفيذ في ذاكرة RAM:
 stm8/ TITLE “boot_RAM.asm” MOTOROLA #include "STM8S103F3P.inc" BYTES segment byte at 0000 'boot_RAM_data' boot_RAM_start: ;  pull-up   (     )   ,   ,  14  ; ld A, #%01001100 ; [A6 4C] ; cpl A ; [43] ; ld PA_CR1, A ; [C7 50 03] ; ld PB_CR1, A ; [C7 50 08] ; ld PC_CR1, A ; [C7 50 0D] ; ld PD_CR1, A ; [C7 50 12]   PD6(UART1_RX), PD2, PD1 ;  UART1  /   9600,     (8 ,   , 1  ) ; mov UART1_BRR2, #0 ; [35 00 52 33]  Fmaster=16/8=2  9600 mov UART1_BRR1, #13 ; [35 0D 52 32]  Fmaster=16/8=2  9600 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1  / ;    UART1 boot_RAM_byte1_tx: mov UART1_DR, #$02 boot_RAM_byte1_wait_tx btjf UART1_SR, #7, boot_RAM_byte1_wait_tx ldw X,#0 ; [AE 00 00] boot_FLASH     X boot_RAM_wait1: decw X ; [5A] jreq boot_RAM_exit1 ; jra boot_RAM_wait1 boot_RAM_exit1: ;   bres PB_DDR,#5 ; bres PB_CR1,#5 ; ;    UART1 boot_RAM_byte2_tx: mov UART1_DR, #$20 ; [35 11 52 31] boot_RAM_byte2_wait_tx btjf UART1_SR, #7, boot_RAM_byte2_wait_tx ldw X,#0 ; [AE 00 00] boot_FLASH     X boot_RAM_wait2: decw X ; [5A] jreq boot_RAM_exit2 ; jra boot_RAM_wait2 boot_RAM_exit2: ;   bset PB_DDR,#5 ; bset PB_CR1,#5 ; jra boot_RAM_byte1_tx end 

قم بتشغيل الملف runSTM8uLoader.bat ، اضغط على زر إعادة الضبط على اللوحة ، يرسل محمل الإقلاع البايت 0x25. يتم إرسال ملف تفريغ مع الرمز من ملف main_RAM.hex إلى RAM STM8 عبر UART. يبدأ اللوحة في وميض LED ويرسل بايت 0x20 و 0x02. اضغط على زر إعادة الضبط مرة أخرى. يتم تشغيل البرنامج التطبيقي من ذاكرة FLASH ، ويبدأ مصباح LED في الوميض بشكل أسرع ويرسل وحدات البايت 0x80 و 0x08.


في المرحلة الأخيرة ، لكتابة صورة برنامج bootloader إلى منطقة OPTION Bytes ، يجب عليك استخدام الطريقة . جوهر الطريقة هو أنك تحتاج أولاً إلى المبرمج لكتابة ملف البرامج الثابتة boot_OPTION_rev25.hex إلى ذاكرة STM8 FLAH ، وإعادة تشغيل وحدة التحكم الدقيقة ، وسيتم ملء منطقة OPTION Bytes بالمعلومات الضرورية وسيتم تشغيل LED. ثم مرة أخرى ، يكتب المبرمج إلى ملف البرامج الثابتة FLASH من هذه المقالة boot_FLASH_OPTION.hex .

تمت إضافة إصدار رمز أداة تحميل "نظيفة" 0x14 بدون رمز التطبيق. نشر صورة boot_OPTION على شفرة المصدر. التعليقات المصححة. على عكس الإصدار 25 دولارًا ، يوجد عنوان نقل التحكم الخاص بالتطبيق في خلايا $ 9FFE: $ 9FFFF FLASH. الحجم في فلاش 20 بايت على التوالي.
boot_uC_rev14.asm:
 stm8/ TITLE "boot_uC_rev14.asm" ; boot_uC = boot_OPTION + boot_FLASH MOTOROLA .NOLIST #include "STM8S103F3P.inc" .LIST WORDS ; ******************************************************** segment byte at 4800 'boot_O_IMG' ;0000FF00FF00FF00FF00FF350D523235 ;0C5235351452315A2716720B5230F8C6 ;5231720B5230FB3B52314A26F5965CFC ;CE9FFE2BFA90AE427FAE027FCC9FF400 ;    ; $4800    RAM dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF ; OPTION (RAM) ; $480B ($0000)    boot_O boot_O_start: ;  UART 96008N1 Fmaster=16/8=2/9600/16 ; mov UART1_BRR2, #0 ; [35 00 52 33]     mov UART1_BRR1, #13 ; [35 0D 52 32] ; UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1  / mov UART1_CR2, #%00001100 ; [35 0C 52 35] ; $4813 ($0008) boot_E_byte1_tx: ;   $14  mov UART1_DR, #$14 ; [35 14 52 31] ;    ,     ;      ;  X   ( 200 ) ; clrw X ; [5F]  X   boot_F ; $4817 ($000C) boot_O_rx_wait_byte: decw X ; [5A] jreq boot_O_exit ; [27 16]       btjf UART1_SR, #5, boot_O_rx_wait_byte ; [72 OB 52 30 F8] ;   ,   ,  A    ; $481F ($0014) ld A, UART1_DR ; [C6 52 31] ; $4822 ($0017)    boot_O_rx_wait_block: btjf UART1_SR, #5, boot_O_rx_wait_block ; [72 OB 52 30 FB] push UART1_DR ; [3B 52 31] dec A ; [4A] ;      A      jrne boot_O_rx_wait_block ; [26 F5] ; $482D ($0022)      ldw X, SP ; [96] incw X ; [5C] boot_O_exit_to_FLASH: jp (X) ; [FC] ; $4830 ($0025)     boot_O_exit: ldw X, boot_F_exit_address ; [CE 9F FE] jrmi boot_O_exit_to_FLASH ; [2B FA] ; if X < $8000     $0000 ;     EEPROM boot_O_exit_to_EEPROM: ; Y <- { EEPROM_END} ldw Y, #$427F ; [90 AE 42 7F] ; X <- { EEPROM_END - EEPROM_START } ;   EEPROM  RAM ldw X, #$027F ; [AE 02 7F] jp boot_F_copy ; [CC 9F F4] ; $483F ($0034) dc.b $00 ;   boot_O_end: ; ******************************************************** segment byte at 8000 'RESET_vector' ;96CC9FF0 ldw X, SP ; [96] X <- RAM_END jp boot_F_start ; [CC 9F F0] ; ******************************************************** ;  0x8004...0x9FEF      segment byte at 8004 'main_FLASH' ;20FE jra * ; [20 FE] ; ******************************************************** ;   boot_FLASH segment byte at 9FF0 'boot_F' ;90AE4C0A90F6F7905A5A2AF85CFC8004 boot_F_start: ; Y <- { boot_O_START + RAM_END} { $480B + $03FF = $4C0A } ldw Y, #$4C0A ; [90 AE 4C 0A] ;     ; boot_FLASH, boot_OPTION      boot_F_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_F_copy ; [2A F8]  X(Y) >= RAM_START(boot_O_START) incw X ; [5C] jp (X) ; [FC] boot_F_exit_address: dc.w $8004 ; [80 04] ; dc.w $0000 ; [00 00] end ; 

تمت إضافة إصدار رمز أداة تحميل "نظيفة" 0x25 بدون رمز التطبيق. نشر صورة boot_OPTION على شفرة المصدر. التعليقات المصححة. على عكس الإصدار 14 دولارًا ، يوجد عنوان نقل التحكم الخاص بالتطبيق في الخلايا $ 4831: $ 4832 من منطقة OPTION Bytes. انخفض الحجم المشغول في ذاكرة فلاش ، على التوالي ، إلى 18 بايت. لم يتغير الحجم المشغول في منطقة OPTION Bytes (52 بايت + 1 احتياطي).
boot_uC_rev14.asm:
 stm8/ TITLE "boot_uC_rev25.asm" ; boot_uC = boot_OPTION + boot_FLASH MOTOROLA .NOLIST #include "STM8S103F3P.inc" .LIST BYTES ; ******************************************************** ;        EEPROM  ; boot_O_exit_address    $0000 (   <$8000) ;       ;          segment byte at 0000 'boot_O_IMG' main_ram: ;20FE jra * ; [20 FE] WORDS ; ******************************************************** segment byte at 4800 'boot_O_IMG' ;0000FF00FF00FF00FF00FF350D523235 ;0C5235351452315A2716720B5230F8C6 ;5231720B5230FB3B52314A26F5965CFC ;AE80042BFA90AE427FAE027FCC9FF600 ;    ; $4800    RAM dc.b $00, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF ; OPTION (RAM) ; $480B ($0000)    boot_OPTION boot_O_start: ;  UART 96008N1 Fmaster=16/8=2/9600/16 ; mov UART1_BRR2, #0 ; [35 00 52 33]     mov UART1_BRR1, #13 ; [35 0D 52 32] ; UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1  / mov UART1_CR2, #%00001100 ; [35 0C 52 35] ; $4813 ($0008) boot_E_byte1_tx: ;   $14  mov UART1_DR, #$14 ; [35 14 52 31] ;    ,     ;      ;  X   ( 200 ) ; clrw X ; [5F]  X   boot_F ; $4817 ($000C) boot_O_rx_wait_byte: decw X ; [5A] jreq boot_O_exit ; [27 16]       btjf UART1_SR, #5, boot_O_rx_wait_byte ; [72 OB 52 30 F8] ;   ,   ,  A    ; $481F ($0014) ld A, UART1_DR ; [C6 52 31] ; $4822 ($0017)    boot_O_rx_wait_block: btjf UART1_SR, #5, boot_O_rx_wait_block ; [72 OB 52 30 FB] push UART1_DR ; [3B 52 31] dec A ; [4A] ;      A      jrne boot_O_rx_wait_block ; [26 F5] ; $482D ($0022)      ldw X, SP ; [96] incw X ; [5C] boot_O_exit_to_FLASH: jp (X) ; [FC] ; $4830 ($0025)     boot_O_exit: dc.b $AE ; ldw X, #boot_O_exit_address ; [AE 80 04] ; $4831 ($0026) ;      boot_O_exit_address: dc.w main_flash ; [80 04] ; dc.w main_ram ; [00 00] jrmi boot_O_exit_to_FLASH ; [2B FA] ; if X < $8000     $0000 ;     EEPROM boot_O_exit_to_EEPROM: ; Y <- { EEPROM_END} ldw Y, #$427F ; [90 AE 42 7F] ; X <- { EEPROM_END - EEPROM_START } ;   EEPROM  RAM ldw X, #$027F ; [AE 02 7F] jp boot_F_copy ; [CC 9F F4] ; $483F ($0034) dc.b $00 ;   boot_O_end: ; ******************************************************** segment byte at 8000-8003 'RESET_vector' ;96CC9FF2 ldw X, SP ; [96] X <- RAM_END jp boot_F_start ; [CC 9F F2] ; ******************************************************** ;  0x8004...0x9FF1      segment byte at 8004 'main_FLASH' main_flash: ;20FE jra * ; [20 FE] ; ******************************************************** ;   boot_FLASH segment byte at 9FF2-9FFF 'boot_F' ;90AE4C0A90F6F7905A5A2AF85CFC boot_F_start: ; Y <- { boot_O_START + RAM_END} { $480B + $03FF = $4C0A } ldw Y, #$4C0A ; [90 AE 4C 0A] ;     ; boot_FLASH, boot_OPTION      boot_F_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_F_copy ; [2A F8]  X(Y) >= RAM_START(boot_O_START) incw X ; [5C] jp (X) ; [FC] end ; 

يمكن تحديد عنوان نقل التحكم للتطبيق في ذاكرة FLASH من نطاق $ 8004 ... $ 9FF1. للحصول على صورة رمز التطبيق من ذاكرة EEPROM ، لا يمكن نقل عنصر التحكم إلا على العنوان $ 0000 في ذاكرة RAM.
يمكن للبرنامج المضيف تمرير أي عنوان نقل تحكم كوسيطة سطر الأوامر الثانية.
يمكن العثور على الكود المصدري للبرنامج المضيف هنا . هناك أيضًا جهات اتصال لمزيد من التواصل التفصيلي.
أطلب من القراء الانتقادات الموجهة والاقتراحات لمزيد من تخفيض التعليمات البرمجية.

أقترح أيضًا قراءة المقالة "كيفية ضغط محمل الإقلاع لـ STM8 إلى حجم 8 بايت في ذاكرة FLASH" .

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


All Articles