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

 
 
> Копирование из flash в RAM и выполнение кода до передачи управления main(), Копирование сегмента CODE_ID в CODE_I вручную из функции __low_level_i
Ykidia
сообщение Aug 3 2006, 13:30
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287



Здравствуйте!

Задача - перед выполнением main() запускается некий firmware programmer (FP), в котором необходимо прочитать сигнатуру из внешнего хранилища (например, микросхема внешней flash-памяти), и, в зависимости от ее значения 1) либо запрограммировать внутренний flash из внешнего; 2) либо передать управление имеющемуся firmware.
При этом желательно, чтобы из той же внешней flash можно было бы перепрошивать сам FP.

Используется IAR EWARM.

Я предполагаю поместить FP в __low_level_init(), которая выполняется как раз до main(). Т.к. надо программировать внутренний flash, значит, надо переместить основное хозяйство FP во встроенный RAM, обычно это делается указанием __ramfunc перед функцией, которая будет выполняться в RAM. Но при выполнении __low_level_init() сегменты еще не проинициализированы и нужные функции в RAM не скопированы. Как взять значения начала и размера у сегментов CODE_ID (сегмент в ROM, в котором лежит код, к-рый будет скопирован в ОЗУ) и CODE_I (сегмент в RAM, куда будет скопирован код, лежащий в CODE_ID), я еще не разобрался, а внутренние (intrinsic) ф-и __segment_begin и __segment_size посылают куда подальше.
Или нужно производить ручную инициализацию сегмента CODE_I как-то по-другому?

Добавлю, что соль размещения FP в __low_level_init() мне видится в том, что другой разработчик будет просто вставлять файлы исходников low_level_init.c и остальные, относящиеся к FP, а затем перекомпилять свой проект, ничего в нем не меняя и даже не глядя в исходники FP.

Еще, если это поможет, - в __low_level_init() будет располагаться только сама инициализация и передача управления ф-и, расположенной в RAM, которая, видимо, будет вызывать несколько других, расположенных там же в RAM, по ходу своей работы. Сам же __low_level_init() остается во внутреннем flash.

Спасибо за любую возможную помощь!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
KRS
сообщение Aug 3 2006, 13:58
Сообщение #2


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Поставте в начале функции main вызов функции проверки и программирования флеша
если такой способ почему то не устаривает (интерсно почему)
то проще всего переписать cstartup
Go to the top of the page
 
+Quote Post
Ykidia
сообщение Aug 3 2006, 14:18
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287



Цитата(KRS @ Aug 3 2006, 17:58) *
Поставте в начале функции main вызов функции проверки и программирования флеша
если такой способ почему то не устаривает (интерсно почему)
то проще всего переписать cstartup


Да меня бы наверное устроило поставить вызов проверки в начале main(), но этот способ добавит геморроя, если понадобится изменить firmware programmer (FP) без изменения самой firmware.
Т.е. в идеале имеем возможность прошивать FP и firmware независимо друг от друга.
Как это используется. Через Ethernet посылается прошивка основной программы либо программатора; основная программа, принявшая данные по Ethernet, записывает их во внешнее хранилище, помечая в сигнатуре необходимость перепрошивки, и reset'тится. После сброса контроллера запускается cstartup, оттуда __low_level_init(), где выясняется, нужно ли перепрошиваться и в случае необходимости запускается FP и нужные страницы flash контроллера перепрошиваются. Причем, если __low_level_init() загружает сам FP уже из внешнего хранилища (если он там есть, если нет, то производится копирование в RAM и запуск имеющегося), то было бы несложно вызывать FP, как бы ни изменился FP и/или firmware.
А в случае с проверкой из main() любое изменение в одном или в другом месте влечет за собой перезаливку и того, и другого, т.к. оба куска уже завязаны друг на друга.

А как переписать cstartup? Что там нужно делать, что нет, как инициализировать сегменты? Хотя, там вроде может быть много работы, есть ли смысл заморачиваться? Ведь предполагается использовать FP в любых проектах, где это потребуется, а не в одном-двух, и заранее неизвестно, что будут из себя представлять эти проекты... wink.gif
Go to the top of the page
 
