GD32IAP升级(BootLoader)

这里写自定义目录标题

  • GD32IAP升级---BootLoader
    • IAP升级
    • 重点部分
      • 1.中断向量设置
      • 2.程序起始地址设置说明
    • 升级出现的问题
      • 判断程序地址出错
      • 写入Flash之后,跳转失败
    • 写在最后

GD32IAP升级—BootLoader

本文记录并说明GD32使用IAP升级过程中,必要的操作和关键步骤。

IAP升级

IAP升级原理很简单,简要介绍如下:
先下载BootLoader程序,如果有需要对程序进行升级时,BootLoader通过串口或者其他接口接收升级程序,接收之后把接收到的文件放到指定位置,然后设置中断向量,最后跳转过去即可;

重点部分

1.中断向量设置

代码如下

// 设置偏移量
nvic_vector_table_set(FLASH_BASE,0x4000);//设置偏移量

2.程序起始地址设置说明

BootLoader中不需要设置程序其实地址,可以设置长度;
APP程序中需要设置程序起始地址:设置如下

GD32IAP升级(BootLoader)_第1张图片

升级出现的问题

判断程序地址出错

在代码中判断出错

f(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
{  
           iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
}

原因分析:
1、可能是接收数据出错
2、可能是写数据出错
3、见下面分析

写入Flash之后,跳转失败

调用GD32的提供的fmc.c文件时在写数据到flash中时,fmc_write_32bit_data函数擦除数据的时候是一次性擦除需要用到的所有块,而第二次写入数据的时候会造成把刚刚写进去的数据又进行擦除,所以会导致,上面提到的判断程序地址出错

void fmc_write_32bit_data(uint32_t address, uint16_t length, int32_t* data_32)
{
    uint16_t StartSector, EndSector,i;
    /* unlock the flash program erase controller */
    fmc_unlock();
    /* clear pending flags */
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
	

	/* get the number of the start and end sectors */
	StartSector = fmc_sector_get(address);
	EndSector = fmc_sector_get(address + 4*length);
	/* each time the sector number increased by 8, refer to the sector definition */
	for(i = StartSector; i <= EndSector; i += 8){
			if(FMC_READY != fmc_sector_erase(i)){
					while(1);
			}
	}

    /* write data_32 to the corresponding address */
    for(i=0; i<length; i++){
        if(FMC_READY == fmc_word_program(address, data_32[i])){
            address = address + 4;
        }else{ 
            while(1);
        }
    }
    /* lock the flash program erase controller */
    fmc_lock();
}

修改方法:

void fmc_write_32bit_data(uint32_t address, uint16_t length, int32_t* data_32)
{
    uint16_t StartSector, EndSector,i;
    /* unlock the flash program erase controller */
    fmc_unlock();
    /* clear pending flags */
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
	
		if(frist_flag == 0){
			frist_flag = 1;
			/* get the number of the start and end sectors */
			StartSector = fmc_sector_get(address);
			EndSector = fmc_sector_get(address + 4*length);
			/* each time the sector number increased by 8, refer to the sector definition */
			for(i = StartSector; i <= EndSector; i += 8){
					if(FMC_READY != fmc_sector_erase(i)){
							while(1);
					}
			}
		}
    /* write data_32 to the corresponding address */
    for(i=0; i<length; i++){
        if(FMC_READY == fmc_word_program(address, data_32[i])){
            address = address + 4;
        }else{ 
            while(1);
        }
    }
    /* lock the flash program erase controller */
    fmc_lock();
}

添加一个标志位,只需擦除一次即可,一次性擦除后面所有的块;或者每次擦除需要用到的块,但是要对地址进行计算和拼接;

GD32擦除是根据SECTOR擦除,地址分配如下

/* base address of the FMC sectors */
#define ADDR_FMC_SECTOR_0     ((uint32_t)0x08000000) /*!< base address of sector 0, 16 kbytes */
#define ADDR_FMC_SECTOR_1     ((uint32_t)0x08004000) /*!< base address of sector 1, 16 kbytes */
#define ADDR_FMC_SECTOR_2     ((uint32_t)0x08008000) /*!< base address of sector 2, 16 kbytes */
#define ADDR_FMC_SECTOR_3     ((uint32_t)0x0800C000) /*!< base address of sector 3, 16 kbytes */
#define ADDR_FMC_SECTOR_4     ((uint32_t)0x08010000) /*!< base address of sector 4, 64 kbytes */
#define ADDR_FMC_SECTOR_5     ((uint32_t)0x08020000) /*!< base address of sector 5, 64 kbytes */
#define ADDR_FMC_SECTOR_6     ((uint32_t)0x08040000) /*!< base address of sector 6, 64 kbytes */
#define ADDR_FMC_SECTOR_7     ((uint32_t)0x08060000) /*!< base address of sector 7, 64 kbytes */
#define ADDR_FMC_SECTOR_8     ((uint32_t)0x08080000) /*!< base address of sector 8, 64 kbytes */
#define ADDR_FMC_SECTOR_9     ((uint32_t)0x080A0000) /*!< base address of sector 9, 64 kbytes */
#define ADDR_FMC_SECTOR_10    ((uint32_t)0x080C0000) /*!< base address of sector 10, 64 kbytes */
#define ADDR_FMC_SECTOR_11    ((uint32_t)0x080E0000) /*!< base address of sector 11, 64 kbytes */

写在最后

IAP升级和STM32一样,需要注意的是flash写的操作,Demo中的flash写,是只对块进行擦除,没有对原有的数据进行保护;
PS:当然,可能和我使用的版本不一样。

你可能感兴趣的:(GD32)