Эх сурвалжийг харах

add:远程升级CORE,由于升级空间比较大,需要放置在外部spiflash中

alienwalker 3 жил өмнө
parent
commit
09e183e02a

+ 78 - 1
application/src/luat_mcu_air105.c

@@ -21,7 +21,7 @@
 
 #include "luat_base.h"
 #include "luat_mcu.h"
-
+#include "luat_spi.h"
 #include "app_interface.h"
 
 #include "FreeRTOS.h"
@@ -83,3 +83,80 @@ void luat_mcu_set_clk_source(uint8_t source_main, uint8_t source_32k, uint32_t d
 		break;
 	}
 }
+
+int luat_mcu_fota_init(uint32_t start_address, uint32_t len, luat_spi_device_t* spi_device, const char *path, uint32_t pathlen)
+{
+	PV_Union uPV;
+	CoreUpgrade_HeadStruct *Head = luat_heap_malloc(sizeof(CoreUpgrade_HeadStruct));
+	memset(Head, 0, sizeof(CoreUpgrade_HeadStruct));
+	Head->MaigcNum = __APP_START_MAGIC__;
+	uPV.u8[0] = CORE_OTA_MODE_FULL;
+	Head->DataStartAddress = start_address;
+	if (path && pathlen)
+	{
+		uPV.u8[1] = CORE_OTA_IN_FILE;
+		memcpy(Head->FilePath, path, pathlen);
+	}
+	else
+	{
+		if (start_address > __FLASH_BASE_ADDR__)
+		{
+			uPV.u8[1] = CORE_OTA_IN_FLASH;
+		}
+		else
+		{
+			uPV.u8[1] = CORE_OTA_OUT_SPI_FLASH;
+			uPV.u8[2] = luat_spi_get_hw_bus(spi_device->bus_id);
+			Head->Param1 = uPV.u32;
+
+			switch(luat_spi_get_hw_bus(spi_device->bus_id))
+			{
+			case HSPI_ID0:
+				uPV.u8[0] = GPIOC_13;
+				uPV.u8[1] = GPIOC_12;
+				uPV.u8[2] = GPIOC_15;
+				break;
+			case SPI_ID0:
+				uPV.u8[0] = GPIOB_14;
+				uPV.u8[1] = GPIOB_15;
+				uPV.u8[2] = GPIOB_12;
+				break;
+			case SPI_ID1:
+				uPV.u8[0] = GPIOA_08;
+				uPV.u8[1] = GPIOA_09;
+				uPV.u8[2] = GPIOA_06;
+				break;
+			case SPI_ID2:
+				uPV.u8[0] = GPIOB_04;
+				uPV.u8[1] = GPIOB_05;
+				uPV.u8[2] = GPIOB_02;
+				break;
+
+			}
+			uPV.u8[3] = spi_device->spi_config.cs;
+			Head->Param2 = uPV.u32;
+		}
+	}
+	return Core_OTAInit(Head, len);
+}
+
+int luat_mcu_fota_write(uint8_t *data, uint32_t len)
+{
+	return Core_OTAWrite(data, len);
+}
+
+int luat_mcu_fota_done(void)
+{
+	return Core_OTACheckDone();
+}
+
+int luat_mcu_fota_end(uint8_t is_ok)
+{
+	Core_OTAEnd(is_ok);
+	return 0;
+}
+
+uint8_t luat_mcu_fota_wait_ready(void)
+{
+	return Core_OTACheckReadyStart();
+}

+ 5 - 0
application/src/luat_spi_air105.c

@@ -257,6 +257,11 @@ int luat_lcd_draw_no_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint
 	}
 }
 
+int luat_spi_get_hw_bus(int spi_id)
+{
+	return luat_spi[spi_id].id;
+}
+
 void luat_lcd_draw_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, luat_color_t* color, uint8_t last_flush)
 {
 	LCD_DrawStruct draw;

+ 0 - 1
application/src/luat_uart_air105.c

@@ -102,7 +102,6 @@ static int32_t luat_uart_cb(void *pData, void *pParam){
         	}
             break;
         case UART_CB_RX_BUFFER_FULL:
-            break;
         case UART_CB_RX_TIMEOUT:
             if (serials[uartid].rx_mark) return 0;
             serials[uartid].rx_mark = 1;

+ 27 - 21
bsp/air105/hal/core_uart.c

@@ -27,7 +27,7 @@
 //static Buffer_Struct prvUartTxBuffer[UART_MAX];
 #define RX_BUF_LOW	(1024)
 #define RX_BUF_INIT	(2048)
-#define RX_BUF_HIGH	(4096)
+#define RX_BUF_HIGH	(8192)
 #define RX_BUF_BAND (3)
 #define TX_BUF_INIT	(2048)
 //#define __RX_USE_DMA__
@@ -55,6 +55,7 @@ typedef struct
 	uint8_t RxCacheMode;
 	uint8_t DMATxStream;
 	uint8_t DMARxStream;
+//	uint8_t IsHighSpeed;
 }Uart_ResourceStruct;
 
 static Uart_ResourceStruct prvUart[UART_MAX] = {
@@ -258,8 +259,15 @@ void Uart_BaseInit(uint8_t UartID, uint32_t BaudRate, uint8_t IsRxCacheEnable, u
 #ifdef __BUILD_OS__
     if (IsRxCacheEnable)
     {
-    	OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_INIT);
-    	OS_ReInitBuffer(&prvUart[UartID].TxCacheBuf, TX_BUF_INIT);
+    	if (BaudRate >= 1000000)
+    	{
+    		OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_HIGH);
+    	}
+    	else
+    	{
+    		OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_INIT);
+    	}
+
 #ifdef __RX_USE_DMA__
     	for(i = 0; i < RX_BUF_BAND; i++)
     	{
@@ -496,6 +504,20 @@ static uint32_t prvUart_FifoRead(uint8_t UartID, uint8_t *Data, uint8_t Len)
 
 }
 
