Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: собственный загрузчик для STM32
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
mronetwo
Собственно, мешается это долбанное значение для стек поинтера. Если разместить загрузчик в начале то придется его целиком стирать для того чтобы переписать это значение вместе с вектором ресета, а это опасно. Если размещать в конце памяти - тратиться 128К под сам загрузчик и еще 128К под константы которые тоже всячески могут переписываться. Это тоже никуда не годится. Если писать загрузчик во второй сектор, константы в третий - непонятно каким образом должен выглядеть скрипт для линкера для загружаемой программы (IAR).

Я уже башку сломал, и не только себе, в попытках придумать как правильно. Кто реализовывал уже - поделитесь идеями пжалста.
Сергей Борщ
QUOTE (mronetwo @ May 24 2012, 13:23) *
придется его целиком стирать для того чтобы переписать это значение вместе с вектором ресета
А что мешает использовать __set_MSP(), взяв это значение из векторов приложения непосредственно перед передачей управления приложению?
Откуда смещение в 128К? Значение VTOR может быть любым кратным 512 байт, размер страницы флеша - 1К или 2К.
mronetwo
Цитата(Сергей Борщ @ May 24 2012, 14:44) *
А что мешает использовать __set_MSP(), взяв это значение из векторов приложения непосредственно перед передачей управления приложению?


Только мое глубокое владение вопросом. Спасибо за подсказку!


Цитата(Сергей Борщ @ May 24 2012, 14:44) *
Откуда смещение в 128К? Значение VTOR может быть любым кратным 512 байт, размер страницы флеша - 1К или 2К.


Речь не о смещении, я про объем. Флеш в конце делиться на сектора по 128К.

Цитата(Сергей Борщ @ May 24 2012, 14:44) *
размер страницы флеша - 1К или 2К.


погодите-ка, а это где? У меня f205 в качестве подопытного. Не там там таких страничек.
Сергей Борщ
QUOTE (mronetwo @ May 24 2012, 14:06) *
Речь не о смещении, я про объем. Флеш в конце делиться на сектора по 128К.
Так это в конце. Неужели для загрузчика мало первого сектора в 16К? Ну двух первых секторов по 16К. Ну четырех... А остальное - под настройки и приложение отдать.
QUOTE (mronetwo @ May 24 2012, 14:06) *
погодите-ка, а это где? У меня f205 в качестве подопытного.
А это в F100 wink.gif Видите - неточный вопрос породил неожиданный ответ.
mronetwo
Цитата(Сергей Борщ @ May 24 2012, 15:40) *
Так это в конце. Неужели для загрузчика мало первого сектора в 16К? Ну двух первых секторов по 16К. Ну четырех... А остальное - под настройки и приложение отдать.


Не мало.Ппросто чтобы не затирать его (ну не увидел я что ему sp так легко переинитить) расположить в конце, а приложение в начале и при загрузке подменять приложению вектор ресета. Вариант такой был неудачный.

Цитата(Сергей Борщ @ May 24 2012, 15:40) *
А это в F100 wink.gif Видите - неточный вопрос породил неожиданный ответ.



Да я вижу подпись sm.gif. Однако, вопрос был не в этом!
KnightIgor
Цитата(mronetwo @ May 24 2012, 14:06) *
Не мало.Ппросто чтобы не затирать его (ну не увидел я что ему sp так легко переинитить) расположить в конце, а приложение в начале и при загрузке подменять приложению вектор ресета. Вариант такой был неудачный.

Тут как раз недавно написал загрузчик под наши нужды. Основные параметры: расположен в первых 16K памяти, считывает прошивку с SD-карты, приложение должно располагаться выше 16K (то есть, загрузчик присутствует всегда).

О стеке.
В приложениях я располагаю его в самом верху имеющегося RAM. Для этого я модифицирую ассемблерный startup файл. Например:

Код
    
IF  :DEF:   RAM_SIZE

__initial_sp    EQU     0x20000000+RAM_SIZE*1024
Stack_Mem       EQU     __initial_sp - Stack_Size

ELSE
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

ENDIF


Определение RAM_SIZE=48 (48кБ для STM32F103RC) находится в опциях всего проекта (KEIL).

О приложении.
Приложение "отсылается" на 16кБ выше, за загрузчик, с помощью SCATTER файла компоновщика:

