NFLic

STM8uLoader

Функционал начального копировщика boot_FLASH. (Статья 2)

Назначение начального копировщика 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 тут.

 

[Требования к загрузчику. (Статья 1)] [Оглавление.] [Функционал начального загрузчика boot_OPTION. (Статья 3)]