Embedded STM32F030F4P6仅在从闪存引导时运行中断处理程序。从引导加载程序引导时重置

Embedded STM32F030F4P6仅在从闪存引导时运行中断处理程序。从引导加载程序引导时重置,embedded,stm32,cortex-m,stm32f0,Embedded,Stm32,Cortex M,Stm32f0,该守则— #include<stm32f030x6.h> void _delay_ms(unsigned int del) { //Delay with systick } void sys_init() { //Set Clock to 6 * 8MHz crystal } void TIM14_IRQHandler(void) { //If UEV was generated, toggle PA4 (Connected to LED) if(TIM14-&

该守则—

#include<stm32f030x6.h>

void _delay_ms(unsigned int del) {
  //Delay with systick
}

void sys_init() {
  //Set Clock to 6 * 8MHz crystal
}

void TIM14_IRQHandler(void) {
  //If UEV was generated, toggle PA4 (Connected to LED)
  if(TIM14->SR & TIM_SR_UIF) {
    GPIOA->BSRR = (GPIOA->ODR & GPIO_ODR_4)?(GPIO_BSRR_BR_4):(GPIO_BSRR_BS_4);
    TIM14->SR &= ~TIM_SR_UIF;
  }
}


int main(void) {
  sys_init();
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM14EN;

  GPIOA->MODER = 0b1 << GPIO_MODER_MODER4_Pos;
  //GPIOA->AFR[0] = 4 << GPIO_AFRL_AFRL4_Pos;

  //Init timer
  TIM14->ARR = 731;
  TIM14->PSC = 0xffff;
  TIM14->DIER |= TIM_DIER_UIE;
  TIM14->CR1 |= TIM_CR1_CEN;

  NVIC_EnableIRQ(TIM14_IRQn);
  NVIC_SetPriority(TIM14_IRQn, 0);

  while(1);
}
#包括
无效延迟毫秒(无符号整数del){
//systick延迟
}
void sys_init(){
//将时钟设置为6*8MHz晶体
}
无效TIM14_IRQHandler(无效){
//如果生成UEV,切换PA4(连接至LED)
如果(TIM14->SR&TIM\U SR\U UIF){
GPIOA->BSRR=(GPIOA->ODR&GPIO\U ODR\U 4)?(GPIO\U BSRR\U BR\U 4):(GPIO\U BSRR\U BS\U 4);
TIM14->SR&=~TIM_SR_UIF;
}
}
内部主(空){
sys_init();
RCC->AHBENR |=RCC_AHBENR|u GPIOAEN;
RCC->APB1ENR |=RCC_APB1ENR_TIM14EN;
GPIOA->MODER=0b1 AFR[0]=4 ARR=731;
TIM14->PSC=0xffff;
TIM14->DIER |=TIM | u DIER |;
TIM14->CR1 |=TIM_CR1_CEN;
NVIC_EnableIRQ(TIM14_IRQn);
NVIC_设置优先级(TIM14_IRQn,0);
而(1),;
}
正如问题中提到的,当我直接从闪存中引导它(BOOT0连接到GND)时,这段代码工作得很好,但当使用引导加载程序时,它不工作。一旦中断被触发,芯片就会复位并再次回到引导加载程序。我如何解决这个问题?

我应该提到的是,我使用的是定制的和经过大量修改的。

您遇到了该微控制器中使用的Cortex-M0内核的限制

Cortex-M0只能使用在地址0x0处映射的中断向量表。当微控制器配置为引导到引导加载程序时,系统内存映射到地址0,因此引导加载程序的向量表用于所有中断。因此,您无法在通过引导加载程序启动的应用程序中安全地使用中断

在Cortex-M0+和更高的部分上,您可以设置
SCB->VTOR
以使用内存中其他位置的向量表。但是,该寄存器不存在于Cortex-M0部件上,如STM32F0,因此这不是您的选项


考虑使用SWD程序员,比如ST Link,来编程微控制器,而不是引导加载程序。这也将允许您调试应用程序。

根据Dashwufs的评论,由于您到boot.s和linker.script的链接可以工作,我假设,您的向量表仍然是引导加载程序中的向量表,并且您的应用程序中断只是跳到那里。如果引导加载程序在该向量表中没有映射ISR,那么它可能只是发出一个重置(由于非法地址/指令而导致的陷阱/异常)。您可以使用通用向量表间接跳转到RAM提供的向量表,该向量表由您的应用程序在启动代码中覆盖。

谢谢您的回答。我知道您不能偏移向量表,但不知道您不能执行中断,因为您可以在引导加载程序模式下运行重置处理程序(使用stm32flash-g0),我没有专门研究过,但我怀疑这实际上不是作为中断发生的。STM32引导加载程序协议没有“重置为闪存”命令。它确实有一个“跳转到地址”命令,但地址是随命令提供的
stm32flash
可能正在从二进制文件中读取重置向量。虽然向量表必须从地址0开始,但MCU可以将内部RAM映射到那里,因此应用程序可以将向量表复制到RAM的开头,并更改
SYSCFG
中的映射,使MCU使用新的向量表。