Перейти к содержанию

    

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

 

Конфигурация: ADSP Blackfin BF532, код выполняется из SDRAM, кеширование включено.

Первичная загрузка - из SPI флешки 8-битной (микросхема AT45DB....), затем переход кода в SDRAM.

 

Нужно сбросить процессор, чтобы снова подгрузилась программа из SPI-флешки. (причем именно чтобы снова повторился цикл загрузки с SPI-флешки, ттак как старый образ программы в L1 может быть уже разрушен - стеком, буферами DMA)

 

Вот так - НЕ работает:

while(1) __asm__ ("raise 1;");

 

Спецы, подскажите плиз как сбросить программно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Спецы, подскажите плиз как сбросить программно?

Перейти на начало загрузчика в ROM?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Перейти на начало загрузчика в ROM?

Да. Штатный загрузчик, который по двум ногам определяет, что надо скопировать код с spi-флешки AT45DB... и передать на него управление

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Да. Штатный загрузчик, который по двум ногам определяет, что надо скопировать код с spi-флешки AT45DB... и передать на него управление

Вот я и говорю: если нет возможности установить состояние этих ног и сделать POR-сброс, то попробуйте найти его начало в ROM и явно передать туда управление.

Ещё в некоторых МК есть возможность задать тип загрузки при программном сбросе через спец. регистры (например в Infineon). Может у Вас так.

А эти ваши 2 ноги - они скорее всего считываются только при POR-сбросе и внешнем RESET. При программном сбросе - скорее всего нет. Хотя можно попробовать ещё сброс через WDT.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, хотелось бы так как при сбросе нажатием кнопки.

Пара ног, которые определяют с какого носителя грузиться всегда в одном состоянии и не меняются.

 

С какого адреса у BF532 начинается загрузчик?

Попробую сделать прямой переход туда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Да, хотелось бы так как при сбросе нажатием кнопки.

Пара ног, которые определяют с какого носителя грузиться всегда в одном состоянии и не меняются.

Скорей всего, ваш МК переходит на соответствующий загрузчик когда эти ноги в соответствующем состоянии И тип сброса == POR или внешний сигнал RESET.

Это должно быть описано в соответствующем разделе мануала на проц (типа: "Загрузка и сброс").

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если программно ресет не сделать, то прийдётся выводить на экран сообщение, чтоб пользователь нажал кнопку RESET.

А хочется автоматически чтоб.... :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Если программно ресет не сделать, то прийдётся выводить на экран сообщение, чтоб пользователь нажал кнопку RESET.

А хочется автоматически чтоб.... :rolleyes:

Ну если так припёрло, то можно кинуть одну GPIO-ножку МК на RESET, которую по дефолту держать в состоянии "ввод". Хотя лучше её кинуть на вход MR внешнего сторожевика+супервизора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
С какого адреса у BF532 начинается загрузчик?

Попробую сделать прямой переход туда.

а если всё-таки почитать описание регистров SWRST и SYSCR? там вроде что-то было про сброс и вход в загрузчик.

ну и вочдог ещё есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня программная перезагрузка работает на BF533.

Завтра смогу глянуть исходники и сказать точно что нужно делать.

Помнится надо было в SWRST что-то записать потом сделать ssync, csync и только потом raise

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал вот так:

 

static __inline__ void BlackFin_SoftReset(void)
{
*pSWRST=0x0007;
ssync();
register u32 i=75;
while(i--);
__asm__ __volatile__ ("NOP;");
*pSWRST=0x0000;
ssync();
__asm__ __volatile__ ("RAISE 1;");
}

 

Работает, но не всегда - зависит от расположения данного кода. Подозреваю, что этот фрагмент должен быть в кеше инструкций целиком, тогда успешно.

 

Каким образом можно сделать чтобы данный код был гарантированно в кеше инструкций? (код выполняется из SDRA со включенным write-back кешированием)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну раз пример из мануала переписали, там же рядом чёрным по белому написано, что исполнять надо исключительно из L1.

объясните линкеру чтобы он эту конкретную функцию в внутреннюю память положил.

 

p.s. точку с запятой после while(i--) уберите, она там немного лишняя, а то компилятор может этот цикл выкинуть за ненадобностью.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем, найдёно изящное решение - сброс по сторожевому таймеру:

 

static __inline__ void BlackFin_Reset(void)
{
*pWDOG_CNT=13200000; //таймаут 0.1 секунды (число тактов шины SCLK, у меня 132 МГц)
*pWDOG_CTL=0;        //выбираем RESET и включаем watchdog
while(1);                    //зацикливание
}

 

Работает надёжно и с любого адреса, ресет такой же как при нажатии на кнопку, загрузчик снова тянет из SPI-флеш самописанную программу-загрузчик-инициализатор в SDRAM.

 

До этого ещё пробовал как здесь:

http://electronix.ru/forum/index.php?showtopic=32272 - НЕ помогло.

 

Всё-же RAISE 1 и SWRST - это от лукавого (при выполнения кода из кешируемой области памяти) :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мануалы читать надо, там написано для чего и какая пауза должна быть между записями в SWRST.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
объясните линкеру чтобы он эту конкретную функцию в внутреннюю память положил.

 

А как он её положет, если сама программа исполняется в SDRAM с адреса 0x00000004 ? Образ программы в LDF-файле задается как ROM, но это для линковщика, на самом деле там всё RAM :rolleyes: (ох уж эти линковщики :)

 

Или речь идёт о том, что линкер сделает стартап, который сделает копию функции из SDRAM в L1 и сформирует вызовы именно из L1 ? (это фантастика =)

 

p.s. точку с запятой после while(i--) уберите, она там немного лишняя, а то компилятор может этот цикл выкинуть за ненадобностью.

 

Ну я под этим подразумевал пустой цикл :) А если запятую убрать, то получится 75 раз NOP-ов )) Ну а на счёт выкинет, есть же volatile)

 

мануалы читать надо, там написано для чего и какая пауза должна быть между записями в SWRST.

Если фрагмент кода сброса находится во внешней кешируемой памяти - не поможет.

Надо чтоб этот фрагмент гарантировано был закеширован, тогда отключение SDRAM не страшно. Иначе получается - программа рубит сук на котором сидит)

Изменено пользователем __inline__

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация