华大M0中断向量重映射

参考链接:
https://blog.csdn.net/pilihuo182175954/article/details/124856479
https://blog.csdn.net/qq_58099085/article/details/131813593
https://bbs.21ic.com/icview-3214976-1-1.html
https://blog.csdn.net/weixin_38848977/article/details/72523561
https://shatang.github.io/2020/08/12/M0%E7%9A%84%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8%E9%87%8D%E6%98%A0%E5%B0%84/

方法一,华大M0内核的CPU内核为M0+,支持中断向量偏移寄存器。根据华大官方IAP例程,修改SCB->VTOR寄存器即可

方法二、直接在Boot程序的中断向量函数跳转到APP的中断函数。参考链接1、2

方法三、参考STM32F0把中断向量表映射到内存上华大MCU不支持此方法

下面具体说一下方法二的实现:
实现原理,在boot和app程序同时定义一个变量irq_jump_flag在内存0x2000000位置


#define FLAG_JUMP_BOOTLOADER                    0x5A5A5A5A
#define FLAG_JUMP_APP                           0xA0A0A0A0
//static uint32_t irq_jump_flag  __attribute__ ((at(0x20000000)));//AC5编译
__IO uint32_t irq_jump_flag __attribute__((section(".ARM.__at_0x20000000")));//AC6编译

在Boot程序里面此变量赋值为FLAG_JUMP_BOOTLOADER,在APP程序此变量赋值为FLAG_JUMP_APP。

boot里面的所有中断函数,对变量irq_jump_flag进行判断,根据irq_jump_flag内容选择执行Boot的中断函数,还是跳转到app的中断函数

代码片段
startup_hc32.s文件中


__Vectors       DCD     __initial_sp              ; Top of Stack
DCD     Reset_Handler             ; Reset
DCD     NMI_Handler               ; NMI
DCD     HardFault_Handler         ; Hard Fault
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     SVC_Handler               ; SVCall
DCD     0                         ; Reserved
DCD     0                         ; Reserved
DCD     PendSV_Handler            ; PendSV
DCD     SysTick_Handler           ; SysTick

DCD IRQ000_Handler ;
DCD IRQ001_Handler ;
DCD IRQ002_Handler ;
DCD IRQ003_Handler ;
DCD IRQ004_Handler ;
DCD IRQ005_Handler ;
DCD IRQ006_Handler ;
DCD IRQ007_Handler ;
DCD IRQ008_Handler ;
DCD IRQ009_Handler ;
DCD IRQ010_Handler ;
DCD IRQ011_Handler ;
DCD IRQ012_Handler ;
DCD IRQ013_Handler ;
DCD IRQ014_Handler ;
DCD IRQ015_Handler ;
DCD IRQ016_Handler ;
DCD IRQ017_Handler ;
DCD IRQ018_Handler ;
DCD IRQ019_Handler ;
DCD IRQ020_Handler ;
DCD IRQ021_Handler ;
DCD IRQ022_Handler ;
DCD IRQ023_Handler ;
DCD IRQ024_Handler ;
DCD IRQ025_Handler ;
DCD IRQ026_Handler ;
DCD IRQ027_Handler ;
DCD IRQ028_Handler ;
DCD IRQ029_Handler ;
DCD IRQ030_Handler ;
DCD IRQ031_Handler ;

Boot程序的main.c文件中


/* Flash相关宏定义 */
#define FLASH_SECTOR_SIZE           0x200ul                           //一个sector的尺寸
#define FLASH_BASE                  ((uint32_t)0x00000000)            //flash基地址
#define FLASH_SIZE                  (128u * FLASH_SECTOR_SIZE)        //flash尺寸
/* BootLoader flash相关宏定义 */
#define BOOT_SIZE                   (8*FLASH_SECTOR_SIZE)             //BootLoader flash尺寸
#define BOOT_PARA_ADDRESS           (FLASH_BASE + BOOT_SIZE - 0x100u) //BootLoader para存储地址
/* APP flash相关宏定义 */
#define APP_FLAG                    ((uint32_t)0x67890123)            //从BootLoader para区读到此值,表示APP需要更新
#define APP_ADDRESS                 (FLASH_BASE + BOOT_SIZE)          //APP程序存储基地址

