双Bank OTA升级:N32L40X APP (二)

 接上一篇文章:双Bank OTA升级:N32L40X BootLoader (一):跳转链接

什么是双Bank升级:将Flash划分为以下4个区域。

BootLoader区:程序进行升级的引导程序,根据Upade_Flag来判断程序是跳转Bank1区运行程序或是将Bank2区的程序搬运到Bank1区,然后在运行程序。

Upade_Flag区:判断BootLoader是否能跳转IAP程序的标志位。

Bank1区:用户程序区。

Bank2区:接收升级程序的备份区域,如果接收完成后就进入BootLoader将此区域的程序搬运到Bank1区。

 1.芯片:N32L406CB

2.开发环境:keil5

Flash为128k,64页每页2k。那么我们就将Flash进行从低地址到高地址进行划分,6kBootLoader,2k为判断升级标志位。50k为Bank1空间,50k为Bank2空间.设置BootLoader工程Flash空间为6k。

设置IAP工程起始为0x8002000,Flash空间为50kb,

双Bank OTA升级:N32L40X APP (二)_第1张图片

IAP升级代码如下。

#define FLASH_Updata_Flag_ADDR	(0x08000000 + 3*2048)
#define FLASH_Bank1_ADDR	(0x08000000 + 4*2048)
#define FLASH_Bank2_ADDR	(0x08000000 + 34*2048)
#define FLASH_Page_Num		(30)
#define FLASH_Page_Size		(2048)


int main(void)
{
	SCB->VTOR = FLASH_Bank1_ADDR;
	
	USART1_Configuration();
	USART2_Configuration();
	NVIC_Uart_Configuration();
	
	Sys_GPIO_Init();
	ADC_Initial();
	I2C1_GPIO_Init();
	I2C1_AW9523_Init();
	I2C2_GPIO_Init();
	I2C2_AW9523_Init();
	I2C3_GPIO_Init();
	I2C3_AW9523_Init();
    ALL_LED_High;
	printf("Project Starting\r\n");
    while (1)
    {
		Usart_Get_Data_Handler();
    }
}
void Updata_Handler(uint8_t *data, uint16_t DataLen)
{
	uint16_t i = 0;
	uint32_t Data;
	FLASH_Unlock();
	for(i = 0; i < DataLen; i += 4)
	{
		Data = data[i + 0] << 0;
		Data |= data[i + 1] << 8; 
		Data |= data[i + 2] << 16; 
		Data |= data[i + 3] << 24; 
		if (FLASH_COMPL != FLASH_ProgramWord(FLASH_Bank2_ADDR + UpgradeSoftRecvLen + i , Data))
		{
			while(1)
			{
				printf("Flash ProgramWord Error. Please Deal With This Error Promptly\r\n");
			}
		}
	}
	FLASH_Lock();
	//DBG("Write ADDR = %x, DataLen = %d\r\n", FLASH_WRITE_START_ADDR +(i) + UpgradeSoftRecvLen, DataLen);
}

void DualBankDataSaveFlash(uint16_t DataLen)
{
	Updata_Handler(Upgrade_Data_Buf, DataLen);
	UpgradeSoftRecvLen = UpgradeSoftRecvLen + DataLen;
	DBG("OTA data recv:%d,%d\r\n",UpgradeSoftRecvLen,UpgradeSoftTotalSize);
}

bool BankFlashErase(void)
{
	uint8_t i = 0;
	FLASH_Unlock();
	for(i = 0; i < FLASH_Page_Num; i++)
	{
		if (FLASH_COMPL != FLASH_EraseOnePage(FLASH_Bank2_ADDR + (FLASH_Page_Size * i)))
		{
			while(1)
			{
				printf("Flash EraseOnePage Error. Please Deal With This Error Promptly\r\n");
			}
		}
		//DBG("Erase ADDR = %x\r\n", FLASH_WRITE_START_ADDR + (FLASH_START_2k_ADDR * i));
	}
	FLASH_Lock();
}


void DualBankDataUpgrade(uint32_t DataLen)
{	
	FLASH_Unlock();
	FLASH_EraseOnePage(FLASH_Updata_Flag_ADDR);
	FLASH_ProgramWord(FLASH_Updata_Flag_ADDR, 0x55555555);
	NVIC_SystemReset();
}

你可能感兴趣的:(单片机升级,stm32,嵌入式硬件,单片机)