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

 
 
> Проблемы при работе со встроенной flash, AT91SAM7A3, bootloader
Costa
сообщение Feb 4 2009, 17:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726



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

Делаю загрузчик (bootloader) для AT91SAM7A3, одной из функций которого должно быть обновление (через USART, но это не суть) собственной прошивки. Все получается, из под JTAG, т.е. когда код загрузчика расположен и исполняется в RAM, все замечательно работает.
Проблема возникает, когда этот же код зашивается во flash. Когда дело доходит собственно до работы с flash (lock/unlock, write page), программа зависает, а поскольку в устройстве есть внешний watchdog, происходит reset.

Сделал маленькую функцию, которая блокирует (lock) регион 0 flash:
Код
__ramfunc void Lock(void)
{
    unsigned int interrupt_mask;
    unsigned int flash_status;
    unsigned short lock_status = *AT91C_MC_FSR >> 16;
    if (lock_status & 0x1)
        return;
  *AT91C_MC_FMR = FMCN_FOR_LOCK | AT91C_MC_FWS_1FWS;
    interrupt_mask = *AT91C_AIC_IMR;
  *AT91C_AIC_IDCR = AT91C_ALL_INT;
  *AT91C_MC_FCR = AT91C_MC_KEY | AT91C_MC_FCMD_LOCK;
  do
  {
    flash_status = *AT91C_MC_FSR & AT91C_MC_EOL;
  }
  while (!flash_status);
  *AT91C_AIC_IECR = interrupt_mask;
}

Штука в том, что собственно lock происходит, т.к. после reset функция выскакивает по первому return; - но вот если регион в состоянии unlock, то все стопорится в цикле do while. Причем пробовал тупо вставлять счетчик в тело цикла, чтобы по его окончании выходить из цикла - все равно виснет...
Уже весь мозг сломал и не знаю, в какую сторону рыть. То ли проблема в том, что как-то некорректно выключаются прерывания на время операций с flash, т.к. хотя сами обработчики прерываний и сделаны __ramfunc, но есть еще вектора прерываний, обертка... То ли вышеприведенный код не попадает на самом деле в RAM, хотя в стартапе __segment_init прописан, и соотв. библиотека к проекту подключена... Помогите разобраться, где накосячил.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Costa
сообщение Feb 6 2009, 16:13
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726



aaarrr, спасибо за наводку!

Действительно, программа вылетала из процедуры раньше, чем нужно, а не зависала в ней, как я предполагал. Связано это с параметром FMCN_FOR_LOCK. Я измерил время, в течение которого процедура ожидает флагов, результаты такие получились:
FMCN_FOR_LOCK = 5, t = 1 ms, сбой
FMCN_FOR_LOCK = 48, t = 10 ms, норм
Примерно та же картина и при записи страниц наблюдается:
FMCN_FOR_WRITE = 72, t = 6 ms, сбой
FMCN_FOR_WRITE = 720, t = 18 ms, норм

Master Clock = 48 MHz, и почему приходится применять такие большие значения, я так и не понял. В даташите сказано:

• FMCN: Flash Microsecond Cycle Number
Before writing Lock bits, this field must be set to the number of Master Clock cycles in one hundred nanoseconds.
When writing the rest of the Flash, this field defines the number of Master Clock cycles in 1.5 microseconds. This number
must be rounded up.


В итоге, если не обращать внимания на большие значения FMCN, все работает нормально.

P.S. Про прерывания полностью согласен, так и сделал. Еще раз, большое спасибо! smile.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 6 2009, 16:53
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Costa @ Feb 6 2009, 19:13) *
В итоге, если не обращать внимания на большие значения FMCN, все работает нормально.

Может, сдвинули недостаточно? Типа 10 вместо 0x10.

Upd. Нет, не похоже: FMCN при присвоении 720 будет равен 208 (8 бит), что примерно в три раза больше 72 и соответствует результатам измерений.
Go to the top of the page
 
+Quote Post



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

 


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


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