Stm32 bootloader 与APP 跳转的方式和问题点。

  我们需要实现的任务是不需要去切换BOOT  pin的状态来升级我们的程序。

1.硬件必须从flash 启动。如下图BOOT0必须接低电位。

Stm32 bootloader 与APP 跳转的方式和问题点。_第1张图片

2.  flash 地址分配,根据所用芯片flash 大小,可以从选型手册查看。 例如STM32F103C8为64K

  我们可以根据bootloader和APP大小分配。这里我如下分配

  bootloader   30K    IROM1 如下配置,0x7800,是30K转换成16进制填入。 此flash需要1k的倍数。有的需要2k倍数,看手册。

Stm32 bootloader 与APP 跳转的方式和问题点。_第2张图片

APP  32k   IROM1 如下配置:

Stm32 bootloader 与APP 跳转的方式和问题点。_第3张图片

剩下空闲区,放一些bootflag等一些参数,可以供bootloader和app使用而不会被擦除。

 

3.bootloader 代码部分。

    void (*jump2app)();
void iap_load_app(u32 appxaddr)
{
    if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)    //appxaddr为app烧录地址,这里是0x8007800¨,我们可以通过memory查看内容,第一个地址存0x2开头的栈顶地址。如果烧录,这个地址可以判断通过。
    { 
        jump2app=(void(*)())*(vu32*)(appxaddr+4);        //    appxaddr+4  就是程序复位地址
        MSR_MSP(*(vu32*)appxaddr);                    //初始化APP堆栈指针
        __disable_irq();                      //关闭中断
        jump2app();                                    //跳转
    }
}

 

bootloader 部分加入这部分代码,就可实现跳转。这里我们在flash 中增加bootflag标志位。

if(bootflag)  //如为真,直接跳到app,为假进入bootloader,可升级程序。

{

iap_load_app(userapplication);

}

 

4. app代码部分 

在system_stm32f10x.c

#define VECT_TAB_OFFSET  0x8007800

void SystemInit (void)中最下面增加

    #ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 

以上中断向量表一定要做,不然中断例如串口中断还会跳到bootloader中。如果需要回到bootload,只要在app中bootflag写为假。因为程序,都是从bootloader程序开始运行决定跳转不跳转的。

 

5.调试

可以打开两个工程项目,bootloader和app都可以单独调试,但是调试app时,必须已经烧录了bootloader程序,调试时,直接会跳转到app代码调试,如果没有bootloader,app无法调试。

 

6.串口烧录部分

以上调试完后,bootloader中可接收写flash,这部分需研究flash擦除,读写操作,并将app转成bin如下图设定,既能产生bin,再将bin文件传送给bootloader后,写入要求地址。也可在bin文件中加入参数信息,便于bootloader处理。

Stm32 bootloader 与APP 跳转的方式和问题点。_第4张图片此处注意路径,不对会无法生成。

 

5.问题点   

*下面函数一般都是直接用的,里面做了向量表的定义,划线部分,一定要注释掉,不然前面做的中断向量表的重映射就没用。 一定要注意,容易忽视。  

 void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
  // NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //
  
   /* Configure the NVIC Preemption Priority Bits */  
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
   /* Enable the USART1 Interrupt */
   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;       //???????1??
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       //???????0
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //????
   NVIC_Init(&NVIC_InitStructure);                            //???
}

 

6.结语

  流程走完后,感觉不难,过程中反反复复,后面完善bootloader代码。

 

 

 

你可能感兴趣的:(STM32)