#define FLAG_JUMP_BOOTLOADER                    0x5A5A5A5A
#define FLAG_JUMP_APP                           0xA0A0A0A0
//static uint32_t irq_jump_flag  __attribute__ ((at(0x20000000)));//AC5编译
__IO uint32_t irq_jump_flag __attribute__((section(".ARM.__at_0x20000000")));//AC6编译



__WEAK void __SVC_Handler(void);
__WEAK void __PendSV_Handler(void);
__WEAK void __SysTick_Handler(void);

__WEAK void PORTA_IRQHandler(void);
__WEAK void PORTB_IRQHandler(void);
__WEAK void PORTC_IRQHandler(void);
__WEAK void PORTD_IRQHandler(void);
__WEAK void DMAC_IRQHandler(void);
__WEAK void TIM3_IRQHandler(void);
__WEAK void UART0_IRQHandler(void);
__WEAK void UART1_IRQHandler(void);
__WEAK void LPUART0_IRQHandler(void);
__WEAK void LPUART1_IRQHandler(void);
__WEAK void SPI0_IRQHandler(void);
__WEAK void SPI1_IRQHandler(void);
__WEAK void I2C0_IRQHandler(void);
__WEAK void I2C1_IRQHandler(void);
__WEAK void TIM0_IRQHandler(void);
__WEAK void TIM1_IRQHandler(void);
__WEAK void TIM2_IRQHandler(void);
__WEAK void LPTIM_IRQHandler(void);
__WEAK void TIM4_IRQHandler(void);
__WEAK void TIM5_IRQHandler(void);
__WEAK void TIM6_IRQHandler(void);
__WEAK void PCA_IRQHandler(void);
__WEAK void WDT_IRQHandler(void);
__WEAK void RTC_IRQHandler(void);
__WEAK void ADC_IRQHandler(void);
__WEAK void PCNT_IRQHandler(void);
__WEAK void VC0_IRQHandler(void);
__WEAK void VC1_IRQHandler(void);
__WEAK void LVD_IRQHandler(void);
__WEAK void LCD_IRQHandler(void);
__WEAK void FLASH_RAM_IRQHandler(void);
__WEAK void CLK_TRIM_IRQHandler(void);


typedef uint32_t( *pImageTaskFn)( void );

static uint32_t JumpNext(void)
{
	return APP_ADDRESS;
}

static void GotoVector(uint32_t IRQn)
{
	((pImageTaskFn *)JumpNext())[IRQn + 16]();
}

void SVC_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        __SVC_Handler();
    }
    else
    {
        GotoVector(SVC_IRQn);
    }
}
    
void PendSV_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        __PendSV_Handler();
    }
    else
    {
        GotoVector(PendSV_IRQn);
    }
}
    
void SysTick_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        __SysTick_Handler();
    }
    else
    {
        GotoVector(SysTick_IRQn);
    }
}
    
void IRQ000_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PORTA_IRQHandler();
    }
    else
    {
        GotoVector(PORTA_IRQn);
    }
}
   
void IRQ001_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PORTB_IRQHandler();
    }
    else
    {
        GotoVector(PORTB_IRQn);
    }
}
    
void IRQ002_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PORTC_IRQHandler();
    }
    else
    {
        GotoVector(PORTC_IRQn);
    }
}
    
void IRQ003_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PORTD_IRQHandler();
    }
    else
    {
        GotoVector(PORTD_IRQn);
    }
}
    
void IRQ004_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        DMAC_IRQHandler();
    }
    else
    {
        GotoVector(DMAC_IRQn);
    }
}
     
void IRQ005_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM3_IRQHandler();
    }
    else
    {
        GotoVector(TIM3_IRQn);
    }
}
     
void IRQ006_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        UART0_IRQHandler();
    }
    else
    {
        GotoVector(UART0_IRQn);
    }
}
    
void IRQ007_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        UART1_IRQHandler();
    }
    else
    {
        GotoVector(UART1_IRQn);
    }
}
    
void IRQ008_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        LPUART0_IRQHandler();
    }
    else
    {
        GotoVector(LPUART0_IRQn);
    }
}
  
void IRQ009_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        LPUART1_IRQHandler();
    }
    else
    {
        GotoVector(LPUART1_IRQn);
    }
}
  
void IRQ010_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        SPI0_IRQHandler();
    }
    else
    {
        GotoVector(SPI0_IRQn);
    }
}
     
void IRQ011_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        SPI1_IRQHandler();
    }
    else
    {
        GotoVector(SPI1_IRQn);
    }
}
     