+static void Uart_CacheRead(uint8_t UartID, uint8_t Len)
+{
+	uint8_t Flag = 0;
+	if ((prvUart[UartID].RxBuf.Pos + 32) > prvUart[UartID].RxBuf.MaxLen)
+	{
+		prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], Len);
+		OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
+	}
+	else
+	{
+		prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], Len);
+	}
+}
+
 uint32_t Uart_FifoRead(uint8_t UartID, uint8_t *Data)
 {
 	uint32_t i = 0;
@@ -628,15 +650,7 @@ static void prvUart_IrqHandle(int32_t IrqLine, void *pData)
 #ifdef __BUILD_OS__
 			if (prvUart[UartID].RxCacheMode)
 			{
-				if ((prvUart[UartID].RxBuf.Pos + 32) < prvUart[UartID].RxBuf.MaxLen)
-				{
-					prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 7);
-				}
-				else
-				{
-					OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
-					prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 7);
-				}
+				Uart_CacheRead(UartID, 8);
 				break;
 			}
 #endif
@@ -689,15 +703,7 @@ static void prvUart_IrqHandle(int32_t IrqLine, void *pData)
 #else
 		if (prvUart[UartID].RxCacheMode)
 		{
-			if ((prvUart[UartID].RxBuf.Pos + 32) < prvUart[UartID].RxBuf.MaxLen)
-			{
-				prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 32);
-			}
-			else
-			{
-				OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
-				prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 32);
-			}
+			Uart_CacheRead(UartID, 33);
 		}
 #endif
 #endif

+ 2 - 0
bsp/air105/include/global_config.h

@@ -44,4 +44,6 @@
 #else
 #define __FUNC_IN_RAM__	__attribute__((section (".RamFunc")))
 #endif
+#define __BL_VERSION__	(1)
+#define __CORE_VERSION__	(8)
 #endif

+ 2 - 2
bsp/air105/platform/app_main.c

@@ -38,8 +38,8 @@ const uint32_t __attribute__((section (".app_info")))
 {
 	__APP_START_MAGIC__,
 	&__isr_start_address,
-	0,//此处后期放入luatos固件版本
-	0,
+	__BL_VERSION__,
+	__CORE_VERSION__,
 	SCRIPT_LUADB_START_ADDR,
 	SCRIPT_LUADB_START_ADDR + __SCRIPT_FLASH_BLOCK_NUM__ * __FLASH_BLOCK_SIZE__,
 	0,

+ 85 - 79
bsp/air105/platform/bl_main.c

@@ -49,10 +49,10 @@ typedef struct
 	uint32_t NextLzmaDataLen;
 	uint8_t NextLzmaHeader[LZMA_PROPS_SIZE + 8];
 	uint32_t NextLzmaHeaderSize;
-	uint32_t CurSPIFlashStart;
-	uint32_t NextSPIFlashStart;
-	uint8_t *CurSPIFlashData;
-	uint8_t *NextSPIFlashData;
+//	uint32_t CurSPIFlashStart;
+//	uint32_t NextSPIFlashStart;
+//	uint8_t *CurSPIFlashData;
+//	uint8_t *NextSPIFlashData;
 	uint8_t State;
 	uint8_t ForceOut;
 	uint8_t SPIFlashReadDone;
@@ -116,11 +116,6 @@ static void BL_OTAErase(uint32_t Address, uint32_t Len)
 	Flash_Erase(Address, Len);
 }
 
-static void BL_OTAWrite(uint32_t Address, uint8_t *Data, uint32_t Len)
-{
-	Flash_Program(Address, Data, Len);
-}
-
 void FileSystem_Init(void)
 {
 
@@ -229,6 +224,7 @@ void Local_Upgrade(void)
 			}
 			break;
 		case FW_UPGRADE_STATE_START:
+			BL_OTAErase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
 			AllToTick = GetSysTick() + FW_UPGRADE_ALL_TIME * CORE_TICK_1MS;
 			prvBL.State = FW_UPGRADE_STATE_RUN;
 			uint8_t *CurLzmaData = NULL;
