|
Определение размера 0-го сектора в LPC2000, есть ли какой-нибудь способ без вызова IAP |
|
|
|
Apr 4 2007, 14:04
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Здравствуйте!
У меня вопрос: есть ли какие-нибудь трюки определения размера 0-го сектора в Philips LPC2000 без вызова IAP? Например, в LPC2138 размер равен 4k, а в LPC2214 - 8k. Собственно, варианта на данной архитектуре всего два.
Зачем это нужно. Есть большой проект под IAR EWARM 4.41. Там свой cstartup, который располагался, как ему и положено, в 0-м секторе, так что любые изменения обработчиков исключений в cstartup'е соответственно и адекватно отражались на работе всего проекта. Теперь решили сделать свой загрузчик. Вообще-то, сделан он уже давно, но сейчас решили поместить его в 0-й сектор, а основной проект "подвинуть" на сектор вверх - расположить его с 1-го сектора. Это для того, чтобы при перепрошивке LPC2000 данным загрузчиком не было сбоев, связанных с перепрошивкой 0-го сектора. Т.е., основной проект получает по Ethernet новую firmware самого себя (простой бинарник, включающий в себя также и загрузчик в 0-м секторе), записывает ее в Data Flash AT45DB161x, взводит сигнатуру в Data Flash и перезапускает контроллер. При перезапуске первым получает управление (после Philips'овского bootloader'а) загрузчик в 0-м секторе, который читает и проверяет сигнатуру из Data Flash на предмет перепрошивки. Если надо перепрошиваться, то проверяется другая сигнатура на предмет использования внешнего прошивальщика. Если нужно использовать внешний, то он загружается из Data Flash во внутренний RAM LPC2000, ему передается управление, далее он перепрошивает контроллер полностью, включая 0-й сектор, обновляет сигнатуру (мол, прошито) и перезапускает контроллер. Если же внешний прошивальщик использовать не нужно, то загрузчик сам перепрошивает контроллер, но исключая 0-й сектор. Затем он обновляет сигнатуру и передает управление на 1-й сектор, где располагается основной проект.
Такая схема позволяет обойтись без сбоев в режиме перепрошивки без 0-го сектора. Загрузчик запустился, определил ID контроллера, сравнил новую прошивку с текущим содержимым Flash контроллера, составил битовое поле различных секторов, перепрошил только те сектора, которые нуждаются в обновлении, и передал управление дальше, главному проекту. Однако это накладывает некоторые ограничения. Например, обработчики исключений/прерываний теперь находятся в загрузчике, а не в основном проекте (и поэтому его cstartup уже "не катит"). Чтобы передать управление на обработчики основного проекта, нужно знать размер 0-го сектора: 4k или 8k. Я упомянул, что по старту загрузчика определяется ID контроллера, чтобы знать карту секторов - для перепрошивки и просто для того, чтобы корректно передать управление основному проекту. В конце концов, нужно где-то хранить всего 1 бит, хотя желательно байт (для уверенности, что ID был прочитан), однако неизвестно, как распределяет память основной проект и, соответственно, нет гарантии, что нужный нам байт/бит не будет затерт. Если делать каждый раз при входе в исключение/прерывание вызов IAP - это долго, да и потом полученный ID надо еще дешифровать, чтобы узнать размер сектора.
Отсюда вопрос - возможно ли как-то сразу при входе в исключение/прерывание узнать, какой размер сектора? Может, где-то есть какой-нибудь битик, либо может его можно где-то хранить?
P.S. Сейчас основной проект использует работу с исключениями при MEMMAP = 2, что освобождает от данного ограничения. Но хотелось бы сделать максимально совместимо (типа задела на будущее).
Сообщение отредактировал Ykidia - Apr 4 2007, 14:09
|
|
|
|
|
 |
