天天看点

YC1147的IAP程序分析1、如何擦写数据2、BLE_APP跳转

文章目录

  • 1、如何擦写数据
  • 2、BLE_APP跳转
    • 2.1首先判断是否把新程序都写进flash,即comm_info_var.ble_updata_success_fg标志为true
    • 2.2切换到新的程序空间,即跳到新的程序地址开始跑咯

程序都是大佬搭的,我也只能分析整个流程,方便日后维护。

comm_info_var.ble_updata_success_fg //蓝牙程序更新成功标志位

1、如何擦写数据

先看下APP_ONE和APP_TWO的起始地址

APP_ONE:0x40000

APP_TWO :0x2000

(0x40000-0x2000)/1024 =248K 。。。。其实都不知道是不是真的这么大!!!

我们的自定义协议规定,app每次发一块数据(512)个字节。so blocknum是块号,每一块是512dates.重写空间是255*512 B的code代码,不够255块就补0xff之类的,然后程序只要判断是否blocknum==255 就comm_info_var.ble_updata_success_fg = true;

App_Updata_BlueProgrammer(blocknum,buf,512);

static void App_Updata_BlueProgrammer(uint16_t blocknum,uint8_t *flash_data, uint16_t flash_len)
{
	static uint32_t flashaddr = 0,flashaddrS = 0x2000;
	
	if(blocknum == 1) // start updata
	{
		if(Read_ProgramStartAddr() == APP_TWO){ //check out addr 0x1000 code
			flashaddrS = 0x2000;
		}else if(Read_ProgramStartAddr() == APP_ONE){ //check out addr 0x40000 code
			flashaddrS = 0x40000;
		}else
		{
			flashaddrS = 0x40000;
		}
	}
	// 写flash 地址
	flashaddr  = (blocknum-1)*flash_len;
	flashaddr += flashaddrS;	
	YC_FlashWrite(flashaddr,flash_len,flash_data);
}
           
uint8_t Read_ProgramStartAddr()
{
	uint8_t startaddr[3]; 
	YC_FlashRead(0,3,startaddr);
	if(startaddr[0] == 0x00 && startaddr[1] == 0x20 && startaddr[2] == 0x03) {
		return APP_ONE;
	}else if(startaddr[0] == 0x04 && startaddr[1] == 0x00 && startaddr[2] == 0x03){
		return APP_TWO;
	}else if(startaddr[0] == 0x00 && startaddr[1] == 0x00 && startaddr[2] == 0x03){
		return APP_THREE;
	}
		return ERR;	
}

           

2、BLE_APP跳转

2.1首先判断是否把新程序都写进flash,即comm_info_var.ble_updata_success_fg标志为true

#define UPDATA_REST_DELAY_EN 0 // 升级程序成功,是否进行延时500ms之后复位

if((comm_info_var.ble_updata_success_fg==true)&&(comm_info_var.resendfg == false))
		{// 升级写数据成功,进行延时500ms 后复位	
			#if UPDATA_REST_DELAY_EN
			if(updata_rest_fg == 0)
			{
				updata_delay_start = systick_get_ms();
				updata_rest_fg     = 0x01;
			}else
			{
				updata_delay_end = systick_get_ms();
				updata_delay_end = (updata_delay_end >= updata_delay_start)?(updata_delay_end-updata_delay_start):(updata_delay_end+((uint32_t)(0xffffffff) - updata_delay_start));
				if(updata_delay_end >= 500)
				{
					comm_info_var.ble_updata_success_fg = false;
					updata_rest_fg = 0;
					Switch_NewProgramAndReset();
				}
			}
			#else
			comm_info_var.ble_updata_success_fg = false;
			Switch_NewProgramAndReset();
			#endif
		}
           

2.2切换到新的程序空间,即跳到新的程序地址开始跑咯

void Switch_NewProgramAndReset()
{
	uint8_t bootaddr[3]; 
	if(Read_ProgramStartAddr()==APP_ONE){
		bootaddr[0] = 0x04;
		bootaddr[1] = 0x00;
		bootaddr[2] = 0x03;
	}else if(Read_ProgramStartAddr()==APP_TWO){
		bootaddr[0] = 0x00;
		bootaddr[1] = 0x20;
		bootaddr[2] = 0x03;
	}else{
		bootaddr[0] = 0x04;
		bootaddr[1] = 0x00;
		bootaddr[2] = 0x03;
	}
	//QSPI_Init();
	//QSPI_SectorEraseFlash(0x00);	
	YC_FlashWrite(0x00,3,bootaddr);//重写bootaddr 地址标志位 
	HW_REG_8BIT(reg_map(CORE_RESET),0x03); //程序复位
}
           

整个工程就不能发出来了~~~哈哈

继续阅读