STM32--STM32F051 IAP的实现

一、IAP原理及过程

《正点原子--STM32F10x串口IAP实验》

《stm32f030 IAP》

《STM32F051 IAP源码分享》

二、遇到的问题

1、中断向量表的充定向问题

(1)与M3核的单片机由区别

      1)、STM32F0系列没有void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)这个函数,所以不能像其他系列的那样设置中断向量表;

      2)、M0核中需要把APP部分中的中断向量表重定向到SRAM中(在M3中一般是重定向在flash中);

STM32--STM32F051 IAP的实现_第1张图片

STM32--STM32F051 IAP的实现_第2张图片

在M3内核中可以通过操作VTOR寄存器来重映射中断向量表
SCB->VTOR = FLASH_BASE | 0x10000;
/* Vector Table Relocation in Internal FLASH. */

在M0内核中需要
memcpy((void*)0x20000000, (void*)IAP_ADDR, 0xB4);
__HAL_SYSCFG_REMAPMEMORY_SRAM();
其中,0x2000 0000是SRAM的起始地址,这个不需要改动。
而之后的两个参数需要根据实际情况作出修改。IAP_ADDR是应用程序的起址地址,从这里开始的VECTOR_SIZE字节,存放是的应用程序的中断向量表。VECTOR_SIZE是指中断向量表的大小,具体多大可以在startup.s文件里计算得到。

      3)、跳转

STM32--STM32F051 IAP的实现_第3张图片

       4)、几种中断向量表重定向的方法

          A: memcpy((void*)0x20000000, (void*)IAP_ADDR, 0xB4);

          B: 

void InterruptRemap(void)
{
	uint8_t   i;
	u32_t  Data;
	u32_t  Address;
	for(i=1;i<48;i++)
	{
		Data =  *(__IO uint32_t *)(0x08003000+i*4);
		Address = 0x20000000 + (i*4);
		*(__IO uint32_t *)Address= (uint32_t )Data;
	}
	
	__HAL_SYSCFG_REMAPMEMORY_SRAM();
}

 三、FLASH和SRAM的配置

   1、BootLoader部分

STM32--STM32F051 IAP的实现_第4张图片

2、app部分

STM32--STM32F051 IAP的实现_第5张图片

ROM的设定值要与程序中分配的空间地址对应,例如程序中的地址分配如下:

/*< Bootloader address base. 12KB>*/
/* bootloader: 12KB 0x08000000--0x08003000  */
#define   	        BOOTLOADER_ADDR_BASE                   0x08000000  


/*< APP address base. 24KB >*/
/* 0x08003000--0x08009000 */
#define 	        APP_START_ADDR       			        0x08003000  

 
/*< Parameter address base. 2KB. >*/
#define   			PARAM_ADDR_BASE               			0x08009000
#define   			UPDATE_FLAG_L8_ADDR                     (PARAM_ADDR_BASE+0)
#define   			UPDATE_FLAG_H8_ADDR                     (PARAM_ADDR_BASE+1)
#define  	 		APP_SIZE_L8_ADDR                        (PARAM_ADDR_BASE+2)
#define   			APP_SIZE_M1_ADDR                        (PARAM_ADDR_BASE+3)
#define   			APP_SIZE_M2_ADDR                        (PARAM_ADDR_BASE+4)
#define   			APP_SIZE_H8_ADDR                        (PARAM_ADDR_BASE+5)
#define   			APP_CRC_L8_ADDR                         (PARAM_ADDR_BASE+6)	
#define   			APP_CRC_H8_ADDR                         (PARAM_ADDR_BASE+7)	



/*< APP TEMP address base. 24KB  >*/
#define 			APP_TEMP_START_ADDR       				0x08009800  


/*< Deserve address base. 2KB  >*/
#define 			DESERVE_ADDR_START       				0x0800F800 

设定APP部分的SRAM,要注意剩余长度的计算,剩余长度=SRAM总长度 - 中断向量表所用长度 - 1:

 

四、待解决的问题

发现flash不能字读取(或是要字节对齐,起始地址要是4的倍数),这个问题还没有找到原因,可能是我字读取函数写的有问题。

    /* Get the new app size. */
	//newAPPSize = hal_flash_read_word(APP_SIZE_L8_ADDR);//直接读取字,不成功
	newAPPSizeL = hal_flash_read_half_word(APP_SIZE_L8_ADDR);
	newAPPSizeH = hal_flash_read_half_word(APP_SIZE_M2_ADDR);
	newAPPSize = (newAPPSizeH<<16) | newAPPSizeL;

    u32_t hal_flash_read_word(u32_t addr)
   {
      return *(__IO u32_t *)addr;
    } 

你可能感兴趣的:(单片机编程,单片机,c语言,stm32,iap)