Ответов
|
Apr 6 2007, 17:02
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Спасибо. Но мне нужно было немного другое. Чтобы автор главного проекта, забыв (или не зная) о том, что его cstartup находится не в 0-м секторе, и захотев сделать таблицу векторов во Flash (MEMMAP = 1), не бежал сразу ко мне, мол, с твоим загрузчиком мои прерывания не работают, а без него - работают. Пока сделал так: Код org 0x00 __program_start b __first_init
org 0x04 __undefined_instruction b __undef_handler
org 0x08 __software_interrupt b __soft_handler
org 0x0C __prefetch_abort b __pref_handler
org 0x10 __data_abort b __data_handler
org 0x14 __checksum dc32 0x99FFFFCE
org 0x18 __irq b __irq_handler
org 0x1C __fiq b __fiq_handler
;--------------------------------------------------------------- ; Exception handlers routers __reset_handler dc32 0xFFFFFFFF __undef_handler dc32 0xFFFFFFFF __soft_handler dc32 0xFFFFFFFF __pref_handler dc32 0xFFFFFFFF __data_handler dc32 0xFFFFFFFF __rsrv_handler dc32 0xFFFFFFFF __irq_handler dc32 0xFFFFFFFF __fiq_handler dc32 0xFFFFFFFF При первом старте загрузчика все __*_handler прошиваются (при помощи IAP, без стирания сектора) соответствующей командой перехода на адреса 0x10XX или 0x20XX. Срабатывает железно, при старте отладки через J-link/J-Trace данные адреса уже прошиты, даже при задержке после сброса 0 мс (а вот RDI в отладке не дает прошивать, вернее, он сам перепрошивает сектор для работы с точками останова, поэтому старые значения dc32 0xFFFFFFFF возвращаются на место). Однако мне этот метод немного непривычен. Может, у кого-то все же найдутся еще какие-нибудь соображения, как это (определение размера сектора без вызова IAP) можно сделать?
Сообщение отредактировал Ykidia - Apr 6 2007, 17:04
|
|
|
|
|
Apr 9 2007, 23:18
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Извиняюсь за задержку с ответом. Выходные. Теща-блины, тесть-водка Цитата(Ykidia @ Apr 6 2007, 16:02)  Пока сделал так: Мне кажется вы делаете все слишком сложно. Ваш загрузчик лежит в нулевом секторе и честно стартует при включении питания. Главный проект ("приложение") линкуется с первого сектора. В начале первого сектора располагается копия векторов приложения, которая будет скопирована в адреса 0x40000000 - 0x40000040 а после MEMMAP = 2 окажется и в адресах 0x00 - 0x3F , причем линкуется она так, чтобы работала после копирования (точно также как работают __ramfunc - функции). Пример кусочка .xcl. Код -DROMSTART=00002000 // application ROM starts at 2000. 0-1FFF reserved for bootloader -DROMEND=00003ffff
-Z(CODE)INTVEC=00000000-0000003F -Z(CODE)INTVEC_F=ROMSTART-(ROMSTART+3F) -QINTVEC=INTVEC_F Ваш загрузчик просто делает копирование векторов, remap и передает управление на адрес RESET-вектора. Разработчику основной программы надо помнить только три вещи - линковать вектора указанным выше способом, не трогать memmap, настраивать всю периферию - ибо что-то может быть уже настроено загрузчиком не так как надо приложению. В остальном все работает как будто загрузчика и нет, что вам и нужно, при этом процесс перегрузки приложения не трогает вектора загрузчика и при любом сбое не запорет загрузчик. Вот старт приложения из загрузчика: Код #define APP_START 0x00002000 extern "C" __arm void __program_start();
void StartApplication() { __disable_interrupt(); MEMMAP = 0x02; // REMAP // copy application INTVEC_ID to remapped INTVEC uint32_t const *Src = (uint32_t *)APP_START; uint32_t *Dst = (uint32_t *)0; uint_fast8_t Size = 0x40 / sizeof *Dst; do { *Dst++ = *Src++; } while (--Size);
__program_start(); } А размер нулевого сектора вы задаете при компиляции загрузчика (#define APP_START 0x00002000). Вы ведь точно знаете, в какой процессор вы его будете заливать. Если интересно, я могу сделать вам "рыбу" загрузчика и приложения из своего проекта.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
Сообщений в этой теме
Ykidia Определение размера 0-го сектора в LPC2000 Apr 4 2007, 14:04 Alex03 1. А чем MEMMAP = 2 не нравится?
2. А в загрузчик... Apr 4 2007, 14:51 Ykidia Спасибо за ответ!
1. Да в принципе нравится, т... Apr 4 2007, 15:29 Сергей Борщ Цитата(Ykidia @ Apr 4 2007, 14:29) 1. Да ... Apr 4 2007, 16:13 Ykidia Здравствуйте! Спасибо за подробный ответ.
Цит... Apr 12 2007, 09:47 Сергей Борщ Цитата(Ykidia @ Apr 12 2007, 08:47) В том... Apr 12 2007, 13:45 Ykidia Да, и идеи насчет определения размера 0-го сектора... Apr 12 2007, 13:15 Ykidia Цитатавы создаете себе лишние трудности.
Есть тако... Apr 12 2007, 14:28
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|