@@ -349,42 +345,15 @@ static int32_t BL_OTAReadDataInSpiFlash(void *pData, void *pParam)
 {
 	uint32_t StartAddress = (uint32_t)pData;
 	Buffer_Struct *pBuffer = (Buffer_Struct *)pParam;
-//	DBG_INFO("%x,%x,%x,%x,%x", StartAddress, prvBL.CurSPIFlashStart, prvBL.NextSPIFlashStart, prvBL.CurSPIFlashData, prvBL.NextSPIFlashData);
-	if (prvBL.CurSPIFlashData)
+	while(!SPIFlash_WaitOpDone(&prvSPIFlash))
 	{
-		if (StartAddress >= prvBL.NextSPIFlashStart)
-		{
-			if (!prvBL.SPIFlashReadDone)
-			{
-				while(!SPIFlash_WaitOpDone(&prvSPIFlash))
-				{
-					;
-				}
-				prvBL.SPIFlashReadDone = 1;
-			}
-			free(prvBL.CurSPIFlashData);
-			prvBL.CurSPIFlashStart = prvBL.NextSPIFlashStart;
-			prvBL.CurSPIFlashData = prvBL.NextSPIFlashData;
-			prvBL.NextSPIFlashData = malloc(FW_OTA_FLASH_BUF_LEN);
-			prvBL.NextSPIFlashStart += FW_OTA_FLASH_BUF_LEN;
-			SPIFlash_Read(&prvSPIFlash, prvBL.NextSPIFlashStart, prvBL.NextSPIFlashData, FW_OTA_FLASH_BUF_LEN, 1);
-			prvBL.SPIFlashReadDone = 0;
-		}
-
+		;
 	}
-	else
+	SPIFlash_Read(&prvSPIFlash, StartAddress, pBuffer->Data, pBuffer->Pos, 1);
+	while(!SPIFlash_WaitOpDone(&prvSPIFlash))
 	{
-		prvBL.CurSPIFlashData = malloc(FW_OTA_FLASH_BUF_LEN);
-		prvBL.NextSPIFlashData = malloc(FW_OTA_FLASH_BUF_LEN);
-		SPIFlash_Read(&prvSPIFlash, prvBL.CurSPIFlashStart, prvBL.CurSPIFlashData, FW_OTA_FLASH_BUF_LEN, 1);
-		while(!SPIFlash_WaitOpDone(&prvSPIFlash))
-		{
-			;
-		}
-		SPIFlash_Read(&prvSPIFlash, prvBL.NextSPIFlashStart, prvBL.NextSPIFlashData, FW_OTA_FLASH_BUF_LEN, 1);
-		prvBL.SPIFlashReadDone = 0;
+		;
 	}
-	memcpy(pBuffer->Data, prvBL.CurSPIFlashData, pBuffer->Pos);
 	return 0;
 }
 
@@ -451,16 +420,21 @@ static void BL_SpiInit(uint8_t SpiID, uint8_t *Pin)
 
 void Remote_Upgrade(void)
 {
-
+	CoreUpgrade_SectorStruct Sector;
 	CoreUpgrade_HeadStruct Head;
 	Buffer_Struct ReadBuffer;
 	CBFuncEx_t pReadFunc;
 	PV_Union uPV, uPin;
 	uint32_t Check;
-	uint32_t DoneLen;
+	uint32_t DoneLen, ReadLen;
+	volatile uint32_t ProgramPos, FlashPos;
 	int32_t Result;
 	uint8_t Reboot = 0;
+	uint32_t LzmaDataLen;
+	uint8_t LzmaHead[LZMA_PROPS_SIZE + 8];
+	uint8_t LzmaHeadLen;
 	OS_InitBuffer(&ReadBuffer, FW_OTA_FLASH_BUF_LEN);
+
 	memcpy(&Head, __FLASH_OTA_INFO_ADDR__, sizeof(CoreUpgrade_HeadStruct));
 	Check = CRC32_Cal(CRC32_Table, &Head.Param1, sizeof(Head) - 8, 0xffffffff);
 	if (Head.MaigcNum != __APP_START_MAGIC__)
@@ -498,10 +472,6 @@ void Remote_Upgrade(void)
 		SPI_DMATxInit(prvSPIFlash.SpiID, FLASH_SPI_TX_DMA_STREAM, 0);
 		SPI_DMARxInit(prvSPIFlash.SpiID, FLASH_SPI_RX_DMA_STREAM, 0);
 		SPIFlash_Init(&prvSPIFlash, NULL);
-		prvBL.CurSPIFlashStart = Head.DataStartAddress;
-		prvBL.NextSPIFlashStart = Head.DataStartAddress + FW_OTA_FLASH_BUF_LEN;
-		prvBL.CurSPIFlashData = NULL;
-		prvBL.NextSPIFlashData = NULL;
 		pReadFunc = BL_OTAReadDataInSpiFlash;
 		DoneLen = 0;
 		Check = 0xffffffff;
@@ -532,49 +502,85 @@ void Remote_Upgrade(void)
 		break;
 	}
 
-	switch(uPV.u8[0])
-	{
-	case CORE_OTA_MODE_FULL:
-		goto OTA_FULL;
-		break;
-	default:
-		DBG_INFO("core ota mode %u not support", uPV.u8[0]);
-		return;
-		break;
-	}
-	goto OTA_END;
-OTA_FULL:
 	DoneLen = 0;
