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

 
 
> 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  < 1 2 3 4 5 > »   
Start new topic
Ответов (30 - 44)
Сергей Борщ
сообщение Sep 21 2012, 13:25
Сообщение #31


Гуру
******

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



Возможность записи во флеш есть. Ведь как-то этот bootloader должен записать во флеш вашу основную программу? И делается это вызовом функций встроенного заводского загрузчика (IAP). Что писать и куда писать - ему все равно. И на каком языке вы напишете вызов его функций - ему тоже все равно. Почему с REMAP ом не получится - непонятно. У всех получается. Посмотрите внимательно, на какие адреса попадает ваша команда ремапа. Я обращал внимание Артема в той ветке на этот момет - в момент ремапа содержимое первых 512 байтов флеш "накрывается" содержимым ОЗУ. И если следующая за ремапом команда вашего загрузчика попала в эту область - вместо нее будет выполнен мусор из соответствующих адресов ОЗУ. Поэтому если ваш загрузчик настолько мал, что команда находится в первых 512 байтах флеша - надо как-то ее оттуда отодвинуть. Либо поколдовать со скриптом линкера, либо добавить кода.


--------------------
На любой вопрос даю любой ответ
"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
Almaz1988
сообщение Sep 21 2012, 14:57
Сообщение #32


Частый гость
**

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



А IAP-команды переводятся же в ассемблерный код при компилляции? Это ведь не отдельный язык программирования.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 21 2012, 16:10
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(Almaz1988 @ Sep 21 2012, 18:57) *
А IAP-команды переводятся же в ассемблерный код при компилляции? Это ведь не отдельный язык программирования.

нет, конечно

в разные регистры заносятся команда, номер начального сектора, конечного сектора, адрес блока данных
вызывается IAP, адрес которого заранее известен
из еще одного регистра читается результат операции

какая разница, каким языком это дело описать?

