реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вопрос по scatter-файлу, KEIL, stm32f103c8
Nikitoc
сообщение Sep 19 2011, 15:02
Сообщение #1


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Всем привет. Пытаюсь изменить адрес загрузки кода (и соответственно адрес сброса) путем редактирования scatter-файла.
Его изначальный вид:
Код
LR_IROM1 0x08000000 0x000010000 {   ; load region size_region
     ER_IROM1 0x08000000 0x000010000 { ; load address = execution address
      *.o (RESET, +First)
      *(InRoot$Sections)
      .ANY (+RO)
    
     }
     RW_IRAM1 0x20000000 0x00005000  { ; RW data
      .ANY (+RW +ZI)
     }
   }

Пытаюсь изменить на такой адрес:
Код
LR_IROM1 0x08000600 0x00000FA00 {   ; load region size_region
     ER_IROM1 0x08000600 0x00000FA00 { ; load address = execution address
      *.o (RESET, +First)
      *(InRoot$Sections)
      .ANY (+RO)
  
     }
     RW_IRAM1 0x20000000 0x00005000  { ; RW data
      .ANY (+RW +ZI)
     }
   }

Запускаю отладчик - перехода по вектору сброса не происходит. Что я делаю неправильно?
Цель этих извращений - оставить место для загрузчика (будет отдельным проектом) с 0x08000000 по 0x08000600.
Похожих тем перелопатил целую кучу, ответа не нашел. Может быть я в корне неправильно понимаю процедуру переназначения стартового адреса?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Sep 20 2011, 11:52
Сообщение #2


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Смотрю map-файл:
Код
Memory Map of the image

  Image Entry point : 0x080006ed

  Load Region LR_IROM1 (Base: 0x08000600, Size: 0x00002dfc, Max: 0x0000fa00, ABSOLUTE)

    Execution Region ER_IROM1 (Base: 0x08000600, Size: 0x00002d6c, Max: 0x0000fa00, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x08000600   0x000000ec   Data   RO            3    RESET               startup_stm32f10x_md.o
    0x080006ec   0x00000008   Code   RO          868  * !!!main             c_w.l(__main.o)
    0x080006f4   0x00000034   Code   RO         1344    !!!scatter          c_w.l(__scatter.o)

Reset расположен как и требовалось по адресу 0x08000600, т.е. в самом начале. Но почему-то программа все равно не стартует с него. Прям беда.
Может быть вектор сброса задается как-то отдельно? Кто-нибудь делал подобное уже?
Go to the top of the page
 
+Quote Post
SII
сообщение Sep 21 2011, 08:31
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Местоположение таблицы векторов на любых МК архитектур ARMv6-M и ARMv7-M (ядра семейства Cortex-M) задаётся регистром VTOR. Соответственно, недостаточно загрузить прошивку в память, надо ещё загрузить правильное значение в этот регистр.
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Sep 21 2011, 10:14
Сообщение #4


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(SII @ Sep 21 2011, 11:31) *
Местоположение таблицы векторов на любых МК архитектур ARMv6-M и ARMv7-M (ядра семейства Cortex-M) задаётся регистром VTOR. Соответственно, недостаточно загрузить прошивку в память, надо ещё загрузить правильное значение в этот регистр.


Спасибо, конечно. Однако, записать в этот регистр (по адресу 0xE000ED08) значение на этапе компиляции мне никак не удается.
Т.к. этот диапазон не относится ни к доступной RAM ни к FLASH. Из программы, можно. Но она не стартует. В общем, замкнутый круг получается :-(
Go to the top of the page
 
+Quote Post
SII
сообщение Sep 21 2011, 10:53
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Вообще-то для этого служит скрипт, управляющий процессом загрузки программы и настройки контроллера через JTAG/SW. Вот, например, кусок моего скрипта (слепленного на основе одного из примеров, идущих с Кейлом):

Код
LOAD %L  INCREMENTAL
SP = _RDWORD(0x20000000);
PC = _RDWORD(0x20000004);
_WDWORD(0xE000ED08, 0x20000000);


LOAD грузит файл (адреса устанавливаются компоновщиком на основе scatter-файла), дальше устанавливаются начальные значения SP и PC (путём чтения из указанных ячеек), а затем производится настройка базы таблицы векторов.
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Sep 21 2011, 12:09
Сообщение #6


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(SII @ Sep 21 2011, 13:53) *
Вообще-то для этого служит скрипт, управляющий процессом загрузки программы и настройки контроллера через JTAG/SW. Вот, например, кусок моего скрипта (слепленного на основе одного из примеров, идущих с Кейлом):

Код
LOAD %L  INCREMENTAL
SP = _RDWORD(0x20000000);
PC = _RDWORD(0x20000004);
_WDWORD(0xE000ED08, 0x20000000);


LOAD грузит файл (адреса устанавливаются компоновщиком на основе scatter-файла), дальше устанавливаются начальные значения SP и PC (путём чтения из указанных ячеек), а затем производится настройка базы таблицы векторов.


Спасибо! Так работает. Но ведь после сброса МК содержимое регистра VTOR тоже сбрасывается. И мы снова попадаем не туда куда нужно. Т.е. для отладки пользоваться можно, а реально нет :-( Как быть? И еще Вы бы не могли привести Ваш скрипт полностью или тот примерчик из Keil'а на основе которого Вы его написали?
Go to the top of the page
 
+Quote Post
SII
сообщение Sep 21 2011, 12:20
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Да там ничего интересного больше нет -- настройка для трассировки с использованием ULINK Pro, что к Вашей задаче никакого отношения не имеет.

Что касается серийного изделия, то и программа для него прошивается во флэш-память, размещаясь по нужным адресам, то есть обычно с нулевого, что автоматически снимает проблему: после сброса в VTOR лежат нули, и всё будет на месте. Естественно, и scatter-файл тогда должен строить образ для размещения и работы по указанному адресу.

Кроме того, обычно есть несколько альтернативных вариантов загрузки, задаваемых физическим подключением определённых ног МК к земле или питанию. Всё это описывается в даташите. Поскольку речь о STM32F103xx, то могу сказать точно, где именно: страницы 60-61 (даташит ревизии 13 от мая этого года).
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Sep 21 2011, 20:56
Сообщение #8


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(SII @ Sep 21 2011, 15:20) *
Что касается серийного изделия, то и программа для него прошивается во флэш-память, размещаясь по нужным адресам, то есть обычно с нулевого, что автоматически снимает проблему: после сброса в VTOR лежат нули, и всё будет на месте. Естественно, и scatter-файл тогда должен строить образ для размещения и работы по указанному адресу.

Так. Я вроде немного прояснил для себя ситуацию. Получается, этот финт ушами помогает при разработке бутлоадера и основной программы двумя разными проектами? Бутлоадер разрабатывается одним проектом (без перемещения таблицы) и в конце имеет команду перехода на адрес 0x08000600 (в данном случае). А основная программа отлаживается с адреса 0x08000600, так будто бы она получила управление от бутлоадера?
Выходит, проект можно разбить таким образом на несколько отдельных модулей, размещенных по конкретным адресам и передающим управление друг другу при заданных условиях? Главное, только, чтобы "стартовый" модуль располагался в самом начале флешь-памяти? Я правильно рассуждаю?
И еще один вопросик: как сказать программатору (у меня ULINK), чтобы при программировании одной части проекта (бута или основной программы) он не затирал другую? Т.е. программировал четко заданную область? В настройках программатора выбрать "Erase Sectors"?
P.S.: совсем забыл! Спасибо за помощь! cheers.gif
Go to the top of the page
 
+Quote Post
SII
сообщение Sep 21 2011, 21:37
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Насчёт того, как сказать программатору, я без понятия: нужды не возникало, поэтому не экспериментировал. Но, по идее, именно так и поступить.

Отлаживать можно вообще по любым адресам. Если программа написана хоть сколько-нибудь грамотно, она не будет к ним привязана вообще. Я, например, всю отладку вообще в ОЗУ веду.
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Sep 22 2011, 08:14
Сообщение #10


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(SII @ Sep 22 2011, 00:37) *
Я, например, всю отладку вообще в ОЗУ веду.

1.А какие преимущества дает такой метод на Cortex?
2. Откуда по этим адресам берутся начальные значения стека и программного счетчика:
Цитата
Код
SP = _RDWORD(0x20000000);
    PC = _RDWORD(0x20000004);

Из стартапа?
Go to the top of the page
 
+Quote Post
SII
сообщение Sep 22 2011, 10:36
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



1. А зачем лишний раз шить во флэш, когда мне хватает объёма имеющегося ОЗУ?
2. Из ОЗУ, естественно. А туда попадают в результате загрузки образа, собранного как раз с адреса 20000000 (откуда у меня начинается таблица векторов). LOAD стоит раньше, чем эти присваивания, поэтому сначала загружается образ, а потом уже ячейки считываются и присваиваются указателю стека и счётчику команд. В общем, скриптовая имитация аппаратного сброса.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01443 секунд с 7
ELECTRONIX ©2004-2016