+
 	while(DoneLen < Head.DataLen)
 	{
-		ReadBuffer.Pos = ((Head.DataLen - DoneLen) > ReadBuffer.MaxLen)?ReadBuffer.MaxLen:(Head.DataLen - DoneLen);
+		ReadBuffer.Pos = sizeof(CoreUpgrade_SectorStruct);
+
 		Result = pReadFunc(Head.DataStartAddress + DoneLen, &ReadBuffer);
-		if (Result < 0)
+		DoneLen += sizeof(CoreUpgrade_SectorStruct);
+		memcpy(&Sector, ReadBuffer.Data, sizeof(CoreUpgrade_SectorStruct));
+		if (Sector.MaigcNum != __APP_START_MAGIC__)
 		{
-			Reboot = 1;
-			DBG_INFO("core ota read data fail");
+			DBG_INFO("ota sector info error %x", Sector.MaigcNum);
 			goto OTA_END;
 		}
-		if (memcmp(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Data, ReadBuffer.Pos))
+		ProgramPos = Sector.StartAddress;
+		FlashPos = DoneLen + Head.DataStartAddress;
+		DoneLen += Sector.TotalLen;
+//		CRC32_CreateTable(CRC32_Table, CRC32_GEN);
+		if (Sector.DataLen && (Sector.DataLen != Sector.TotalLen))
 		{
-			DBG_INFO("ota %x", __FLASH_APP_START_ADDR__ + DoneLen);
-			BL_OTAErase(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Pos);
-			BL_OTAWrite(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Data, ReadBuffer.Pos);
+			ReadLen = 0;
+			while(ReadLen < Sector.TotalLen)
+			{
+				DBG_INFO("ota %x,%x,%u,%u", ProgramPos, FlashPos, ReadLen, Sector.TotalLen);
+				Flash_EraseStart(ProgramPos, 1);
+				ReadBuffer.Pos = 1;
+				pReadFunc(FlashPos, &ReadBuffer);
+				FlashPos += ReadBuffer.Pos;
+				ReadLen += ReadBuffer.Pos;
+				LzmaHeadLen = ReadBuffer.Data[0];
+				if (LzmaHeadLen > sizeof(LzmaHead))
+				{
+					Reboot = 1;
+					DBG_INFO("ota zip head error");
+					goto OTA_END;
+				}
+				ReadBuffer.Pos = LzmaHeadLen + 4;
+				pReadFunc(FlashPos, &ReadBuffer);
+				FlashPos += ReadBuffer.Pos;
+				ReadLen += ReadBuffer.Pos;
+				memcpy(LzmaHead, ReadBuffer.Data, LzmaHeadLen);
+				memcpy(&LzmaDataLen, ReadBuffer.Data + LzmaHeadLen, 4);
+				ReadBuffer.Pos = LzmaDataLen;
+				pReadFunc(FlashPos, &ReadBuffer);
+				FlashPos += ReadBuffer.Pos;
+				ReadLen += ReadBuffer.Pos;
+
+				prvBL.FWDataBuffer.Pos = __FLASH_BLOCK_SIZE__;
+				Result = LzmaUncompress(prvBL.FWDataBuffer.Data, &prvBL.FWDataBuffer.Pos, ReadBuffer.Data, &LzmaDataLen, LzmaHead, LzmaHeadLen);
+				while(Flash_CheckBusy()){;}
+				Flash_Program(ProgramPos, prvBL.FWDataBuffer.Data, prvBL.FWDataBuffer.Pos);
+				WDT_Feed();
+				ProgramPos += __FLASH_BLOCK_SIZE__;
+
+			}
 			CACHE_CleanAll(CACHE);
-			WDT_Feed();
+			Check = CRC32_Cal(CRC32_Table, Sector.StartAddress, Sector.DataLen, 0xffffffff);
+			DBG_INFO("%08x,%08x", Check, Sector.DataCRC32);
+			if (Sector.DataCRC32 != Check)
+			{
+//				Reboot = 1;
+				DBG_INFO("ota final check crc32 fail %x %x", Check, Sector.DataCRC32);
+				goto OTA_END;
+			}
 		}
-		DoneLen += ReadBuffer.Pos;
-	}
-	Check = CRC32_Cal(CRC32_Table, __FLASH_APP_START_ADDR__, Head.DataLen, 0xffffffff);
-	if (Head.DataCRC32 != Check)
-	{
-		Reboot = 1;
-		DBG_INFO("core ota final check crc32 fail %x %x", Check, Head.DataCRC32);
-		goto OTA_END;
+		else
+		{
+			DBG_INFO("fota file must zip file!!!");
+			goto OTA_END;
+		}
+
+
+
+
+
+
 	}
-	goto OTA_END;
-OTA_DIFF:
-	goto OTA_END;
+
+
 OTA_END:
 	if (Reboot)
 	{

+ 22 - 0
bsp/common/include/bsp_common.h

@@ -40,6 +40,28 @@ typedef struct
 	char FilePath[100];//升级包在文件系统中的绝对路径,如果在flash中则随意填写
 }CoreUpgrade_HeadStruct;
 
