Собственный Bootloader для stm32. Не запускаются прерывания

Рейтинг: 1Ответов: 2Опубликовано: 20.07.2023

Ld файл bootloader:

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 8K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 64K
}

Функция перехода в основною программу

#define APPLICATION_ADDRESS    0x8003000//адрес начала программы

void Go_To_User_App(void)
{
uint32_t app_jump_address;

typedef void(*pFunction)(void);
pFunction Jump_To_Application;
 __disable_irq();
app_jump_address = *( uint32_t*) (APPLICATION_ADDRESS + 4);    
Jump_To_Application = (pFunction)app_jump_address;            
  __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);          
Jump_To_Application();
}

Ld файл основного софта:

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 8K
FLASH    (rx)    : ORIGIN = 0x8003000,   LENGTH = 64K
}

Вектор tab offset:

#define VECT_TAB_OFFSET  0x0003000U

                     

Если не включены таймеры в основной программе, все отрабатывает корректно.

Проблема, при включении любого таймера программа доходя до таймера прекращает работу,.

Подскажите, кто-то сталкивался с такой проблемой, как решили?

Ответы

▲ 0

Надо добавить деиниты

#define APPLICATION_ADDRESS    0x8005000//адрес начала программы

void Go_To_User_App(void) { uint32_t app_jump_address;

typedef void(*pFunction)(void);//объявляем пользовательский тип
pFunction Jump_To_Application;//и создаём переменную этого типа


 //__disable_irq();

app_jump_address = *( uint32_t*) (APPLICATION_ADDRESS + 4);
HAL_RCC_DeInit();
HAL_DeInit();

Jump_To_Application = (pFunction)app_jump_address;            //приводим его к пользовательскому типу
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);          //устанавливаем SP приложения
__disable_irq();
SCB->VTOR = APPLICATION_ADDRESS;
__enable_irq();
Jump_To_Application();

}

▲ 0

Судя по всему используется HAL, для него нужно сбросить настройки SysTick.

Вместо

__disable_irq();

надо прописать

HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;