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

stm32 bootloader, разьясните новичку

Подскажите, как сделать безусловный переход по адресу. Бутлоадер записал прогу например по адресу 0х08010000.

 

как организовать прыжек из бутлоадера в основную программу?

Если приложение скомпилировано для загрузки с адреса 0x8010000, по этому адресу будет размещаться таблица векторов.

Вектор Reset находится по смещению +4, но это не точка входа, а указатель на нее. Поэтому нужно достать адрес из таблицы векторов и уже его присвоить указателю на функцию.

Смотрим проверенный пример от ST:

 

#define ApplicationAddress    0x08010000                                 //Начало нашего приложения
typedef  void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;

if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) //Проверяем, есть ли что-нибудь по адресу (там должно лежать значение SP для приложения, его кладет линкер)
    { 
      JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);  //Адрес перехода из вектора Reset
      Jump_To_Application = (pFunction) JumpAddress;                 //Указатель на функцию перехода
      __set_MSP(*(__IO uint32_t*) ApplicationAddress);                //Устанавливаем SP приложения
      Jump_To_Application();                                                       //Запускаем приложение
    }
    while(1);                                                                              // Если приложение не записано, Watchdog вернеет нас на начало бутлоадера

 

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

 

 

void main(void)
{
    __disable_interrupt();                                                  // Запрещаем прерывания
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000); //Адрес таблицы относительно начала Flash

...
}

Ответы на все вопросы лежат в примерах из AN2557

 

 

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

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


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

//Указатель на функцию перехода

__set_MSP(*(__IO uint32_t*) ApplicationAddress); //Устанавливаем SP приложения

__disable_interrupt();

}[/code]

что то ругается компилятр на эи строчки, хотя путь к CoreM3 прописан.

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


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

что то ругается компилятр на эи строчки, хотя путь к CoreM3 прописан.

Мне вот такой способ больше нравится:

#define APP_ADDR 0х08010000

void
start_app(void)
{
        static const uint16_t code[] =
        {
                0xF850, 0xDB04, /* LDR.W SP, [R0], #4   */
                0x6800,         /* LDR.W R0, [R0]       */
                0x4700,         /* BX R0                */
        };
        ((void (*)(uint32_t))(1 + (int)code))(APP_ADDR);
}

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


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

что то ругается компилятр на эи строчки, хотя путь к CoreM3 прописан.

Пример под IAR, компилировал на 6.21.

__disable_interrupt() объявлена в intrinsics.h

 

Под другие компиляторы примеры есть в AN2557

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


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

Мне вот такой способ больше нравится:

Вылетает в хард фолт.

 

Меня интересует этот вопрос только для кейла.

Изменено пользователем IgorKossak
бездумное цитирование

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


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

Вылетает в хард фолт.

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

 

Меня интересует этот вопрос только для кейла.

Прелесть этого кода состоит в том, что он должен работать с любым компилятором.

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


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

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

Например???

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


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

подскажите плиз по переходу из бутлоадера в основную программу:

- можно ли одной простой коммандой деинициализировать всю переферию, которая была инициализирована в бутлоадере??? ну или каким нибудь простым изящным движением руки?

- при переходе в основную программу оперативная память контроллера остается занятой данными из бутлоадера, так? подскажите плиз простой способ подчистить память от всех этих данных?

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


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

Вот такой алгоритм обеспечивает 100%-надёжное удалённое обновление прошивки в устройстве по рабочему протоколу, не боящееся неожиданных сбоев питания и с возможностью широковещательного

обновления ПО.

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

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


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

Конечно перед заливкой, надо провести полные испытания новой прошивки.

Ваши предложения как обойти этот минус?

Учтите, что рабочий интерфейс в общем случае у нас может быть сложным - сокет TCP/IP поверх Ethernet или GSM или ZigBee и т.п., т.е. - канал, для которого нельзя задать конфигурационные параметры по умолчанию.

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


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

- можно ли одной простой коммандой деинициализировать всю переферию, которая была инициализирована в бутлоадере??? ну или каким нибудь простым изящным движением руки?

- при переходе в основную программу оперативная память контроллера остается занятой данными из бутлоадера, так? подскажите плиз простой способ подчистить память от всех этих данных?

В начале бутлоадера проверяем признак его запуска (это может быть состояние Option Byte или бита в регистре Backup Domain, далее, если не надо его запускать, идем на основную программу с неинициализированной периферией, если надо - инициализируем периферию, пишем прошивку, сбрасываем признак запуска и делаем NVIC_SystemReset(), который выкидывает нас снова на старт,

но уже со сброшенным признаком запуска.

 

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

Если приложение на Си самостоятельное, не является частью проекта бутлоадера, то компилятор пропишет в стартовом коде все инициализации переменных.

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

 

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


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

Ваши предложения как обойти этот минус?

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

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


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

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

 

Конечно, от необнаруженных при помощи CRC ошибок в прошивке это может и не спасти (если ошибки в прошивке есть, а сама функция-ключ будет работоспособной), но хотя бы спасет от заливки "левых" прошивок и выполнения устройством непредусмотренных действий.

 

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...