void IRQ012_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        I2C0_IRQHandler();
    }
    else
    {
        GotoVector(I2C0_IRQn);
    }
}
     
void IRQ013_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        I2C1_IRQHandler();
    }
    else
    {
        GotoVector(I2C1_IRQn);
    }
}
     
void IRQ014_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM0_IRQHandler();
    }
    else
    {
        GotoVector(TIM0_IRQn);
    }
}
     
void IRQ015_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM1_IRQHandler();
    }
    else
    {
        GotoVector(TIM1_IRQn);
    }
}
     
void IRQ016_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM2_IRQHandler();
    }
    else
    {
        GotoVector(TIM2_IRQn);
    }
}
     
void IRQ017_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        LPTIM_IRQHandler();
    }
    else
    {
        GotoVector(LPTIM_IRQn);
    }
}
    
void IRQ018_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM4_IRQHandler();
    }
    else
    {
        GotoVector(ADTIM4_IRQn);
    }
}
     
void IRQ019_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM5_IRQHandler();
    }
    else
    {
        GotoVector(ADTIM5_IRQn);
    }
}
     
void IRQ020_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        TIM6_IRQHandler();
    }
    else
    {
        GotoVector(ADTIM6_IRQn);
    }
}
     
void IRQ021_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PCA_IRQHandler();
    }
    else
    {
        GotoVector(PCA_IRQn);
    }
}
      
void IRQ022_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        WDT_IRQHandler();
    }
    else
    {
        GotoVector(WDT_IRQn);
    }
}
      
void IRQ023_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        RTC_IRQHandler();
    }
    else
    {
        GotoVector(RTC_IRQn);
    }
}
      
void IRQ024_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        ADC_IRQHandler();
    }
    else
    {
        GotoVector(ADC_IRQn);
    }
}
      
void IRQ025_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        PCNT_IRQHandler();
    }
    else
    {
        GotoVector(PCNT_IRQn);
    }
}
     
void IRQ026_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        VC0_IRQHandler();
    }
    else
    {
        GotoVector(VC0_IRQn);
    }
}
      
void IRQ027_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        VC1_IRQHandler();
    }
    else
    {
        GotoVector(VC1_IRQn);
    }
}
      
void IRQ028_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        LVD_IRQHandler();
    }
    else
    {
        GotoVector(LVD_IRQn);
    }
}
      
void IRQ029_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        LCD_IRQHandler();
    }
    else
    {
        GotoVector(LCD_IRQn);
    }
}
      
void IRQ030_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        FLASH_RAM_IRQHandler();
    }
    else
    {
        GotoVector(FLASH_RAM_IRQn);
    }
}

void IRQ031_Handler(void)
{
    if(FLAG_JUMP_BOOTLOADER==irq_jump_flag)
    {
        CLK_TRIM_IRQHandler();
    }
    else
    {
        GotoVector(CLKTRIM_IRQn);
    }
} 

/**
 *******************************************************************************
 ** \brief  IAP 主函数
 **
 ** \param  None
 **
 ** \retval int32_t Return value, if needed
 **
 ******************************************************************************/
int32_t main(void)
{
    irq_jump_flag=FLAG_JUMP_BOOTLOADER;
    
    IAP_UpdateCheck();
    IAP_Init();
    IAP_Main();
}

Boot程序Keil设置:

app程序的main.c文件


#define FLAG_JUMP_BOOTLOADER                    0x5A5A5A5A
#define FLAG_JUMP_APP                           0xA0A0A0A0
//static uint32_t irq_jump_flag  __attribute__ ((at(0x20000000)));//AC5编译
__IO uint32_t irq_jump_flag __attribute__((section(".ARM.__at_0x20000000")));//AC6编译

int32_t main(void)
{      
    irq_jump_flag=FLAG_JUMP_APP;

    //时钟配置
    App_ClkCfg();
    
    //串口引脚配置
    App_PortInit();
    
    //串口配置
    App_UartCfg();
    
    //flash擦写初始化
    Flash_Init(6, TRUE);
        
    while(1)
    {        
        ///< LED点亮
        Gpio_SetIO(STK_LED_PORT, STK_LED_PIN);
        delay1ms(1000);

        ///< LED关闭
        Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN);
        delay1ms(1000);
    }
}

app程序Keil设置

发表评论

邮箱地址不会被公开。 必填项已用*标注