Код
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
;
;   V1.0:
;   This scatter file is modified to allocate the main section
;   at 0x4000 (16kB) boundary while the reflashable settings
;   constants - at the end of the image (256K-2K, for
;   STM32F103RC).
;
;   FlashSize = 0x00040000 (256K):
;
;       BOOT_LOADER     @ 0x08000000 .. 0x08003FFF, size         0x4000
;       USER_CODE       @ 0x08004000 .. 0x0803F7FF, size 0x40000-0x4000-0x800
;       B_ARC_C_PARAMS  @ 0x0803F800 .. 0x0803FBFF, size                0x400
;       B_ARC_C_USB@    @ 0x0803FC00 .. 0x0803FFFF, size                0x400
;
;
LR_IROM2   (0x08000000 + 0x4000) (0x40000-0x4000-0x800) {; load region size_region
  ER_IROM2 (0x08000000 + 0x4000) (0x40000-0x4000-0x800) {; load address = execution address
   *.o (USER_VECTORS, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x0000C000  {; RW data
   .ANY (+RW +ZI)
  }
}
LR_IROM3   (0x08000000 + (0x00040000-0x800)) 0x800 {; load region size_region
  ER_IROM3 (0x08000000 + (0x00040000-0x800)) 0x400 {; load address = execution address
   *(B_ARC_C_PARAMS)
  }
  ER_IROM4 (0x08000000 + (0x00040000-0x400)) 0x400 {; load address = execution address
   *(B_ARC_C_USB)
  }
}

На LR_IROM3 можно не обращать внимание, - это наша "примочка" хранить установки в последней странице флэша.

startup.s имеет имя секции векторов (USER_VECTORS) согласованое со "скатертью" выше:
Код
; Future user program vector table

                AREA    USER_VECTORS, DATA, READONLY, ALIGN=9; 2^9=512
                EXPORT  __Vectors

__Vectors       DCD     __initial_sp        ; Top of Stack
                DCD     Reset_Handler    ; Reset Handler
                DCD    ...
                DCD    ...


Загрузчик переходит на основное приложение с помощью кода ниже (который для удобства размещен в startup.s загрузчика, чтобы не порождать новый *.s файл):

Код
VTOR            EQU     (0xE000E000 + 0x0D08)                
StartMainApp    PROC; R0 - parameter with the APP vector table address
                EXPORT  StartMainApp               [WEAK]
                MOV32   R1, #VTOR            ; Load VTOR register address
                STR     R0, [R1]                ; Store to VTOR to relocate the vector table
                LDR     SP, [R0]                ; Reinit the user stack
                LDR     R0, [R0, #4]            ; Get the user entry point...
                BX      R0                ; ... and jump to it
                ENDP


Код:
1). принимает в R0 адрес загрузки приложения, что есть по сути адрес таблицы векторов.
2). Переназначает VTOR на эту таблицу
3). считывает из таблицы (первое ее слово) значение стека и инициализирует указатель стека
4). считывает второе слово из таблицы, что и есть адрес начала исполняемой программы, и переходит на нее.

Вызов его осуществляется как:

extern void StartMainApp(void *app);
StartMainApp((void*)LoadAddressOfApp);

В конкретном случае LoadAddressOfApp равно тупо 16K.
SSerge
Цитата(mronetwo @ May 24 2012, 17:23) *
каким образом должен выглядеть скрипт для линкера для загружаемой программы (IAR).

Насчёт размещения загрузчика в начале флеш-памяти и способа передачи управления согласен с предыдущими ораторами. sm.gif

Теперь чтобы собрать программу для работы с загрузчиком достаточно в IAR поправить файл .icf, заменить ему только две строчки:
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
тут вместо 0x08000000 нужно указать адрес откуда начинается приложение.

В самой программе, если она аккуратно написана, ничего не меняется, только перекомпилировать с другим .icf
Единственное, что нужно проконтролировать - это правильность инициализации контроллера прерываний.
В примерах в функции NVIC_SetVectorTable() обычно тупо пишут константу, а лучше взять адрес начала секции .intvec с помощью __section_begin(".intvec").
mronetwo
Спасибо всем! Я уже все реализовал. С загрузчиком в начале флеш, разумеется. Просто не догадался что стек как-то можно налету переинициализировать - знаний по данному ядру пока не очень много и в это как раз и уперся.

Остался пока не нужный но все же интригующий вопрос: как в скрипте "обойти" некоторую часть ROM, чтоб программа думала что у меня два банка памяти, например, с 0 по 1FFFF и с 2FFFF по FFFFF ?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.