Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите выгрузить ОС и перейти в Bootloader
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Spider
Всем првиеТ!

Экспериментирую с bootloader и пока сделал так: в самое начало Flash располагаю Bootloader, а с 0x0800400 первый попавшийся пример с USART из набора ChibiOS (ессестно с измененным .ld скриптом, чтобы начиналось всё с 0x0800400). Бутлоадер проверяет не нажата ли кнопочка при подаче питания на протяжении там 500ms и если нет, то перекидывает таблицу указателей и стек "на основное приложение", ежеле нажата кнопочка, то загружается сам и делает своё грязное дело. Ну всё примитивно просто и как обычно. Теперь захотелось странного - загрузить бутлоадер из приложения. Самое простое сделать SoftReset, но надо держать кнопочку. тогда я сделал ячейку в памяти куда пишу флаг и снова переношу таблицу векторов и вызываю ResetHandler бутлоадера. Но вот беда, всё падает и зависает.
Нет, переходить то оно переходит, но вызываются какие-то прерывания, видать которые были настроены в примере. Я пошёл в ЛОБ - перечислил перед переносом таблицы прерывания все регистры переферии, где можно было бы разрешить прерывание и запретил их наверняка. Отключил SysTick. Но ВСЁ РАВНО что-то происходит и bootloader зависает в Assert вызванный из заглушки на прерывание.
Есть способ выяснить что его вызывает? Дебагер не видит какое прерывание прыгнуло в этот указатель - back trace тупо начинается сразу с Assert().
Сижу вот и описываю все вектора в пустышки, дабы понять какая именно пустышка вызывается.
A. Fig Lee
Цитата(Alexey Belyaev @ Jan 8 2015, 11:58) *
Всем првиеТ!

Экспериментирую с bootloader и пока сделал так: в самое начало Flash располагаю Bootloader, а с 0x0800400 первый попавшийся пример с USART из набора ChibiOS (ессестно с измененным .ld скриптом, чтобы начиналось всё с 0x0800400). Бутлоадер проверяет не нажата ли кнопочка при подаче питания на протяжении там 500ms и если нет, то перекидывает таблицу указателей и стек "на основное приложение", ежеле нажата кнопочка, то загружается сам и делает своё грязное дело. Ну всё примитивно просто и как обычно. Теперь захотелось странного - загрузить бутлоадер из приложения. Самое простое сделать SoftReset, но надо держать кнопочку. тогда я сделал ячейку в памяти куда пишу флаг и снова переношу таблицу векторов и вызываю ResetHandler бутлоадера. Но вот беда, всё падает и зависает.
Нет, переходить то оно переходит, но вызываются какие-то прерывания, видать которые были настроены в примере. Я пошёл в ЛОБ - перечислил перед переносом таблицы прерывания все регистры переферии, где можно было бы разрешить прерывание и запретил их наверняка. Отключил SysTick. Но ВСЁ РАВНО что-то происходит и bootloader зависает в Assert вызванный из заглушки на прерывание.
Есть способ выяснить что его вызывает? Дебагер не видит какое прерывание прыгнуло в этот указатель - back trace тупо начинается сразу с Assert().
Сижу вот и описываю все вектора в пустышки, дабы понять какая именно пустышка вызывается.


Чтото не так сделано, наверное.
В HardFaultHandlere можно поймать откуда что пришло.
Но: какая микросхема хоть?. А! СТМ32

А таблицу векторов зачем переносить? Просто SoftReset.
Код
void NVIC_GenerateSystemReset(void)
{
  SCB->AIRCR = AIRCR_VECTKEY_MASK | (u32)0x04;
}
Spider
А как поймать?
Яж написал, что не хочу ресет, ибо придётся деражать кнопочку. Хочется перейти в бутлоадер, да так, чтобы дать ему понять, что это произошло не по ресету, а именно его вызвали "на сцену".
A. Fig Lee
Цитата(Alexey Belyaev @ Jan 9 2015, 12:41) *
А как поймать?
Яж написал, что не хочу ресет, ибо придётся деражать кнопочку. Хочется перейти в бутлоадер, да так, чтобы дать ему понять, что это произошло не по ресету, а именно его вызвали "на сцену".

1.Я в JLink/IAR ставлю брейкпоинт на HardFaultHandler.

2. Легче использовать ресет, но передавать флаг.
Флаг может быть разный. У меня есть внешняя EEPROM, там флаг.
Работает так:
На ресет (в том числе и ресет/принудительный переход в бутлоадер) или питание:
а) проверяется состояние кнопки, если она нажата, стоим в бутлоадере
б) если она не нажата, читаем флаг, если он 0xFF, значит программы нет или она недействительна (или был принудительный переход в бутлоадер),
стоим в бутлоадере
в) если там 0хFE, значит мы записали правильную программу, и прыгаем туда
д) если мы все еще в бутлоадере, ждем команды. В гланую программу прыгаем по определенной команде

