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

 
 
> STM32 bootloader, написание собственного бута
ierofant
сообщение Jan 3 2012, 13:31
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-02-11
Из: Украина, Киев
Пользователь №: 62 695



Всем привет.

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

Во-первых, для себя я вижу 2 концепции бутлоадера, каждый со своими плюсами и минусами.

1. Основная программа качает прошивку, пишет её в определенное место флеша(например, с 16-й страницы флеша), проверяет, все ли правильно записалось, устанавливает в энергонезависимом регистре флаг, что нужно войти в бут, перезагружается, происходит вход в бутлоадер, который очищает основную программу(например, со 2й страницы флеша) и перезаписывает новую прошивку на это место и переходит на выполнение основной программы.

Преимущества(+)/недостатки(-):
+простота бутлоадера, в том числе не нужно инициализировать юарт и модуль из бутлоадера.
+не нужно долго висеть в буте
+перезагружаться в бут можно только после того, как прошивка успешно закачана
-если не верно закачалась прошивка либо же не рабочая прошивка - только вручную перепрошивать
-нужен МК с бОльшим обьемом Flash

2. Основная программа перегружает МК в бут, который удаляет старую прошивку, качает новую и сразу записывает её вместо старой.

Преимущества(+)/недостатки(-):
+бут может сам скачать новую прошивку
+контроллер с меньшим обьемом флеша
-сложность бута - нужно будет иниициализировать юарт, включать и инициализировать gsm модуль.
-долго находиться в бутлоадере

Какой вариант лучше? И, может, есть более совершенные решения?

Теперь вопросы по реализации:
1. Какие подводные камни могут быть в написании бута?
2. Читал на форуме про то, что нужно перезаписывать таблицу векторов(или вектора прерываний?)? Можно об этом подробнее? Как это делается? Где об этом можно подробнее почитать, а то никакой вразумительной инфы не нашел.
3. Бут и основная программа пишуться ведь как 2 разных проекта?


Отадельным вопросом - как заставить программу перейти на выполнение с определенного адреса? Где найти об этом информацию?
Пробывал как в примере от ST:
CODE
#include "common.h"
#define ApplicationAddress 0x08000073

extern pFunction Jump_To_Application;
extern uint32_t JumpAddress;

/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();


Не получилось. На ф-ции Jump_To_Application(); уходит в hardfault
Особенно не понятно, где тело этой функции, нигде в присоединенных файлах эта функция не описана. (файлы примера прикрепил к сообщению)

Был бы очень благодарен, если бы кто-то подсказал, где об этом можно прочитать и где можно найти рабочие и понятные примеры.


