Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/34: Рейтинг темы: голосов - 34, средняя оценка - 4.76
q0296

Bootloader STM32F030

05.05.2017, 13:40. Показов 6961. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам


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

В интернете почти везде один и тот же пример бутлоадера и у меня почти такой же. Исключение составляет то, что на моем контроллере таблицу векторов можно размещать только в двух местах
1) по адресу 0x08000000, но тут хранятся вектора моего бутлоадера
2) в оперативной памяти, у меня в примере по адресу 0x20000000
3) как я понял есть 3 место, но в нем хранится заводской бутлоадер (т.е. туда лезть не надо)

Тестовая программа заливается на контроллер (сравнил бинарники заливаемого файла и снятого с контроллера, все сходится).
Вручную переношу вектора прерывания и в регистре указываю, что они будут в оперативной памяти. Ошибка может быть в том, что вектора повторяются т.е. они будут и по адресу 0х20000000 и по 0x08001400. (Сомневаюсь что ошибка тут)
Вектора занимают 0xC0 места, значит мне нужно задать, что начало программы будет по адресу 0x080014С0 не уверен что у меня это указано. Как указывать начало программы в Keil uVision не совсем понял.

Переход советуют делать на вектор ресета, если он сбрасывает оперативную память, тогда нужно вектора переносить уже в теле тестовой прошивки(так уже пробовал делать). Либо вообще не переходить на вектор Riseta и в ручную сбрасывать настройки на стандартные и потом переходить на начало программы.

Все что написано выше это только мои фантазии о том как работает микроконтроллер.

Код перехода из бутлоадера на программу:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// функция ремапа таблицы векторов прерываний
void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
{
uint32_t tmpctrl = 0;
 
ossirt_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
tmpctrl = SYSCFG->CFGR1;
tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
SYSCFG->CFGR1 = tmpctrl;
}
 
// функция перехода на основную программу
void Go_MainProkram(void)
{
uint32_t jumpAddress;
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
 
uint16_t i;
__disable_irq();
 
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SROM);
for (i=0; i<COUNT_VECTORS; i++) {
if (i == 3) {
*(__IO uint32_t*)(NVIC_VectTab_ROM+i*4) = *(__IO uint32_t*)(BOOTLOADER_START_ADDRESS+i*4);
}
else
{
*(__IO uint32_t*)(NVIC_VectTab_ROM+i*4) = *(__IO uint32_t*)(MAIN_PROGROM_START_ADDRESS+i*4);
}
}
jumpAddress = *(__IO uint32_t*) (MAIN_PROGROM_START_ADDRESS + 4);
Jump_To_Application = (pFunction) jumpAddress;
__set_MSP(*(__IO uint32_t*) MAIN_PROGROM_START_ADDRESS);
//__enable_irq();
Jump_To_Application();
}
Тестовая прошивка:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main(void)
{
uint16_t i;
 
__set_PRIMASK(1);
 
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SROM);
for (i=0; i<COUNT_VECTORS; i++) {
if (i == 3) {
*(__IO uint32_t*)(NVIC_VectTab_ROM+i*4) = *(__IO uint32_t*)(BOOTLOADER_START_ADDRESS+i*4);
}
else
{
*(__IO uint32_t*)(NVIC_VectTab_ROM+i*4) = *(__IO uint32_t*)(MAIN_PROGROM_START_ADDRESS+i*4);
}
}
// перенос векторов
__set_PRIMASK(1);
 
__enable_irq();
Init();
 
while(1) {
Delay_ms(10000);
USORT_SendData(T);
USORT_SendData(E);
USORT_SendData(S);
USORT_SendData(T);
}
}
Сам проект:
https://dryve.google.com/open?... 0FNLUxoMzQ

Попробовал абстрагироваться от переноса векторов и задание начала программы и сделал такую прошивку:
https://dryve.google.com/open?... WNGZ2JJZlU
Смысл ее в том, чтобы вывести что-то на экран и потом как и бутлоадере перейти с помощью функции по заданному адресу, но тут уже переход совершает на себя же (Получается что-то типа цикла). Но прошивка тоже не работает

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(void)
{
__enable_irq();
Init();
 
for(i=48;i<58;i++){
Delay_ms(5000);
USORT_SendData((char)i); // вывожу цифры
}
Delay_ms(30000);
Go_MainProkram();
}
 
void Go_MainProkram(void)
{
uint32_t jumpAddress;
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
 
__disable_irq(); //выключаем прерывания
 
jumpAddress = *(__IO uint32_t*) (BOOTLOADER_START_ADDRESS + 4);
Jump_To_Application = (pFunction) jumpAddress;
//__set_MSP(*(__IO uint32_t*) BOOTLOADER_START_ADDRESS);
Jump_To_Application();
}
Без понятия в чем проблема.
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.05.2017, 13:40
Ответы с готовыми решениями:

STM32F030 bootloader и основное приложение
Написал boottooder для STM32F030. Boottooder умеет шить флешь микропроцессора через RS-485. После зашивания, boottooder делает прыжок по...

Программирование STM32F030 с помощью встроенного bootloader
Выбрал, но еще не купил STM32F030! Остался один вопрос - смогу ли я на этом МК пользуватся Boottooderом. Дело в том что у него...

STM32F030 CRC
Добрый день! У меня не сходится аппаратный расчет CRC. Полином фиксированный 0x4C11DB7 Начальное значение дефолтное 0xffffffff ...

6
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
05.05.2017, 17:26
Ну прям зачастили, последняя тема 2 недели назад. Я там даже скрины давал как настраивать в кейле.
0
q0296
06.05.2017, 09:46
Код бутлоадера
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define MAIN_PROGROM_START_ADDRESS          ((uint32_t)0x08001400)
 
