Назначение начального копировщика boot_FLASH: после сброса STM8 скопировать образ начального загрузчика boot_OPTION из блока памяти OPTION Bytes c адресами $480B...$483F в SRAM память данных/программ по адресам $0000...$0034 и передать управление по адресу $0000. Также часть кода начального копировщика boot_FLASH может быть вызвана начальным загрузчиком boot_OPTION для перемещения кода прикладной программы из памяти EEPROM в память RAM с последующей передачей управления.
Копировщик boot_FLASH версии $14 занимает первые 4 ячейки FLASH памяти программ с адресами $8000...$8003 и последние 16 ячеек FLASH памяти программ с адресами $9FF0...$9FFF, две последние из которых $9FFE:$9FFF содержат адрес передачи управления прикладной программе.
Копировщик boot_FLASH версии $25 занимает первые 4 ячейки FLASH памяти программ с адресами $8000...$8003 и последние 14 ячеек FLASH памяти программ с адресами $9FF2...$9FFF. Адрес передачи управления прикладной программе содержится в регистровой паре $4831:$4832 блока памяти OPTION Bytes.
Версия начального загрузчика $14.
Код начинается с команды [ldw X, SP]. Здесь в индексный регистр X загружается адрес вершины стека ($03FF), который аппаратно попадает в указатель вершины стека SP после сброса микроконтроллера. Необходимо обратить внимание, что аппартная инициализация указателя вершины стека не происходит, если мы попадаем на вектор $8000 не по сбросу, а какой-нибудь командой перехода. Для корректного копирования областей памяти для вызова загрузчика необходимо пользоваться кнопкой сброса (RESET).
Далее команда перехода [jp boot_FLASH_start] к основному коду копировщика boot_FLASH (метка boot_FLASH_start).
; ******************************************************** WORDS ; segment byte at 8000 'RESET_vector' ldw X, SP ; [96] X <- RAM_END jp boot_FLASH_start ; [CC 9F F0] ; здесь может находиться таблица векторов прерываний ; или код/данные основной (прикладной) программы
Ранее в индексный регистр X была загружена величина RAM_END. Теперь в индексный регистр Y загружаем величину boot_OPTION_START + RAM_END. Копируем таблицу boot_OPTION_START ... { boot_OPTION_START + RAM_END } в таблицу 0 ... RAM_END. И переходим по адресу $0000. В регистровой паре $9FFE:$9FFE (метка boot_FLASH_exit_address) содержится адрес перехода к основной (прикладной) программе. Этот адрес использует начальный загрузчик boot_OPTION для передачи управления по окончанию тайм-аута.
; ******************************************************** ; копировщик boot_FLASH ; задача: минимизировать код находящийся во FLASH WORDS ; segment byte at 9FF0-9FFF 'boot_FLASH' boot_FLASH_start: ldw Y, #$4C0A ; [90 AE 4C 0A] Y <- { boot_OPTION_START + RAM_END} ; Y <- { $480B + $03FF = $4C0A } boot_FLASH_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_FLASH_copy ; [2A F8] если X >= RAM_START ; Y >= boot_OPTION_START incw X ; [5C] если X < RAM_START то X = 0 jp (X) ; [FC] передаем управление по адресу $0000 boot_FLASH_exit_address: ; адрес перехода к основной (прикладной) программе dc.w $8004 ; [80 04] $8004...$9FEF во FLASH ; dc.w $0000 ; [00 00] $0000 при переносе кода из EEPROM end
Версия начального загрузчика $25.
Код начинается с команды [ldw X, SP]. Здесь в индексный регистр X загружается адрес вершины стека ($03FF), который аппаратно попадает в указатель вершины стека SP после сброса микроконтроллера. Необходимо обратить внимание, что аппартная инициализация указателя вершины стека не происходит, если мы попадаем на вектор $8000 не по сбросу, а какой-нибудь командой перехода. Для корректного копирования областей памяти для вызова загрузчика необходимо пользоваться кнопкой сброса (RESET).
Далее команда перехода [jp boot_FLASH_start] к основному коду копировщика boot_FLASH (метка boot_FLASH_start).
; ******************************************************** WORDS ; segment byte at 4831-4832 'address' ; адрес перехода к основной (прикладной) программе dc.w $8004 ; [80 04] $8004...$9FF1 во FLASH ; dc.w $0000 ; [00 00] $0000 при переносе кода из EEPROM ; ******************************************************** WORDS ; segment byte at 8000 'RESET_vector' ldw X, SP ; [96] X <- RAM_END jp boot_FLASH_start ; [CC 9F F2] ; здесь может находиться таблица векторов прерываний ; или код/данные основной (прикладной) программы
Ранее в индексный регистр X была загружена величина RAM_END. Теперь в индексный регистр Y загружаем величину boot_OPTION_START + RAM_END. Копируем таблицу boot_OPTION_START ... { boot_OPTION_START + RAM_END } в таблицу 0 ... RAM_END. И переходим по адресу $0000. В регистровой паре $4831:$4832 содержится адрес перехода к основной (прикладной) программе. Этот адрес использует начальный загрузчик boot_OPTION для передачи управления по окончанию тайм-аута.
; ******************************************************** ; копировщик boot_FLASH ; задача: минимизировать код находящийся во FLASH WORDS ; segment byte at 9FF2-9FFF 'boot_FLASH' boot_FLASH_start: ldw Y, #$4C0A ; [90 AE 4C 0A] Y <- { boot_OPTION_START + RAM_END} ; Y <- { $480B + $03FF = $4C0A } boot_FLASH_copy: ld A, (Y) ; [90 F6] ld (X), A ; [F7] decw Y ; [90 5A] decw X ; [5A] jrpl boot_FLASH_copy ; [2A F8] если X >= RAM_START ; Y >= boot_OPTION_START incw X ; [5C] если X < RAM_START то X = 0 jp (X) ; [FC] передаем управление по адресу $0000 end
Машинные коды STM8 и команды ассемблера здесь. Адресное пространство STM8S103F3 тут.