В программе:
а) делаем какуюто инициализацию
б) проверяем наш флажок, если там 0xFF, пишем туда 0xFE, чтобы бутлоадер нас загружал
в) если поступила команда в бутлоадер, пишем в флажок 0хFF, делаем ресет

В качестве флажка можно использовать:
а) внешнюю EEPROM
cool.gif внутренюю flash
c) battery backed RAM (RTC)
d) обычную RAM память. Только надо одну ячейку в определенном для бутлоадера и программе месте назначить __no_init в IAR и проверять ее на каой нибудь ключ, типа
0х3FDEADEB..

Spider
а RAM проца после SoftReset в каком состоянии?
A. Fig Lee
Цитата(Alexey Belyaev @ Jan 9 2015, 13:17) *
а RAM проца после SoftReset в каком состоянии?

Как после хард ресета, все в 0. он же переходит на начальный аддресс, там обнуление глобальной памяти,
поэтому и надо __no_init для какойто ячейки, чтоб ЕЕ не обнуляли никогда
Сергей Борщ
Цитата(Alexey Belyaev @ Jan 8 2015, 18:58) *
тогда я сделал ячейку в памяти куда пишу флаг и снова переношу таблицу векторов и вызываю ResetHandler бутлоадера.
Такой флажок у вас уже есть, он называется RCC_CSR_SFTRSTF и лежит в RCC->CSR. Просто делайте программный сброс и проверяйте его в загрузчике. После проверки сбрасывайте битом RCC_CSR_RMVF. После окончания загрузки сбрасывайте процессор собакой, это позволит не попасть снова в загрузку после сброса.

Spider
Цитата(Сергей Борщ @ Jan 9 2015, 22:53) *
Такой флажок у вас уже есть, он называется RCC_CSR_SFTRSTF и лежит в RCC->CSR. Просто делайте программный сброс и проверяйте его в загрузчике. После проверки сбрасывайте битом RCC_CSR_RMVF. После окончания загрузки сбрасывайте процессор собакой, это позволит не попасть снова в загрузку после сброса.

Думал об этом. Но в программу у меня хорошо получается переходить переносом прерывайний и всего такого.

Цитата(A. Fig Lee @ Jan 9 2015, 22:04) *
Как после хард ресета, все в 0. он же переходит на начальный аддресс, там обнуление глобальной памяти,
поэтому и надо __no_init для какойто ячейки, чтоб ЕЕ не обнуляли никогда

Просто интересно было, если не учитывать действия "софта" содержимое RAM после софтового сброса сохраняется...
Сергей Борщ
Цитата(Alexey Belyaev @ Jan 10 2015, 10:03) *
Думал об этом. Но в программу у меня хорошо получается переходить переносом прерывайний и всего такого.
Пока получается. Усложните загрузчик - начнется цирк. После того, как ваша программа или загрузчик запустит кучу прерываний, что будет вызываться после подмены таблицы векторов? А если программа или загрузчик еще и ПДП запустит - будет вообще весело, когда ПДП начнет складывать данные поверх данных загрузчика/программы. Сброс гарантирует, что все последствия работы предыдущей программы будут устранены. И достигается это минимальными усилиями - одной командой сброса. Приводить периферию в исходное состояние вручную гораздо сложнее.

То есть при переходе в программу вам нужно будет переносить прерывания и все такое, но делать это желательно сразу после сброса, пока периферия находится в нетронутом состоянии.
Spider
Цитата(Сергей Борщ @ Jan 10 2015, 15:28) *
Пока получается. Усложните загрузчик - начнется цирк. После того, как ваша программа или загрузчик запустит кучу прерываний, что будет вызываться после подмены таблицы векторов? А если программа или загрузчик еще и ПДП запустит - будет вообще весело, когда ПДП начнет складывать данные поверх данных загрузчика/программы. Сброс гарантирует, что все последствия работы предыдущей программы будут устранены. И достигается это минимальными усилиями - одной командой сброса. Приводить периферию в исходное состояние вручную гораздо сложнее.

То есть при переходе в программу вам нужно будет переносить прерывания и все такое, но делать это желательно сразу после сброса, пока периферия находится в нетронутом состоянии.

Да как бы загрузчик уже закончен и работает. И всё после себя подтирает и выходит красиво. Просто там я знаю что трогал и что убрать. Всё красиво работает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.