Писал я писал прошивку и написал. Теперь захотелось сделать бутлоадер. Взял готовый бутлоадер, и подправил пару мест в своей прошивке:
В Ld скрипте заменил
Код
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
на
Код
FLASH (rx) : ORIGIN = 0x8002000, LENGTH = 120K
В system_stm32f1xx.c убрал строки:
Код
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
а добавил их в самом начале main()
Код
SCB->VTOR = FLASH_BASE + 0x2000; /* Vector Table Relocation in Internal FLASH. */
На этом казалось бы и всё. Если стартовать прошивку отладчиком - всё работает. Линковщик собирает адреса начиная с 0х08002000 и так далее. В таком случае Reset_Handler находится по смещению 0x0800db7c, а main() в 0x0800bb7c
Теперь немного о способе запуска основного кода из Bootloader:
Первое что делаю перед запуском это:
- Останавливаю используемый бутлоадером SysTick таймер:
Код
SysTick->CTRL = SysTick->LOAD = SysTick->VAL = 0;
- запрещаю прерывания:
Код
__asm volatile ("cpsid i");
Уже от отчаянья сбрасываю NVIC:
Код
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICER[2] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
NVIC->ICPR[2] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICER[2] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
NVIC->ICPR[2] = 0xFFFFFFFF;
Отключаю периферию:
Код
RCC->APB1RSTR = 0;
RCC->APB2RSTR = 0;
RCC->APB1ENR = 0;
RCC->APB2ENR = 0;
RCC->APB2RSTR = 0;
RCC->APB1ENR = 0;
RCC->APB2ENR = 0;
Сбрасываю RCC:
Код
RCC_DeInit();
Далее стандартные шаги расчёта вектора перехода:
Код
pProgResetHandler = (void(*)(void))(*((blt_addr *)(*(FLASH_BASE+0x2000)+0x00000004))); //Тут получается 0x0800db7c - та же цифра что и .Reset_Handler
__set_MSP(FLASH_BASE+0x2000);
pProgResetHandler();
while(1); // Это строка вроде как никогда не достижима
__set_MSP(FLASH_BASE+0x2000);
pProgResetHandler();
while(1); // Это строка вроде как никогда не достижима
И вот тут самое интересное. Вектор переходит на .Reset_Handler и идёт исполнять его код, но к моменту когда надо прыгнуть на main() в отладке видно что строка имеет положенный ей вид:
Код
bl 0x0800bb7c
и он даже прыгает туда, и попадает по нужному адресу, но о УЖАС в окне отладки совсем другой код. Какой-то вырванный из середины прошивки код. НО ОН ПО ЭТОМУ АДРЕСУ. а сам main() где-то в другом месте. Совсем в другом месте.
Как так то?
Что я делаю не так?
И естественно исполняя этот код процессор попадает в жуткие состояния.
Помогите чем нить

ЗЫ. Основная прошивка построена на FreeRTOS, но я не могу связать FreeRTOS и это состояние, т.к. до неё дело даже не доходит.