+typedef struct
+{
+	uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
+	uint32_t CRC32;		//后续字节的CRC32校验
+	uint32_t MainVersion;//目标的底层版本,升级成功的话就是这个版本号了
+	uint32_t AppVersion;//整包的版本号
+	uint32_t STDVersion;//允许升级的底层版本号
+	uint32_t DataLen;//升级包大小
+	uint32_t DataCRC32;//升级包整包数据的CRC32,这里验证传输的准确性
+}CoreUpgrade_FileHeadStruct;
+
+typedef struct
+{
+	uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
+	uint32_t TotalLen;	//解压前占据的空间
+	uint32_t DataLen;	//解压后占据的空间,如果和TotalLen一样,则表示未启用压缩,不需要解压,也没有压缩参数
+						//如果是0,则表示是差分升级
+						//其他表示是整包升级,数据包经过了lzma压缩
+	uint32_t DataCRC32;	//解压后的数据的CRC32,这里验证烧录的正确性
+	uint32_t StartAddress;	//烧写的起始地址
+}CoreUpgrade_SectorStruct;
+
 typedef struct
 {
 	uint32_t param_max_num;

+ 6 - 0
bsp/common/include/core_service.h

@@ -84,4 +84,10 @@ uint32_t Core_VHIDRxBufferRead(uint8_t USB_ID, uint8_t *Data, uint32_t Len);
 void Core_UDiskAttachSDHC(uint8_t USB_ID, void *pCtrl);
 void Core_UDiskDetachSDHC(uint8_t USB_ID, void *pCtrl);
 void Core_UDiskAttachSDHCRecovery(uint8_t USB_ID, void *pCtrl);
+
+int Core_OTAInit(CoreUpgrade_HeadStruct *Head, uint32_t size);
+int Core_OTAWrite(uint8_t *Data, uint32_t Len);
+uint8_t Core_OTACheckReadyStart(void);
+int Core_OTACheckDone(void);
+void Core_OTAEnd(uint8_t isOK);
 #endif

+ 0 - 1
bsp/common/include/platform_define.h

@@ -73,7 +73,6 @@ enum
 	CORE_OTA_OUT_SPI_FLASH,
 	CORE_OTA_IN_FILE,
 
-
 };
 
 enum

+ 336 - 1
bsp/common/src/core_service.c

@@ -20,7 +20,7 @@
  */
 
 #include "user.h"
-
+#include "LzmaLib.h"
 #ifdef __BUILD_OS__
 #include "zbar.h"
 #include "symbol.h"
@@ -42,7 +42,9 @@ enum
 	SERVICE_LCD_DRAW = SERVICE_EVENT_ID_START + 1,
 	SERVICE_CAMERA_DRAW,
 	SERVICE_SDHC_WRITE,
+	SERVICE_SPIFLASH_ERASE,
 	SERVICE_SPIFLASH_WRITE,
+	SERVICE_SPIFLASH_CLOSE,
 	SERVICE_DECODE_QR,
 	SERVICE_SCAN_KEYBOARD,
 	SERVICE_ENCODE_JPEG_START,
@@ -55,6 +57,8 @@ typedef struct
 {
 	tje_write_func *JPEGEncodeWriteFun;
 	void *JPEGEncodeWriteParam;
+	CoreUpgrade_HeadStruct *pFotaHead;
+	SPIFlash_CtrlStruct *pSpiFlash;
 	HANDLE LCDHandle;
 	HANDLE ServiceHandle;
 	HANDLE StorgeHandle;
@@ -63,9 +67,16 @@ typedef struct
 	uint64_t LCDDrawDoneByte;
 	uint32_t InitAllocMem;
 	uint32_t LastAllocMem;
+	uint32_t CRC32_Table[256];
+	Buffer_Struct FotaDataBuf;
+	uint32_t FotaPos;
+	uint32_t FotaDoneLen;
+	uint32_t FotaCRC32;
 	uint8_t RFix;
 	uint8_t GFix;
 	uint8_t BFix;
+	uint8_t FotaFindHead;
+	uint8_t FotaReady;
 }Service_CtrlStruct;
 
 static Service_CtrlStruct prvService;
@@ -221,6 +232,7 @@ static void prvStorge_Task(void* params)
 	OS_EVENT Event;
 	uint32_t *Param;
 	SDHC_SPICtrlStruct *pSDHC;
+	CommonFun_t CB;
 	while(1)
 	{
 		Task_GetEventByMS(prvService.StorgeHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
@@ -240,6 +252,30 @@ static void prvStorge_Task(void* params)
 			free(Event.Param2);
 			free(Event.Param3);
 			break;
+		case SERVICE_SPIFLASH_ERASE:
+			if (prvService.pSpiFlash)
+			{
+				SPIFlash_Erase(prvService.pSpiFlash, Event.Param1, Event.Param2);
+			}
+			if (Event.Param3)
+			{
+				CB = (CommonFun_t )Event.Param3;
+				CB();
+			}
+			break;
+		case SERVICE_SPIFLASH_WRITE:
+			if (prvService.pSpiFlash)
+			{
+				SPIFlash_Write(prvService.pSpiFlash, Event.Param1, Event.Param2, Event.Param3);
+				prvService.FotaCRC32 = CRC32_Cal(prvService.CRC32_Table, Event.Param2, Event.Param3, prvService.FotaCRC32);
+				prvService.FotaDoneLen += Event.Param3;
+			}
+			free(Event.Param2);
+			break;
+		case SERVICE_SPIFLASH_CLOSE:
+			free(prvService.pSpiFlash);
+			prvService.pSpiFlash = NULL;
+			break;
 		}
 	}
 }