И чтобы не плодить сообщения, напишу про еще одну проблему с отладочной платой: на STM32VLDiscovery целевой контроллер работает, прошивается, но невероятно греется. Даже на 2 секунды нельзя на нем задержать палец. Очень горячий. Закороток визуально нет, да и паяльником я не притрагивался к плате , не знаю, с чего все и началось. Тестера под рукой тоже нет. Не работает светодиод LD4. Правда я не знаю, это следствие или причина нагрева, сейчас далеко от цивилизации, протестить и перепаять ничего не могу. (схема : http://www.st.com/internet/com/TECHNICAL_R...CD00267113.pdf)


Прикрепленные файлы
Прикрепленный файл  an2557.rar ( 1.64 мегабайт ) Кол-во скачиваний: 79
 
Go to the top of the page
 
+Quote Post
8 страниц V  « < 4 5 6 7 8 >  
Start new topic
Ответов (75 - 89)
esaulenka
сообщение Feb 25 2015, 15:14
Сообщение #76


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(ViKo @ Feb 25 2015, 17:00) *
Дохожу в загрузчике до JumpAppl() и улетаю незнамо куда, в 0xBFFFXXXX.

Кайл умеет ходить шагами по дизассемблеру. Рекомендую, сразу будет видно, ОТКУДА улетает.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 25 2015, 15:45
Сообщение #77


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(esaulenka @ Feb 25 2015, 18:14) *
Кайл умеет ходить шагами по дизассемблеру. Рекомендую, сразу будет видно, ОТКУДА улетает.

Да вот оттуда и улетает, как JumpAppl() жму. Больше же нет ничего для дизассемблера, проект кончается.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Feb 25 2015, 17:29
Сообщение #78


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(ViKo @ Feb 25 2015, 21:00) *
Дохожу в загрузчике до JumpAppl() и улетаю незнамо куда, в 0xBFFFXXXX.

Надо смотреть куда линкер таблицу векторов засунул, похоже она осталась на прежнем месте.
Возможно что сегмент кода и сегмент под таблицу векторов настраиваются отдельно.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 25 2015, 17:58
Сообщение #79


Гуру
******

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



Цитата(ViKo @ Feb 25 2015, 17:45) *
Да вот оттуда и улетает, как JumpAppl() жму.
Вот прямо в дизассемблере так и написано JumpAppl()? У меня там обычно что-то вроде BL R0 и чуть выше можно увидеть, откуда в R0 вдруг оказался неправильный адрес перехода.


--------------------
На любой вопрос даю любой ответ
"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
ViKo
сообщение Feb 25 2015, 18:29
Сообщение #80


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(SSerge @ Feb 25 2015, 20:29) *
Надо смотреть куда линкер таблицу векторов засунул, похоже она осталась на прежнем месте.

Я ее (их обеих) вижу в окнах Memory в отладчике. Все, как надо: адрес стека, адрес по сбросу...

Цитата(Сергей Борщ @ Feb 25 2015, 20:58) *
Вот прямо в дизассемблере так и написано JumpAppl()? У меня там обычно что-то вроде BL R0 и чуть выше можно увидеть, откуда в R0 вдруг оказался неправильный адрес перехода.

У меня тоже, естественно. BL R1. И адрес в нем правильный, из таблицы, что находится по адресу 0x08004004.
А дальше - то, что описал.

Здесь вот какая штука - в основной программе использую Keil RTX RTOS. Может, она и меняет что-то, например, VTOR. Надо посмотреть в несдвинутом проекте.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 26 2015, 13:33
Сообщение #81


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Из программы-загрузчика по стартовому адресу основной программы 0x08004000 переходит. Начинает обнулять переменные и когда обращается к внешнему ОЗУ, впадает в HardFault. Устанавливается бит Imprecise data access violation, и всё.
Если же основную программу скомпилировать с адреса 0x08000000, то работает.

Складывается впечатление, что нужно сконфигурировать ExtMem. Что делается в кейловской SystemInit, вместе с установкой рабочей частоты, еще до обнуления переменных в __main.
Я SystemInit использую свою, контроллер внешней памяти программирую потом. Почему же программа не висла до этого?

Еще вижу в отладчике для сдвинутой программы в панели NVIC VTO=0x08004000 (как и должно быть), и TBLOFF=0x100080 (а это что за хрень?). В несдвинутой программе последнее - по нулям.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 27 2015, 15:58
Сообщение #82


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Перенес инициализацию FSMC (заодно и всего остального) в SystemInit. Как и предполагал, переход из загрузчика заработал. И как только до этого инициализировались переменные (массивы-буферы), ума не приложу.
Вот только просто ждать таймаута для перехода - не по человечески. Можно по кнопке оставаться в загрузчике. Так ее еще передать и принять нужно...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 2 2015, 19:43
Сообщение #83


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Feb 24 2015, 16:58) *
Судя по рисунку, STM32F20X может выполнять программу из внешней памяти. А также и из внутренней OTP Flash, наверное.
...
То есть, можно команды выбирать откуда хочешь!? rolleyes.gif

Должен выполнять, но возможно нужно настроить MPU предварительно.
По-крайней мере для LPC1788 в UM указано:
Default memory space permissions for the Cortex-M3 do not allow program
execution from the address range that includes the dynamic memory chip selects.
These permissions can be changed by programming the MPU

В реальности если запустить код в SDRAM, то при шагании JTAG видно, что несколько команд (с десяток) код выполняется нормально, но на некоторой команде вдруг улетает в
Memory Management Fault (MMFSR.IACCVIOL = 1).
Я только что прописал конфигурирование MPU и после этого всё заработало - теперь программа нормально выполняется из SDRAM (LPC1788).
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 9 2015, 10:10
Сообщение #84


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Хочу спросить... Что-то не могу после прошивки новой программы перескочить в основную. Если после сброса, и таймер отсчитал 2 с - переходит нормально. За эти 2 с я должен нажать кнопку на панели, тогда дается таймер в 16 с для приема кода прошивки. Так вот, если кода не пришло, тоже не могу перейти в основную программу. Как будто, что-то переинициализировать нужно.