а вот требования к выполнению IAP (как то - отключить PLL, например, или вызов IAP не из области FLASH) нужно выполнять обязательно
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Sep 22 2012, 12:13
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(toweroff @ Sep 21 2012, 19:10) *
а вот требования к выполнению IAP (как то - отключить PLL, например

В UM10398 Chapter 26: LPC111x/LPC11Cxx Flash programming firmware PLL не упоминается (или я не нашёл). Ссылку приведёте?


Цитата(toweroff @ Sep 21 2012, 19:10) *
вызов IAP не из области FLASH

В примере от NXP функции IAP вызываются из flash. Наверняка потому, что из bootloader не использует прерываний. В случае испоользования прерываний таблицу векторов и обработчики нужно поместить в RAM или запрещать прерывания на время стирания/записи flash.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 22 2012, 16:05
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(_Артём_ @ Sep 22 2012, 16:13) *
Ссылку приведёте?


Цитата(toweroff)
(как то - отключить PLL, например,


где-то это требуется, где-то - нет. Здесь весь смысл в том, что требования выполнения IAP, если они есть, выполнять нужно, а вот на каком языке это делать - никакой принципиальной разницы нет
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Sep 22 2012, 17:00
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(toweroff @ Sep 22 2012, 19:05) *
Здесь весь смысл в том, что требования выполнения IAP, если они есть, выполнять нужно,

Ну, если так...
Но всё равно спасибо - просмотрел ещё раз UM и обнаружил требование запрета прерываний на момент записи .
Хотя работало и без запрета - может функции IAP запрещают прерывания, если таблица не в ОЗУ?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 22 2012, 20:02
Сообщение #37


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Кхм...
Господа, а как обсуждение IAP от NXP относится к теме "STM32 bootloader"? sm.gif
Может быть, выделить это обсуждение в отдельную тему? А то путаница получается.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 22 2012, 20:16
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(AHTOXA @ Sep 23 2012, 00:02) *
Господа, а как обсуждение IAP от NXP относится к теме "STM32 bootloader"? sm.gif

да все как обычно biggrin.gif
Go to the top of the page
 
+Quote Post
Almaz1988
сообщение Sep 24 2012, 08:44
Сообщение #39


Частый гость
**

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



#include "LPC11xx.h"
#include "rom_drivers.h"
#include "gpio.h"
#include "string.h"
#include "type.h"
#include "core_cm0.h"
#include "system_LPC11xx.h"
#include "application_Flash.h"


__ASM void __copy_MSP_( )
{
ldr r0, =0x10000000
ldr r0, [r0]
mov sp, r0
}

__ASM void __copy_reset_handler_( )
{
ldr r0, =0x10000004
ldr r0, [r0]
bx r0
}

/********************************************************** Main function ********************************/
int main(void)
{
SystemInit();

LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

uint32_t const * pSrc = (uint32_t const *)0x00001000; //копируем первые 200 байт флеша, начиная с адреса 0х1000 в ОЗУ
uint32_t * pDst = (uint32_t *)0x10000000;
#define VECTORS_COUNT 128
for(uint_fast8_t i = 0; i < VECTORS_COUNT; ++i)
*pDst++ = *pSrc++;

__copy_MSP_( ); //загружаем в стек

__disable_irq(); //запрещаем прерывания
LPC_SYSCON->SYSMEMREMAP = 0x01; // remap to ram

__copy_reset_handler_(); //прыгаем на Resrt_handler

while(1);
}


Работает только если в "рабочей программе" не используются прерывания. Если прерывания используются, то "Рабоча программа" нивкакую не стартует.
Go to the top of the page
 
+Quote Post
AndreFF
сообщение Mar 2 2013, 07:01
Сообщение #40





Группа: Новичок
Сообщений: 3
Регистрация: 10-01-11
Пользователь №: 62 117



Здравствуйте!
Просьба откликнуться кто в теме. Пишу загрузчик для своего приложения (IAR 6.40, STM32F103VET). Как можно в процессе линковки вставить размер образа по конкретному адресу? Это точно можно сделать, тому пример пост Сергея Борща :

'У меня при сборке приложения линкер сразу за таблицей векторов вписывает размер образа, чтобы загрузчик мог просчитать контрольную сумму загруженного приложения (и только его, не учитывая свободную память).'

Go to the top of the page
 
+Quote Post
MK2
сообщение Mar 2 2013, 19:40
Сообщение #41


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535



тоже интересовал этот вопрос, но решил следующим образом: зафиксировал длину прошивки контроллера, просто принимаю за максимальный объем флешки контроллера (вернее то что остается от бутлоадера)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2013, 23:03
Сообщение #42


Гуру
******

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



QUOTE (AndreFF @ Mar 2 2013, 09:01) *
Это точно можно сделать, тому пример пост Сергея Борща :
Я использую gcc. Про ИАР ничего не скажу. Должна быть какая-то директива размещения константы, надо читать описание линкера.


--------------------
На любой вопрос даю любой ответ
"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
AndreFF
сообщение Mar 3 2013, 06:27
Сообщение #43





Группа: Новичок
Сообщений: 3
Регистрация: 10-01-11
Пользователь №: 62 117



Спасибо за ответы.
Пробовал следовать советам официальной техподдержки IAR
http://supp.iar.com/Support/?note=62709&from=note+65473
а именно пункта Alternative solution using checksum-start and checksum-end markers
Всё отлично, есть константы с адресами начала и конца проекта, считается CRC32, только в Нех файл значение CRC не заносится категорически, вместо него там нули. А в дизассемблере нормальное значение. Пока не победил это.
Go to the top of the page
 
+Quote Post
vovanxp
сообщение Dec 11 2014, 08:55
Сообщение #44


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 28-10-11
Пользователь №: 68 026



Хочу сделать загрузку прошивки через веб, но неполучается, не запускается основная программа.

Делаю на основе проекта с STM32CubeF4, LwIP_IAP. Манеул к этому проекту
http://www.st.com/st-web-ui/static/active/.../DM00103145.pdf

Среда Keil uVision, мк STM32f4
------------------------------------------

В бутлоадере выставил начальный адрес с которого будет стартовать основная программа
#define USER_FLASH_FIRST_PAGE_ADDRESS 0x08020000


В основной программе изменил начальный адресс 0x08020000
В основной программе изменил смещение для таблици векторов #define VECT_TAB_OFFSET 0x20000
------------------------------------------
После загрузки прошивок, доходит до Jump_To_Application(); и все, дальше тишина.
Переменная JumpAddress = 0x080201A5

if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
Jump_To_Application();
}

Основная программа начинается с адреса 0x08020000 смотрел через STM32 ST-LINK Utility
На скринах без смещения с со смещением, данные совпадаю, отличие только адресами.

В чем может быть причина?
Спасибо.
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 12 2014, 10:46
Сообщение #45


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(vovanxp @ Dec 11 2014, 11:55) *
В чем может быть причина?
Спасибо.

Выглядит более менее, за исключением того что неясно как вы меняете таблицу прерываний с бутлоадера на вашу программу. Вы блинк пробовали прошить?
Go to the top of the page
 
+Quote Post

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

 


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


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