@@ -589,6 +625,304 @@ void Core_DebugMem(uint8_t HeapID, const char *FuncName, uint32_t Line)
 	}
 }
 
+static void Core_OTAReady(void)
+{
+	prvService.FotaReady = 1;
+}
+
+int Core_OTAInit(CoreUpgrade_HeadStruct *Head, uint32_t size)
+{
+	prvService.FotaReady = 0;
+	PV_Union uPV;
+	Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
+	if (prvService.pFotaHead)
+	{
+		free(prvService.pFotaHead);
+	}
+	prvService.pFotaHead = Head;
+	OS_ReInitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
+	prvService.FotaPos = 0;
+	uPV.u32 = prvService.pFotaHead->Param1;
+	if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
+	{
+		if (prvService.pSpiFlash)
+		{
+			free(prvService.pSpiFlash);
+		}
+	}
+	prvService.FotaCRC32 = 0xffffffff;
+	prvService.FotaPos = 0;
+	prvService.FotaDoneLen = 0;
+	prvService.FotaFindHead = 0;
+	if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
+	{
+		prvService.pSpiFlash = zalloc(sizeof(SPIFlash_CtrlStruct));
+		prvService.pSpiFlash->SpiID = uPV.u8[2];
+		uPV.u32 = prvService.pFotaHead->Param2;
+		prvService.pSpiFlash->CSPin = uPV.u8[3];
+		prvService.pSpiFlash->IsBlockMode = 1;
+		SPIFlash_Init(prvService.pSpiFlash, NULL);
+		if (!prvService.pSpiFlash->IsInit)
+		{
+			return -1;
+		}
+		Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_ERASE, prvService.pFotaHead->DataStartAddress, size, Core_OTAReady);
+	}
+	return 0;
+}
+
+int Core_OTAWrite(uint8_t *Data, uint32_t Len)
+{
+	if (!prvService.FotaFindHead)
+	{
+		if (Len < sizeof(CoreUpgrade_FileHeadStruct))
+		{
+			return -1;
+		}
+		CoreUpgrade_FileHeadStruct Head;
+		memcpy(&Head, Data, sizeof(CoreUpgrade_FileHeadStruct));
+
+		if (Head.MaigcNum != __APP_START_MAGIC__)
+		{
+			DBG("%x", Head.MaigcNum);
+			return -1;
+		}
+		uint32_t crc32 = CRC32_Cal(prvService.CRC32_Table, &Head.MainVersion, sizeof(CoreUpgrade_FileHeadStruct) - 8, 0xffffffff);
+		if (crc32 != Head.CRC32)
+		{
+			DBG("crc32 %x,%x", crc32, Head.CRC32);
+			return -1;
+		}
+		//由于是整包升级,就不考虑版本的事情了
+		prvService.FotaFindHead = 1;
+		prvService.pFotaHead->DataLen = Head.DataLen;
+		prvService.pFotaHead->DataCRC32 = Head.DataCRC32;
+		prvService.pFotaHead->CRC32 = CRC32_Cal(prvService.CRC32_Table, &prvService.pFotaHead->Param1, sizeof(CoreUpgrade_HeadStruct) - 8, 0xffffffff);
+		Data = Data + sizeof(CoreUpgrade_FileHeadStruct);
+		Len -= sizeof(CoreUpgrade_FileHeadStruct);
+		if (!Len) return 0;
+	}
+	uint32_t DummyLen;
+	PV_Union uPV;
+	uPV.u32 = prvService.pFotaHead->Param1;
+	if (!prvService.pFotaHead )
+	{
+		return -1;
+	}
+	switch(uPV.u8[1])
+	{
+	case CORE_OTA_IN_FLASH:
+		break;
+	case CORE_OTA_OUT_SPI_FLASH:
+		if (!prvService.pSpiFlash)
+		{
+			return -1;
+		}
+		break;
+	case CORE_OTA_IN_FILE:
+		break;
+	}
+
+	DummyLen = ((prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos) >= Len)?Len:(prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos);
+	OS_BufferWrite(&prvService.FotaDataBuf, Data, DummyLen);
+	if (prvService.FotaDataBuf.Pos == __FLASH_BLOCK_SIZE__)
+	{
+		switch(uPV.u8[1])
+		{
+		case CORE_OTA_IN_FLASH:
+			prvService.FotaDataBuf.Pos = 0;
+			prvService.FotaDoneLen += __FLASH_BLOCK_SIZE__;
+			break;
+		case CORE_OTA_OUT_SPI_FLASH:
+			Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, __FLASH_BLOCK_SIZE__);
+			OS_InitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
+			break;
+		case CORE_OTA_IN_FILE:
+			prvService.FotaDataBuf.Pos = 0;
+			prvService.FotaDoneLen += __FLASH_BLOCK_SIZE__;
+			break;
+		}
+		prvService.FotaPos += __FLASH_BLOCK_SIZE__;
+	}
+	else if ((prvService.FotaPos + prvService.FotaDataBuf.Pos) >= prvService.pFotaHead->DataLen)
+	{
+//		DBG("all data rx");
+		switch(uPV.u8[1])
+		{
+		case CORE_OTA_IN_FLASH:
+			prvService.FotaDoneLen += prvService.FotaDataBuf.Pos;
+			OS_DeInitBuffer(&prvService.FotaDataBuf);
+			break;
+		case CORE_OTA_OUT_SPI_FLASH:
+			Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
+			memset(&prvService.FotaDataBuf, 0, sizeof(prvService.FotaDataBuf));
+			break;
+		case CORE_OTA_IN_FILE:
+			prvService.FotaDoneLen += prvService.FotaDataBuf.Pos;
+			OS_DeInitBuffer(&prvService.FotaDataBuf);
+			break;
+		}
+		return 0;
+	}
+	if (DummyLen < Len)
+	{
+		OS_BufferWrite(&prvService.FotaDataBuf, Data + DummyLen, Len - DummyLen);
+	}
+
+	if (prvService.FotaDoneLen < prvService.FotaPos)
+	{
+		return (prvService.FotaPos - prvService.FotaDoneLen);
+	}
+
+	return 1;
+}
+
+uint8_t Core_OTACheckReadyStart(void)
+{
+	return prvService.FotaReady;
+}
+
+int Core_OTACheckDone(void)
+{
+	if (!prvService.pFotaHead )
+	{
+		return -1;
+	}
+	if (prvService.FotaDoneLen >= prvService.pFotaHead->DataLen)
+	{
+		return (prvService.FotaCRC32 == prvService.pFotaHead->DataCRC32)?0:-1;
+	}
+	return 1;
+}
+
+//static void Core_OTACheckSpiFlash(void)
+//{
+//	CoreUpgrade_SectorStruct Sector;
+//	Buffer_Struct ReadBuffer;
+//	Buffer_Struct DataBuffer;
+//	int result;
+//	uint32_t Check;
+//	uint32_t DoneLen, ReadLen;
+//	volatile uint32_t ProgramPos, FlashPos;
+//	uint32_t LzmaDataLen;
+//	uint8_t LzmaHead[LZMA_PROPS_SIZE + 8];
+//	uint8_t LzmaHeadLen;
+//
+//	DoneLen = 0;
+//	OS_InitBuffer(&DataBuffer, SPI_FLASH_BLOCK_SIZE);
+//	OS_InitBuffer(&ReadBuffer, SPI_FLASH_BLOCK_SIZE);
+//	while(DoneLen < prvService.pFotaHead->DataLen)
+//	{
+//		ReadBuffer.Pos = sizeof(CoreUpgrade_SectorStruct);
+//		SPIFlash_Read(prvService.pSpiFlash, prvService.pFotaHead->DataStartAddress + DoneLen, ReadBuffer.Data, ReadBuffer.Pos, 1);
+//		DoneLen += sizeof(CoreUpgrade_SectorStruct);
+//		memcpy(&Sector, ReadBuffer.Data, sizeof(CoreUpgrade_SectorStruct));
+//		DBG("%x,%x,%x,%x,%x", Sector.MaigcNum, Sector.StartAddress, Sector.TotalLen, Sector.DataLen, Sector.DataCRC32);
+//		if (Sector.MaigcNum != __APP_START_MAGIC__)
+//		{
+//			DBG("ota sector info error %x", Sector.MaigcNum);
+//			return;
+//		}
+//		ProgramPos = Sector.StartAddress;
+//		FlashPos = DoneLen + prvService.pFotaHead->DataStartAddress;
+//		DoneLen += Sector.TotalLen;
+//
+//		Check = 0xffffffff;
+//		ReadLen = 0;
+//		while(ReadLen < Sector.TotalLen)
+//		{
+//			DBG("ota %x,%x,%u,%u", ProgramPos, FlashPos, ReadLen, Sector.TotalLen);
+//			ReadBuffer.Pos = 1;
+//			SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
+//			FlashPos += ReadBuffer.Pos;
+//			ReadLen += ReadBuffer.Pos;
+//			LzmaHeadLen = ReadBuffer.Data[0];
+//			if (LzmaHeadLen > sizeof(LzmaHead))
+//			{
+//				DBG("ota zip head error");
+//				return;
+//			}
+//			ReadBuffer.Pos = LzmaHeadLen + 4;
+//			SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
+//			FlashPos += ReadBuffer.Pos;
+//			ReadLen += ReadBuffer.Pos;
+//			memcpy(LzmaHead, ReadBuffer.Data, LzmaHeadLen);
+//			memcpy(&LzmaDataLen, ReadBuffer.Data + LzmaHeadLen, 4);
+//			ReadBuffer.Pos = LzmaDataLen;
+//			SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
+//			FlashPos += ReadBuffer.Pos;
+//			ReadLen += ReadBuffer.Pos;
+//
+//			DataBuffer.Pos = __FLASH_BLOCK_SIZE__;
+//			result = LzmaUncompress(DataBuffer.Data, &DataBuffer.Pos, ReadBuffer.Data, &LzmaDataLen, LzmaHead, LzmaHeadLen);
+//			if (DataBuffer.Pos != __FLASH_BLOCK_SIZE__)
+//			{
+//				DataBuffer.Pos = Sector.DataLen - (ProgramPos - Sector.StartAddress);
+//			}
+//			Check = CRC32_Cal(prvService.CRC32_Table, DataBuffer.Data, DataBuffer.Pos, Check);
+//			ProgramPos += DataBuffer.Pos;
+//
+//		}
+//		DBG("%u, %u", ProgramPos - Sector.StartAddress, Sector.DataLen);
+//		if (Sector.DataCRC32 != Check)
+//		{
+////				Reboot = 1;
+//			DBG("ota %x check crc32 fail %x %x", Sector.StartAddress, Check, Sector.DataCRC32);
+//			return;
+//		}
+//		else
+//		{
+//			DBG("ota %x check ok", Sector.StartAddress);
+//		}
+//	}
+//	OS_DeInitBuffer(&DataBuffer);
+//	OS_DeInitBuffer(&ReadBuffer);
+//}
+
+void Core_OTAEnd(uint8_t isOK)
+{
+	PV_Union uPV;
+	uPV.u32 = prvService.pFotaHead->Param1;
+	if (isOK && prvService.pFotaHead)
+	{
+		Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
+		Flash_Program(__FLASH_OTA_INFO_ADDR__, prvService.pFotaHead, sizeof(CoreUpgrade_HeadStruct));
+		switch(uPV.u8[1])
+		{
+		case CORE_OTA_IN_FLASH:
+			break;
+		case CORE_OTA_OUT_SPI_FLASH:
+//			Core_OTACheckSpiFlash();
+
+			free(prvService.pSpiFlash);
+			prvService.pSpiFlash = NULL;
+			break;
+		case CORE_OTA_IN_FILE:
+			break;
+		}
+
+	}
+	else
+	{
+		switch(uPV.u8[1])
+		{
+		case CORE_OTA_IN_FLASH:
+			break;
+		case CORE_OTA_OUT_SPI_FLASH:
+			Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_CLOSE, 0, 0, 0);
+			break;
+		case CORE_OTA_IN_FILE:
+			break;
+		}
+	}
+	free(prvService.pFotaHead);
+	prvService.pFotaHead = NULL;
+	OS_DeInitBuffer(&prvService.FotaDataBuf);
+}
+
+
+
+
 void Core_LCDTaskInit(void)
 {
 	prvService.LCDHandle = Task_Create(prvLCD_Task, NULL, 2 * 1024, HW_TASK_PRO, "lcd task");
@@ -596,6 +930,7 @@ void Core_LCDTaskInit(void)
 
 void Core_ServiceInit(void)
 {
+	CRC32_CreateTable(prvService.CRC32_Table, CRC32_GEN);
 	prvService.ServiceHandle = Task_Create(prvService_Task, NULL, 4 * 1024, SERVICE_TASK_PRO, "service task");
 }
 

+ 1 - 0
bsp/device/include/dev_spiflash.h

@@ -80,6 +80,7 @@ typedef struct
 	uint8_t IsBlockMode;					//是否在擦读写操作时采用阻塞模式,如果是0,则需要调用SPIFlash_WaitOpDone来获取结果
 	uint8_t IsSpiDMAMode;
 	uint8_t CSPin;
+	uint8_t IsInit;
 }SPIFlash_CtrlStruct;
 
 