int main(void){
unsykned char buf_adr;
Init();
Delay_ms(1000);
USORT_SendData(B);
USORT_SendData(O);
USORT_SendData(O);
USORT_SendData(T);
Delay_ms(1000);
Go_MainProkram();
}
 
void Go_MainProkram(void){
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t jumpAddress;
 
__disable_irq();
 
jumpAddress = *(__IO uint32_t*) (MAIN_PROGROM_START_ADDRESS + 4);
Jump_To_Application = (pFunction)jumpAddress;
__set_MSP(*(__IO uint32_t*) MAIN_PROGROM_START_ADDRESS);
 
Jump_To_Application();
}
и его настройки


Код заливаемой программы
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uint8_t i;
volatile uint32_t *VectorTable = (volatile uint32_t *)0x20000000;
int main(void)
{
for (i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t *)(MAIN_PROGROM_START_ADDRESS + (i << 2));
}
SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
__enable_irq();
Init();
while(1) {
Delay_ms(1000);
USORT_SendData(T);
USORT_SendData(2);
}
}
настройки программы:


Вроде все сделал как в том посте, но после "перехода" выводит сообщение бутлоадера т.е. не переходит на основную программу.
Может с настройками бутлоадера не так что-то?
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
06.05.2017, 11:31
MAIN_PROGROM_START_ADDRESS где определен в основной программе?
И что там за Init()
Как она у вас вообще собралась?
0
q0296
06.05.2017, 14:14
Думал ничего интересного в ней нет.
В Init() происходит настройка портов, периферии и т.п.
Code
1
2
3
4
5
6
7
8
9
10
void Init (void)
{
SysTick_conf(SystemCoreClock/100000 - 1); // прерывание каждые 10 мкс
Init_GPIO();
Init_USORT();
Init_SPI();
Init_EXTI();
Init_NRF();
Init_CRC32();
}
Если нужно подробнее:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void Init_GPIO (void)
{
// Включить тактирование порта A
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
 
// инициализация светодиода (PA.3), SPI - (PA.4-PA.7), USORT - (PA.9, PA.10), PA.14 - IRQ, PA.13 - CE
GPIOA->MODER =    GPIO_MODER_MODER3_0 | GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_1 |
GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 | GPIO_MODER_MODER9_1 |
GPIO_MODER_MODER10_1 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_1;
 
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR9;    // PA10 (RX) PA9 (TX) - High speed
GPIOA->BSRR = GPIO_BSRR_BS_4;
}
 
void Init_SPI(void)
{
//инициализация SPI, кроме портов GPIO
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
 
SPI1->CR2 = 0;
SPI1->CR1 = 0;
 
SPI1->CR2 = SPI_CR2_FRXTH | SPI_CR2_SSOE | SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_SPE;
}
 
void Init_EXTI(void)
{
// Настраиваем EXTI1 и EXTI2  на выводы порта А
SYSCFG->EXTICR[3]|= SYSCFG_EXTICR4_EXTI14_PA;
 
// Разрешаем прерывания в периферии
EXTI->IMR |= EXTI_IMR_MR14;
EXTI->FTSR |=EXTI_FTSR_TR14;      // Прерывание по спаду уровня на ноге 14 порта привязанного к EXTI
NVIC_SetPriority(EXTI4_15_IRQn, 0); // функция, которая позволяет изменить приоритет прерывания
NVIC_EnableIRQ(EXTI4_15_IRQn);
}
Все хорошо собирается, только для примера MAIN_PROGROM_START_ADDRESS вынес из заголовочного файла, чтоб все переменные не вываливать сюда. На самом деле все макросы находятся в заголовочном файле, который подключен к бутлоадеру и основной программе.
Вот часть макросов из заголовка (остальные не используются):
Code
1
2
3
#define BOOTLOADER_START_ADDRESS            ((uint32_t)0x08000000)
#define MAIN_PROGROM_START_ADDRESS          ((uint32_t)0x08001400)
#define NVIC_VectTab_ROM                    ((uint32_t)0x20000000)
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
06.05.2017, 14:24
У вас инит одинаковый для бутлоадера и для основной программы?
Вы уже один раз инициализировали периферию в бутлоадере. В основной программе нужно сбросить ее и заново все инициализировать. Таблица векторов поменялась для прерываний.
Но для начала уберите инит вообще, просто помигайте светодиодом в основной программе в цикле.
И еще, вы когда в Кейле шьете флеш у вас там случайно не стоит "стирать всю память"?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 886
06.05.2017, 15:55
Кроме метода пристального вглядывания, есть метод отладки при помощи отладчика.
Пройдите по шагам и увидите где ошибка в буквах и настройках.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.05.2017, 15:55
Помогаю со студенческими работами здесь

STM32F030 + АЦП
Господа, не сочтите за нубство, но может кто поделится рабочими примерами АЦП в STM32F030 (всевозможные вариации)? Буду ооочень благодарен

stm32f030 UID
Добрый день! подскажите, есть ль ли в stm32f030 UID (Уникальный номер). в документации за него ни слова ни сказано. В reference...

Перезагрузка tim17 на stm32f030
Доброго времени суток всем. Столкнулся с проблемой (вроде даже детской) которую не могу уже целый день решить. Если вкратце, то нужно: ...

Инициализация периферии STM32F030
Здравствуйте. Сделал небольшую железку на STM32F030K6T6. Так вот она должна пару раз в секунду оцифровывать один канал АЦП и передавать...

STM32F030 2 прерывания в 1 таймере
Подскажите, как сделать следующее: Необходимо настроить, чтобы 1 таймер вызывал 2 прерывания. Одно прерывание допустим раз в 1 ms. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru