|
Копирование из flash в RAM и выполнение кода до передачи управления main(), Копирование сегмента CODE_ID в CODE_I вручную из функции __low_level_i |
|
|
|
Aug 3 2006, 13:30
|
Частый гость
 
Группа: Свой
Сообщений: 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.
Спасибо за любую возможную помощь!
|
|
|
|
|
 |
Ответов
(1 - 7)
|
Aug 3 2006, 14:18
|
Частый гость
 
Группа: Свой
Сообщений: 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 в любых проектах, где это потребуется, а не в одном-двух, и заранее неизвестно, что будут из себя представлять эти проекты...
|
|
|
|
|
Aug 3 2006, 14:37
|

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

|
Цитата(Ykidia @ Aug 3 2006, 18:18)  А как переписать cstartup? Что там нужно делать, что нет, как инициализировать сегменты? Хотя, там вроде может быть много работы, есть ли смысл заморачиваться? Ведь предполагается использовать FP в любых проектах, где это потребуется, а не в одном-двух, и заранее неизвестно, что будут из себя представлять эти проекты...  cstartup перписать просто там производится инициализация стека и копирование и обнуление сегментов, потом вызов main если прошивать программер и main раздельно то вообще стартап должен быть у каждого свой это получатся разные программы вам можно просто подменить функцию main Код void main(void) { Check(); AppMain(); }
|
|
|
|
|
Aug 3 2006, 20:53
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Да, прагму на эти сегменты я не указывал, думал, и так уже все есть, даже мысли как-то не возникло. А что даст повторное указание? Насчет копирования 2 раза - это Вы говорите про то, что один раз скопирую я ручками, а другой раз - процедура инициализации сегментов? Если так, то мне это как-то по барабану %). Не слишком высокая плата за универсальность. Еще - если я объявлю другие сегменты (это уже не желательно, ибо уже необходимо менять командный файл линкера), как линкер сопоставит их с теми, что уже есть (CODDE_ID и CODE_I) ?
P.S. Я извиняюсь за, возможно, глупые вопросы, но больше не знаю, кому их задать. Спасибо, что ответили!
|
|
|
|
|
Aug 4 2006, 07:34
|

Профессионал
    
Группа: Модераторы
Сообщений: 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 это делает компилер сам
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|