1

Тема: Bootloader для мікроконтролера STM32F030

Добрий день!
Підкажіть будь ласка, як перенести таблицю векторів переривать при старті основної програми?
Робив bootloader для STM32F4xx, то там був регістр VTOR, а у 030 нема.

#define MAIN_PROGRAM_START_ADDRESS     (uint32_t)0x08008000

void GoToApplication(void)
{
    if (((*(__IO uint32_t*)MAIN_PROGRAM_START_ADDRESS) & 0x20000000 ) == 0x20000000 ||
       ((*(__IO uint32_t*)MAIN_PROGRAM_START_ADDRESS) & 0x10000000 ) == 0x10000000)
    {
        char buf[] = "--------------- Firmware is loaded ---------------\r\n";
        HAL_UART_Transmit(&huart5, (uint8_t*)buf, sizeof(buf), 1000);

                // DeInit
        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);
        HAL_UART_DeInit(&huart5);

        /* Jump to main application */
        Jump_To_Application = (pFunction) (*(__IO uint32_t*) (MAIN_PROGRAM_START_ADDRESS + 4));
        __set_MSP(*(__IO uint32_t*) MAIN_PROGRAM_START_ADDRESS);
        Jump_To_Application();
    }
}

Основна програма запускається, але переривання не працюють.
Підкажіть будь ласка - де помилка?
Дякую.

2

Re: Bootloader для мікроконтролера STM32F030

Див сторінку 42 тут

Подякували: leofun01, Gruffi2

3

Re: Bootloader для мікроконтролера STM32F030

Дякую. Буду розбиратися.

4

Re: Bootloader для мікроконтролера STM32F030

Додав ремап таблиці векторів:

void RelocateVectorTable(void)
{
    // Copy interrupt vector table to the RAM.
    volatile uint32_t *VectorTable = (volatile uint32_t *)0x20000000;
    uint32_t ui32_VectorIndex = 0;

    for(ui32_VectorIndex = 0; ui32_VectorIndex < 48; ui32_VectorIndex++)
    {
        uint32_t vector_addr = ((uint32_t)MAIN_PROGRAM_START_ADDRESS + (ui32_VectorIndex << 2));
        VectorTable[ui32_VectorIndex] = vector_addr;
    }

    __HAL_RCC_AHB_FORCE_RESET();

    //  Enable SYSCFG peripheral clock
    __HAL_RCC_SYSCFG_CLK_ENABLE();
    __HAL_RCC_AHB_RELEASE_RESET();

    // Remap RAM into 0x0000 0000
    __HAL_SYSCFG_REMAPMEMORY_SRAM();
}

Але все одне нічого не працює. Програма падає і видає наступне:

main() at main.c:102 0x800825e    
0x8    
<signal handler called>() at 0xfffffff1    
g_pfnVectors() at 0x800800c    

5

Re: Bootloader для мікроконтролера STM32F030

Программа падає при виклику HAL_Delay, але g_pfnVectors() at 0x800800c це обробник Hard_Fault, наскільки я зрозумів, але у нього не заходить.

6

Re: Bootloader для мікроконтролера STM32F030

Так там же на початку оперативної пам'яті лежать різні дані, гляньте .map.

Це краще лінкерним скриптом на початку оперативки фіксовано відрізати шматок для копії векторів, а далі хай лінкер .rodata/.data/.bss пхає.

Подякували: leofun011

7

Re: Bootloader для мікроконтролера STM32F030

Дякую. Буду далі вивчати :)

8

Re: Bootloader для мікроконтролера STM32F030

ReAI: А підкажіть будь ласка, якщо я додаю вектори на початок SRAM, а потім проєцую їч на нульови адрес, то все одно ці данні можуть починатися не с початку. Це я до того, що треба з лінкером працювати...

9 Востаннє редагувалося ReAl (14.09.2023 15:38:37)

Re: Bootloader для мікроконтролера STM32F030

Якщо вектори записані на початок SRAM з адреси 0x20000000, то при відображенні SRAM на нульову адресу
ядро бачитиме їх починаючи і з адреси 0x00000000

Задача в тому, щоб лінкер всі інші змінні розміщував починаючи з адреси 0x200000C0 (якщо векторів 48).
Тоді запис векторів у діапазон 0x20000000..0x200000BF не перетре ніяких змінних.
Після відображення оперативки в 0, ядро в адресах 0x00000000..0x000000BF бачитиме вектори,
а програма в адресах 0x200000С0..0x2000xxxx бачитиме свої змінні, стек, ...

p.s. ReAl (остання літера - маленька L)

Подякували: Gruffi1

10

Re: Bootloader для мікроконтролера STM32F030

Велике дякую (літеру не догледів - сорі).