Добавлю информации. После записи во флэш проверяю, что есть новый адрес для стека (т.е., что прошивка записана, и есть куда идти). Этот момент сигнализирую вспышкой светодиода. Дальше перехожу в основную программу.
Сразу после программирования диод не пыхает, т.е., не обнаруживается зашитая прошивка. После сброса - нормально проходит, после 2 с ожидания в загрузчике. Если нажму кнопку в это время, после 16 с светодиод тоже пыхает, но перехода нет. Чудо.
Запросы от USART стираю. Больше никакими прерываниями не пользуюсь.
P.S. Я, собственно, прерываниями от USART не пользуюсь. Проверяю состояние. Постирал pending биты запросов. Еще забыл про таймер. От него тоже стер. Всё то же.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 9 2015, 14:10
Сообщение #85


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



А в отладчике после 16 с перескакивает в основную программу и работает. И после обновления прошивки тоже перескакивает. Что-то я пасую.
Похоже, перескакивает он всегда, только работать, как надо, не хочет.

А еще у меня Keil пишет "*** error 34, line 32: undefined identifier" на строку G, main в файле инициализации отладчика. Конкретно, на main. ?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 10 2015, 13:27
Сообщение #86


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Так и не могу разобраться, что же не дает загрузчику перейти в основную программу сразу после ее прошивки. Ну, попринимал я что-то USART-ом, посчитал время таймером, пописал во флэш... и хочу выйти. Чего не хватает? После сброса (тот же загрузчик, но без приема нового кода) - все нормально запускается. Может, барьеры нужны?

Про кэши ART почитал.
Цитата
To limit the time lost due to jumps, it is possible to retain 64 lines of 128 bits in an instruction cache memory.
...
data cache ... feature works like the instruction cache memory, but the retained data size is limited to 8 rows of 128 bits.

Неслабые такие кэши? Но в загрузчике я их не включаю. И prefetch тоже.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 10 2015, 14:33
Сообщение #87


Гуру
******

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



Выходите через сброс (я выхожу через сброс по собаке). При вашем подходе потом замучаетесь в приложении приводить в исходное состояние использованную в загрузчике периферию.


--------------------
На любой вопрос даю любой ответ
"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
ViKo
сообщение Mar 13 2015, 13:47
Сообщение #88


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Все, исправил. Кнопка от панели передается двумя байтами, да еще и нажатое и отпущенное состояния. Лезло ненужное в основную программу.
Сбрасываю флаг USART_SR_RXNE, основная программа перестала улетать в прерывание.

Теперь задача - зашифровать-расшифровать прошивку. Думаю, не задействовать ли вычислитель CRC в мк.
Go to the top of the page
 
+Quote Post
veteq
сообщение Mar 19 2015, 13:24
Сообщение #89


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 5-12-06
Пользователь №: 23 160



Есть проблема со входом в бутлоадер STM32L051 (cortex m0+) из тела программы, микроконтроллер сбрасывается. Тот же код только с другими адресами прекрасно работает на STM32L151 и STM32L401 (cortex m3/m4). Подскажите в чем может быть проблема?

CODE


void (*SysMemBootJump)(void);

SysMemBootJump = (void (*)(void)) (*((unsigned int*) 0x1FF00004));

__disable_irq();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;

__set_MSP(0x20001000);
SysMemBootJump();



Сообщение отредактировал veteq - Mar 19 2015, 13:25
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 23 2015, 11:29
Сообщение #90


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(ViKo @ Mar 13 2015, 16:47) *
Теперь задача - зашифровать-расшифровать прошивку.

Попробовал XTEA. Пока только закодировал. rolleyes.gif Не знаю, сколько времени будет декодироваться в микроконтроллере.
Есть одно замечание. Поскольку кодируются блоки из двух слов, то и перемешивание битов идет в пределах этих двух слов. Дальше все начинается сначала. То есть, одинаковые последовательности слов в начале двоичного файла прошивки (пустые обработчики прерываний) после кодирования тоже будут выглядеть одинаково. Что наталкивает взломщика на принцип кодирования.

Сделал и декодирование, все по https://ru.wikipedia.org/wiki/XTEA#cite_note-report-1
Декодируется быстро, практически, мгновенно.
Фактически, имеется 4 32-битовых ключа, и количество итераций тоже можно выбрать на свой вкус.
Go to the top of the page
 
+Quote Post

8 страниц V  « < 4 5 6 7 8 >
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0

 


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


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