+Quote Post
KRS
сообщение Aug 3 2006, 14:24
Сообщение #4


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



а - __segment_begin и __segment_size не работают потому что вы наверное забыли укзать
#pragma segment="SEGMENT_NAME"
для CODE_I и CODE_ID

но лучше использовать другие сегменты, если у вас и другие функции __ramfunc есть они могут например не поместиться и вообще копрование будет 2 раза

так что лучше использовать другую пару сегментов и xcl файл есть специальная опция -Q
Go to the top of the page
 
+Quote Post
KRS
сообщение Aug 3 2006, 14:37
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Ykidia @ Aug 3 2006, 18:18) *
А как переписать cstartup? Что там нужно делать, что нет, как инициализировать сегменты? Хотя, там вроде может быть много работы, есть ли смысл заморачиваться? Ведь предполагается использовать FP в любых проектах, где это потребуется, а не в одном-двух, и заранее неизвестно, что будут из себя представлять эти проекты... wink.gif


cstartup перписать просто
там производится инициализация стека и копирование и обнуление сегментов, потом вызов main

если прошивать программер и main раздельно то вообще стартап должен быть у каждого свой это получатся разные программы

вам можно просто подменить функцию main

Код
void main(void)
{
   Check();
   AppMain();
}
Go to the top of the page
 
+Quote Post
Ykidia
сообщение Aug 3 2006, 20:53
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287



Да, прагму на эти сегменты я не указывал, думал, и так уже все есть, даже мысли как-то не возникло. А что даст повторное указание?
Насчет копирования 2 раза - это Вы говорите про то, что один раз скопирую я ручками, а другой раз - процедура инициализации сегментов? Если так, то мне это как-то по барабану %). Не слишком высокая плата за универсальность.
Еще - если я объявлю другие сегменты (это уже не желательно, ибо уже необходимо менять командный файл линкера), как линкер сопоставит их с теми, что уже есть (CODDE_ID и CODE_I) ?

P.S. Я извиняюсь за, возможно, глупые вопросы, но больше не знаю, кому их задать. Спасибо, что ответили!
Go to the top of the page
 
+Quote Post
KRS
сообщение Aug 4 2006, 07:34
Сообщение #7


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Ykidia @ Aug 4 2006, 00:53) *
Да, прагму на эти сегменты я не указывал, думал, и так уже все есть, даже мысли как-то не возникло. А что даст повторное указание?

Эта прагма генерирует в асме объявления сегментов, дело в том что если имеенно в этом С файле нету фунций __ramfunc то обисаний сегментов нет и работать с ними нельзя.

Цитата(Ykidia @ Aug 4 2006, 00:53) *
Насчет копирования 2 раза - это Вы говорите про то, что один раз скопирую я ручками, а другой раз - процедура инициализации сегментов? Если так, то мне это как-то по барабану %). Не слишком высокая плата за универсальность.

Тогда можно смело использовать

Цитата(Ykidia @ Aug 4 2006, 00:53) *
Еще - если я объявлю другие сегменты (это уже не желательно, ибо уже необходимо менять командный файл линкера), как линкер сопоставит их с теми, что уже есть (CODDE_ID и CODE_I) ?

Линкер и не будет сопоставлять это будут другие сегменты!
и кстати __segment_init не будет копировать один в другой если принудительно не создать вхождение в сегменте INITTAB
просто надо описать эти сегменты в XCL файле и указать
-QMYCODE_I=MYCODE_ID
что бы линкер положил содержимое сегмента MYCODE_I в сегмент MYCODE_ID

для DATA_I, CODE_I это делает компилер сам
Go to the top of the page
 
+Quote Post
Ykidia
сообщение Aug 4 2006, 09:42
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287



Вот! Как же я раньше пропустил про __segment_init() - наверное это как раз то, что мне нужно: вызываю __segment_init() из __low_level_init(), на выходе же из __low_level_init() выдаю 0 - мол, инициализировать сегменты не надо (ибо они уже проинициализированы).
Осталось только __low_level_init() и иже с ним положить, например, в конец встроенного flash, перед philips'овским bootlader'ом.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 15:07
Рейтинг@Mail.ru


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