STM32F030F4P6仅在从Flash引导时运行中断处理程序。从引导程序引导时重置

时间:2019-02-25 01:41:00

标签: embedded stm32 electronics 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->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);
}

正如问题中提到的那样,当我直接从闪存(将BOOT0连接到GND)上直接引导它时,此代码可以正常工作,但在使用引导加载程序时,此代码不起作用。一旦产生中断,芯片就会复位并再次回到引导加载程序中。我该如何解决?
我应该提到我使用了自定义linker script和经过大量修改的boot.s

2 个答案:

答案 0 :(得分:1)

根据黄昏的注释,由于您指向boot.s和linker.script的链接可以正常工作,我认为您的向量表仍然是引导程序中的那个,而您的应用程序中断仅跳到那里。如果您的引导加载程序在该向量表上没有映射任何ISR,则它可能随后发出一个复位(由于非法的地址/指令而导致的陷阱/异常)。您也许可以使用通用向量表来间接跳转到RAM提供的向量表,并由应用程序在启动代码中覆盖。

答案 1 :(得分:0)

您已经遇到了此微控制器中使用的Cortex-M0内核的局限性。

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

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

请考虑使用SWD编程器(例如ST-Link)来对微控制器进行编程,而不是对引导加载器进行编程。这也将允许您调试应用程序。