repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Здравствуйте! Конфигурация: ADSP Blackfin BF532, код выполняется из SDRAM, кеширование включено. Первичная загрузка - из SPI флешки 8-битной (микросхема AT45DB....), затем переход кода в SDRAM. Нужно сбросить процессор, чтобы снова подгрузилась программа из SPI-флешки. (причем именно чтобы снова повторился цикл загрузки с SPI-флешки, ттак как старый образ программы в L1 может быть уже разрушен - стеком, буферами DMA) Вот так - НЕ работает: while(1) __asm__ ("raise 1;"); Спецы, подскажите плиз как сбросить программно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Спецы, подскажите плиз как сбросить программно? Перейти на начало загрузчика в ROM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Перейти на начало загрузчика в ROM? Да. Штатный загрузчик, который по двум ногам определяет, что надо скопировать код с spi-флешки AT45DB... и передать на него управление Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Да. Штатный загрузчик, который по двум ногам определяет, что надо скопировать код с spi-флешки AT45DB... и передать на него управление Вот я и говорю: если нет возможности установить состояние этих ног и сделать POR-сброс, то попробуйте найти его начало в ROM и явно передать туда управление. Ещё в некоторых МК есть возможность задать тип загрузки при программном сбросе через спец. регистры (например в Infineon). Может у Вас так. А эти ваши 2 ноги - они скорее всего считываются только при POR-сбросе и внешнем RESET. При программном сбросе - скорее всего нет. Хотя можно попробовать ещё сброс через WDT. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Да, хотелось бы так как при сбросе нажатием кнопки. Пара ног, которые определяют с какого носителя грузиться всегда в одном состоянии и не меняются. С какого адреса у BF532 начинается загрузчик? Попробую сделать прямой переход туда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Да, хотелось бы так как при сбросе нажатием кнопки. Пара ног, которые определяют с какого носителя грузиться всегда в одном состоянии и не меняются. Скорей всего, ваш МК переходит на соответствующий загрузчик когда эти ноги в соответствующем состоянии И тип сброса == POR или внешний сигнал RESET. Это должно быть описано в соответствующем разделе мануала на проц (типа: "Загрузка и сброс"). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Если программно ресет не сделать, то прийдётся выводить на экран сообщение, чтоб пользователь нажал кнопку RESET. А хочется автоматически чтоб.... :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Если программно ресет не сделать, то прийдётся выводить на экран сообщение, чтоб пользователь нажал кнопку RESET. А хочется автоматически чтоб.... :rolleyes: Ну если так припёрло, то можно кинуть одну GPIO-ножку МК на RESET, которую по дефолту держать в состоянии "ввод". Хотя лучше её кинуть на вход MR внешнего сторожевика+супервизора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба С какого адреса у BF532 начинается загрузчик? Попробую сделать прямой переход туда. а если всё-таки почитать описание регистров SWRST и SYSCR? там вроде что-то было про сброс и вход в загрузчик. ну и вочдог ещё есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба У меня программная перезагрузка работает на BF533. Завтра смогу глянуть исходники и сказать точно что нужно делать. Помнится надо было в SWRST что-то записать потом сделать ssync, csync и только потом raise Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба Сделал вот так: 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 кешированием) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба ну раз пример из мануала переписали, там же рядом чёрным по белому написано, что исполнять надо исключительно из L1. объясните линкеру чтобы он эту конкретную функцию в внутреннюю память положил. p.s. точку с запятой после while(i--) уберите, она там немного лишняя, а то компилятор может этот цикл выкинуть за ненадобностью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба В общем, найдёно изящное решение - сброс по сторожевому таймеру: 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 - это от лукавого (при выполнения кода из кешируемой области памяти) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба мануалы читать надо, там написано для чего и какая пауза должна быть между записями в SWRST. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 19 сентября, 2017 Опубликовано 19 сентября, 2017 (изменено) · Жалоба объясните линкеру чтобы он эту конкретную функцию в внутреннюю память положил. А как он её положет, если сама программа исполняется в SDRAM с адреса 0x00000004 ? Образ программы в LDF-файле задается как ROM, но это для линковщика, на самом деле там всё RAM :rolleyes: (ох уж эти линковщики :) Или речь идёт о том, что линкер сделает стартап, который сделает копию функции из SDRAM в L1 и сформирует вызовы именно из L1 ? (это фантастика =) p.s. точку с запятой после while(i--) уберите, она там немного лишняя, а то компилятор может этот цикл выкинуть за ненадобностью. Ну я под этим подразумевал пустой цикл :) А если запятую убрать, то получится 75 раз NOP-ов )) Ну а на счёт выкинет, есть же volatile) мануалы читать надо, там написано для чего и какая пауза должна быть между записями в SWRST. Если фрагмент кода сброса находится во внешней кешируемой памяти - не поможет. Надо чтоб этот фрагмент гарантировано был закеширован, тогда отключение SDRAM не страшно. Иначе получается - программа рубит сук на котором сидит) Изменено 19 сентября, 2017 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться