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

 
 
> Определение размера 0-го сектора в LPC2000, есть ли какой-нибудь способ без вызова IAP
Ykidia
сообщение Apr 4 2007, 14:04
Сообщение #1


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

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Ykidia
сообщение Apr 4 2007, 15:29
Сообщение #2


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

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



Спасибо за ответ!
1. Да в принципе нравится, только отлаживать неудобно - кроме сброса нужно еще MEMMAP = 1 каждый раз прописывать в отладчике, мелочь, а достает. В программе приходится каждый раз инициализировать вектора, а вдруг понадобится их намертво зашить?
2. Это надо будет обдумать, если других вариантов не предвидится... Т.е., например так: изобразить переменную, естественно, со значением 0xFFFF, внутри 0-го сектора, а при запуске загрузчика и получении ID прописать при помощи IAP в эту переменную размер сектора - записать 512 байт, внутри к-рых лежит эта переменная, без стирания (хотя данный режим не рекомендуется). А потом брать оттуда значение и проверять его... или же сразу прошивать все вектора, и тогда ничего даже проверять не надо. Было бы неплохо, однако это, повторюсь, не рекомендуется... Чем чревато НЕ следование данной рекомендации (сначала обязательно стирать, а потом прошивать)?
3. В главном проекте пока используются IRQ и FIQ. Используется uC/OS-II, так что крайне нежелательно принимать решения по обработке конкретного прерывания прямо в загрузчике wink.gif
4. Да, Вы правы, загрузчик прерывания не пользует. Насчет перепрошивки векторов надо подумать, не опасно ли это, как в п.2.

добавлено

Нет, прошивка векторов напрямую не катит: там изначально должна быть контрольная сумма (а не 0xFFFFFFFF), которая изменится при прошивке векторов, и возможно для правильного ее обновления придется прежде стирать весь сектор... Остается вариант с "однократно прошиваемой" переменной в области 0-го сектора, а также остается вопрос: чем чревато прошивание без предварительного стирания (т.е. использовать прошивание лишь для сброса нужных бит в OTP-переменной)?
Ну и также приветствуются другие принципы быстрого получения информации о размере сектора.

Сообщение отредактировал Ykidia - Apr 4 2007, 15:31
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 4 2007, 16:13
Сообщение #3


Гуру
******

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



Цитата(Ykidia @ Apr 4 2007, 14:29) *
1. Да в принципе нравится, только отлаживать неудобно - кроме сброса нужно еще MEMMAP = 1 каждый раз прописывать в отладчике, мелочь, а достает. В программе приходится каждый раз инициализировать вектора, а вдруг понадобится их намертво зашить?
Тогда добавьте в .mac такую конструкцию:
Код
Remap_RAM()
{
    __var i;
    __var tmp;


    for( i = 0; i < 0x40; i += 4 )                      // copy vectors from app
    {
        tmp = __readMemory32(0x00002000 + i, "Memory");     // read from flash
        __writeMemory32(tmp,0x40000000 + i, "Memory");     // write to RAM
    }

    // remap throw JTAG
    __writeMemory8(0x02,0xE01FC040,"Memory");           // MEMMAP, remap vectors to RAM
    __message " remaped to RAM ";

}
execUserReset()
{
    Remap_RAM();
}
и все будет происходить автоматически.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 02:19
Рейтинг@Mail.ru


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