首页 文章

SysTick中断导致执行跳转到STM32F030上的0x1fffxxxx

提问于
浏览
0

我正在尝试在Linux的SW4STM32中使用 SysTick_Handler ,但每当触发SysTick中断时,执行都会跳转到系统内存中的某个位置 . 根据我的理解,它应该跳转到我声明或未通过的 void SysTick_Handler(void) 中,在startup_stm32中声明的 Default_Handler 中定义了中断向量表 . 我在 SysTick_Handler 中设置了一个断点,但它永远不会到达 . 在下面的代码中,如果我没有按预期包含 SysTick_CTRL_TICKINT_Msk ,它会通过 init_systick() 并保持在无尽的 for 循环中,但是当我确实包含它时,调试器会告诉我它最终会在地址0x1fffda7c附近 .

main.c中:

#include "stm32f0xx.h"

volatile uint32_t ticks = 0;

void SysTick_Handler(void) {
    ticks++;
}

void init_systick(void) {
    SysTick->LOAD = 43999;
    SCB->SHP[1] |= 0x40000000L;
    SysTick->VAL = 0;
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}

int main(void)
{
    init_systick();
    for(;;);
}

我在 .map 文件中验证了链接器正在使用声明的 SysTick_Handler 而不是 Default_Handler .

我还尝试了以下变体来使用标准外设库进行设置,以及其他中断优先级值,结果相同:

#include "stm32f0xx.h"

volatile uint32_t ticks = 0;

void SysTick_Handler(void) {
    ticks++;
}

void init_systick(void) {
    SysTick_Config(44000);
    NVIC_EnableIRQ(SysTick_IRQn);
    NVIC_SetPriority(SysTick_IRQn, 0);
}

int main(void)
{
    init_systick();
    for(;;);
}

这不应该有定时晶体,我还修改了system_stm32f0xx.c中的 void SetSysClock(void) 以使用HSI时钟和PLL,它似乎正常工作:

static void SetSysClock(void)
{
    RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) ;
    FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
    RCC->CR &= ~RCC_CR_PLLON;
    while (RCC->CR & RCC_CR_PLLRDY) ;
    RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_PLLMUL & ~RCC_CFGR_PLLSRC) | RCC_CFGR_PLLMUL11;   // PLL takes 8 MHz HSI / 2 as input
    RCC->CR |= RCC_CR_PLLON;
    while (!(RCC->CR & RCC_CR_PLLRDY)) ;
    RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) ;
}

-- EDIT: More info requested in the comments --

它是M0核心,因此它没有向量表重定位 . 参考手册第2.5节(第44页):

与Cortex®M3和M4不同,M0 CPU不支持向量表重定位 .

地址0x00000000应映射到0x08000000的FLASH存储器,0x1fffd800的系统存储器或0x20000000的SRAM . 地址0x00000000处的存储器与0x1fffd800处的系统存储器匹配,即使SYSCFG_CFGR1 MEM_MODE设置为00,也应将FLASH存储器映射到那里 . 地址0x08000000处的主FLASH存储器包含正确的向量表,但地址0x00000000填充了SysTick向量的地址0x1fffd99d(以及除复位向量之外的所有其他非NULL向量,即0x1fffdc41);调试器在地址0x00000000处显示的向量与观察到的行为一致 . 在执行中断之前,在地址0x08000298(FLASH存储器中已加载正确代码的正确位置)的断点处暂停时收集所有这些信息 .

1 回答

  • -1

    根据datasheet,该区域是系统内存(用于内置引导加载程序) . 你可以尝试两件事:

    • 仔细检查BOOTx引脚,确保MCU加载FLASH而不是系统内存 .

    • 确保已将SCB->VTOR分配给您自己的中断向量表的正确地址 .

相关问题