+ 8 - 3
bsp/device/src/dev_spiflash.c

@@ -140,9 +140,13 @@ __attribute__ ((aligned (8))) static char lfs_lookahead_buff[16];
 
 void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *LFSConfig)
 {
+	Ctrl->IsInit = 0;
 	Ctrl->State = SPIFLASH_STATE_IDLE;
-	SPIFlash_ID(Ctrl);
-
+	if (SPIFlash_ID(Ctrl) != ERROR_NONE)
+	{
+		return;
+	}
+	Ctrl->IsInit = 1;
 //用外部flash存储文件才需要开启
 #if 0
 	struct lfs_config *config = LFSConfig;
@@ -172,7 +176,7 @@ void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *LFSConfig)
 	Ctrl->EraseSectorWaitTime = 50;
 	Ctrl->EraseBlockWaitTime = 250;
 	Ctrl->ProgramWaitTimeUS = 300;
-	Ctrl->ProgramTime = 3;
+	Ctrl->ProgramTime = 10;
 	Ctrl->EraseSectorTime = 400;
 	Ctrl->EraseBlockTime = 2400;
 	SPIFlash_ReadSR(Ctrl);
@@ -187,6 +191,7 @@ void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *LFSConfig)
 			{
 				SPIFlash_ReadSR(Ctrl);
 			}
+
 		}
 	}
 

BIN
project/air105/soc_download.exe